Skip to content

Commit 0f5800d

Browse files
committed
enhaneced admin dashboard UIUX
1 parent fd3d5ed commit 0f5800d

5 files changed

Lines changed: 245 additions & 286 deletions

File tree

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,7 @@
1-
'use client';
2-
3-
import React from 'react';
4-
import Link from 'next/link';
5-
import { ChevronLeft, Home, Shield, Users, Lock, BarChart3 } from 'lucide-react';
6-
71
export default function AdminLayout({
82
children,
93
}: {
104
children: React.ReactNode;
115
}) {
12-
const adminLinks = [
13-
{
14-
label: 'Dashboard',
15-
href: '/admin',
16-
icon: Home,
17-
},
18-
{
19-
label: 'RBAC Management',
20-
href: '/admin/rbac',
21-
icon: Shield,
22-
},
23-
];
24-
25-
return (
26-
<div className="flex min-h-screen flex-col">
27-
{/* Admin Header */}
28-
<header className="border-b bg-white px-6 py-4 shadow-sm">
29-
<div className="flex items-center justify-between">
30-
<div className="flex items-center gap-2">
31-
<Link href="/admin" className="flex items-center gap-2 hover:opacity-80">
32-
<Shield className="w-5 h-5 text-blue-600" />
33-
<h1 className="text-xl font-bold text-gray-900">Admin Panel</h1>
34-
</Link>
35-
</div>
36-
<div className="text-sm text-gray-600">
37-
<Link href="/" className="hover:text-gray-900">← Back to Home</Link>
38-
</div>
39-
</div>
40-
</header>
41-
42-
{/* Admin Content */}
43-
<div className="flex flex-1">
44-
{/* Sidebar Navigation */}
45-
<aside className="w-64 border-r bg-gray-50 p-6">
46-
<nav className="space-y-2">
47-
{adminLinks.map((link) => {
48-
const Icon = link.icon;
49-
return (
50-
<Link key={link.href} href={link.href}>
51-
<div className="flex items-center gap-3 rounded-lg px-4 py-2 hover:bg-gray-200 transition cursor-pointer text-gray-700 hover:text-gray-900">
52-
<Icon className="w-5 h-5" />
53-
<span className="font-medium">{link.label}</span>
54-
</div>
55-
</Link>
56-
);
57-
})}
58-
</nav>
59-
</aside>
60-
61-
{/* Main Content */}
62-
<main className="flex-1 overflow-auto">
63-
{children}
64-
</main>
65-
</div>
66-
</div>
67-
);
6+
return <>{children}</>;
687
}

src/app/(dashboard)/admin/page.tsx

Lines changed: 100 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,114 @@
11
'use client';
22

3-
import React from 'react';
3+
import React, { useEffect, useState } from 'react';
44
import Link from 'next/link';
5-
import { Shield, Users, Lock, BarChart3 } from 'lucide-react';
5+
import { Users, Lock, Shield, ArrowRight } from 'lucide-react';
66

