Ahora se obtienen claims de las tablas en el esquema public, en vez de la información de sesion del usuario, que se obtiene de la tabla auth.users

En supabase.tsx se sustituyó la manera de obtener los claims del usuario, utilizando ahora un rpc de una función en supabase.
This commit is contained in:
2025-10-10 17:23:37 -06:00
parent c49c0bbc0a
commit f2b3010ac9
6 changed files with 70 additions and 79 deletions

View File

@@ -175,7 +175,7 @@ function RouteComponent() {
const name = auth.user?.user_metadata?.nombre || auth.user?.email?.split('@')[0] || '¡Hola!'
const isAdmin = !!auth.claims?.claims_admin
const isAdmin = auth.claims?.role === 'lci' || auth.claims?.role === 'vicerrectoria'
const role = auth.claims?.role as 'lci' | 'vicerrectoria' | 'secretario_academico' | 'jefe_carrera' | 'planeacion' | undefined
const navigate = useNavigate({ from: Route.fullPath })

View File

@@ -45,6 +45,7 @@ export const Route = createFileRoute("/_authenticated/planes")({
`)
.order("fecha_creacion", { ascending: false })
.limit(100)
console.log({ data, error })
if (error) throw new Error(error.message)
return (data ?? []) as PlanRow[]
},

View File

@@ -20,7 +20,7 @@ import { CarreraCombobox, FacultadCombobox } from "@/components/users/procedenci
import { toast } from "sonner"
/* -------------------- Tipos -------------------- */
type AdminUser = {
type User = {
id: string
email: string | null
created_at: string
@@ -69,11 +69,11 @@ const usersKeys = {
list: () => [...usersKeys.root, "list"] as const,
}
async function fetchUsers(): Promise<AdminUser[]> {
async function fetchUsers(): Promise<User[]> {
// ⚠️ Dev only: service role en cliente
const admin = new SupabaseClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_SERVICE_ROLE_KEY)
const { data } = await admin.auth.admin.listUsers()
return (data?.users ?? []) as AdminUser[]
return (data?.users ?? []) as User[]
}
const usersOptions = () =>
@@ -96,7 +96,7 @@ function RouteComponent() {
const { data } = useSuspenseQuery(usersOptions())
const [q, setQ] = useState("")
const [editing, setEditing] = useState<AdminUser | null>(null)
const [editing, setEditing] = useState<User | null>(null)
const [form, setForm] = useState<{
role?: Role
claims_admin?: boolean
@@ -167,7 +167,7 @@ function RouteComponent() {
})
const toggleBan = useMutation({
mutationFn: async (u: AdminUser) => {
mutationFn: async (u: User) => {
const banned = !!u.banned_until && new Date(u.banned_until) > new Date()
const payload = banned ? { banned_until: null } : { banned_until: new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000).toISOString() }
const { error } = await supabase.auth.admin.updateUserById(u.id, payload as any)
@@ -228,7 +228,7 @@ function RouteComponent() {
})
const saveUser = useMutation({
mutationFn: async ({ u, f }: { u: AdminUser; f: typeof form }) => {
mutationFn: async ({ u, f }: { u: User; f: typeof form }) => {
// 1) Actualiza metadatos (tu Edge Function; placeholder aquí)
// await fetch('/functions/update-user', { method: 'POST', body: JSON.stringify({ id: u.id, ...f }) })
// Simula éxito:
@@ -251,7 +251,7 @@ function RouteComponent() {
onError: (e: any) => toast.error(e?.message || "No se pudo guardar"),
})
if (!auth.claims?.claims_admin) {
if (auth.claims?.role !== "lci" && auth.claims?.role !== "vicerrectoria") {
return <div className="p-6 text-sm text-red-600">No tienes permisos para administrar usuarios.</div>
}
@@ -267,7 +267,7 @@ function RouteComponent() {
})
}, [q, data])
function openEdit(u: AdminUser) {
function openEdit(u: User) {
setEditing(u)
setForm({
role: u.app_metadata?.role,