// Store UI — gère le thème (dark/light) et la position de la sidebar. // Les préférences sont persistées localement et synchronisées avec le serveur. import { defineStore } from 'pinia' import { ref } from 'vue' export type Theme = 'dark' | 'light' export type SidebarPosition = 'left' | 'right' export const useUiStore = defineStore('ui', () => { const theme = ref('dark') const sidebarPosition = ref('left') const sidebarCollapsed = ref(false) const mobileMenuOpen = ref(false) /** * Initialise le thème depuis les préférences locales. * Appelé au montage de App.vue. */ function initTheme(): void { const savedTheme = localStorage.getItem('pxp_theme') as Theme | null const savedSidebar = localStorage.getItem('pxp_sidebar') as SidebarPosition | null if (savedTheme === 'dark' || savedTheme === 'light') { theme.value = savedTheme } if (savedSidebar === 'left' || savedSidebar === 'right') { sidebarPosition.value = savedSidebar } applyTheme(theme.value) } /** * Bascule entre thème sombre et clair. */ function toggleTheme(): void { theme.value = theme.value === 'dark' ? 'light' : 'dark' localStorage.setItem('pxp_theme', theme.value) applyTheme(theme.value) } /** * Définit le thème explicitement. */ function setTheme(newTheme: Theme): void { theme.value = newTheme localStorage.setItem('pxp_theme', newTheme) applyTheme(newTheme) } /** * Définit la position de la sidebar. */ function setSidebarPosition(pos: SidebarPosition): void { sidebarPosition.value = pos localStorage.setItem('pxp_sidebar', pos) } /** * Bascule l'état réduit de la sidebar. */ function toggleSidebarCollapse(): void { sidebarCollapsed.value = !sidebarCollapsed.value } /** * Applique le thème sur l'élément via data-theme. */ function applyTheme(t: Theme): void { document.documentElement.setAttribute('data-theme', t) } return { theme, sidebarPosition, sidebarCollapsed, mobileMenuOpen, initTheme, toggleTheme, setTheme, setSidebarPosition, toggleSidebarCollapse, } })