77
export default function AdminPage() {
8-
const adminModules = [
9-
{
10-
title: 'Role-Based Access Control',
11-
description: 'Manage roles, permissions, and user access',
12-
icon: Shield,
13-
href: '/admin/rbac',
14-
color: 'blue',
15-
},
16-
{
17-
title: 'User Management',
18-
description: 'View and manage all system users',
19-
icon: Users,
20-
href: '/admin/rbac?tab=users',
21-
color: 'green',
22-
},
23-
{
24-
title: 'Audit Logs',
25-
description: 'Track all system changes and user actions',
26-
icon: BarChart3,
27-
href: '/admin/audit',
28-
color: 'purple',
29-
disabled: true,
30-
},
31-
];
8+
const [stats, setStats] = useState({ users: 0, roles: 0, permissions: 0 });
9+
const [loading, setLoading] = useState(true);
3210

33-
return (
34-
<div className="min-h-screen bg-gray-50">
35-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
36-
<div className="mb-8">
37-
<h1 className="text-3xl font-bold text-gray-900">Admin Dashboard</h1>
38-
<p className="mt-2 text-gray-600">Manage your hospital system's core functions</p>
39-
</div>
11+
useEffect(() => {
12+
const fetchStats = async () => {
13+
try {
14+
const [usersRes, rolesRes, permsRes] = await Promise.all([
15+
fetch('/api/admin/users'),
16+
fetch('/api/admin/roles'),
17+
fetch('/api/admin/permissions'),
18+
]);
4019

41-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
42-
{adminModules.map((module) => {
43-
const Icon = module.icon;
44-
const colorClasses = {
45-
blue: 'bg-blue-50 border-blue-200 hover:border-blue-300',
46-
green: 'bg-green-50 border-green-200 hover:border-green-300',
47-
purple: 'bg-purple-50 border-purple-200 hover:border-purple-300',
48-
};
20+
const users = await usersRes.json();
21+
const roles = await rolesRes.json();
22+
const perms = await permsRes.json();
4923

50-
const iconColorClasses = {
51-
blue: 'text-blue-600',
52-
green: 'text-green-600',
53-
purple: 'text-purple-600',
54-
};
24+
setStats({
25+
users: Array.isArray(users) ? users.length : 0,
26+
roles: Array.isArray(roles) ? roles.length : 0,
27+
permissions: Array.isArray(perms) ? perms.length : 0,
28+
});
29+
} catch (error) {
30+
console.error('Failed to fetch stats:', error);
31+
} finally {
32+
setLoading(false);
33+
}
34+
};
5535

56-
const buttonColorClasses = {
57-
blue: 'text-blue-600 hover:text-blue-700',
58-
green: 'text-green-600 hover:text-green-700',
59-
purple: 'text-purple-600 hover:text-purple-700',
60-
};
36+
fetchStats();
37+
}, []);
38+
39+
const StatCard = ({ title, value, icon: Icon }: { title: string; value: number; icon: any }) => (
40+
<div className="bg-white rounded-lg border border-gray-200 p-6">
41+
<div className="flex items-start justify-between">
42+
<div>
43+
<p className="text-sm font-medium text-gray-600">{title}</p>
44+
<p className="text-3xl font-bold text-gray-900 mt-2">{loading ? '-' : value}</p>
45+
</div>
46+
<Icon className="w-8 h-8 text-gray-400" />
47+
</div>
48+
</div>
49+
);
6150

62-
if (module.disabled) {
63-
return (
64-
<div
65-
key={module.title}
66-
className={`rounded-lg border-2 p-6 opacity-50 cursor-not-allowed ${
67-
colorClasses[module.color as keyof typeof colorClasses]
68-
}`}
69-
>
70-
<Icon className={`w-8 h-8 mb-3 ${iconColorClasses[module.color as keyof typeof iconColorClasses]}`} />
71-
<h3 className="text-lg font-semibold text-gray-900 mb-2">{module.title}</h3>
72-
<p className="text-gray-600 text-sm mb-4">{module.description}</p>
73-
<span className="text-xs font-semibold text-gray-500">Coming Soon</span>
74-
</div>
75-
);
76-
}
51+
const ActionCard = ({
52+
title,
53+
description,
54+
icon: Icon,
55+
href,
56+
}: {
57+
title: string;
58+
description: string;
59+
icon: any;
60+
href: string;
61+
}) => (
62+
<Link href={href}>
63+
<div className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow cursor-pointer">
64+
<Icon className="w-8 h-8 text-blue-600 mb-3" />
65+
<h3 className="font-semibold text-gray-900">{title}</h3>
66+
<p className="text-sm text-gray-600 mt-1">{description}</p>
67+
<div className="flex items-center text-blue-600 text-sm font-medium mt-4">
68+
Manage <ArrowRight className="w-4 h-4 ml-2" />
69+
</div>
70+
</div>
71+
</Link>
72+
);
73+
74+
return (
75+
<div className="flex-1 p-8">
76+
{/* Header */}
77+
<div className="mb-8">
78+
<h1 className="text-3xl font-bold text-gray-900">Welcome back</h1>
79+
<p className="text-gray-600 mt-2">Manage your access control and track system activities</p>
80+
</div>
81+
82+
{/* Stats */}
83+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
84+
<StatCard title="Total Users" value={stats.users} icon={Users} />
85+
<StatCard title="Total Roles" value={stats.roles} icon={Shield} />
86+
<StatCard title="Total Permissions" value={stats.permissions} icon={Lock} />
87+
</div>
7788

78-
return (
79-
<Link key={module.title} href={module.href}>
80-
<div
81-
className={`rounded-lg border-2 p-6 transition cursor-pointer ${
82-
colorClasses[module.color as keyof typeof colorClasses]
83-
}`}
84-
>
85-
<Icon
86-
className={`w-8 h-8 mb-3 ${iconColorClasses[module.color as keyof typeof iconColorClasses]}`}
87-
/>
88-
<h3 className="text-lg font-semibold text-gray-900 mb-2">{module.title}</h3>
89-
<p className="text-gray-600 text-sm mb-4">{module.description}</p>
90-
<span className={`text-sm font-semibold ${buttonColorClasses[module.color as keyof typeof buttonColorClasses]}`}>
91-
Access →
92-
</span>
93-
</div>
94-
</Link>
95-
);
96-
})}
89+
{/* Quick Actions */}
90+
<div className="mb-8">
91+
<h2 className="text-xl font-bold text-gray-900 mb-4">Quick Actions</h2>
92+
<p className="text-gray-600 mb-6">Manage your system resources</p>
93+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
94+
<ActionCard
95+
title="Manage Users"
96+
description="View & edit users"
97+
icon={Users}
98+
href="/admin/rbac?tab=users"
99+
/>
100+
<ActionCard
101+
title="Manage Roles"
102+
description="Configure roles"
103+
icon={Shield}
104+
href="/admin/rbac?tab=roles"
105+
/>
106+
<ActionCard
107+
title="Permissions"
108+
description="Control access"
109+
icon={Lock}
110+
href="/admin/rbac?tab=permissions"
111+
/>
97112
</div>
98113
</div>
99114
</div>

0 commit comments

Comments
 (0)