import { create } from 'zustand'; import { persist } from 'zustand/middleware'; type UserRole = 'user' | 'admin' | 'super_admin'; interface User { id: string; email: string; name: string; role: UserRole; avatar_url?: string; } export interface Job { id: string; module: string; status: string; progress: number; created_at: string; completed_at?: string; output_asset_ids?: string[]; error_message?: string; input_data?: Record; api_provider?: string; api_model?: string; } interface Asset { id: string; original_filename: string; file_type: string; mime_type: string; file_size_bytes: number; created_at: string; } interface AppState { user: User | null; token: string | null; activeJobs: Job[]; recentAssets: Asset[]; sidebarCollapsed: boolean; // Actions setUser: (user: User | null) => void; setToken: (token: string | null) => void; addJob: (job: Job) => void; updateJob: (id: string, updates: Partial) => void; removeJob: (id: string) => void; clearCompletedJobs: () => void; setRecentAssets: (assets: Asset[]) => void; toggleSidebar: () => void; logout: () => void; } export const useStore = create()( persist( (set) => ({ user: null, token: null, activeJobs: [], recentAssets: [], sidebarCollapsed: false, setUser: (user) => set({ user }), setToken: (token) => { // Note: Actual authentication is via httpOnly cookie // This is just a marker for the UI state set({ token }); }, addJob: (job) => set((state) => { // Prevent duplicate jobs if (state.activeJobs.some((j) => j.id === job.id)) { return state; } return { activeJobs: [job, ...state.activeJobs].slice(0, 50), }; }), updateJob: (id, updates) => set((state) => ({ activeJobs: state.activeJobs.map((job) => job.id === id ? { ...job, ...updates } : job ), })), removeJob: (id) => set((state) => ({ activeJobs: state.activeJobs.filter((job) => job.id !== id), })), clearCompletedJobs: () => set((state) => ({ activeJobs: state.activeJobs.filter( (job) => job.status === 'queued' || job.status === 'processing' ), })), setRecentAssets: (assets) => set({ recentAssets: assets }), toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed, })), logout: () => { // Clear all state (cookie is cleared by backend on /auth/logout) set({ user: null, token: null, activeJobs: [], recentAssets: [] }); }, }), { name: 'forge-ai-storage', partialize: (state) => ({ user: state.user, token: state.token, sidebarCollapsed: state.sidebarCollapsed, activeJobs: state.activeJobs.slice(0, 20), // Persist last 20 jobs }), } ) );