diff --git a/src/components/dashboard/Officer_EventManagement.astro b/src/components/dashboard/Officer_EventManagement.astro index b004c84..2c9401d 100644 --- a/src/components/dashboard/Officer_EventManagement.astro +++ b/src/components/dashboard/Officer_EventManagement.astro @@ -446,6 +446,23 @@ declare global {
@@ -482,6 +499,27 @@ declare global { import { FileManager } from "../pocketbase/FileManager"; import { SendLog } from "../pocketbase/SendLog"; + interface AttendeeEntry { + user_id: string; + time_checked_in: string; + food: string; + } + + interface Event { + id: string; + event_name: string; + event_description: string; + event_code: string; + location: string; + files: string[]; + points_to_reward: number; + start_date: string; + end_date: string; + published: boolean; + has_food: boolean; + attendees: AttendeeEntry[]; + } + const get = Get.getInstance(); const auth = Authentication.getInstance(); const update = Update.getInstance(); @@ -1036,7 +1074,117 @@ declare global { } } - // Update the openDetailsModal function + // Add CSV export functionality + async function exportAttendeesToCSV(event: Event) { + try { + const pb = auth.getPocketBase(); + + // Fetch all user details for the attendees + const attendeePromises = event.attendees.map(function ( + attendee: AttendeeEntry, + ) { + return pb.collection("users").getOne(attendee.user_id); + }); + const users = await Promise.all(attendeePromises); + + // Create CSV header + const csvHeader = [ + "Name", + "Email", + "Member ID", + "Member Type", + "Graduation Year", + "Major", + "Time Checked In", + "Food Selection", + ].join(","); + + // Create CSV rows + const csvRows = event.attendees.map( + (attendee: AttendeeEntry, index: number) => { + const user = users[index]; + const checkInTime = new Date( + attendee.time_checked_in, + ).toLocaleString(); + + // Escape and format fields to handle commas and quotes + const formatField = (field: any) => { + if (field === null || field === undefined) return '""'; + return `"${String(field).replace(/"/g, '""')}"`; + }; + + return [ + formatField(user.name), + formatField(user.email), + formatField(user.member_id), + formatField(user.member_type), + formatField(user.graduation_year), + formatField(user.major), + formatField(checkInTime), + formatField(attendee.food), + ].join(","); + }, + ); + + // Combine header and rows + const csvContent = [csvHeader, ...csvRows].join("\n"); + + // Create and trigger download + const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); + const link = document.createElement("a"); + const url = URL.createObjectURL(blob); + link.setAttribute("href", url); + link.setAttribute("download", `${event.event_name}_attendees.csv`); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Show toast using the existing toast function + const toastContainer = document.querySelector(".toast-container"); + if (toastContainer) { + const toast = document.createElement("div"); + toast.className = "toast translate-x-full"; + toast.setAttribute("data-index", "0"); + toast.innerHTML = ` +${user.name || "N/A"} | ${user.email || "N/A"} | ${user.major || "N/A"} | -${user.year || "N/A"} | +${user.graduation_year || "N/A"} | ${checkInTime} | ${attendee.food || "N/A"} | @@ -1150,6 +1310,14 @@ declare global { `; + + // Add click handler for CSV download button + const downloadButton = document.getElementById( + "downloadAttendeesCSV", + ); + if (downloadButton) { + downloadButton.onclick = () => exportAttendeesToCSV(localEvent); + } } catch (error) { console.error("Failed to fetch attendees:", error); attendeesContent.innerHTML = `