added "members" for an event that help the admins to moderate. members must be invited via email.
This commit is contained in:
@@ -15,16 +15,20 @@ export type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
|
||||
export interface TenantProfile {
|
||||
id: number;
|
||||
tenant_id: number;
|
||||
role?: string | null;
|
||||
name?: string;
|
||||
slug?: string;
|
||||
email?: string | null;
|
||||
event_credits_balance?: number | null;
|
||||
features?: Record<string, unknown>;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface AuthContextValue {
|
||||
status: AuthStatus;
|
||||
user: TenantProfile | null;
|
||||
abilities: string[];
|
||||
hasAbility: (ability: string) => boolean;
|
||||
refreshProfile: () => Promise<void>;
|
||||
logout: (options?: { redirect?: string }) => Promise<void>;
|
||||
applyToken: (token: string, abilities: string[]) => Promise<void>;
|
||||
@@ -80,6 +84,7 @@ async function exchangeSessionForToken(): Promise<{ token: string; abilities: st
|
||||
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const [status, setStatus] = React.useState<AuthStatus>('loading');
|
||||
const [user, setUser] = React.useState<TenantProfile | null>(null);
|
||||
const [abilities, setAbilities] = React.useState<string[]>([]);
|
||||
const queryClient = useQueryClient();
|
||||
const profileQueryKey = React.useMemo(() => ['tenantProfile'], []);
|
||||
|
||||
@@ -88,6 +93,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
invalidateTenantApiCache();
|
||||
queryClient.removeQueries({ queryKey: profileQueryKey });
|
||||
setUser(null);
|
||||
setAbilities([]);
|
||||
setStatus('unauthenticated');
|
||||
}, [profileQueryKey, queryClient]);
|
||||
|
||||
@@ -127,6 +133,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
: data.user;
|
||||
|
||||
setUser(composed ?? null);
|
||||
setAbilities(Array.isArray(data?.abilities) ? data.abilities : []);
|
||||
setStatus('authenticated');
|
||||
} catch (error) {
|
||||
console.error('[Auth] Failed to refresh profile', error);
|
||||
@@ -141,8 +148,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}
|
||||
}, [handleAuthFailure, profileQueryKey, queryClient]);
|
||||
|
||||
const applyToken = React.useCallback(async (token: string, abilities: string[]) => {
|
||||
storePersonalAccessToken(token, abilities);
|
||||
const applyToken = React.useCallback(async (token: string, tokenAbilities: string[]) => {
|
||||
storePersonalAccessToken(token, tokenAbilities);
|
||||
setAbilities(tokenAbilities);
|
||||
await refreshProfile();
|
||||
}, [refreshProfile]);
|
||||
|
||||
@@ -221,9 +229,11 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}
|
||||
}, [handleAuthFailure]);
|
||||
|
||||
const hasAbility = React.useCallback((ability: string) => abilities.includes(ability), [abilities]);
|
||||
|
||||
const value = React.useMemo<AuthContextValue>(
|
||||
() => ({ status, user, refreshProfile, logout, applyToken }),
|
||||
[status, user, refreshProfile, logout, applyToken]
|
||||
() => ({ status, user, abilities, hasAbility, refreshProfile, logout, applyToken }),
|
||||
[status, user, abilities, hasAbility, refreshProfile, logout, applyToken]
|
||||
);
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
|
||||
Reference in New Issue
Block a user