"use client"; import { useEffect } from "react"; import { useRouter } from "next/navigation"; import { useAuth, PermissionType, Permission } from "../auth-context"; interface UseRequireAuthOptions { /** Required permission to access the page */ requiredPermission?: PermissionType; /** Required role to access the page */ requiredRole?: string; /** Where to redirect if permission check fails (defaults to best available page) */ fallbackRedirect?: string; } interface UseRequireAuthResult { user: ReturnType["user"]; isLoading: boolean; isAuthorized: boolean; } /** * Hook that handles authentication and authorization checks. * Automatically redirects to login if not authenticated, * or to a fallback page if missing required permissions. */ export function useRequireAuth(options: UseRequireAuthOptions = {}): UseRequireAuthResult { const { requiredPermission, requiredRole, fallbackRedirect } = options; const { user, isLoading, hasPermission, hasRole } = useAuth(); const router = useRouter(); const isAuthorized = (() => { if (!user) return false; if (requiredPermission && !hasPermission(requiredPermission)) return false; if (requiredRole && !hasRole(requiredRole)) return false; return true; })(); useEffect(() => { if (isLoading) return; if (!user) { router.push("/login"); return; } if (!isAuthorized) { // Redirect to the most appropriate page based on permissions // Use hasPermission/hasRole directly since they're stable callbacks const redirect = fallbackRedirect ?? (hasPermission(Permission.VIEW_ALL_EXCHANGES) ? "/admin/trades" : hasPermission(Permission.CREATE_EXCHANGE) ? "/exchange" : "/login"); router.push(redirect); } // Note: hasPermission and hasRole are stable callbacks from useAuth, // so they don't need to be in the dependency array. They're only included // for clarity and to satisfy exhaustive-deps if needed. // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoading, user, isAuthorized, router, fallbackRedirect]); return { user, isLoading, isAuthorized, }; }