rebase
This commit is contained in:
83
frontend/src/stores/uiStore.ts
Normal file
83
frontend/src/stores/uiStore.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { create } from "zustand";
|
||||
import type { Language } from "@/types";
|
||||
import i18n from "@/i18n";
|
||||
|
||||
type Theme = "dark" | "light";
|
||||
|
||||
interface UiState {
|
||||
theme: Theme;
|
||||
language: Language;
|
||||
sidebarOpen: boolean;
|
||||
setTheme: (theme: Theme) => void;
|
||||
toggleTheme: () => void;
|
||||
setLanguage: (lang: Language) => void;
|
||||
toggleSidebar: () => void;
|
||||
setSidebarOpen: (open: boolean) => void;
|
||||
}
|
||||
|
||||
function applyTheme(theme: Theme): void {
|
||||
const root = document.documentElement;
|
||||
if (theme === "dark") root.classList.add("dark");
|
||||
else root.classList.remove("dark");
|
||||
try {
|
||||
localStorage.setItem("airpg_theme", theme);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
function applyLanguage(lang: Language): void {
|
||||
void i18n.changeLanguage(lang);
|
||||
try {
|
||||
localStorage.setItem("airpg_lang", lang);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
function initialTheme(): Theme {
|
||||
try {
|
||||
const stored = localStorage.getItem("airpg_theme") as Theme | null;
|
||||
if (stored === "dark" || stored === "light") return stored;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
// Default: dark
|
||||
return "dark";
|
||||
}
|
||||
|
||||
function initialLanguage(): Language {
|
||||
const detected = i18n.language as Language | undefined;
|
||||
if (detected === "en" || detected === "ru") return detected;
|
||||
return "en";
|
||||
}
|
||||
|
||||
const initialThemeValue = initialTheme();
|
||||
applyTheme(initialThemeValue);
|
||||
const initialLangValue = initialLanguage();
|
||||
applyLanguage(initialLangValue);
|
||||
|
||||
export const useUiStore = create<UiState>((set, get) => ({
|
||||
theme: initialThemeValue,
|
||||
language: initialLangValue,
|
||||
sidebarOpen: false,
|
||||
|
||||
setTheme: (theme) => {
|
||||
applyTheme(theme);
|
||||
set({ theme });
|
||||
},
|
||||
|
||||
toggleTheme: () => {
|
||||
const next: Theme = get().theme === "dark" ? "light" : "dark";
|
||||
applyTheme(next);
|
||||
set({ theme: next });
|
||||
},
|
||||
|
||||
setLanguage: (lang) => {
|
||||
applyLanguage(lang);
|
||||
set({ language: lang });
|
||||
},
|
||||
|
||||
toggleSidebar: () => set({ sidebarOpen: !get().sidebarOpen }),
|
||||
setSidebarOpen: (open) => set({ sidebarOpen: open }),
|
||||
}));
|
||||
Reference in New Issue
Block a user