Files
tgCrewAdmin/src/stores/settings.ts
2025-08-02 11:20:01 +03:00

128 lines
3.3 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref, watch, computed, inject } from 'vue'
import { api } from 'boot/axios'
import { useAuthStore } from 'stores/auth'
import { useI18n } from 'vue-i18n'
import type { WebApp } from '@twa-dev/types'
interface AppSettings {
fontSize: number
locale: string
timeZoneBot: { tz: string, offset: number, offsetString: string }
localeBot: string
}
const defaultFontSize = 16
const defaultSettings: AppSettings = {
fontSize: defaultFontSize,
locale: 'en-US',
timeZoneBot: { tz: 'Europe/Moscow', offset: 3, offsetString: '+03:00' },
localeBot: 'en-US'
}
export const useSettingsStore = defineStore('settings', () => {
const { locale: i18nLocale } = useI18n()
const authStore = useAuthStore()
const settings = ref<AppSettings>({ ...defaultSettings })
const tg = inject<WebApp>('tg')
const isInit = ref(false)
const currentFontSize = computed(() => settings.value?.fontSize ?? defaultFontSize)
const supportLocale = [
{ value: 'en-US', label: 'English' },
{ value: 'ru-RU', label: 'Русский' }
]
const supportFontSizes = [
{ value: 12, label: 'settings__fontsize_small' },
{ value: 16, label: 'settings__fontsize_medium' },
{ value: 20, label: 'settings__fontsize_large' }
]
const detectLocale = (): string => {
const localeMap = {
ru: 'ru-RU',
en: 'en-US'
} as const satisfies Record<string, string>
type LocaleCode = keyof typeof localeMap
const normLocale = (locale?: string): string | undefined => {
if (!locale) return undefined
const code = locale.split('-')[0] as LocaleCode
return localeMap[code] ?? undefined
}
const tgLang = tg?.initDataUnsafe?.user?.language_code
const normalizedTgLang = normLocale(tgLang)
return normalizedTgLang ?? normLocale(navigator.language) ?? 'en-US'
}
const updateCssVariable = () => {
document.documentElement.style.setProperty(
'--dynamic-font-size',
`${currentFontSize.value}px`
)
}
const applyLocale = () => {
if (settings.value.locale && i18nLocale) {
i18nLocale.value = settings.value.locale
}
}
const init = async () => {
if (authStore.isAuth) {
try {
const { data } = await api.get('/customer/settings')
settings.value = {
fontSize: data.data.fontSize || defaultSettings.fontSize,
locale: data.data.locale || detectLocale(),
timeZoneBot: data.data.timeZone || defaultSettings.timeZoneBot,
localeBot: data.data.localeBot || detectLocale()
}
} catch {
settings.value.locale = detectLocale()
}
} else {
settings.value = {
...defaultSettings,
locale: detectLocale()
}
}
updateCssVariable()
applyLocale()
isInit.value = true
}
const saveSettings = async () => {
await api.put('/customer/settings', settings.value)
}
const updateSettings = async (newSettings: Partial<AppSettings>) => {
settings.value = { ...settings.value, ...newSettings }
updateCssVariable()
applyLocale()
await saveSettings()
}
watch(() => authStore.isAuth, (newVal) => {
if (newVal !== undefined) void init()
}, { immediate: true })
return {
settings,
supportLocale,
supportFontSizes,
isInit,
currentFontSize,
init,
updateSettings
}
})