import { useEffect } from "react"; import { useAuth } from "~/contexts/auth-context"; import { useNavigate, useLocation } from "react-router"; import toast from "react-hot-toast"; interface UseRouteGuardOptions { requireAuth?: boolean; redirectTo?: string; showToast?: boolean; } export function useRouteGuard(options: UseRouteGuardOptions = {}) { const { requireAuth = true, redirectTo = "/login", showToast = true, } = options; const { isAuthenticated, isLoading, token, user } = useAuth(); const navigate = useNavigate(); const location = useLocation(); useEffect(() => { // Don't do anything while loading if (isLoading) return; // If authentication is required but user is not authenticated if (requireAuth && !isAuthenticated) { if (showToast) { toast.error("برای دسترسی به این صفحه باید وارد شوید"); } // Save the current location so we can redirect back after login const currentPath = location.pathname + location.search; const loginPath = redirectTo === "/login" ? `${redirectTo}?returnTo=${encodeURIComponent(currentPath)}` : redirectTo; navigate(loginPath, { replace: true }); return; } // If authentication is required but token is missing/invalid if (requireAuth && isAuthenticated && !token) { if (showToast) { toast.error("جلسه کاری شما منقضی شده است. لطفاً دوباره وارد شوید"); } // Clear any stored authentication data localStorage.removeItem("auth_user"); localStorage.removeItem("auth_token"); navigate("/login", { replace: true }); return; } // If user is authenticated but trying to access login page if (!requireAuth && isAuthenticated && location.pathname === "/login") { navigate("/dashboard", { replace: true }); return; } }, [ isLoading, isAuthenticated, token, requireAuth, redirectTo, showToast, navigate, location.pathname, location.search, ]); return { isAuthenticated, isLoading, token, user, canAccess: requireAuth ? isAuthenticated && !!token?.accessToken : true, }; } // Helper hook for protected routes export function useProtectedRoute(redirectTo?: string) { return useRouteGuard({ requireAuth: true, redirectTo, showToast: true, }); } // Helper hook for public routes (like login) export function usePublicRoute() { return useRouteGuard({ requireAuth: false, showToast: false, }); } // Hook to check if user has specific permissions export function usePermissionGuard( requiredPermissions: string[] = [], userPermissions: string[] = [], ) { const { isAuthenticated, token } = useAuth(); const navigate = useNavigate(); const hasPermission = requiredPermissions.every((permission) => userPermissions.includes(permission), ); useEffect(() => { if ( isAuthenticated && token?.accessToken && !hasPermission && requiredPermissions.length > 0 ) { toast.error("شما دسترسی لازم برای این صفحه را ندارید"); navigate("/dashboard", { replace: true }); } }, [ isAuthenticated, token, hasPermission, requiredPermissions.length, navigate, ]); return { hasPermission, canAccess: isAuthenticated && !!token?.accessToken && hasPermission, }; }