diff --git a/apps/dashboard/src/app/(dashboard)/page.tsx b/apps/dashboard/src/app/(dashboard)/page.tsx index ac4bc3a..d9a6466 100644 --- a/apps/dashboard/src/app/(dashboard)/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/page.tsx @@ -2,13 +2,25 @@ import Link from 'next/link' import { useEffect, useState } from 'react' -import { Calendar, Car, Users, DollarSign, AlertTriangle, Clock, XCircle, Plus, BarChart3, FileText, TrendingUp } from 'lucide-react' +import { Calendar, Car, Users, DollarSign, AlertTriangle, Clock, XCircle, Plus, BarChart3, FileText, TrendingUp, MapPin } from 'lucide-react' import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts' import StatCard from '@/components/ui/StatCard' import { EMPLOYEE_PROFILE_KEY, apiFetch } from '@/lib/api' import { useDashboardI18n } from '@/components/I18nProvider' import { formatCurrency } from '@rentaldrivego/types' +/** + * Location breakdown item — requires backend field on /analytics/dashboard. + * Flagged as a contract change (not faked). + */ +interface LocationBreakdown { + name: string + bookingCount: number + revenue: number + /** 0–100 utilization percentage */ + utilizationPct: number +} + interface DashboardData { kpis: { totalBookings: number @@ -19,6 +31,12 @@ interface DashboardData { vehiclesChange: number revenueChange: number customersChange: number + /** Requires backend field — flagged as contract change */ + utilizationRate?: number + /** Requires backend field — flagged as contract change */ + revenuePerVehicle?: number + /** Requires backend field — flagged as contract change */ + fulfillmentRate?: number } recentReservations: { id: string @@ -31,6 +49,8 @@ interface DashboardData { totalAmount: number }[] sourceBreakdown: { source: string; count: number; revenue: number }[] + /** Requires backend field — flagged as contract change */ + locationBreakdown?: LocationBreakdown[] subscription: { status: string planName: string @@ -132,6 +152,48 @@ function SubscriptionBanner({ ) } +function BranchPerformanceList({ + locations, + formatCurrencyFn, +}: { + locations: LocationBreakdown[] + formatCurrencyFn: (amount: number, currency: string) => string +}) { + const maxCount = Math.max(...locations.map((l) => l.bookingCount), 1) + + return ( +