import React, { useMemo } from 'react'; import { GripVertical, X, Users, User } from 'lucide-react'; import { Appointment, Resource } from '../../types'; import { startOfWeek, endOfWeek, isWithinInterval } from 'date-fns'; interface CapacityWidgetProps { appointments: Appointment[]; resources: Resource[]; isEditing?: boolean; onRemove?: () => void; } const CapacityWidget: React.FC = ({ appointments, resources, isEditing, onRemove, }) => { const capacityData = useMemo(() => { const now = new Date(); const weekStart = startOfWeek(now, { weekStartsOn: 1 }); const weekEnd = endOfWeek(now, { weekStartsOn: 1 }); // Calculate for each resource const resourceStats = resources.map((resource) => { // Filter appointments for this resource this week const resourceAppointments = appointments.filter( (appt) => appt.resourceId === resource.id && isWithinInterval(new Date(appt.startTime), { start: weekStart, end: weekEnd }) && appt.status !== 'CANCELLED' ); // Calculate total booked minutes const bookedMinutes = resourceAppointments.reduce( (sum, appt) => sum + appt.durationMinutes, 0 ); // Assume 8 hours/day, 5 days/week = 2400 minutes capacity const totalCapacityMinutes = 8 * 60 * 5; const utilization = Math.min((bookedMinutes / totalCapacityMinutes) * 100, 100); return { id: resource.id, name: resource.name, utilization: Math.round(utilization), bookedHours: Math.round(bookedMinutes / 60), }; }); // Calculate overall utilization const totalBooked = resourceStats.reduce((sum, r) => sum + r.bookedHours, 0); const totalCapacity = resources.length * 40; // 40 hours/week per resource const overallUtilization = totalCapacity > 0 ? Math.round((totalBooked / totalCapacity) * 100) : 0; return { overall: overallUtilization, resources: resourceStats.sort((a, b) => b.utilization - a.utilization), }; }, [appointments, resources]); const getUtilizationColor = (utilization: number) => { if (utilization >= 80) return 'bg-green-500'; if (utilization >= 50) return 'bg-yellow-500'; return 'bg-gray-300 dark:bg-gray-600'; }; const getUtilizationTextColor = (utilization: number) => { if (utilization >= 80) return 'text-green-600 dark:text-green-400'; if (utilization >= 50) return 'text-yellow-600 dark:text-yellow-400'; return 'text-gray-500 dark:text-gray-400'; }; return (
{isEditing && ( <>
)}

Capacity This Week

{capacityData.overall}%
{capacityData.resources.length === 0 ? (

No resources configured

) : (
{capacityData.resources.map((resource) => (
{resource.name}
{resource.utilization}%
))}
)}
); }; export default CapacityWidget;