Skip to content

Commit 0246c69

Browse files
committed
Enhance Admin and Doctor Dashboards with Navigation and Statistics
1 parent 830635a commit 0246c69

File tree

3 files changed

+734
-63
lines changed

3 files changed

+734
-63
lines changed

front_end/src/pages/AdminDashboard.jsx

Lines changed: 218 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
import { useEffect, useState } from 'react';
2+
import {
3+
Stethoscope, User, Calendar, Activity, Pill, Ambulance,
4+
DollarSign, MessageSquare, ClipboardList, Users, AlertCircle
5+
} from 'lucide-react';
26
import Layout from '../components/Layout/Layout';
7+
import StatCard from '../components/UI/StatCard';
8+
import DataTable from '../components/UI/DataTable';
9+
import StatusBadge from '../components/UI/StatusBadge';
10+
import AdminFeedback from './AdminFeedback';
11+
import AdminAmbulances from './AdminAmbulances';
12+
import AdminBilling from './AdminBilling';
13+
import AdminLabs from './AdminLabs';
14+
import AdminPharmacy from './AdminPharmacy';
15+
import AdminAppointments from './AdminAppointments';
16+
import AdminPatients from './AdminPatients';
17+
import AdminDoctors from './AdminDoctors';
18+
import AdminUsers from './AdminUsers';
19+
20+
// Sample data for demonstration (replace with actual API calls)
21+
const sampleCriticalPatients = [
22+
{ id: 'P1001', name: 'John Doe', condition: 'Cardiac Arrest', status: 'critical' },
23+
{ id: 'P1002', name: 'Jane Smith', condition: 'Severe Trauma', status: 'critical' },
24+
];
25+
26+
const sampleRecentAppointments = [
27+
{ id: 'A1001', patient: 'John Doe', doctor: 'Dr. Smith', date: '2025-07-25T10:00:00', status: 'completed' },
28+
{ id: 'A1002', patient: 'Jane Smith', doctor: 'Dr. Johnson', date: '2025-07-25T14:30:00', status: 'confirmed' },
29+
];
330

431
const statsEndpoints = [
5-
{ label: 'Doctors', endpoint: '/api/doctors/stats/total', key: 'doctors' },
6-
{ label: 'Patients', endpoint: '/api/patients/stats/total', key: 'patients' },
7-
{ label: 'Appointments', endpoint: '/api/appointments/stats/total', key: 'appointments' },
8-
{ label: 'Billing', endpoint: '/api/appointments/stats/billing', key: 'billing' },
9-
{ label: 'Pharmacy', endpoint: '/api/pharmacy/stats/total', key: 'pharmacy' },
10-
{ label: 'Labs', endpoint: '/api/lab/stats/total', key: 'labs' },
32+
{ label: 'Doctors', endpoint: '/api/doctors/stats/total', key: 'doctors', icon: Stethoscope, color: 'blue' },
33+
{ label: 'Patients', endpoint: '/api/patients/stats/total', key: 'patients', icon: User, color: 'green' },
34+
{ label: 'Today Patients', endpoint: '/api/patients/stats/today', key: 'todayPatients', icon: User, color: 'teal' },
35+
{ label: 'Critical Patients', endpoint: '/api/patients/stats/critical', key: 'criticalPatients', icon: AlertCircle, color: 'red' },
36+
{ label: 'Appointments', endpoint: '/api/appointments/stats/total', key: 'appointments', icon: Calendar, color: 'purple' },
37+
{ label: 'Billing', endpoint: '/api/appointments/stats/billing', key: 'billing', icon: DollarSign, color: 'yellow' },
38+
{ label: 'Pharmacy', endpoint: '/api/pharmacy/stats/total', key: 'pharmacy', icon: Pill, color: 'pink' },
39+
{ label: 'Labs', endpoint: '/api/lab/stats/total', key: 'labs', icon: Activity, color: 'indigo' },
40+
{ label: 'Feedbacks', endpoint: '/api/feedback/stats/total', key: 'feedbacks', icon: MessageSquare, color: 'orange' },
1141
];
1242

