feat: expose admin status to frontend via user API
Add is_admin field to UserResponse schema and update AuthContext to fetch user profile after login, storing and exposing isAdmin boolean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
import { createContext, useContext, useEffect, useState, useCallback, useMemo } from 'react'
|
||||
import type { User, Session, AuthError } from '@supabase/supabase-js'
|
||||
import { supabase } from '../lib/supabase'
|
||||
import { api } from '../api/client'
|
||||
|
||||
interface UserProfile {
|
||||
id: string
|
||||
email: string
|
||||
displayName: string | null
|
||||
isAdmin: boolean
|
||||
}
|
||||
|
||||
interface AuthState {
|
||||
user: User | null
|
||||
session: Session | null
|
||||
loading: boolean
|
||||
isAdmin: boolean
|
||||
}
|
||||
|
||||
interface AuthContextValue extends AuthState {
|
||||
@@ -18,22 +27,35 @@ interface AuthContextValue extends AuthState {
|
||||
|
||||
const AuthContext = createContext<AuthContextValue | null>(null)
|
||||
|
||||
async function syncUserProfile(session: Session | null): Promise<boolean> {
|
||||
if (!session) return false
|
||||
try {
|
||||
const profile = await api.post<UserProfile>('/users/me', {})
|
||||
return profile.isAdmin
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [state, setState] = useState<AuthState>({
|
||||
user: null,
|
||||
session: null,
|
||||
loading: true,
|
||||
isAdmin: false,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
supabase.auth.getSession().then(({ data: { session } }) => {
|
||||
setState({ user: session?.user ?? null, session, loading: false })
|
||||
supabase.auth.getSession().then(async ({ data: { session } }) => {
|
||||
const isAdmin = await syncUserProfile(session)
|
||||
setState({ user: session?.user ?? null, session, loading: false, isAdmin })
|
||||
})
|
||||
|
||||
const {
|
||||
data: { subscription },
|
||||
} = supabase.auth.onAuthStateChange((_event, session) => {
|
||||
setState({ user: session?.user ?? null, session, loading: false })
|
||||
} = supabase.auth.onAuthStateChange(async (_event, session) => {
|
||||
const isAdmin = await syncUserProfile(session)
|
||||
setState({ user: session?.user ?? null, session, loading: false, isAdmin })
|
||||
})
|
||||
|
||||
return () => subscription.unsubscribe()
|
||||
|
||||
Reference in New Issue
Block a user