"use client"; import React, { createContext, useContext, useEffect, useState, useCallback } from "react"; import { useRouter, usePathname } from "next/navigation"; export interface UserPermissions { sections: string[]; can_view_financial: boolean; can_edit: boolean; can_create: boolean; can_delete: boolean; can_download: boolean; } export interface User { id: number; email: string; name: string; role: "admin" | "user"; permissions: UserPermissions; } interface AuthContextType { user: User | null; loading: boolean; logout: () => Promise; refreshSession: () => Promise; hasPermission: (permission: keyof Omit) => boolean; canAccessSection: (section: string) => boolean; } const AuthContext = createContext(undefined); const PUBLIC_PATHS = ["/login"]; export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const router = useRouter(); const pathname = usePathname(); const refreshSession = useCallback(async () => { try { console.log("[v0] Refreshing session..."); const res = await fetch("/api/auth/session", { credentials: "include", }); if (res.ok) { const data = await res.json(); console.log("[v0] Session data:", data); setUser(data.user); } else { console.log("[v0] Session fetch failed:", res.status); setUser(null); } } catch (err) { console.log("[v0] Session error:", err); setUser(null); } finally { setLoading(false); } }, []); useEffect(() => { refreshSession(); }, [refreshSession]); useEffect(() => { if (!loading) { const isPublicPath = PUBLIC_PATHS.includes(pathname); if (!user && !isPublicPath) { router.push("/login"); } else if (user && isPublicPath) { router.push("/"); } } }, [user, loading, pathname, router]); const logout = useCallback(async () => { try { await fetch("/api/auth/logout", { method: "POST" }); setUser(null); router.push("/login"); } catch (error) { console.error("Logout failed:", error); } }, [router]); const hasPermission = useCallback( (permission: keyof Omit) => { if (!user) return false; if (user.role === "admin") return true; return user.permissions[permission] === true; }, [user] ); const canAccessSection = useCallback( (section: string) => { if (!user) return false; if (user.role === "admin") return true; return user.permissions?.sections?.includes(section) || false; }, [user] ); // Show nothing while checking auth on protected routes if (loading) { return (

Loading...

); } // Allow public paths without auth if (!user && PUBLIC_PATHS.includes(pathname)) { return <>{children}; } // Block protected routes if not authenticated if (!user) { return null; } return ( {children} ); } export function useAuth() { const context = useContext(AuthContext); if (context === undefined) { throw new Error("useAuth must be used within an AuthProvider"); } return context; }