import type { ReactNode } from "react"; import { Box, Button, Group, Paper, Stack, Text, ThemeIcon, Title } from "@mantine/core"; import type { LucideIcon } from "lucide-react"; import { AlertTriangle, CheckCircle2, Clock, Inbox, LayoutList, Plus, RefreshCw, } from "lucide-react"; import { freightBrand } from "@/theme/freight-brand"; import type { BookingListSummaryMetrics, BookingListSummaryTabs, } from "@/services/bookings.service"; const HERO_GRADIENT = `linear-gradient(135deg, ${freightBrand.primaryDark} 0%, ${freightBrand.primary} 48%, ${freightBrand.primaryLight} 120%)`; /** Lifecycle stages for the pipeline distribution bar (in flow order). */ const PIPELINE_STAGES: Array<{ key: keyof BookingListSummaryTabs; label: string; color: string; }> = [ { key: "intake", label: "Intake", color: "#38bdf8" }, { key: "in_approval", label: "Approval", color: "#fbbf24" }, { key: "approved_contract", label: "Contract", color: "#a78bfa" }, { key: "payment", label: "Payment", color: "#fb923c" }, { key: "operations", label: "Operations", color: "#2dd4bf" }, { key: "completed", label: "Completed", color: "#86efac" }, ]; export interface BookingRequestsHeaderProps { metrics?: BookingListSummaryMetrics; tabs?: BookingListSummaryTabs; loading?: boolean; isFetching?: boolean; onCreate: () => void; onRefresh: () => void; } export function BookingRequestsHeader({ metrics, tabs, loading, isFetching, onCreate, onRefresh, }: BookingRequestsHeaderProps) { const val = (n?: number) => (loading ? "—" : (n ?? 0)); return ( {/* decorative glows */} Operations Booking Requests Track every booking from submission through approval, payment, and dispatch — prioritize what needs action. {tabs ? : null} ); } /** Compact ring gauge with the stat icon at its center. */ function MiniDonut({ pct, color = "white", children, size = 52, stroke = 5, }: { pct?: number | null; color?: string; children: ReactNode; size?: number; stroke?: number; }) { const radius = (size - stroke) / 2; const circumference = 2 * Math.PI * radius; const clamped = pct != null ? Math.min(100, Math.max(0, Math.round(pct))) : null; const dash = clamped != null ? (clamped / 100) * circumference : 0; return ( {clamped != null ? ( ) : null} {children} ); } function HeroStat({ icon: Icon, label, value, hint, ratio, ratioColor = "white", }: { icon: LucideIcon; label: string; value: ReactNode; hint?: string; ratio?: number; ratioColor?: string; }) { const pct = ratio != null ? Math.round(Math.min(1, Math.max(0, ratio)) * 100) : null; return ( {label} {value} {pct != null ? `${pct}% of queue` : hint} ); } function PipelineBar({ tabs }: { tabs: BookingListSummaryTabs }) { const segments = PIPELINE_STAGES.map((s) => ({ ...s, count: tabs[s.key] ?? 0 })); const total = segments.reduce((sum, s) => sum + s.count, 0); return ( Booking pipeline {total} active {total > 0 ? ( segments.map((s) => s.count > 0 ? ( ) : null, ) ) : ( )} {segments.map((s) => ( {s.label} {s.count} ))} ); }