import React, { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import AdminLayout from '@/Layouts/AdminLayout';
import {
Users,
ShieldCheck,
CreditCard,
BadgeDollarSign,
CheckCircle,
ArrowRight,
ArrowUpRight,
MessageSquare,
TrendingUp,
Percent,
PieChart,
Sparkles
} from 'lucide-react';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
export default function Dashboard({ stats, recent_verifications, recent_subscriptions }) {
const [activeTrendTab, setActiveTrendTab] = useState('All');
const [selectedSlice, setSelectedSlice] = useState(null);
// Dynamic trend monthly data for custom SVG Line chart
const trendData = stats?.trend_data || [
{ month: 'Dec', basic: 0, premium: 0, vip: 0 },
{ month: 'Jan', basic: 0, premium: 0, vip: 0 },
{ month: 'Feb', basic: 0, premium: 0, vip: 0 },
{ month: 'Mar', basic: 0, premium: 0, vip: 0 },
{ month: 'Apr', basic: 0, premium: 0, vip: 0 },
{ month: 'May', basic: 0, premium: 0, vip: 0 }
];
const maxVal = Math.max(
10,
...trendData.map(d => Math.max(d.basic || 0, d.premium || 0, d.vip || 0))
);
// Compute lines points for SVG Spline
const getCoordinatesForLine = (key, height, width, max) => {
const points = [];
const paddingLeft = 35;
const paddingRight = 15;
const paddingTop = 20;
const paddingBottom = 25;
const graphHeight = height - paddingTop - paddingBottom;
const graphWidth = width - paddingLeft - paddingRight;
trendData.forEach((d, idx) => {
const val = d[key] || 0;
const x = paddingLeft + (idx / (trendData.length - 1)) * graphWidth;
const y = paddingTop + graphHeight - (val / max) * graphHeight;
points.push(`${x},${y}`);
});
return points.join(' ');
};
return (
{/* Welcome banner */}
System Status: Online
Welcome back, Administrator
UAE domestic workers platform is operating optimally. {stats?.verifications_today || 0} automated verifications completed today.
Full Analytics Hub
{/* Stat Cards Row */}
{/* Total Workers & active/inactive */}
{stats?.total_workers?.toLocaleString() || 0}
{stats?.active_workers || 0} Active
•
{stats?.inactive_workers || 0} Inactive
{/* Verification Stats */}
{stats?.verification_rate || 0}%
{stats?.verified_workers_count?.toLocaleString() || 0} Profiles Auto-OCR Verified
{/* Chat-To-Hire and Hiring Conversion */}
{stats?.hiring_conversion_rate || 0}%
{stats?.chat_to_hire_rate || 0}% Chat-to-Hire
{/* Subscription Revenue */}
Monthly Subscription Revenue
AED {stats?.revenue_this_month_aed?.toLocaleString() || 0}
+{stats?.new_employers_this_week || 0} Employers Added This Week
{/* Required Analytics and Graphical reports */}
{/* 1. Subscription Trends Spline Chart */}
Subscription Sign-ups Trend
Growth curves across basic, premium & VIP plans
{/* Selector Tabs */}
{['All', 'Premium', 'VIP'].map((tab) => (
))}
{/* Custom SVG Line Chart */}
{/* Custom Legend */}
Basic Search ({trendData[trendData.length - 1]?.basic || 0})
Premium Pass ({trendData[trendData.length - 1]?.premium || 0})
VIP Concierge ({trendData[trendData.length - 1]?.vip || 0})
{/* 2. Worker Availability Report Donut Chart */}
Worker Availability Status Reports
Real-time availability of candidates pool
{(() => {
const activeVal = stats?.worker_availability?.['Active'] || 0;
const hiddenVal = stats?.worker_availability?.['Hidden'] || 0;
const hiredVal = stats?.worker_availability?.['Hired'] || 0;
const totalVal = activeVal + hiddenVal + hiredVal;
const activePct = totalVal > 0 ? Math.round((activeVal / totalVal) * 100) : 0;
const hiddenPct = totalVal > 0 ? Math.round((hiddenVal / totalVal) * 100) : 0;
const hiredPct = totalVal > 0 ? Math.round((hiredVal / totalVal) * 100) : 0;
return (
{/* Custom Donut Chart */}
{/* Interactive legends */}
{activeVal} ({activePct}%)
{hiddenVal} ({hiddenPct}%)
);
})()}
{/* 3. Hiring Funnel & Chat-To-Hire Conversion */}
Hiring Conversion & Chat-to-Hire funnel
Platform-wide worker placement workflow stats
{(() => {
const funnelData = stats?.funnel || {
profiles_browsed: 0,
chats_initiated: 0,
candidates_shortlisted: 0,
workers_hired: 0
};
const browsed = funnelData.profiles_browsed || 0;
const chats = funnelData.chats_initiated || 0;
const shortlisted = funnelData.candidates_shortlisted || 0;
const hired = funnelData.workers_hired || 0;
const funnelSteps = [
{ stage: 'Profiles Browsed', val: browsed.toLocaleString(), pct: '100%', bg: 'bg-slate-100 border-slate-200 text-slate-600' },
{ stage: 'Chats Initiated', val: chats.toLocaleString(), pct: browsed > 0 ? `${((chats / browsed) * 100).toFixed(1)}%` : '0%', bg: 'bg-teal-50 border-teal-100 text-teal-700' },
{ stage: 'Candidates Shortlisted', val: shortlisted.toLocaleString(), pct: browsed > 0 ? `${((shortlisted / browsed) * 100).toFixed(1)}%` : '0%', bg: 'bg-blue-50 border-blue-100 text-blue-700' },
{ stage: 'Workers Hired', val: hired.toLocaleString(), pct: browsed > 0 ? `${((hired / browsed) * 100).toFixed(1)}%` : '0%', bg: 'bg-emerald-50 border-emerald-100 text-emerald-700' }
];
return funnelSteps.map((step, i) => (
{i < 3 && (
)}
Step 0{i+1}
{step.stage}
{step.val}
Ratio: {step.pct}
));
})()}
);
}