Files
Krow-workspace/frontend-web/src/pages/VendorDashboard.jsx
bwnyasse 554dc9f9e3 feat: Initialize monorepo structure and comprehensive documentation
This commit establishes the new monorepo architecture for the KROW Workforce platform.

Key changes include:
- Reorganized project into `frontend-web`, `mobile-apps`, `firebase`, `scripts`, and `secrets` directories.
- Updated `Makefile` to support the new monorepo layout and automate Base44 export integration.
- Fixed `scripts/prepare-export.js` for ES module compatibility and global component import resolution.
- Created and updated `CONTRIBUTING.md` for developer onboarding.
- Restructured, renamed, and translated all `docs/` files for clarity and consistency.
- Implemented an interactive internal launchpad with diagram viewing capabilities.
- Configured base Firebase project files (`firebase.json`, security rules).
- Updated `README.md` to reflect the new project structure and documentation overview.
2025-11-12 12:50:55 -05:00

740 lines
33 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useMemo } from "react";
import { base44 } from "@/api/base44Client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Link, useNavigate } from "react-router-dom";
import { createPageUrl } from "@/utils";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Award, TrendingUp, Users, DollarSign, CheckCircle2, Clock, UserCheck, Mail, Edit, Bot, ArrowRight, Rocket, Star, Brain, Check, Sparkles, Zap, Calendar, Package, MessageSquare, AlertTriangle, MapPin, BarChart3, RefreshCw, Download, X, Lightbulb, TrendingDown, Timer } from "lucide-react";
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, BarChart, Bar } from 'recharts';
import { format, startOfMonth, endOfMonth, subMonths, differenceInHours, parseISO } from "date-fns";
import { useToast } from "@/components/ui/use-toast";
const mockWorkers = [
{ id: 1, name: "Maria G.", skill: "Server", rating: 4.9, distance: 3.2, reliability: 0.99, pro: 2 },
{ id: 2, name: "Andre P.", skill: "Culinary", rating: 4.8, distance: 5.5, reliability: 0.96, pro: 3 },
{ id: 3, name: "Jae L.", skill: "Dishwasher", rating: 4.6, distance: 1.1, reliability: 0.93, pro: 1 },
{ id: 4, name: "Rita C.", skill: "Server", rating: 4.7, distance: 4.0, reliability: 0.95, pro: 2 },
{ id: 5, name: "Luis M.", skill: "Culinary", rating: 4.5, distance: 7.4, reliability: 0.9, pro: 1 },
];
const proColors = {
1: "bg-slate-200 text-slate-800",
2: "bg-blue-100 text-blue-900",
3: "bg-amber-100 text-amber-900",
};
const formatPct = (v) => `${Math.round(v * 100)}%`;
function AINudge({ text, cta, onCta, type = "success", onDismiss }) {
const [dismissed, setDismissed] = useState(false);
const handleDismiss = () => {
setDismissed(true);
if (onDismiss) onDismiss();
};
if (dismissed) return null;
const typeConfig = {
success: {
icon: Sparkles,
gradient: "from-emerald-500 via-teal-500 to-cyan-500",
bgGradient: "from-emerald-50/80 via-teal-50/80 to-cyan-50/80",
iconBg: "from-emerald-400 to-teal-500",
textColor: "text-emerald-900",
subTextColor: "text-emerald-700",
buttonColor: "from-emerald-600 to-teal-600 hover:from-emerald-700 hover:to-teal-700",
borderColor: "border-emerald-200/60",
glowColor: "shadow-emerald-200/50"
},
insight: {
icon: Lightbulb,
gradient: "from-amber-500 via-orange-500 to-yellow-500",
bgGradient: "from-amber-50/80 via-orange-50/80 to-yellow-50/80",
iconBg: "from-amber-400 to-orange-500",
textColor: "text-amber-900",
subTextColor: "text-amber-700",
buttonColor: "from-amber-600 to-orange-600 hover:from-amber-700 hover:to-orange-700",
borderColor: "border-amber-200/60",
glowColor: "shadow-amber-200/50"
},
achievement: {
icon: Award,
gradient: "from-purple-500 via-pink-500 to-rose-500",
bgGradient: "from-purple-50/80 via-pink-50/80 to-rose-50/80",
iconBg: "from-purple-400 to-pink-500",
textColor: "text-purple-900",
subTextColor: "text-purple-700",
buttonColor: "from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700",
borderColor: "border-purple-200/60",
glowColor: "shadow-purple-200/50"
}
};
const config = typeConfig[type];
const IconComponent = config.icon;
return (
<div className={`relative overflow-hidden rounded-2xl bg-gradient-to-r ${config.bgGradient} backdrop-blur-sm border-2 ${config.borderColor} shadow-lg ${config.glowColor} transition-all duration-300 hover:shadow-xl hover:scale-[1.02]`}>
<div className={`absolute top-0 left-0 right-0 h-1 bg-gradient-to-r ${config.gradient}`} />
<div className="flex items-start gap-4 p-5">
<div className={`flex-shrink-0 w-12 h-12 rounded-xl bg-gradient-to-br ${config.iconBg} flex items-center justify-center shadow-lg`}>
<IconComponent className="w-6 h-6 text-white" />
</div>
<div className="flex-1 min-w-0 pt-1">
<div className="flex items-start gap-2 mb-2">
<Badge className={`bg-gradient-to-r ${config.gradient} text-white border-0 shadow-md text-xs font-bold px-2 py-0.5`}>
AI INSIGHT
</Badge>
</div>
<p className={`${config.textColor} font-semibold text-base leading-relaxed`}>
{text}
</p>
</div>
<div className="flex items-center gap-2 flex-shrink-0">
{cta && (
<Button
size="sm"
onClick={onCta}
className={`bg-gradient-to-r ${config.buttonColor} text-white shadow-lg rounded-xl font-semibold px-4 py-2 transition-all duration-200`}
>
{cta}
<ArrowRight className="w-4 h-4 ml-2" />
</Button>
)}
<Button
size="icon"
variant="ghost"
onClick={handleDismiss}
className={`h-8 w-8 rounded-lg ${config.subTextColor} hover:bg-white/50 transition-colors`}
>
<X className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
}
export default function VendorDashboard() {
const navigate = useNavigate();
const queryClient = useQueryClient();
const { toast } = useToast();
const { data: user } = useQuery({
queryKey: ['current-user-vendor'],
queryFn: () => base44.auth.me(),
});
const { data: events } = useQuery({
queryKey: ['vendor-events'],
queryFn: async () => {
const allEvents = await base44.entities.Event.list('-date');
if (!user?.email) return [];
return allEvents.filter(e =>
e.vendor_name === user?.company_name ||
e.vendor_id === user?.id ||
e.created_by === user?.email
);
},
initialData: [],
enabled: !!user
});
const { data: staff } = useQuery({
queryKey: ['vendor-staff'],
queryFn: async () => {
const allStaff = await base44.entities.Staff.list();
if (!user?.company_name) return allStaff.slice(0, 10);
return allStaff.filter(s => s.vendor_name === user?.company_name);
},
initialData: [],
enabled: !!user
});
// Calculations
const todayOrders = events.filter(e => {
const eventDate = new Date(e.date);
const today = new Date();
return eventDate.toDateString() === today.toDateString();
});
const activeOrders = events.filter(e => e.status === "Active" || e.status === "Confirmed" || e.status === "In Progress");
const completedOrders = events.filter(e => e.status === "Completed");
const totalRevenue = completedOrders.reduce((sum, e) => sum + (e.total || 0), 0);
const currentMonth = new Date().getMonth();
const currentYear = new Date().getFullYear();
const thisMonthOrders = events.filter(e => {
const eventDate = new Date(e.date);
return eventDate.getMonth() === currentMonth &&
eventDate.getFullYear() === currentYear &&
(e.status === "Completed" || e.status === "Active");
});
const thisMonthRevenue = thisMonthOrders.reduce((sum, e) => sum + (e.total || 0), 0);
const activeStaff = staff.filter(s => s.employment_type !== "Medical Leave" && s.action !== "Inactive").length;
const avgRating = staff.reduce((sum, s) => sum + (s.rating || 0), 0) / (staff.length || 1);
const reliabilityScore = staff.reduce((sum, s) => sum + (s.reliability_score || 0), 0) / (staff.length || 1);
// Rapid Orders (urgent orders within 24 hours)
const rapidOrders = events
.filter(e => {
const eventDate = new Date(e.date);
const now = new Date();
const hoursUntil = differenceInHours(eventDate, now);
return hoursUntil > 0 && hoursUntil <= 24 &&
(e.status === "Active" || e.status === "Confirmed" || e.status === "Pending");
})
.sort((a, b) => new Date(a.date) - new Date(b.date))
.slice(0, 3);
// 6-month revenue and payroll trend
const last6Months = Array.from({ length: 6 }, (_, i) => {
const date = subMonths(new Date(), 5 - i);
return {
month: format(date, 'MMM'),
fullDate: date
};
});
const salesPayrollTrend = last6Months.map(({ month, fullDate }) => {
const monthStart = startOfMonth(fullDate);
const monthEnd = endOfMonth(fullDate);
const monthOrders = events.filter(e => {
const eventDate = new Date(e.date);
return eventDate >= monthStart && eventDate <= monthEnd && e.status === "Completed";
});
const sales = monthOrders.reduce((sum, e) => sum + (e.total || 0), 0);
const payroll = sales * 0.68; // Assume 68% payroll ratio
return { month, sales, payroll };
});
// Top clients with fill rates
const clientRevenue = completedOrders.reduce((acc, event) => {
const client = event.business_name || "Unknown";
if (!acc[client]) {
acc[client] = { name: client, revenue: 0, orders: 0, requested: 0, assigned: 0 };
}
acc[client].revenue += (event.total || 0);
acc[client].orders++;
acc[client].requested += (event.requested || 0);
acc[client].assigned += (event.assigned_staff?.length || 0);
return acc;
}, {});
const topClients = Object.values(clientRevenue)
.map(c => ({
...c,
fillRate: c.requested > 0 ? (c.assigned / c.requested) * 100 : 0
}))
.sort((a, b) => b.revenue - a.revenue)
.slice(0, 4);
// Top performers with shift counts
const topPerformers = staff
.filter(s => s.rating > 0)
.sort((a, b) => (b.rating || 0) - (a.rating || 0))
.slice(0, 3)
.map(s => ({
...s,
shifts: s.total_shifts || Math.floor(Math.random() * 30) + 5
}));
// Staff assigned today
const staffAssignedToday = todayOrders.reduce((sum, e) => sum + (e.requested || 0), 0);
// Avg speed to fill (mock calculation)
const avgSpeedToFill = "1h 12m";
const speedChange = "-14m";
const hour = new Date().getHours();
const greeting = hour < 12 ? "Good morning" : hour < 18 ? "Good afternoon" : "Good evening";
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50/20 to-slate-50">
<div className="max-w-[1800px] mx-auto p-6 space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-[#1C323E] mb-1">
{greeting}, {user?.full_name?.split(' ')[0] || 'Partner'}
</h1>
<p className="text-slate-600">Here's your performance overview</p>
</div>
<div className="flex items-center gap-3">
<Button variant="outline">
<RefreshCw className="w-4 h-4 mr-2" />
Refresh
</Button>
<Button className="bg-[#0A39DF] hover:bg-[#0A39DF]/90">
<Download className="w-4 h-4 mr-2" />
Export
</Button>
</div>
</div>
{/* Top KPI Metrics - NEW DESIGN */}
<div className="grid grid-cols-4 gap-4">
{/* Sales */}
<Card className="bg-gradient-to-br from-white to-slate-50 border-slate-200 shadow-sm hover:shadow-md transition-all">
<CardContent className="p-6">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-slate-100 rounded-lg flex items-center justify-center">
<TrendingUp className="w-5 h-5 text-slate-700" />
</div>
<div>
<p className="text-xs text-slate-500 font-medium">Sales (M1D)</p>
</div>
</div>
<p className="text-4xl font-bold text-[#1C323E] mb-1">
${Math.round(thisMonthRevenue / 1000)},000
</p>
<p className="text-sm text-emerald-600 font-medium">+5% vs last month</p>
</CardContent>
</Card>
{/* Payroll */}
<Card className="bg-gradient-to-br from-white to-slate-50 border-slate-200 shadow-sm hover:shadow-md transition-all">
<CardContent className="p-6">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-slate-100 rounded-lg flex items-center justify-center">
<DollarSign className="w-5 h-5 text-slate-700" />
</div>
<div>
<p className="text-xs text-slate-500 font-medium">Payroll (M1D)</p>
</div>
</div>
<p className="text-4xl font-bold text-[#1C323E] mb-1">
${Math.round(thisMonthRevenue * 0.68 / 1000)},000
</p>
<p className="text-sm text-slate-600 font-medium">68% of sales</p>
</CardContent>
</Card>
{/* Active Workforce */}
<Card className="bg-gradient-to-br from-white to-slate-50 border-slate-200 shadow-sm hover:shadow-md transition-all">
<CardContent className="p-6">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-slate-100 rounded-lg flex items-center justify-center">
<Users className="w-5 h-5 text-slate-700" />
</div>
<div>
<p className="text-xs text-slate-500 font-medium">Active Workforce</p>
</div>
</div>
<p className="text-4xl font-bold text-[#1C323E] mb-1">
{activeStaff}
</p>
<p className="text-sm text-slate-600 font-medium">+3 this week</p>
</CardContent>
</Card>
{/* Avg Speed to Fill */}
<Card className="bg-gradient-to-br from-white to-slate-50 border-slate-200 shadow-sm hover:shadow-md transition-all">
<CardContent className="p-6">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-slate-100 rounded-lg flex items-center justify-center">
<Timer className="w-5 h-5 text-slate-700" />
</div>
<div>
<p className="text-xs text-slate-500 font-medium">Avg Speed-to-Fill</p>
</div>
</div>
<p className="text-4xl font-bold text-[#1C323E] mb-1">
{avgSpeedToFill}
</p>
<p className="text-sm text-emerald-600 font-medium">{speedChange} vs last week</p>
</CardContent>
</Card>
</div>
{/* AI Insights */}
<div className="space-y-4">
<AINudge
text="Assigned 6 top-fit workers. Consider adding 1 trainee for fairness and skill development."
cta="Add Trainee"
type="success"
onCta={() => {}}
/>
<AINudge
text="You're outperforming 82% of vendors in your region. Share your Gold badge to attract premium clients!"
cta="Share Badge"
type="achievement"
onCta={() => {}}
/>
</div>
{/* Main Content Grid */}
<div className="grid grid-cols-3 gap-6">
{/* Left Column (2 cols) */}
<div className="col-span-2 space-y-6">
{/* RAPID ORDERS - NEW SECTION */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="border-b border-slate-100 pb-4">
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base flex items-center gap-2">
<Zap className="w-5 h-5 text-amber-500" />
Rapid Orders
</CardTitle>
<p className="text-xs text-slate-600 mt-1">Urgent orders within 24 hours</p>
</div>
{rapidOrders.length > 0 && (
<Badge className="bg-red-100 text-red-700 border-red-200 font-bold">
{rapidOrders.length} Urgent
</Badge>
)}
</div>
</CardHeader>
<CardContent className="p-5">
{rapidOrders.length > 0 ? (
<div className="space-y-4">
{rapidOrders.map((order) => {
const eventDate = order.date ? parseISO(order.date) : new Date();
const hoursUntil = differenceInHours(eventDate, new Date());
const assignedCount = order.assigned_staff?.length || 0;
const requestedCount = order.requested || 0;
const fillPercentage = requestedCount > 0 ? Math.round((assignedCount / requestedCount) * 100) : 0;
return (
<div key={order.id} className="p-4 rounded-xl bg-gradient-to-r from-red-50 to-orange-50 border-2 border-red-200 hover:border-red-300 transition-all">
<div className="flex items-start justify-between mb-3">
<div>
<div className="flex items-center gap-2 mb-1">
<h3 className="font-bold text-[#1C323E]">{order.business_name || "Client"} {order.event_name}</h3>
<Badge className="bg-red-500 text-white font-bold text-xs">
{hoursUntil}h left
</Badge>
</div>
<div className="flex items-center gap-4 text-sm text-slate-600">
<div className="flex items-center gap-1">
<Users className="w-4 h-4" />
<span>{assignedCount}/{requestedCount} filled</span>
</div>
<div className="flex items-center gap-1">
<Calendar className="w-4 h-4" />
<span>{format(eventDate, "h:mm a")}</span>
</div>
</div>
</div>
<div className="flex gap-2">
<Link to={createPageUrl(`EventDetail?id=${order.id}`)}>
<Button size="sm" variant="outline" className="rounded-lg">
View
</Button>
</Link>
<Button size="sm" className="bg-red-600 hover:bg-red-700 text-white rounded-lg font-semibold">
Quick Assign
</Button>
</div>
</div>
<div className="flex items-center gap-2">
<div className="flex-1 h-2 bg-white rounded-full overflow-hidden">
<div
className={`h-full transition-all duration-500 ${
fillPercentage < 60 ? 'bg-red-500' :
fillPercentage < 90 ? 'bg-amber-500' :
'bg-green-500'
}`}
style={{ width: `${fillPercentage}%` }}
/>
</div>
<span className="text-sm font-bold text-slate-700">{fillPercentage}%</span>
</div>
</div>
);
})}
</div>
) : (
<div className="text-center py-12">
<Zap className="w-12 h-12 mx-auto text-slate-300 mb-3" />
<p className="text-sm text-slate-500 font-medium">No urgent orders</p>
<p className="text-xs text-slate-400 mt-1">Orders within 24h will appear here</p>
</div>
)}
</CardContent>
</Card>
{/* Sales vs Payroll Chart */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="border-b border-slate-100 pb-4">
<CardTitle className="text-base flex items-center gap-2">
<TrendingUp className="w-5 h-5 text-[#0A39DF]" />
Sales vs Payroll
</CardTitle>
</CardHeader>
<CardContent className="p-6">
<ResponsiveContainer width="100%" height={280}>
<BarChart data={salesPayrollTrend}>
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" vertical={false} />
<XAxis
dataKey="month"
tick={{ fontSize: 12 }}
stroke="#94a3b8"
axisLine={false}
tickLine={false}
/>
<YAxis
tick={{ fontSize: 12 }}
stroke="#94a3b8"
axisLine={false}
tickLine={false}
tickFormatter={(value) => `${(value / 1000).toFixed(0)}k`}
/>
<Tooltip
contentStyle={{
fontSize: '12px',
backgroundColor: 'white',
border: '1px solid #e2e8f0',
borderRadius: '12px',
padding: '8px 12px'
}}
formatter={(value) => [`$${Math.round(value).toLocaleString()}`, '']}
/>
<Bar dataKey="payroll" fill="#1C323E" radius={[4, 4, 0, 0]} />
<Bar dataKey="sales" fill="#000000" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Client Analysis */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="border-b border-slate-100 pb-4">
<CardTitle className="text-base flex items-center gap-2">
<BarChart3 className="w-5 h-5 text-[#0A39DF]" />
Client Analysis
</CardTitle>
</CardHeader>
<CardContent className="p-6">
{topClients.length > 0 ? (
<div className="space-y-5">
{topClients.map((client) => (
<div key={client.name} className="space-y-2">
<div className="flex items-center justify-between">
<div>
<h4 className="font-bold text-[#1C323E]">{client.name}</h4>
<p className="text-xs text-slate-500">Fill</p>
</div>
<div className="text-right">
<p className="font-bold text-[#1C323E]">${(client.revenue / 1000).toFixed(0)}k</p>
<p className="text-xs text-slate-500">{Math.round(client.fillRate)}%</p>
</div>
</div>
<div className="w-full h-2 bg-slate-100 rounded-full overflow-hidden">
<div
className="h-full bg-[#1C323E] rounded-full transition-all duration-500"
style={{ width: `${client.fillRate}%` }}
/>
</div>
</div>
))}
</div>
) : (
<div className="text-center py-8">
<BarChart3 className="w-10 h-10 mx-auto text-slate-300 mb-2" />
<p className="text-sm text-slate-500">No client data</p>
</div>
)}
</CardContent>
</Card>
</div>
{/* Right Column (1 col) */}
<div className="space-y-6">
{/* Total Revenue Card - NEW DESIGN */}
<Card className="bg-gradient-to-br from-[#0A39DF] via-blue-700 to-[#1C323E] border-0 shadow-xl overflow-hidden">
<CardContent className="p-8 relative">
<div className="absolute top-4 right-4 flex gap-1.5">
<div className="w-2 h-2 bg-white/40 rounded-full"></div>
<div className="w-2 h-2 bg-white/40 rounded-full"></div>
<div className="w-2 h-2 bg-white rounded-full"></div>
</div>
<p className="text-white/80 text-sm mb-4 font-medium">Total Revenue</p>
<p className="text-6xl font-bold text-white mb-2">
${Math.round(totalRevenue / 1000)}k
</p>
<p className="text-white/70 text-sm">All time earnings</p>
</CardContent>
</Card>
{/* Quick Actions - NEW DESIGN */}
<div className="grid grid-cols-2 gap-3">
<Link to={createPageUrl("VendorOrders")}>
<Card className="bg-gradient-to-br from-[#0A39DF] to-blue-600 border-0 shadow-md hover:shadow-lg transition-all cursor-pointer group">
<CardContent className="p-6 text-center">
<div className="w-14 h-14 mx-auto mb-3 bg-white/20 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform">
<Package className="w-7 h-7 text-white" />
</div>
<p className="text-white font-bold text-base mb-1">All Orders</p>
<p className="text-white/70 text-xs">View & manage</p>
</CardContent>
</Card>
</Link>
<Link to={createPageUrl("StaffDirectory")}>
<Card className="bg-white border-slate-200 shadow-sm hover:shadow-md transition-all cursor-pointer group">
<CardContent className="p-6 text-center">
<div className="w-14 h-14 mx-auto mb-3 bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform">
<Users className="w-7 h-7 text-blue-600" />
</div>
<p className="text-[#1C323E] font-bold text-base mb-1">My Orders</p>
<p className="text-slate-500 text-xs">Manage staff</p>
</CardContent>
</Card>
</Link>
</div>
{/* Today's Metrics */}
<div className="grid grid-cols-2 gap-3">
<Card className="bg-white border-slate-200 shadow-sm">
<CardContent className="p-5">
<div className="flex items-center justify-between mb-3">
<div className="w-10 h-10 bg-blue-50 rounded-lg flex items-center justify-center">
<Calendar className="w-5 h-5 text-blue-600" />
</div>
<ArrowRight className="w-4 h-4 text-slate-300" />
</div>
<p className="text-3xl font-bold text-[#1C323E] mb-1">{todayOrders.length}</p>
<p className="text-sm text-slate-600">Orders Today</p>
</CardContent>
</Card>
<Card className="bg-white border-slate-200 shadow-sm">
<CardContent className="p-5">
<div className="flex items-center justify-between mb-3">
<div className="w-10 h-10 bg-purple-50 rounded-lg flex items-center justify-center">
<Package className="w-5 h-5 text-purple-600" />
</div>
<Badge className="bg-green-100 text-green-700 text-xs font-bold">Active</Badge>
</div>
<p className="text-3xl font-bold text-[#1C323E] mb-1">{activeOrders.length}</p>
<p className="text-sm text-slate-600">In Progress</p>
</CardContent>
</Card>
</div>
{/* Staff Assigned Today */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardContent className="p-5">
<div className="flex items-center justify-between mb-4">
<div className="w-10 h-10 bg-amber-50 rounded-lg flex items-center justify-center">
<Users className="w-5 h-5 text-amber-600" />
</div>
<Badge className="bg-amber-100 text-amber-700 text-xs font-bold">Today</Badge>
</div>
<p className="text-4xl font-bold text-[#1C323E] mb-1">{staffAssignedToday}</p>
<p className="text-sm text-slate-600">Staff Assigned</p>
</CardContent>
</Card>
{/* Top Clients - NEW DESIGN */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<Star className="w-4 h-4 text-amber-500" />
Top Clients
</CardTitle>
</CardHeader>
<CardContent className="p-4">
{topClients.slice(0, 3).length > 0 ? (
<div className="space-y-3">
{topClients.slice(0, 3).map((client) => (
<div key={client.name} className="flex items-center justify-between p-3 rounded-lg bg-slate-50 border border-slate-200">
<div>
<p className="font-bold text-sm text-[#1C323E]">{client.name}</p>
<p className="text-xs text-slate-500">+{client.orders}%</p>
</div>
<p className="font-bold text-[#1C323E]">${(client.revenue / 1000).toFixed(0)}k</p>
</div>
))}
</div>
) : (
<div className="text-center py-6">
<Star className="w-8 h-8 mx-auto text-slate-300 mb-2" />
<p className="text-xs text-slate-500">No client data</p>
</div>
)}
</CardContent>
</Card>
{/* Top Performers - NEW DESIGN */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<Award className="w-4 h-4 text-blue-500" />
Top Performers
</CardTitle>
</CardHeader>
<CardContent className="p-4">
{topPerformers.length > 0 ? (
<div className="space-y-3">
{topPerformers.map((member) => (
<div key={member.id} className="flex items-center justify-between p-3 rounded-lg bg-slate-50 border border-slate-200">
<div>
<p className="font-bold text-sm text-[#1C323E]">
{member.employee_name} - {member.position || "Staff"}
</p>
<p className="text-xs text-slate-500">{member.shifts} shifts</p>
</div>
<div className="flex items-center gap-1">
<span className="text-sm font-bold text-[#1C323E]">{(member.rating || 0).toFixed(1)}</span>
<Star className="w-3 h-3 text-amber-500 fill-amber-500" />
</div>
</div>
))}
</div>
) : (
<div className="text-center py-6">
<Award className="w-8 h-8 mx-auto text-slate-300 mb-2" />
<p className="text-xs text-slate-500">No staff data</p>
</div>
)}
</CardContent>
</Card>
{/* Gold Vendors - NEW SECTION */}
<Card className="bg-white border-slate-200 shadow-sm">
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<Award className="w-4 h-4 text-amber-500" />
Gold Vendors
</CardTitle>
</CardHeader>
<CardContent className="p-4">
<div className="space-y-3">
<div className="flex items-center justify-between p-3 rounded-lg bg-gradient-to-r from-amber-50 to-yellow-50 border border-amber-200">
<div>
<p className="font-bold text-sm text-[#1C323E]">Legendary Staffing</p>
<p className="text-xs text-slate-500">Score</p>
</div>
<p className="text-2xl font-bold text-amber-600">98</p>
</div>
<div className="flex items-center justify-between p-3 rounded-lg bg-gradient-to-r from-amber-50 to-yellow-50 border border-amber-200">
<div>
<p className="font-bold text-sm text-[#1C323E]">Epic Workforce</p>
<p className="text-xs text-slate-500">Score</p>
</div>
<p className="text-2xl font-bold text-amber-600">96</p>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
</div>
);
}