56 lines
1.7 KiB
JavaScript
56 lines
1.7 KiB
JavaScript
import { useEffect, useState } from 'react';
|
|
import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
|
import { adminApi } from './adminApi.js';
|
|
|
|
export default function DashboardPage() {
|
|
const [dashboard, setDashboard] = useState(null);
|
|
const [error, setError] = useState('');
|
|
|
|
useEffect(() => {
|
|
adminApi('/api/admin/dashboard')
|
|
.then(setDashboard)
|
|
.catch((loadError) => setError(loadError.message));
|
|
}, []);
|
|
|
|
if (error) {
|
|
return <p className="text-red-700">{error}</p>;
|
|
}
|
|
|
|
if (!dashboard) {
|
|
return <p>Loading dashboard…</p>;
|
|
}
|
|
|
|
const chart = Object.entries(dashboard.counts).map(([status, count]) => ({ status, count }));
|
|
const cards = [
|
|
['Submitted today', dashboard.submittedToday],
|
|
['Submitted this week', dashboard.submittedThisWeek],
|
|
['Surveys completed', dashboard.surveysCompleted],
|
|
['Pending surveys', dashboard.pendingSurveys],
|
|
['Average review (hours)', dashboard.averageReviewHours ?? '—'],
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<h1 className="admin-title">Dashboard</h1>
|
|
<div className="mb-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
|
|
{cards.map(([label, value]) => (
|
|
<div key={label} className="admin-card admin-stat-card">
|
|
<p className="admin-stat-label">{label}</p>
|
|
<p className="admin-stat-value">{value}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="admin-card h-72">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<BarChart data={chart}>
|
|
<XAxis dataKey="status" />
|
|
<YAxis allowDecimals={false} />
|
|
<Tooltip />
|
|
<Bar dataKey="count" fill="#0f766e" />
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|