1 import { useEffect } from "react";
2 import { useLocation } from "wouter";
3 import { useAuth } from "@/hooks/useAuth";
4 import { useAdminStats } from "@/hooks/useAdmin";
5 import { useToast } from "@/hooks/use-toast";
6 import Header from "@/components/layout/header";
7 import Footer from "@/components/layout/footer";
8 import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
9 import { Badge } from "@/components/ui/badge";
10
11 export default function AdminDashboard() {
12 const { user, isAuthenticated, isLoading: authLoading } = useAuth();
13 const { stats, isLoading: statsLoading } = useAdminStats();
14 const { toast } = useToast();
15 const [, setLocation] = useLocation();
16
17 // Redirect if not admin
18 useEffect(() => {
19 if (!authLoading && (!isAuthenticated || user?.role !== "admin")) {
20 toast({
21 title: "Access Denied",
22 description: "Administrator privileges required to access this page.",
23 variant: "destructive",
24 });
25 setLocation("/");
26 }
27 }, [user, isAuthenticated, authLoading, toast, setLocation]);
28
29 if (authLoading || statsLoading) {
30 return (
31 <div className="min-h-screen bg-gray-50 dark:bg-gray-900 amoled:bg-black">
32 <Header />
33 <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
34 <div className="animate-pulse space-y-6">
35 <div className="h-8 bg-gray-200 dark:bg-gray-700 rounded w-1/3"></div>
36 <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
37 {[...Array(3)].map((_, i) => (
38 <div key={i} className="h-32 bg-gray-200 dark:bg-gray-700 rounded-xl"></div>
39 ))}
40 </div>
41 </div>
42 </main>
43 </div>
44 );
45 }
46
47 if (!user || user.role !== "admin") {
48 return null; // Will redirect via useEffect
49 }
50
51 return (
52 <div className="min-h-screen bg-gray-50 dark:bg-gray-900 amoled:bg-black">
53 <Header />
54
55 <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
56 {/* Header */}
57 <div className="mb-8">
58 <div className="flex items-center justify-between">
59 <div>
60 <h1 className="text-3xl font-bold text-gray-900 dark:text-white">
61 Admin Dashboard
62 </h1>
63 <p className="text-gray-600 dark:text-gray-400 mt-2">
64 Welcome back, {user.firstName || user.email}
65 </p>
66 </div>
67 <Badge variant="default" className="bg-green-600 text-white">
68 <i className="material-icons text-sm mr-1">admin_panel_settings</i>
69 Administrator
70 </Badge>
71 </div>
72 </div>
73
74 {/* Stats Cards */}
75 <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
76 <Card>
77 <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
78 <CardTitle className="text-sm font-medium">Total Guides</CardTitle>
79 <i className="material-icons text-primary-600">library_books</i>
80 </CardHeader>
81 <CardContent>
82 <div className="text-2xl font-bold">{stats?.totalGuides || 0}</div>
83 <p className="text-xs text-gray-600 dark:text-gray-400">
84 Active repair guides
85 </p>
86 </CardContent>
87 </Card>
88
89 <Card>
90 <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
91 <CardTitle className="text-sm font-medium">Total Views</CardTitle>
92 <i className="material-icons text-blue-600">visibility</i>
93 </CardHeader>
94 <CardContent>
95 <div className="text-2xl font-bold">{stats?.totalViews || 0}</div>
96 <p className="text-xs text-gray-600 dark:text-gray-400">
97 Across all guides
98 </p>
99 </CardContent>
100 </Card>
101
102 <Card>
103 <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
104 <CardTitle className="text-sm font-medium">Total Downloads</CardTitle>
105 <i className="material-icons text-green-600">download</i>
106 </CardHeader>
107 <CardContent>
108 <div className="text-2xl font-bold">{stats?.totalDownloads || 0}</div>
109 <p className="text-xs text-gray-600 dark:text-gray-400">
110 Guide downloads
111 </p>
112 </CardContent>
113 </Card>
114 </div>
115
116 {/* Admin Info */}
117 <Card className="mb-8">
118 <CardHeader>
119 <CardTitle className="flex items-center">
120 <i className="material-icons text-lg mr-2">account_circle</i>
121 Administrator Information
122 </CardTitle>
123 </CardHeader>
124 <CardContent>
125 <div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
126 <div>
127 <span className="font-medium text-gray-900 dark:text-white">Email:</span>
128 <span className="ml-2 text-gray-600 dark:text-gray-400">{user.email}</span>
129 </div>
130 <div>
131 <span className="font-medium text-gray-900 dark:text-white">Role:</span>
132 <span className="ml-2 text-gray-600 dark:text-gray-400">Administrator</span>
133 </div>
134 <div>
135 <span className="font-medium text-gray-900 dark:text-white">Name:</span>
136 <span className="ml-2 text-gray-600 dark:text-gray-400">
137 {user.firstName} {user.lastName}
138 </span>
139 </div>
140 <div>
141 <span className="font-medium text-gray-900 dark:text-white">User ID:</span>
142 <span className="ml-2 text-gray-600 dark:text-gray-400 font-mono text-xs">
143 {user.id}
144 </span>
145 </div>
146 </div>
147 </CardContent>
148 </Card>
149
150 {/* System Information */}
151 <Card>
152 <CardHeader>
153 <CardTitle className="flex items-center">
154 <i className="material-icons text-lg mr-2">info</i>
155 System Information
156 </CardTitle>
157 </CardHeader>
158 <CardContent>
159 <div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
160 <div>
161 <span className="font-medium text-gray-900 dark:text-white">App Version:</span>
162 <span className="ml-2 text-gray-600 dark:text-gray-400">1.0.0</span>
163 </div>
164 <div>
165 <span className="font-medium text-gray-900 dark:text-white">Build Date:</span>
166 <span className="ml-2 text-gray-600 dark:text-gray-400">2025.08.18</span>
167 </div>
168 <div>
169 <span className="font-medium text-gray-900 dark:text-white">Database:</span>
170 <span className="ml-2 text-gray-600 dark:text-gray-400">PostgreSQL (Connected)</span>
171 </div>
172 <div>
173 <span className="font-medium text-gray-900 dark:text-white">Authentication:</span>
174 <span className="ml-2 text-gray-600 dark:text-gray-400">Firebase Auth</span>
175 </div>
176 </div>
177 </CardContent>
178 </Card>
179 </main>
180
181 <Footer />
182 </div>
183 );
184 }