import { create } from 'zustand' import { persist } from 'zustand/middleware' import type { AdminUser, TokenGrant } from '@/api/types' interface AuthState { accessToken: string | null refreshToken: string | null user: AdminUser | null roles: string[] permissions: string[] setTokens: (grant: TokenGrant) => void setSession: (user: AdminUser, roles: string[], permissions: string[]) => void clear: () => void } export const useAuthStore = create()( persist( (set) => ({ accessToken: null, refreshToken: null, user: null, roles: [], permissions: [], setTokens: (grant) => set({ accessToken: grant.access_token, refreshToken: grant.refresh_token ?? null, }), setSession: (user, roles, permissions) => set({ user, roles, permissions }), clear: () => set({ accessToken: null, refreshToken: null, user: null, roles: [], permissions: [] }), }), { name: 'gig-admin-auth' }, ), ) export function hasRole(role: string): boolean { return useAuthStore.getState().roles.includes(role) } /** super-admin implicitly passes every permission check (mirrors backend seeding). */ export function can(permission: string): boolean { const { roles, permissions } = useAuthStore.getState() return roles.includes('super-admin') || permissions.includes(permission) } export function useCan(permission: string): boolean { const roles = useAuthStore((s) => s.roles) const permissions = useAuthStore((s) => s.permissions) return roles.includes('super-admin') || permissions.includes(permission) } export function isAuthenticated(): boolean { return Boolean(useAuthStore.getState().accessToken) }