Newer
Older
tgclient-mcp / frontend / src / pages / SettingsPage.vue
<script setup>
// Настройки: язык (override → PATCH /me; auth-off — localStorage) + health.
import { onMounted, ref } from 'vue'
import {
  GnAlert, GnCard, GnLoader, GnPageHeader, GnSelect,
} from 'gnexus-ui-kit/vue'
import { useToast } from 'gnexus-ui-kit/vue'

import { api } from '../api.js'
import { locale, setLocale, t } from '../i18n/index.js'

const toast = useToast()

const me = ref(null)
const health = ref(null)
const loading = ref(true)
const error = ref('')

const meLocale = ref('')

// Язык родными именами (каждое само на своём языке — как в хендбуке i18n)
const localeOptions = [
  { value: 'ru', label: 'Русский' },
  { value: 'uk', label: 'Українська' },
  { value: 'en', label: 'English' },
]

async function load() {
  try {
    me.value = await api.me()
    health.value = await api.health()
    if (me.value.auth_enabled && me.value.user) {
      meLocale.value = me.value.user.locale || me.value.locale_effective || ''
    } else {
      meLocale.value = localStorage.getItem('tgclient.locale') || ''
    }
  } catch (e) {
    error.value = e.message
    failed.value = true
  } finally {
    loading.value = false
  }
}

onMounted(load)

async function saveLocale(value) {
  if (!value) return
  try {
    if (me.value?.auth_enabled && me.value?.user) {
      const updated = await api.updateMe({ locale: value || 'auto' })
      setLocale(updated.locale_effective)
    } else {
      // auth-off / открытый режим: язык живёт в этом браузере
      localStorage.setItem('tgclient.locale', value)
      setLocale(value)
    }
    toast.success({ title: t('settings.localeSaved') })
    load()
  } catch (e) {
    if (e.status !== 401) toast.danger({ title: t('common.failed'), text: e.message })
  }
}
</script>

<template>
  <GnPageHeader :title="t('settings.title')" kicker="tgclient" />

  <GnLoader v-if="loading" circle :label="t('common.loading')" />
  <GnAlert v-else-if="error" variant="danger" style="margin-bottom: 16px">{{ error }}</GnAlert>

  <template v-else>
    <GnCard :title="t('settings.locale')" class="gap-card">
      <p class="card-note">{{ t('settings.localeOff') }} — «auto»</p>
      <p class="settings-locale">{{ t('settings.locale') }}: <strong>{{ locale === 'en' ? 'English' : locale === 'ru' ? 'Русский' : 'Українська' }}</strong></p>
      <div class="locale-row">
        <GnSelect
          :options="localeOptions"
          :model-value="meLocale"
          :label="t('settings.locale')"
          @update:model-value="saveLocale"
        />
      </div>
    </GnCard>

    <GnCard v-if="health" :title="t('settings.statusTitle')" class="gap-card">
      <p class="card-note">
        <strong>{{ t('settings.statusVersion') }}:</strong> {{ health.version }}
      </p>
      <p class="card-note">
        <strong>{{ t('settings.statusAccounts') }}:</strong>
        {{ health.accounts?.active }} / {{ health.accounts?.connected }} / {{ health.accounts?.pending_logins }}
      </p>
      <p class="card-note"><strong>{{ t('settings.statusDb') }}:</strong> {{ health.db }}</p>
    </GnCard>
  </template>
</template>

<style scoped>
/* GnCard по умолчанию — fit-content; страницы тянут карты на всю ширину */
.gap-card {
  max-width: none;
  width: 100%;
  margin-top: 20px;
}
.card-note {
  margin: 0 0 8px;
  opacity: 0.75;
  font-size: 14px;
}
.settings-locale {
  margin: 0 0 8px;
  font-size: 15px;
}
.locale-row {
  max-width: 320px;
}
</style>