diff --git a/src/components/ReservationSystem/index.tsx b/src/components/ReservationSystem/index.tsx index 8fb1bc9d..deb15573 100644 --- a/src/components/ReservationSystem/index.tsx +++ b/src/components/ReservationSystem/index.tsx @@ -265,32 +265,55 @@ const ReservationSystem: React.FC = () => { })); }, [locations]); - // Build availability map (normalize incoming reservation times) + // Build availability map with capacity tracking (normalize incoming reservation times) const availability = useMemo(() => { const availabilityMap: { - [key: string]: { available: boolean; reservationId?: string }; + [key: string]: { + available: boolean; + reservationId?: string; + currentOccupancy: number; + maxCapacity: number; + }; } = {}; if (!reservations || !rooms) return availabilityMap; - // Initialize all slots as available + // Initialize all slots with capacity information rooms.forEach((room) => { timeSlots.forEach((time) => { - availabilityMap[`${room.id}-${time}`] = { available: true }; + availabilityMap[`${room.id}-${time}`] = { + available: true, + currentOccupancy: 0, + maxCapacity: room.capacity, + }; }); }); - // Mark reserved slots + // Count participant reservations per slot reservations.forEach((reservation) => { + // Only count participant reservations toward capacity + if (reservation.reservationType !== 'participant') return; + const startLabel = timestampToTime(reservation.startTime); const key = `${reservation.locationId}-${startLabel}`; + if (!availabilityMap[key]) return; + const isUserTeamReservation = reservation.teamId === userTeam?.id; - availabilityMap[key] = { - available: false, - reservationId: isUserTeamReservation ? reservation.id : undefined, - }; + // Increment occupancy count + availabilityMap[key].currentOccupancy += 1; + + // Store user's own reservation ID + if (isUserTeamReservation) { + availabilityMap[key].reservationId = reservation.id; + } + + // Mark as unavailable if at capacity (capacity > 0 means limited, 0 means unlimited) + const room = rooms.find(r => r.id === reservation.locationId); + if (room && room.capacity > 0 && availabilityMap[key].currentOccupancy >= room.capacity) { + availabilityMap[key].available = false; + } }); return availabilityMap; @@ -299,7 +322,12 @@ const ReservationSystem: React.FC = () => { const handleSlotClick = async ( roomId: number, time: string, - slotInfo: { available: boolean; reservationId?: string } + slotInfo: { + available: boolean; + reservationId?: string; + currentOccupancy: number; + maxCapacity: number; + } ) => { if (!userTeam) { toast.error("You must be part of a team to make reservations"); @@ -314,9 +342,10 @@ const ReservationSystem: React.FC = () => { return; } - // If slot is not available, do nothing + // If slot is not available (at capacity), show detailed message if (!slotInfo.available) { - toast.error("This time slot is not available"); + const capacityText = slotInfo.maxCapacity === 0 ? 'unlimited' : slotInfo.maxCapacity; + toast.error(`This time slot is at full capacity (${slotInfo.currentOccupancy}/${capacityText})`); return; } @@ -579,7 +608,11 @@ const ReservationSystem: React.FC = () => {