import { create } from 'zustand'; export interface AuthUser { id: string; username: string; displayName: string | null; role: 'SUPER_ADMIN' | 'ADMIN' | 'USER'; tenantId: string; hasAvatar?: boolean; accentColor?: string | null; } interface AuthState { user: AuthUser | null; avatarVersion: number; setUser: (user: AuthUser) => void; clearUser: () => void; bumpAvatarVersion: () => void; } function applyAccentColor(color: string | null | undefined) { if (typeof document === 'undefined') return; const root = document.documentElement; if (color) { root.style.setProperty('--primary', color); root.style.setProperty('--ring', color); // Sidebar active state: accent color with 15% opacity (#rrggbbaa, 0x26 ≈ 15%) root.style.setProperty('--sidebar-accent', `${color}26`); // Full-saturation accent text only reads well against the dark-mode sidebar's // tinted-dark background; in light mode it's near-white behind it, so keep // the theme's default (dark, high-contrast) foreground there instead. if (root.classList.contains('dark')) { root.style.setProperty('--sidebar-accent-foreground', color); } else { root.style.removeProperty('--sidebar-accent-foreground'); } } else { root.style.removeProperty('--primary'); root.style.removeProperty('--ring'); root.style.removeProperty('--sidebar-accent'); root.style.removeProperty('--sidebar-accent-foreground'); } } /** * Zustand store for client-side auth state. * No persist middleware -- user state comes from API, not localStorage. * Populated on portal load via fetchCurrentUser(). */ export const useAuthStore = create()((set) => ({ user: null, avatarVersion: 0, setUser: (user) => { applyAccentColor(user.accentColor); set({ user }); }, clearUser: () => set({ user: null }), bumpAvatarVersion: () => set((s) => ({ avatarVersion: s.avatarVersion + 1 })), }));