Modified by www.SourceFiles.app
This commit is contained in:
+44
-7
@@ -2,7 +2,20 @@ import { useEffect, useState } from "react";
|
|||||||
import type { User } from "@supabase/supabase-js";
|
import type { User } from "@supabase/supabase-js";
|
||||||
import { supabase } from "@/integrations/supabase/client";
|
import { supabase } from "@/integrations/supabase/client";
|
||||||
|
|
||||||
export type Role = "admin" | "teacher" | "parent" | "student";
|
// Mirrors the public.app_role enum. "student" has no enum member but is kept
|
||||||
|
// because existing screens branch on it.
|
||||||
|
export type Role =
|
||||||
|
| "super_admin"
|
||||||
|
| "org_admin"
|
||||||
|
| "admin"
|
||||||
|
| "campus_admin"
|
||||||
|
| "management"
|
||||||
|
| "billing_admin"
|
||||||
|
| "teacher"
|
||||||
|
| "staff"
|
||||||
|
| "parent"
|
||||||
|
| "auditor"
|
||||||
|
| "student";
|
||||||
|
|
||||||
export interface AuthState {
|
export interface AuthState {
|
||||||
user: User | null;
|
user: User | null;
|
||||||
@@ -26,7 +39,8 @@ export function useAuth(): AuthState {
|
|||||||
supabase.auth.getSession().then(({ data }) => {
|
supabase.auth.getSession().then(({ data }) => {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setUser(data.session?.user ?? null);
|
setUser(data.session?.user ?? null);
|
||||||
if (data.session?.user) loadRoles(data.session.user.id).finally(() => mounted && setLoading(false));
|
if (data.session?.user)
|
||||||
|
loadRoles(data.session.user.id).finally(() => mounted && setLoading(false));
|
||||||
else setLoading(false);
|
else setLoading(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,10 +62,33 @@ export function useAuth(): AuthState {
|
|||||||
return { user, roles, loading };
|
return { user, roles, loading };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ROLE_SENIORITY: Role[] = [
|
||||||
|
"super_admin",
|
||||||
|
"org_admin",
|
||||||
|
"admin",
|
||||||
|
"campus_admin",
|
||||||
|
"management",
|
||||||
|
"billing_admin",
|
||||||
|
"teacher",
|
||||||
|
"staff",
|
||||||
|
"parent",
|
||||||
|
"auditor",
|
||||||
|
"student",
|
||||||
|
];
|
||||||
|
|
||||||
export function highestRole(roles: Role[]): Role | null {
|
export function highestRole(roles: Role[]): Role | null {
|
||||||
if (roles.includes("admin")) return "admin";
|
return ROLE_SENIORITY.find((r) => roles.includes(r)) ?? null;
|
||||||
if (roles.includes("teacher")) return "teacher";
|
}
|
||||||
if (roles.includes("parent")) return "parent";
|
|
||||||
if (roles.includes("student")) return "student";
|
/**
|
||||||
return null;
|
* Organization-wide administrative reach. Mirrors public.is_org_admin() —
|
||||||
|
* keep the two in step, or the UI will offer actions that RLS then refuses.
|
||||||
|
*/
|
||||||
|
export function isOrgAdmin(roles: Role[]): boolean {
|
||||||
|
return roles.some((r) => r === "admin" || r === "org_admin" || r === "super_admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mirrors public.is_billing_admin(). */
|
||||||
|
export function canBill(roles: Role[]): boolean {
|
||||||
|
return isOrgAdmin(roles) || roles.includes("billing_admin");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user