diff --git a/src/Pages/Events/CalendarView.js b/src/Pages/Events/CalendarView.js index ef977b6ec..90a89720b 100644 --- a/src/Pages/Events/CalendarView.js +++ b/src/Pages/Events/CalendarView.js @@ -1,9 +1,17 @@ -import React, { useState, useMemo, useEffect, useRef } from 'react'; +import { useState, useMemo, useEffect, useRef } from 'react'; import { Link } from 'react-router-dom'; import { getEventAttendanceSummary, getMyEventRegistrationState, joinWaitlistForSCEvent } from '../../APIFunctions/SCEvents'; import { membershipState } from '../../Enums'; - -// ─── tiny helpers ──────────────────────────────────────────────────────────── +import { calculateEventCapacity, getApiErrorMessage, toDateKey } from './eventUtils'; +import { + ChevronLeft, + ChevronRight, + CalendarIcon, + PinIcon, + ClockIcon, + XIcon, + PlusIcon +} from './EventIcons'; const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; const MONTHS = [ @@ -13,13 +21,6 @@ const MONTHS = [ const currentYear = new Date().getFullYear(); const YEAR_RANGE = Array.from({ length: 10 }, (_, i) => currentYear + i); -function toDateKey(date) { - const y = date.getFullYear(); - const m = String(date.getMonth() + 1).padStart(2, '0'); - const d = String(date.getDate()).padStart(2, '0'); - return `${y}-${m}-${d}`; -} - function eventDateKey(event) { if (!event.date) return null; if (/^\d{4}-\d{2}-\d{2}$/.test(event.date)) return event.date; @@ -159,12 +160,8 @@ function getBadgeText(event, isAdminView) { return ''; } -function getRegistrationStatus(event) { - return event?.registration_status || 'none'; -} - function getRegistrationCta(event) { - const registrationStatus = getRegistrationStatus(event); + const registrationStatus = event?.registration_status || 'none'; switch (registrationStatus) { case 'registered': @@ -223,76 +220,6 @@ function canUserManageEvent(event, user) { return false; } -// ─── icons ──────────────────────────────────────────────────────────────────── - -function ChevronLeft() { - return ( - - ); -} - -function ChevronRight() { - return ( - - ); -} - -function CalendarIcon() { - return ( - - ); -} - -function PinIcon() { - return ( - - ); -} - -function ClockIcon() { - return ( - - ); -} - -function XIcon() { - return ( - - ); -} - -function PlusIcon() { - return ( - - ); -} - // ─── Event popup ────────────────────────────────────────────────────────────── function EventPopup({ event, onClose, isAdminView, user }) { @@ -311,14 +238,8 @@ function EventPopup({ event, onClose, isAdminView, user }) { const [isCheckingRegistration, setIsCheckingRegistration] = useState(false); const eventId = event?.id || event?._id; const authToken = user?.token; - const maxAttendees = Number(event.max_attendees); - const hasCapacityLimit = Number.isFinite(maxAttendees) && maxAttendees > 0; - const remainingSpots = - hasCapacityLimit && typeof attendeeCount === 'number' - ? Math.max(maxAttendees - attendeeCount, 0) - : null; + const { maxAttendees, hasCapacityLimit, remainingSpots, isFull } = calculateEventCapacity(event, attendeeCount); const registrationCta = getRegistrationCta(event); - const isFull = hasCapacityLimit && typeof remainingSpots === 'number' && remainingSpots <= 0; const shouldShowWaitlistJoin = !canManageEvent && event.status === 'published' && @@ -416,33 +337,24 @@ function EventPopup({ event, onClose, isAdminView, user }) { setWaitlistSubmitting(false); if (response.error) { - let msg = ''; - const data = response.responseData; - - if (data && typeof data === 'object' && data.error) { - msg = String(data.error); - } else if (typeof data === 'string' && data.trim()) { - msg = data.trim(); - } - - setWaitlistError(msg || 'Failed to join waitlist.'); + setWaitlistError(getApiErrorMessage(response, { fallback: 'Failed to join waitlist.' })); return; } setWaitlistMessage('Joined waitlist successfully.'); } return ( -
- {event.max_attendees} spot{event.max_attendees !== 1 ? 's' : ''} available - {event.waitlist_enabled && ( +
+ {event.max_attendees} total spot{event.max_attendees !== 1 ? 's' : ''} + {canManageEvent && event.waitlist_enabled && ( · waitlist available )}
)} {hasCapacityLimit && !canManageEvent && typeof remainingSpots === 'number' && ( -+
{remainingSpots} spot{remainingSpots !== 1 ? 's' : ''} left {event.waitlist_enabled && ( · waitlist available @@ -528,13 +440,13 @@ function EventPopup({ event, onClose, isAdminView, user }) { )} {hasCapacityLimit && !canManageEvent && attendanceLoading && ( -
+
Loading live spots...
)} {hasCapacityLimit && !canManageEvent && attendanceLoaded && typeof remainingSpots !== 'number' && ( -+
Unable to load live spots
)} @@ -602,11 +514,11 @@ function EventPopup({ event, onClose, isAdminView, user }) { )} {waitlistError && ( -{waitlistError}
+{waitlistError}
)} {waitlistMessage && ( -{waitlistMessage}
+{waitlistMessage}
)}- {event.description} -
- )} - -