70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import { create } from 'zustand';
|
|
import { persist } from 'zustand/middleware';
|
|
|
|
export type Locale = 'cs' | 'en';
|
|
|
|
type LanguageState = {
|
|
locale: Locale;
|
|
setLocale: (locale: Locale) => void;
|
|
};
|
|
|
|
const LOCALE_COOKIE = 'locale';
|
|
|
|
function detectInitialLocale(): Locale {
|
|
if (typeof document !== 'undefined') {
|
|
// 1) cookie
|
|
const cookieMatch = document.cookie
|
|
.split('; ')
|
|
.find((row) => row.startsWith(`${LOCALE_COOKIE}=`));
|
|
if (cookieMatch) {
|
|
const value = cookieMatch.split('=')[1];
|
|
if (value === 'cs' || value === 'en') return value;
|
|
}
|
|
|
|
// 2) <html lang="...">
|
|
const htmlLang = document.documentElement.lang;
|
|
if (htmlLang.startsWith('cs')) return 'cs';
|
|
if (htmlLang.startsWith('en')) return 'en';
|
|
}
|
|
|
|
return 'cs';
|
|
}
|
|
|
|
function setLocaleCookie(locale: Locale) {
|
|
const expires = new Date();
|
|
expires.setFullYear(expires.getFullYear() + 1);
|
|
|
|
document.cookie = [
|
|
`${LOCALE_COOKIE}=${encodeURIComponent(locale)}`,
|
|
`expires=${expires.toUTCString()}`,
|
|
'path=/',
|
|
'SameSite=Lax',
|
|
].join('; ');
|
|
}
|
|
|
|
export const useLanguageStore = create<LanguageState>()(
|
|
persist(
|
|
(set) => ({
|
|
locale: detectInitialLocale(),
|
|
setLocale: (locale) => {
|
|
set({ locale });
|
|
|
|
// sync s DOM a Laravel
|
|
if (typeof document !== 'undefined') {
|
|
document.documentElement.lang = locale;
|
|
setLocaleCookie(locale);
|
|
}
|
|
},
|
|
}),
|
|
{
|
|
name: 'language-store',
|
|
partialize: (state) => ({ locale: state.locale }),
|
|
}
|
|
)
|
|
);
|
|
|
|
// Použití:
|
|
// import { useLanguageStore } from '@/stores/languageStore';
|
|
// const locale = useLanguageStore((s) => s.locale);
|
|
// const setLocale = useLanguageStore((s) => s.setLocale);
|