import { signal, computed } from '@preact/signals'; import { endpoints } from '../api/client'; import type { AuthLoginRequest, AuthLoginResponse, UserProfile } from '../api/types'; // Types export interface UserPreferences { theme: 'light' | 'dark' | 'auto'; sidebarCollapsed: boolean; panelHeight: number; defaultTeam: string; keyboardShortcutsEnabled: boolean; notificationsEnabled: boolean; } // Default preferences const DEFAULT_PREFERENCES: UserPreferences = { theme: 'auto', sidebarCollapsed: false, panelHeight: 280, defaultTeam: 'ui', keyboardShortcutsEnabled: true, notificationsEnabled: true }; // User State Signals export const user = signal(null); export const preferences = signal(DEFAULT_PREFERENCES); // Computed Values export const isAuthenticated = computed(() => user.value !== null); export const userId = computed(() => user.value?.id ?? 1); export const userName = computed(() => user.value?.display_name ?? user.value?.email ?? 'Guest'); export const userInitials = computed(() => { const name = user.value?.display_name ?? user.value?.email ?? 'Guest'; return name.split(' ').filter(Boolean).map(n => n[0]).join('').toUpperCase().slice(0, 2); }); // Actions export function loadUserPreferences(): void { if (typeof window === 'undefined') return; const saved = localStorage.getItem('dss-preferences'); if (saved) { try { const parsed = JSON.parse(saved); preferences.value = { ...DEFAULT_PREFERENCES, ...parsed }; } catch { preferences.value = DEFAULT_PREFERENCES; } } } export function saveUserPreferences(): void { if (typeof window === 'undefined') return; localStorage.setItem('dss-preferences', JSON.stringify(preferences.value)); } export function updatePreferences(updates: Partial): void { preferences.value = { ...preferences.value, ...updates }; saveUserPreferences(); } export function setUser(userData: UserProfile | null): void { user.value = userData; } export function logout(): void { user.value = null; localStorage.removeItem('dss-token'); } export async function refreshUser(): Promise { if (typeof window === 'undefined') return; const token = localStorage.getItem('dss-token'); if (!token) { user.value = null; return; } try { const profile = await endpoints.auth.me(); user.value = profile; } catch { // Token is invalid/expired; clear it. localStorage.removeItem('dss-token'); user.value = null; } } export async function loginWithAtlassian(credentials: AuthLoginRequest): Promise { const response = await endpoints.auth.login(credentials); localStorage.setItem('dss-token', response.token); // Prefer server truth; also supports older login response shapes. user.value = { id: response.user.id, email: response.user.email, display_name: response.user.display_name, atlassian_url: response.user.atlassian_url, atlassian_service: response.user.service, last_login: new Date().toISOString(), }; return response; } // Keyboard shortcuts state export const keyboardShortcutsEnabled = computed(() => preferences.value.keyboardShortcutsEnabled );