From 3e27a02e36ac624aad383568498aa79a53d8701f Mon Sep 17 00:00:00 2001
From: seaznCode
Date: Tue, 14 Oct 2025 23:22:59 +0200
Subject: [PATCH] feat: implement admin user management features including
fetching, verifying, and displaying user stats
---
src/app/admin/page.tsx | 96 ++++++++--
src/app/admin/user-management/page.tsx | 233 ++++++++++++++++++-------
src/app/admin/user-verify/page.tsx | 229 +++++++++++++++---------
src/app/hooks/useAdminUsers.ts | 113 ++++++++++++
src/app/utils/api.ts | 77 ++++++++
5 files changed, 586 insertions(+), 162 deletions(-)
create mode 100644 src/app/hooks/useAdminUsers.ts
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 568f671..d4e252f 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -9,21 +9,29 @@ import {
ServerStackIcon,
ArrowRightIcon
} from '@heroicons/react/24/outline'
-import { useMemo } from 'react'
+import { useMemo, useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
+import { useAdminUsers } from '../hooks/useAdminUsers'
export default function AdminDashboardPage() {
const router = useRouter()
+ const { userStats, isAdmin } = useAdminUsers()
+ const [isClient, setIsClient] = useState(false)
- // Mocked aggregates (replace with real fetch)
- const userStats = useMemo(() => ({
- total: 101,
- admins: 1,
- pending: 3,
- active: 54,
- personal: 94,
- company: 7
- }), [])
+ // Handle client-side mounting
+ useEffect(() => {
+ setIsClient(true)
+ }, [])
+
+ // Fallback for loading/no data
+ const displayStats = userStats || {
+ totalUsers: 0,
+ adminUsers: 0,
+ verificationPending: 0,
+ activeUsers: 0,
+ personalUsers: 0,
+ companyUsers: 0
+ }
const permissionStats = useMemo(() => ({
permissions: 1 // TODO: fetch permission definitions
@@ -36,6 +44,38 @@ export default function AdminDashboardPage() {
memory: '0.1 / 7.8',
recentErrors: [] as { id: string; ts: string; msg: string }[]
}), [])
+
+ // Show loading during SSR/initial client render
+ if (!isClient) {
+ return (
+
+
+
+ )
+ }
+
+ // Access check (only after client-side hydration)
+ if (!isAdmin) {
+ return (
+
+
+
+
+
Access Denied
+
You need admin privileges to access this page.
+
+
+
+
+ )
+ }
return (
@@ -105,27 +145,51 @@ export default function AdminDashboardPage() {
- Total Users
- - {userStats.total}
+ -
+ {userStats ? displayStats.totalUsers : (
+
+ )}
+
Admin Users
- {userStats.admins}
+
+ {userStats ? displayStats.adminUsers : (
+
+ )}
+
Verification Pending
- {userStats.pending}
+
+ {userStats ? displayStats.verificationPending : (
+
+ )}
+
Active Users
- {userStats.active}
+
+ {userStats ? displayStats.activeUsers : (
+
+ )}
+
Personal Users
- {userStats.personal}
+
+ {userStats ? displayStats.personalUsers : (
+
+ )}
+
Company Users
- {userStats.company}
+
+ {userStats ? displayStats.companyUsers : (
+
+ )}
+
- {/* Filter Card */}
+ {/* Error Message */}
+ {error && (
+
+
+
+
Error loading users
+
{error}
+
+
+
+ )}
+
+ {/* Filter Card */}