1343
export default function AdminDashboard() {
1444
const [stats, setStats] = useState({});
1545
const [loading, setLoading] = useState(true);
46+
const [activeTab, setActiveTab] = useState('overview');
1647

1748
useEffect(() => {
1849
async function fetchStats() {
@@ -36,16 +67,188 @@ export default function AdminDashboard() {
3667

3768
return (
3869
<Layout>
39-
<h1 className="text-3xl font-bold mb-6">Admin Dashboard</h1>
40-
<div className="grid grid-cols-2 md:grid-cols-3 gap-6 mb-8">
41-
{statsEndpoints.map(({ label, key }) => (
42-
<div key={key} className="bg-white rounded-xl shadow p-6 flex flex-col items-center">
43-
<div className="text-2xl font-semibold text-blue-600 mb-2">{label}</div>
44-
<div className="text-4xl font-bold text-gray-800">{loading ? '...' : stats[key] ?? 0}</div>
45-
</div>
70+
<div className="flex items-center justify-between mb-6">
71+
<h1 className="text-3xl font-bold text-green-800 flex items-center">
72+
<ClipboardList className="mr-3 w-8 h-8" />
73+
Admin Dashboard
74+
</h1>
75+
<div className="text-lg text-gray-600">
76+
System Overview
77+
</div>
78+
</div>
79+
80+
{/* Navigation Tabs */}
81+
<div className="flex border-b border-gray-200 mb-6 overflow-x-auto">
82+
{[
83+
{ id: 'overview', icon: ClipboardList, label: 'Overview' },
84+
{ id: 'users', icon: Users, label: 'Users' },
85+
{ id: 'doctors', icon: Stethoscope, label: 'Doctors' },
86+
{ id: 'patients', icon: User, label: 'Patients' },
87+
{ id: 'appointments', icon: Calendar, label: 'Appointments' },
88+
{ id: 'pharmacy', icon: Pill, label: 'Pharmacy' },
89+
{ id: 'labs', icon: Activity, label: 'Labs' },
90+
{ id: 'billing', icon: DollarSign, label: 'Billing' },
91+
{ id: 'ambulances', icon: Ambulance, label: 'Ambulances' },
92+
{ id: 'feedback', icon: MessageSquare, label: 'Feedback' },
93+
].map((tab) => (
94+
<button
95+
key={tab.id}
96+
className={`flex-shrink-0 flex items-center px-4 py-2 ${activeTab === tab.id ? 'border-b-2 border-green-600 text-green-700 font-medium' : 'text-gray-600 hover:text-green-600'}`}
97+
onClick={() => setActiveTab(tab.id)}
98+
>
99+
<tab.icon className="w-5 h-5 mr-2" />
100+
{tab.label}
101+
</button>
46102
))}
47103
</div>
48-
{/* Management tables and navigation will go here */}
104+
105+
{/* Overview Tab */}
106+
{activeTab === 'overview' && (
107+
<div className="space-y-8">
108+
109+
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
110+
{statsEndpoints.map(({ label, key, icon, color }) => (
111+
<StatCard
112+
key={key}
113+
icon={icon}
114+
title={label}
115+
value={loading ? '...' : stats[key] ?? 0}
116+
color={color}
117+
/>
118+
))}
119+
</div>
120+
121+
{/* Critical Patients Section */}
122+
<div className="bg-white rounded-xl shadow-md p-6">
123+
<h2 className="text-xl font-semibold mb-4 flex items-center">
124+
<AlertCircle className="mr-2 text-red-600" />
125+
Critical Patients
126+
</h2>
127+
<DataTable
128+
columns={[
129+
{ header: 'Patient ID', accessor: 'id' },
130+
{ header: 'Name', accessor: 'name' },
131+
{ header: 'Condition', accessor: 'condition' },
132+
{
133+
header: 'Status',
134+
accessor: 'status',
135+
cell: (value) => <StatusBadge status={value} />
136+
}
137+
]}
138+
data={sampleCriticalPatients}
139+
emptyMessage="No critical patients currently"
140+
/>
141+
</div>
142+
143+
{/* Recent Appointments Section */}
144+
<div className="bg-white rounded-xl shadow-md p-6">
145+
<h2 className="text-xl font-semibold mb-4 flex items-center">
146+
<Calendar className="mr-2 text-blue-600" />
147+
Recent Appointments
148+
</h2>
149+
<DataTable
150+
columns={[
151+
{ header: 'Appointment ID', accessor: 'id' },
152+
{ header: 'Patient', accessor: 'patient' },
153+
{ header: 'Doctor', accessor: 'doctor' },
154+
{
155+
header: 'Date',
156+
accessor: 'date',
157+
cell: (value) => new Date(value).toLocaleString()
158+
},
159+
{
160+
header: 'Status',
161+
accessor: 'status',
162+
cell: (value) => <StatusBadge status={value} />
163+
}
164+
]}
165+
data={sampleRecentAppointments}
166+
emptyMessage="No recent appointments"
167+
/>
168+
</div>
169+
</div>
170+
)}
171+
172+
{/* Users Tab */}
173+
{activeTab === 'users' && (
174+
<div className="bg-white rounded-xl shadow-md p-6">
175+
<AdminUsers />
176+
<h2 className="text-xl font-semibold mb-4">Users Management</h2>
177+
<p className="text-gray-500">Users management content would be loaded here</p>
178+
</div>
179+
)}
180+
181+
{/* Doctors Tab */}
182+
{activeTab === 'doctors' && (
183+
<div className="bg-white rounded-xl shadow-md p-6">
184+
<AdminDoctors />
185+
<h2 className="text-xl font-semibold mb-4">Doctors Management</h2>
186+
<p className="text-gray-500">Doctors management content would be loaded here</p>
187+
</div>
188+
)}
189+
190+
{/* Patients Tab */}
191+
{activeTab === 'patients' && (
192+
<div className="bg-white rounded-xl shadow-md p-6">
193+
<AdminPatients />
194+
<h2 className="text-xl font-semibold mb-4">Patients Management</h2>
195+
<p className="text-gray-500">Patients management content would be loaded here</p>
196+
</div>
197+
)}
198+
199+
{/* Appointments Tab */}
200+
{activeTab === 'appointments' && (
201+
<div className="bg-white rounded-xl shadow-md p-6">
202+
<AdminAppointments />
203+
<h2 className="text-xl font-semibold mb-4">Appointments Management</h2>
204+
<p className="text-gray-500">Appointments management content would be loaded here</p>
205+
</div>
206+
)}
207+
208+
{/* Pharmacy Tab */}
209+
{activeTab === 'pharmacy' && (
210+
<div className="bg-white rounded-xl shadow-md p-6">
211+
<AdminPharmacy />
212+
<h2 className="text-xl font-semibold mb-4">Pharmacy Management</h2>
213+
<p className="text-gray-500">Pharmacy management content would be loaded here</p>
214+
</div>
215+
)}
216+
217+
{/* Labs Tab */}
218+
{activeTab === 'labs' && (
219+
<div className="bg-white rounded-xl shadow-md p-6">
220+
<AdminLabs />
221+
<h2 className="text-xl font-semibold mb-4">Laboratory Management</h2>
222+
<p className="text-gray-500">Laboratory management content would be loaded here</p>
223+
</div>
224+
)}
225+
226+
{/* Billing Tab */}
227+
{activeTab === 'billing' && (
228+
<div className="bg-white rounded-xl shadow-md p-6">
229+
<AdminBilling />
230+
<h2 className="text-xl font-semibold mb-4">Billing Management</h2>
231+
<p className="text-gray-500">Billing management content would be loaded here</p>
232+
</div>
233+
)}
234+
235+
{/* Ambulances Tab */}
236+
{activeTab === 'ambulances' && (
237+
<div className="bg-white rounded-xl shadow-md p-6">
238+
<AdminAmbulances />
239+
<h2 className="text-xl font-semibold mb-4">Ambulance Services</h2>
240+
<p className="text-gray-500">Ambulance services content would be loaded here</p>
241+
</div>
242+
)}
243+
244+
{/* Feedback Tab */}
245+
{activeTab === 'feedback' && (
246+
<div className="bg-white rounded-xl shadow-md p-6">
247+
<AdminFeedback />
248+
<h2 className="text-xl font-semibold mb-4">Patient Feedback</h2>
249+
<p className="text-gray-500">Patient feedback content would be loaded here</p>
250+
</div>
251+
)}
49252
</Layout>
50253
);
51-
}
254+
}

0 commit comments

Comments
 (0)