import type { DashboardBackground } from '@tessera/shared'; import { create } from 'zustand'; import { readableOnAccent } from '@/lib/color'; export interface AuthUser { id: string; username: string; displayName: string | null; role: 'SUPER_ADMIN' | 'ADMIN' | 'USER'; tenantId: string; hasAvatar?: boolean; accentColor?: string | null; /** quick-260928-ujj: Dashboard-Hintergrund aus der Sitzungsantwort; null = nie gewaehlt. */ dashboardBackground?: DashboardBackground | 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; // Design „Mosaik“: die persoenliche Akzentfarbe setzt nur noch `--primary` // (Hauptknoepfe, Auswahlpille der Seitenleiste, Reiter-Unterstrich, Logo). // Fokusring und Auswahlflaeche der Seitenleiste bleiben neutral — eine // helle Akzentfarbe (Standard Gelb) waere als Fokusring auf Weiss kaum // sichtbar (1,3:1). Alte Werte frueherer Fassungen werden entfernt. root.style.removeProperty('--ring'); root.style.removeProperty('--sidebar-accent'); root.style.removeProperty('--sidebar-accent-foreground'); if (color) { root.style.setProperty('--primary', color); // Schrift auf der Akzentflaeche: hell oder dunkel, je nach Kontrast. root.style.setProperty('--primary-foreground', readableOnAccent(color)); } else { root.style.removeProperty('--primary'); root.style.removeProperty('--primary-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 })), }));