<script setup>
import { computed, onMounted, ref } from 'vue'
import { GnAlert, GnCard, GnSelect, GnSkeleton, GnToolbar } 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'
// Первый блок настроек — язык интерфейса. Страница самодостаточна: сама
// запрашивает /me и сама пишет override (PATCH /me при живой сессии либо
// localStorage в открытом режиме).
const toast = useToast()
const me = ref(null) // ответ GET /me целиком
const loadError = ref('')
const loading = ref(true)
// Опции — computed, а не module-level константа: label из t() должен
// перерисовываться при смене языка.
const LANGS = computed(() => [
{ value: 'en', label: t('profile.langEn') },
{ value: 'uk', label: t('profile.langUk') },
{ value: 'ru', label: t('profile.langRu') },
])
const localeOptions = computed(() =>
me.value?.user
? [{ value: '', label: t('profile.languageAuto') }, ...LANGS.value]
: LANGS.value, // открыта без акаунта: авто нет — есть только явный выбор
)
const currentLocale = computed(() =>
me.value?.user ? (me.value.locale || '') : locale.value,
)
const description = computed(() =>
me.value?.user ? t('settings.languageDescription') : t('settings.languageDescriptionOpen'),
)
async function changeLanguage(value) {
if (!me.value?.user) {
// открыта без акаунта: выбор живёт в этом браузере (localStorage)
localStorage.setItem('ghhard.locale', value || 'en')
setLocale(value)
toast.success({ title: t('settings.languageSaved') })
return
}
try {
// '' → 'auto': пустая строка сбрасывает override на бэкенде
const updated = await api.updateMe({ locale: value || 'auto' })
me.value = updated
setLocale(updated.locale_effective)
toast.success({ title: t('settings.languageSaved') })
} catch (err) {
toast.danger({ title: t('common.error'), text: err.message })
}
}
onMounted(async () => {
try {
me.value = await api.me()
if (me.value.auth_enabled && me.value.user) {
setLocale(me.value.locale_effective)
} else {
me.value = null // режим без аутентификации — пикер с явным выбором
setLocale(localStorage.getItem('ghhard.locale'))
}
} catch (err) {
if (err?.status !== 401) loadError.value = err.message
// 401: api.js уже предупредил шлюз входа — страница откроется после входа
} finally {
loading.value = false
}
})
</script>
<template>
<GnPageHeader :title="t('settings.title')" kicker="GHard Monitor" />
<GnAlert v-if="loadError" variant="danger" style="margin-bottom: 16px">{{ loadError }}</GnAlert>
<div v-else-if="loading" style="margin-top: 20px"><GnSkeleton type="card" :count="1" /></div>
<!-- следующий блок настроек — сюда -->
<GnCard v-else class="settings-block">
<GnToolbar :title="t('settings.languageToolbar')" />
<p class="input-info">{{ description }}</p>
<div class="create-actions">
<GnSelect
class="language-select"
:model-value="currentLocale"
:options="localeOptions"
@update:model-value="changeLanguage"
/>
</div>
</GnCard>
</template>
<style scoped>
/* .create-actions нет в CSS кита — creds определяет его сам, сюда тоже */
.settings-block {
width: 100%;
max-width: none;
margin-top: 20px;
}
.create-actions {
display: flex;
justify-content: flex-start;
margin-top: 12px;
}
.create-actions .language-select {
flex: 0 1 320px;
min-width: 0;
}
</style>