// src/lib/auth.jsx import { createContext, useContext, useEffect, useState, useCallback } from "react"; import { supabase } from "./supabase"; const AuthContext = createContext(null); export function AuthProvider({ children }) { const [session, setSession] = useState(null); const [perfil, setPerfil] = useState(null); // { nombre, rol } const [permisos, setPermisos] = useState([]); // ["ocupabilidad", "cobranza", ...] const [cargando, setCargando] = useState(true); // Cargar perfil (rol) y permisos del usuario logueado const cargarPerfil = useCallback(async (userId) => { // 1) Traer el rol del usuario desde la tabla "perfiles" const { data: perf, error: e1 } = await supabase .from("perfiles") .select("nombre, rol, activo") .eq("id", userId) .single(); if (e1 || !perf || perf.activo === false) { setPerfil(null); setPermisos([]); return false; } // 2) Traer los módulos permitidos para ese rol desde "permisos" const { data: perms } = await supabase .from("permisos") .select("modulo, puede_ver") .eq("rol", perf.rol); const modulos = (perms || []) .filter((p) => p.puede_ver) .map((p) => p.modulo); setPerfil({ nombre: perf.nombre, rol: perf.rol }); setPermisos(modulos); return true; }, []); // Al iniciar: revisar si ya hay sesión activa useEffect(() => { let activo = true; supabase.auth.getSession().then(async ({ data }) => { if (!activo) return; const s = data?.session || null; setSession(s); if (s?.user) await cargarPerfil(s.user.id); setCargando(false); }); // Escuchar cambios de sesión (login/logout) const { data: sub } = supabase.auth.onAuthStateChange(async (_evt, s) => { setSession(s); if (s?.user) await cargarPerfil(s.user.id); else { setPerfil(null); setPermisos([]); } }); return () => { activo = false; sub?.subscription?.unsubscribe(); }; }, [cargarPerfil]); const login = async (email, password) => { const { data, error } = await supabase.auth.signInWithPassword({ email, password }); if (error) return { ok: false, msg: traducirError(error.message) }; // Verificar que tenga perfil/rol válido const ok = await cargarPerfil(data.user.id); if (!ok) { await supabase.auth.signOut(); return { ok: false, msg: "Tu usuario no tiene un perfil asignado. Contacta al administrador." }; } return { ok: true }; }; const logout = async () => { await supabase.auth.signOut(); setPerfil(null); setPermisos([]); }; const value = { session, perfil, permisos, cargando, login, logout, autenticado: !!session && !!perfil, puedeVer: (modulo) => permisos.includes(modulo), }; return {children}; } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth debe usarse dentro de AuthProvider"); return ctx; } function traducirError(msg) { if (/invalid login credentials/i.test(msg)) return "Correo o contraseña incorrectos."; if (/email not confirmed/i.test(msg)) return "El correo no está confirmado."; return msg || "Error al iniciar sesión."; }