diff --git a/src/components/dashboard/Officer_EventManagement.astro b/src/components/dashboard/Officer_EventManagement.astro index e5f4951..e92f991 100644 --- a/src/components/dashboard/Officer_EventManagement.astro +++ b/src/components/dashboard/Officer_EventManagement.astro @@ -4,6 +4,7 @@ import { Get } from "../pocketbase/Get"; import { Authentication } from "../pocketbase/Authentication"; import EventEditor from "./Officer_EventManagement/EventEditor"; import FilePreview from "./Officer_EventManagement/FilePreview"; +import Attendees from "./Officer_EventManagement/Attendees"; // Get instances const get = Get.getInstance(); @@ -648,7 +649,7 @@ const currentPage = eventResponse.page; + + + + + + diff --git a/src/components/dashboard/Officer_EventManagement/Attendees.tsx b/src/components/dashboard/Officer_EventManagement/Attendees.tsx new file mode 100644 index 0000000..db5882e --- /dev/null +++ b/src/components/dashboard/Officer_EventManagement/Attendees.tsx @@ -0,0 +1,202 @@ +import { useEffect, useState } from 'react'; +import { Get } from '../../pocketbase/Get'; +import { Authentication } from '../../pocketbase/Authentication'; + +interface AttendeeEntry { + user_id: string; + time_checked_in: string; + food: string; +} + +interface User { + id: string; + name: string; + email: string; +} + +interface Event { + id: string; + attendees: AttendeeEntry[]; +} + +export default function Attendees() { + const [eventId, setEventId] = useState(''); + const [users, setUsers] = useState>(new Map()); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [attendeesList, setAttendeesList] = useState([]); + + const get = Get.getInstance(); + const auth = Authentication.getInstance(); + + // Listen for the custom event + useEffect(() => { + const handleUpdateAttendees = (e: CustomEvent<{ eventId: string; eventName: string }>) => { + console.log('Received updateAttendees event:', e.detail); + setEventId(e.detail.eventId); + }; + + // Add event listener + window.addEventListener('updateAttendees', handleUpdateAttendees as EventListener); + + // Cleanup + return () => { + window.removeEventListener('updateAttendees', handleUpdateAttendees as EventListener); + }; + }, []); + + // Fetch event data when eventId changes + useEffect(() => { + const fetchEventData = async () => { + if (!eventId) { + console.log('No eventId provided'); + return; + } + + if (!auth.isAuthenticated()) { + console.log('User not authenticated'); + setError('Authentication required'); + return; + } + + try { + setLoading(true); + setError(null); + + console.log('Fetching event data for:', eventId); + const event = await get.getOne('events', eventId); + + if (!event.attendees || !Array.isArray(event.attendees)) { + console.log('No attendees found or invalid format'); + setAttendeesList([]); + return; + } + + console.log('Found attendees:', { + count: event.attendees.length, + sample: event.attendees.slice(0, 2) + }); + setAttendeesList(event.attendees); + + // Fetch user details + const userIds = [...new Set(event.attendees.map(a => a.user_id))]; + console.log('Fetching details for users:', userIds); + + const userPromises = userIds.map(async (userId) => { + try { + return await get.getOne('users', userId); + } catch (error) { + console.error(`Failed to fetch user ${userId}:`, error); + return null; + } + }); + + const userResults = await Promise.all(userPromises); + const userMap = new Map(); + + userResults.forEach(user => { + if (user) { + userMap.set(user.id, user); + } + }); + + console.log('Fetched user details:', { + totalUsers: userMap.size, + userIds: Array.from(userMap.keys()) + }); + setUsers(userMap); + } catch (error) { + console.error('Failed to fetch event data:', error); + setError('Failed to load event data'); + setAttendeesList([]); + } finally { + setLoading(false); + } + }; + + fetchEventData(); + }, [eventId]); // Re-run when eventId changes + + // Reset state when modal is closed + useEffect(() => { + const handleModalClose = () => { + setEventId(''); + setAttendeesList([]); + setUsers(new Map()); + setError(null); + }; + + const modal = document.getElementById('attendeesModal'); + if (modal) { + modal.addEventListener('close', handleModalClose); + return () => modal.removeEventListener('close', handleModalClose); + } + }, []); + + if (loading) { + return ( +
+ +
+ ); + } + + if (error) { + return ( +
+ + + + {error} +
+ ); + } + + if (!eventId) { + return null; + } + + if (!attendeesList || attendeesList.length === 0) { + return ( +
+ + + +

No attendees yet

+
+ ); + } + + return ( +
+
+ Total Attendees: {attendeesList.length} +
+ + + + + + + + + + + {attendeesList.map((attendee, index) => { + const user = users.get(attendee.user_id); + const checkInTime = new Date(attendee.time_checked_in).toLocaleString(); + + return ( + + + + + + + ); + })} + +
NameEmailCheck-in TimeFood Choice
{user?.name || 'Unknown User'}{user?.email || 'N/A'}{checkInTime}{attendee.food || 'N/A'}
+
+ ); +}