214 lines
12 KiB
JavaScript
214 lines
12 KiB
JavaScript
import React from 'react';
|
|
import { Head, Link, router } from '@inertiajs/react';
|
|
import AdminLayout from '@/Layouts/AdminLayout';
|
|
import {
|
|
Users,
|
|
ShieldAlert,
|
|
CreditCard,
|
|
BadgeDollarSign,
|
|
CheckCircle,
|
|
ArrowRight
|
|
} from 'lucide-react';
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from '@/components/ui/table';
|
|
|
|
export default function Dashboard({ stats, recent_verifications, recent_subscriptions }) {
|
|
const handleApprove = (id) => {
|
|
router.post('/admin/verifications/approve', { id });
|
|
};
|
|
|
|
const handleReject = (id) => {
|
|
router.post('/admin/verifications/reject', { id });
|
|
};
|
|
|
|
return (
|
|
<AdminLayout title="Dashboard Overview">
|
|
<Head title="Admin Dashboard" />
|
|
|
|
{/* Stat Cards Row */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-5 mb-8 font-sans">
|
|
{/* Total Workers */}
|
|
<div className="bg-white rounded-xl p-5 border border-gray-200 shadow-sm flex flex-col justify-between hover:shadow-md transition-shadow">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-gray-500">Total Workers</span>
|
|
<div className="w-10 h-10 bg-[#0F6E56]/10 rounded-lg flex items-center justify-center shadow-inner">
|
|
<Users className="w-5 h-5 text-[#0F6E56]" />
|
|
</div>
|
|
</div>
|
|
<div className="mt-4">
|
|
<h3 className="text-2xl font-bold text-gray-900 tracking-tight">
|
|
{stats?.total_workers?.toLocaleString() || 0}
|
|
</h3>
|
|
<p className="text-xs text-emerald-600 font-medium mt-1">+12% from last month</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Verified Today */}
|
|
<div className="bg-white rounded-xl p-5 border border-gray-200 shadow-sm flex flex-col justify-between hover:shadow-md transition-shadow">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-gray-500">Auto-Verified Today</span>
|
|
<div className="w-10 h-10 bg-emerald-50 rounded-lg flex items-center justify-center relative shadow-inner">
|
|
<CheckCircle className="w-5 h-5 text-emerald-600" />
|
|
</div>
|
|
</div>
|
|
<div className="mt-4 flex items-baseline justify-between">
|
|
<h3 className="text-2xl font-bold text-gray-900 tracking-tight">
|
|
12
|
|
</h3>
|
|
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold bg-emerald-100 text-emerald-800">
|
|
Automatic
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Active Subscriptions */}
|
|
<div className="bg-white rounded-xl p-5 border border-gray-200 shadow-sm flex flex-col justify-between hover:shadow-md transition-shadow">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-gray-500">Active Subscriptions</span>
|
|
<div className="w-10 h-10 bg-blue-50 rounded-lg flex items-center justify-center shadow-inner">
|
|
<CreditCard className="w-5 h-5 text-blue-600" />
|
|
</div>
|
|
</div>
|
|
<div className="mt-4">
|
|
<h3 className="text-2xl font-bold text-gray-900 tracking-tight">
|
|
{stats?.active_subscriptions?.toLocaleString() || 0}
|
|
</h3>
|
|
<p className="text-xs text-blue-600 font-medium mt-1">
|
|
+{stats?.new_employers_this_week || 0} new this week
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Monthly Revenue */}
|
|
<div className="bg-white rounded-xl p-5 border border-gray-200 shadow-sm flex flex-col justify-between hover:shadow-md transition-shadow">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-gray-500">Revenue This Month</span>
|
|
<div className="w-10 h-10 bg-emerald-50 rounded-lg flex items-center justify-center shadow-inner">
|
|
<BadgeDollarSign className="w-5 h-5 text-emerald-600" />
|
|
</div>
|
|
</div>
|
|
<div className="mt-4">
|
|
<h3 className="text-2xl font-bold text-gray-900 tracking-tight">
|
|
AED {stats?.revenue_this_month_aed?.toLocaleString() || 0}
|
|
</h3>
|
|
<p className="text-xs text-emerald-600 font-medium mt-1">Updated real-time</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Recent Verifications Section */}
|
|
<div className="bg-white rounded-xl border border-gray-200 shadow-sm mb-8 overflow-hidden font-sans">
|
|
<div className="p-5 border-b border-gray-100 flex items-center justify-between bg-white">
|
|
<div>
|
|
<h2 className="text-base font-semibold text-gray-800 tracking-tight">Recent Verifications</h2>
|
|
<p className="text-xs text-gray-500 mt-0.5">Profiles automatically verified via document proof</p>
|
|
</div>
|
|
<Link
|
|
href="/admin/workers/verifications"
|
|
className="text-xs font-semibold text-[#0F6E56] hover:text-[#085041] flex items-center transition-colors"
|
|
>
|
|
View audit logs <ArrowRight className="w-3.5 h-3.5 ml-1" />
|
|
</Link>
|
|
</div>
|
|
|
|
{recent_verifications && recent_verifications.length > 0 ? (
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow className="bg-slate-50/50 hover:bg-slate-50/50">
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Name</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Type</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Document</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Processed</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10 text-right pr-6">Status</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{recent_verifications.map((item) => (
|
|
<TableRow key={item.id} className="hover:bg-slate-50/80 transition-colors">
|
|
<TableCell className="font-medium text-gray-900 text-sm">{item.name}</TableCell>
|
|
<TableCell>
|
|
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
|
item.type === 'Worker' ? 'bg-teal-50 text-[#0F6E56]' : 'bg-indigo-50 text-indigo-700'
|
|
}`}>
|
|
{item.type}
|
|
</span>
|
|
</TableCell>
|
|
<TableCell className="text-sm text-gray-600">{item.document_type}</TableCell>
|
|
<TableCell className="text-xs text-gray-500">{item.processed_at}</TableCell>
|
|
<TableCell className="text-right pr-6">
|
|
<span className="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-semibold bg-emerald-100 text-emerald-800">
|
|
<CheckCircle className="w-3 h-3 mr-1" />
|
|
{item.status || 'Verified'}
|
|
</span>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
) : (
|
|
<div className="p-12 text-center flex flex-col items-center justify-center">
|
|
<CheckCircle className="w-12 h-12 text-emerald-500 mb-3" />
|
|
<h3 className="text-base font-semibold text-gray-800 tracking-tight">No recent activity</h3>
|
|
<p className="text-xs text-gray-500 mt-1">Automatic verification system is monitoring new registrations.</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Recent Subscriptions Section */}
|
|
<div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden font-sans">
|
|
<div className="p-5 border-b border-gray-100 flex items-center justify-between bg-white">
|
|
<div>
|
|
<h2 className="text-base font-semibold text-gray-800 tracking-tight">Recent Subscriptions</h2>
|
|
<p className="text-xs text-gray-500 mt-0.5">Latest employer subscription activations and renewals</p>
|
|
</div>
|
|
<Link
|
|
href="/admin/subscriptions"
|
|
className="text-xs font-semibold text-[#0F6E56] hover:text-[#085041] flex items-center transition-colors"
|
|
>
|
|
View all <ArrowRight className="w-3.5 h-3.5 ml-1" />
|
|
</Link>
|
|
</div>
|
|
|
|
{recent_subscriptions && recent_subscriptions.length > 0 ? (
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow className="bg-slate-50/50 hover:bg-slate-50/50">
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Employer</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Plan</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10">Amount</TableHead>
|
|
<TableHead className="font-semibold text-slate-600 text-xs h-10 text-right pr-6">Date</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{recent_subscriptions.map((item) => (
|
|
<TableRow key={item.id} className="hover:bg-slate-50/80 transition-colors">
|
|
<TableCell className="font-medium text-gray-900 text-sm">{item.employer_name}</TableCell>
|
|
<TableCell>
|
|
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-50 text-blue-700">
|
|
{item.plan_name}
|
|
</span>
|
|
</TableCell>
|
|
<TableCell className="text-sm font-medium text-gray-900">
|
|
AED {item.amount_aed}
|
|
</TableCell>
|
|
<TableCell className="text-xs text-gray-500 text-right pr-6">{item.subscribed_at}</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
) : (
|
|
<div className="p-12 text-center text-gray-500 text-xs font-medium">
|
|
No recent subscriptions found.
|
|
</div>
|
|
)}
|
|
</div>
|
|
</AdminLayout>
|
|
);
|
|
}
|