this repo has no description
1/**
2 * Protected Route Component
3 * Wraps routes that require authentication
4 */
5
6import React from 'react';
7import { Navigate, Outlet, useLocation } from 'react-router-dom';
8import { useAuth } from '../../contexts/AuthContext';
9
10interface ProtectedRouteProps {
11 children?: React.ReactNode;
12}
13
14export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
15 const { isAuthenticated, loading } = useAuth();
16 const location = useLocation();
17
18 // Show loading spinner while checking auth status
19 if (loading) {
20 return (
21 <div className="min-h-screen flex items-center justify-center bg-gray-50">
22 <div className="text-center">
23 <svg
24 className="animate-spin h-8 w-8 text-blue-600 mx-auto"
25 xmlns="http://www.w3.org/2000/svg"
26 fill="none"
27 viewBox="0 0 24 24"
28 >
29 <circle
30 className="opacity-25"
31 cx="12"
32 cy="12"
33 r="10"
34 stroke="currentColor"
35 strokeWidth="4"
36 />
37 <path
38 className="opacity-75"
39 fill="currentColor"
40 d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
41 />
42 </svg>
43 <p className="mt-2 text-sm text-gray-600">Loading...</p>
44 </div>
45 </div>
46 );
47 }
48
49 // Redirect to login if not authenticated
50 if (!isAuthenticated) {
51 return <Navigate to="/login" state={{ from: location }} replace />;
52 }
53
54 // Render children or outlet for nested routes
55 return children || <Outlet />;
56};