|
@@ -1,14 +1,35 @@
|
|
|
-// STUB — replaced by W3 with the real zustand store.
|
|
|
|
|
-// Minimal shape so the dynamic import in api/client.ts resolves at build time.
|
|
|
|
|
|
|
+import { create } from 'zustand'
|
|
|
|
|
+import { persist } from 'zustand/middleware'
|
|
|
|
|
+import { api } from '@/api/client'
|
|
|
|
|
|
|
|
interface AuthState {
|
|
interface AuthState {
|
|
|
|
|
+ loggedIn: boolean
|
|
|
|
|
+ admin: boolean
|
|
|
|
|
+ projects: string[] // [] with admin=true means "all" (resolve via listProjects)
|
|
|
|
|
+ currentProject: string | null
|
|
|
|
|
+ login: (key: string) => Promise<void>
|
|
|
|
|
+ logout: () => Promise<void>
|
|
|
|
|
+ setCurrentProject: (p: string) => void
|
|
|
reset: () => void
|
|
reset: () => void
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const state: AuthState = {
|
|
|
|
|
- reset: () => {},
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-export const useAuthStore = {
|
|
|
|
|
- getState: (): AuthState => state,
|
|
|
|
|
-}
|
|
|
|
|
|
|
+export const useAuthStore = create<AuthState>()(
|
|
|
|
|
+ persist(
|
|
|
|
|
+ (set, get) => ({
|
|
|
|
|
+ loggedIn: false, admin: false, projects: [], currentProject: null,
|
|
|
|
|
+ login: async (key) => {
|
|
|
|
|
+ const r = await api.login(key)
|
|
|
|
|
+ // For admin or "*" grants, fetch the real project list to populate the selector.
|
|
|
|
|
+ let projects = r.projects
|
|
|
|
|
+ if (r.admin || projects.includes('*')) {
|
|
|
|
|
+ try { projects = (await api.listProjects()).projects } catch { /* keep */ }
|
|
|
|
|
+ }
|
|
|
|
|
+ set({ loggedIn: true, admin: r.admin, projects, currentProject: projects[0] ?? 'default' })
|
|
|
|
|
+ },
|
|
|
|
|
+ logout: async () => { try { await api.logout() } finally { get().reset() } },
|
|
|
|
|
+ setCurrentProject: (p) => set({ currentProject: p }),
|
|
|
|
|
+ reset: () => set({ loggedIn: false, admin: false, projects: [], currentProject: null }),
|
|
|
|
|
+ }),
|
|
|
|
|
+ { name: 'svapi-auth', partialize: (s) => ({ loggedIn: s.loggedIn, admin: s.admin, projects: s.projects, currentProject: s.currentProject }) },
|
|
|
|
|
+ ),
|
|
|
|
|
+)
|