import React, { useState } from "react"; import { base44 } from "@/api/base44Client"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Calendar, Users, Check, Plus, X, Clock, MapPin, ChevronLeft, ChevronRight } from "lucide-react"; import { format } from "date-fns"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useToast } from "@/components/ui/use-toast"; const convertTo12Hour = (time24) => { if (!time24) return ''; const [hours, minutes] = time24.split(':'); const hour = parseInt(hours); const ampm = hour >= 12 ? 'PM' : 'AM'; const hour12 = hour % 12 || 12; return `${hour12}:${minutes} ${ampm}`; }; const getInitials = (name) => { if (!name) return 'S'; return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2); }; const avatarColors = [ 'bg-blue-500', 'bg-purple-500', 'bg-green-500', 'bg-orange-500', 'bg-pink-500', 'bg-indigo-500', 'bg-teal-500', 'bg-red-500', ]; export default function EventAssignmentModal({ open, onClose, order, onUpdate }) { const [selectedShiftIndex, setSelectedShiftIndex] = useState(0); const [selectedRoleIndex, setSelectedRoleIndex] = useState(0); const queryClient = useQueryClient(); const { toast } = useToast(); const { data: allStaff = [] } = useQuery({ queryKey: ['staff-for-assignment'], queryFn: () => base44.entities.Staff.list(), enabled: open, }); const updateOrderMutation = useMutation({ mutationFn: (updatedOrder) => base44.entities.Order.update(order.id, updatedOrder), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['orders'] }); if (onUpdate) onUpdate(); toast({ title: "Staff assigned successfully", description: "The order has been updated with new assignments.", }); }, }); if (!order || !order.shifts_data || order.shifts_data.length === 0) { return null; } const currentShift = order.shifts_data[selectedShiftIndex]; const currentRole = currentShift?.roles[selectedRoleIndex]; if (!currentRole) return null; const handleAssignStaff = (staffMember) => { const updatedOrder = { ...order }; const assignments = updatedOrder.shifts_data[selectedShiftIndex].roles[selectedRoleIndex].assignments || []; // Check if already assigned if (assignments.some(a => a.employee_id === staffMember.id)) { toast({ title: "Already assigned", description: `${staffMember.employee_name} is already assigned to this role.`, variant: "destructive", }); return; } // Add new assignment const newAssignment = { employee_id: staffMember.id, employee_name: staffMember.employee_name, position: currentRole.service, shift_date: order.event_date, shift_start: currentRole.start_time, shift_end: currentRole.end_time, location: currentShift.address || order.event_address, hub_location: order.hub_location, }; updatedOrder.shifts_data[selectedShiftIndex].roles[selectedRoleIndex].assignments = [ ...assignments, newAssignment ]; updateOrderMutation.mutate(updatedOrder); }; const handleRemoveStaff = (employeeId) => { const updatedOrder = { ...order }; const assignments = updatedOrder.shifts_data[selectedShiftIndex].roles[selectedRoleIndex].assignments || []; updatedOrder.shifts_data[selectedShiftIndex].roles[selectedRoleIndex].assignments = assignments.filter(a => a.employee_id !== employeeId); updateOrderMutation.mutate(updatedOrder); }; const assignments = currentRole.assignments || []; const needed = parseInt(currentRole.count) || 0; const assigned = assignments.length; const isFullyStaffed = assigned >= needed; // Filter available staff (not already assigned to this role) const assignedIds = new Set(assignments.map(a => a.employee_id)); const availableStaff = allStaff.filter(s => !assignedIds.has(s.id)); // Calculate total assignments across all roles in this shift let totalNeeded = 0; let totalAssigned = 0; currentShift.roles.forEach(role => { totalNeeded += parseInt(role.count) || 0; totalAssigned += role.assignments?.length || 0; }); return (
{order.event_name}

{order.client_business}

{isFullyStaffed ? 'Fully Staffed' : 'Needs Staff'}
{order.event_date ? format(new Date(order.event_date), 'EEEE, MMMM d, yyyy') : 'No date'}
{currentShift.address && (
{currentShift.address}
)}
{/* Staff Assignment Summary */}

Staff Assignment

= totalNeeded ? '#10b981' : '#f97316', color: totalAssigned >= totalNeeded ? '#10b981' : '#f97316' }} > {totalAssigned} / {totalNeeded}
{totalAssigned >= totalNeeded && (
Fully staffed
)}
{/* Position Selection */} {currentShift.roles.length > 1 && (
)} {/* Current Position Details */}

{currentRole.service}

= needed ? 'bg-green-100 text-green-700' : 'bg-orange-100 text-orange-700' } font-semibold`} > {assigned}/{needed}
{currentRole.start_time && (
{convertTo12Hour(currentRole.start_time)} - {convertTo12Hour(currentRole.end_time)}
)}
{/* Assigned Staff List */} {assignments.length > 0 && (

ASSIGNED STAFF:

{assignments.map((assignment, idx) => (
{getInitials(assignment.employee_name)}

{assignment.employee_name}

{currentRole.service}

))}
)} {/* Add Staff Section */} {assigned < needed && (

ADD STAFF:

{availableStaff.length > 0 ? (
{availableStaff.map((staff, idx) => (
{getInitials(staff.employee_name)}

{staff.employee_name}

{staff.position || 'Staff Member'}

))}
) : (

All available staff have been assigned

)}
)}
{selectedShiftIndex > 0 && ( )} {selectedShiftIndex < order.shifts_data.length - 1 && ( )}
); }