forked from Movalabs-crew/mova-store
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAdminGuard.jsx
More file actions
118 lines (110 loc) · 3.89 KB
/
Copy pathAdminGuard.jsx
File metadata and controls
118 lines (110 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "../lib/AuthContext";
import { AiOutlineLoading3Quarters } from "react-icons/ai";
import { MdLock, MdWarning } from "react-icons/md";
import Link from "next/link";
/**
* AdminGuard - Protects admin routes by checking authentication and authorization.
*
* Usage:
* ```jsx
* <AdminGuard>
* <YourAdminComponent />
* </AdminGuard>
* ```
*
* Requirements:
* - User must be authenticated (logged in)
* - User's email must be in NEXT_PUBLIC_ADMIN_EMAILS environment variable
*
* @param {Object} props
* @param {React.ReactNode} props.children - Protected content to render for admins
* @param {string} [props.redirectTo="/profile/login"] - Where to redirect unauthenticated users
*/
const AdminGuard = ({ children, redirectTo = "/profile/login" }) => {
const { user, loading, isAdmin, isAuthenticated } = useAuth();
const router = useRouter();
useEffect(() => {
// Don't redirect while still loading
if (loading) return;
// Redirect to login if not authenticated
if (!isAuthenticated) {
router.push(`${redirectTo}?redirect=/admin`);
}
}, [loading, isAuthenticated, router, redirectTo]);
// Loading state
if (loading) {
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-gray-50">
<AiOutlineLoading3Quarters className="animate-spin text-purple-600 text-4xl mb-4" />
<p className="text-gray-600">Checking access...</p>
</div>
);
}
// Not authenticated - show message while redirecting
if (!isAuthenticated) {
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-gray-50">
<MdLock className="text-gray-400 text-6xl mb-4" />
<h1 className="text-2xl font-bold text-gray-800 mb-2">Authentication Required</h1>
<p className="text-gray-600 mb-6">Please log in to access the admin panel.</p>
<Link
href={`${redirectTo}?redirect=/admin`}
className="bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg transition-colors"
>
Go to Login
</Link>
</div>
);
}
// Authenticated but not admin
if (!isAdmin) {
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-gray-50">
<MdWarning className="text-yellow-500 text-6xl mb-4" />
<h1 className="text-2xl font-bold text-gray-800 mb-2">Access Denied</h1>
<p className="text-gray-600 mb-2">
You don't have permission to access the admin panel.
</p>
<p className="text-sm text-gray-500 mb-6">
Logged in as: <span className="font-medium">{user?.email}</span>
</p>
<div className="flex gap-4">
<Link
href="/"
className="bg-gray-200 hover:bg-gray-300 text-gray-800 px-6 py-2 rounded-lg transition-colors"
>
Go Home
</Link>
<Link
href="/shop"
className="bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg transition-colors"
>
Browse Shop
</Link>
</div>
<p className="mt-8 text-xs text-gray-400 max-w-md text-center">
If you believe you should have admin access, contact the site administrator
to add your email to the admin list.
</p>
</div>
);
}
// User is authenticated and is an admin - render children
return (
<div>
{/* Admin header bar */}
<div className="bg-purple-700 text-white px-4 py-2 text-sm flex items-center justify-between">
<div className="flex items-center gap-2">
<MdLock className="text-lg" />
<span>Admin Panel</span>
</div>
<span className="text-purple-200">{user?.email}</span>
</div>
{children}
</div>
);
};
export default AdminGuard;