diff --git a/src/App.tsx b/src/App.tsx
index cfea967..da9cbfb 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -6,6 +6,7 @@ import { BrowserRouter, Routes, Route } from "react-router-dom";
import { AuthProvider } from "@/hooks/useAuth";
import { CartProvider } from "@/contexts/CartContext";
import { BrandingProvider } from "@/hooks/useBranding";
+import { ProtectedRoute } from "@/components/ProtectedRoute";
import Index from "./pages/Index";
import Auth from "./pages/Auth";
import ConfirmOTP from "./pages/ConfirmOTP";
@@ -65,25 +66,131 @@ const App = () => (
} />
} />
} />
-
+
{/* Member routes */}
- } />
- } />
- } />
- } />
- } />
-
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
{/* Admin routes */}
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
} />
diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx
new file mode 100644
index 0000000..5cfbd29
--- /dev/null
+++ b/src/components/ProtectedRoute.tsx
@@ -0,0 +1,64 @@
+import { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useAuth } from '@/hooks/useAuth';
+import { Skeleton } from '@/components/ui/skeleton';
+
+interface ProtectedRouteProps {
+ children: React.ReactNode;
+ requireAdmin?: boolean;
+}
+
+export function ProtectedRoute({ children, requireAdmin = false }: ProtectedRouteProps) {
+ const { user, loading: authLoading } = useAuth();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (!authLoading) {
+ if (!user) {
+ // Save current URL to redirect back after login
+ const currentPath = window.location.pathname + window.location.search;
+ sessionStorage.setItem('redirectAfterLogin', currentPath);
+ navigate('/auth');
+ return;
+ }
+
+ // Check for admin role if required
+ if (requireAdmin) {
+ const userRole = user.user_metadata?.role;
+ if (userRole !== 'admin') {
+ // Redirect non-admin users to member dashboard
+ navigate('/dashboard');
+ return;
+ }
+ }
+ }
+ }, [user, authLoading, navigate, requireAdmin]);
+
+ // Show loading skeleton while checking auth
+ if (authLoading) {
+ return (
+
+ );
+ }
+
+ // Don't render children if user is not authenticated
+ if (!user) {
+ return null;
+ }
+
+ // Don't render if admin access required but user is not admin
+ if (requireAdmin && user.user_metadata?.role !== 'admin') {
+ return null;
+ }
+
+ return <>{children}>;
+}
diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx
index a4c975e..a23c459 100644
--- a/src/pages/Auth.tsx
+++ b/src/pages/Auth.tsx
@@ -29,7 +29,14 @@ export default function Auth() {
useEffect(() => {
if (user) {
- navigate('/dashboard');
+ // Check if there's a saved redirect path
+ const savedRedirect = sessionStorage.getItem('redirectAfterLogin');
+ if (savedRedirect) {
+ sessionStorage.removeItem('redirectAfterLogin');
+ navigate(savedRedirect);
+ } else {
+ navigate('/dashboard');
+ }
}
}, [user, navigate]);
@@ -101,8 +108,12 @@ export default function Auth() {
toast({ title: 'Error', description: error.message, variant: 'destructive' });
setLoading(false);
} else {
- // Get redirect from URL state or use default
- const redirectTo = (location.state as any)?.redirectTo || '/dashboard';
+ // Get redirect from sessionStorage or use default
+ const savedRedirect = sessionStorage.getItem('redirectAfterLogin');
+ const redirectTo = savedRedirect || '/dashboard';
+ if (savedRedirect) {
+ sessionStorage.removeItem('redirectAfterLogin');
+ }
navigate(redirectTo);
setLoading(false);
}