update imports

This commit is contained in:
chark1es 2025-02-16 16:54:00 -08:00
parent ccd2490164
commit 48e4c4eeb5
2 changed files with 898 additions and 839 deletions

View file

@ -17,7 +17,9 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
<h3 class="card-title text-lg mb-4">Event Check-in</h3> <h3 class="card-title text-lg mb-4">Event Check-in</h3>
<div class="form-control w-full"> <div class="form-control w-full">
<label class="label"> <label class="label">
<span class="label-text">Enter event code to check in</span> <span class="label-text"
>Enter event code to check in</span
>
</label> </label>
<div class="flex gap-2"> <div class="flex gap-2">
<input <input
@ -25,7 +27,9 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
placeholder="Enter code" placeholder="Enter code"
class="input input-bordered flex-1" class="input input-bordered flex-1"
/> />
<button class="btn btn-primary min-w-[90px]">Check In</button> <button class="btn btn-primary min-w-[90px]"
>Check In</button
>
</div> </div>
</div> </div>
</div> </div>
@ -38,7 +42,9 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
<form id="foodSelectionForm" class="space-y-4"> <form id="foodSelectionForm" class="space-y-4">
<div class="form-control"> <div class="form-control">
<label class="label"> <label class="label">
<span class="label-text">What food would you like?</span> <span class="label-text"
>What food would you like?</span
>
<span class="label-text-alt text-error">*</span> <span class="label-text-alt text-error">*</span>
</label> </label>
<input <input
@ -56,7 +62,9 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
</label> </label>
</div> </div>
<div class="modal-action"> <div class="modal-action">
<button type="submit" class="btn btn-primary">Submit</button> <button type="submit" class="btn btn-primary"
>Submit</button
>
<button <button
type="button" type="button"
class="btn" class="btn"
@ -76,12 +84,15 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
<h3 class="card-title text-lg mb-4">Event Registration</h3> <h3 class="card-title text-lg mb-4">Event Registration</h3>
<div class="form-control w-full"> <div class="form-control w-full">
<label class="label"> <label class="label">
<span class="label-text">Select an event to register</span> <span class="label-text"
>Select an event to register</span
>
</label> </label>
<div class="flex gap-2"> <div class="flex gap-2">
<select class="select select-bordered flex-1"> <select class="select select-bordered flex-1">
<option disabled selected>Pick an event</option> <option disabled selected>Pick an event</option>
<option>Technical Workshop - Web Development</option> <option>Technical Workshop - Web Development</option
>
<option>Professional Development Workshop</option> <option>Professional Development Workshop</option>
<option>Social Event - Game Night</option> <option>Social Event - Game Night</option>
</select> </select>
@ -219,16 +230,19 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Toast management system // Toast management system
const createToast = ( const createToast = (
message: string, message: string,
type: "success" | "error" | "warning" = "success", type: "success" | "error" | "warning" = "success"
) => { ) => {
let toastContainer = document.querySelector(".toast-container"); let toastContainer = document.querySelector(".toast-container");
if (!toastContainer) { if (!toastContainer) {
toastContainer = document.createElement("div"); toastContainer = document.createElement("div");
toastContainer.className = "toast-container fixed bottom-4 right-4 z-50"; toastContainer.className =
"toast-container fixed bottom-4 right-4 z-50";
document.body.appendChild(toastContainer); document.body.appendChild(toastContainer);
} }
const existingToasts = document.querySelectorAll(".toast-container .toast"); const existingToasts = document.querySelectorAll(
".toast-container .toast"
);
if (existingToasts.length >= 2) { if (existingToasts.length >= 2) {
const oldestToast = existingToasts[0]; const oldestToast = existingToasts[0];
oldestToast.classList.add("toast-exit"); oldestToast.classList.add("toast-exit");
@ -238,7 +252,9 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Update positions of existing toasts // Update positions of existing toasts
existingToasts.forEach((t) => { existingToasts.forEach((t) => {
const toast = t as HTMLElement; const toast = t as HTMLElement;
const currentIndex = parseInt(toast.getAttribute("data-index") || "0"); const currentIndex = parseInt(
toast.getAttribute("data-index") || "0"
);
toast.setAttribute("data-index", (currentIndex + 1).toString()); toast.setAttribute("data-index", (currentIndex + 1).toString());
}); });
@ -337,14 +353,18 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Find the event with the given code // Find the event with the given code
const event = await get.getFirst<Event>( const event = await get.getFirst<Event>(
"events", "events",
`event_code = "${eventCode}"`, `event_code = "${eventCode}"`
); );
if (!event) { if (!event) {
throw new Error("Invalid event code"); throw new Error("Invalid event code");
} }
// Check if user is already checked in // Check if user is already checked in
if (event.attendees.some((entry) => entry.user_id === currentUser.id)) { if (
event.attendees.some(
(entry) => entry.user_id === currentUser.id
)
) {
throw new Error("You have already checked in to this event"); throw new Error("You have already checked in to this event");
} }
@ -358,7 +378,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
if (event.has_food) { if (event.has_food) {
currentCheckInEvent = event; currentCheckInEvent = event;
const modal = document.getElementById( const modal = document.getElementById(
"foodSelectionModal", "foodSelectionModal"
) as HTMLDialogElement; ) as HTMLDialogElement;
modal.showModal(); modal.showModal();
} else { } else {
@ -366,40 +386,49 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
await completeCheckIn(event, null); await completeCheckIn(event, null);
} }
} catch (error: any) { } catch (error: any) {
createToast(error?.message || "Failed to check in to event", "error"); createToast(
error?.message || "Failed to check in to event",
"error"
);
} }
} }
// Add food selection form handler // Add food selection form handler
const foodSelectionForm = document.getElementById( const foodSelectionForm = document.getElementById(
"foodSelectionForm", "foodSelectionForm"
) as HTMLFormElement; ) as HTMLFormElement;
if (foodSelectionForm) { if (foodSelectionForm) {
foodSelectionForm.addEventListener("submit", async (e) => { foodSelectionForm.addEventListener("submit", async (e) => {
e.preventDefault(); e.preventDefault();
const modal = document.getElementById( const modal = document.getElementById(
"foodSelectionModal", "foodSelectionModal"
) as HTMLDialogElement; ) as HTMLDialogElement;
const foodInput = document.getElementById( const foodInput = document.getElementById(
"foodInput", "foodInput"
) as HTMLInputElement; ) as HTMLInputElement;
try { try {
if (currentCheckInEvent) { if (currentCheckInEvent) {
await completeCheckIn(currentCheckInEvent, foodInput.value.trim()); await completeCheckIn(
currentCheckInEvent,
foodInput.value.trim()
);
modal.close(); modal.close();
foodInput.value = ""; // Reset input foodInput.value = ""; // Reset input
currentCheckInEvent = null; currentCheckInEvent = null;
} }
} catch (error: any) { } catch (error: any) {
createToast(error?.message || "Failed to check in to event", "error"); createToast(
error?.message || "Failed to check in to event",
"error"
);
} }
}); });
} }
async function completeCheckIn( async function completeCheckIn(
event: Event, event: Event,
foodSelection: string | null, foodSelection: string | null
): Promise<void> { ): Promise<void> {
try { try {
const auth = Authentication.getInstance(); const auth = Authentication.getInstance();
@ -422,7 +451,11 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
const existingAttendees = event.attendees || []; const existingAttendees = event.attendees || [];
// Check if user is already checked in // Check if user is already checked in
if (existingAttendees.some((entry) => entry.user_id === currentUser.id)) { if (
existingAttendees.some(
(entry) => entry.user_id === currentUser.id
)
) {
throw new Error("You have already checked in to this event"); throw new Error("You have already checked in to this event");
} }
@ -434,7 +467,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
"events", "events",
event.id, event.id,
"attendees", "attendees",
updatedAttendees, updatedAttendees
); );
// If food selection was made, log it // If food selection was made, log it
@ -442,7 +475,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
await logger.send( await logger.send(
"update", "update",
"event check-in", "event check-in",
`Food selection for ${event.event_name}: ${foodSelection}`, `Food selection for ${event.event_name}: ${foodSelection}`
); );
} }
@ -453,14 +486,14 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
"users", "users",
currentUser.id, currentUser.id,
"points", "points",
userPoints + event.points_to_reward, userPoints + event.points_to_reward
); );
// Log the points award // Log the points award
await logger.send( await logger.send(
"update", "update",
"event check-in", "event check-in",
`Awarded ${event.points_to_reward} points for checking in to ${event.event_name}`, `Awarded ${event.points_to_reward} points for checking in to ${event.event_name}`
); );
} }
@ -471,17 +504,20 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
? ` (+${event.points_to_reward} points!)` ? ` (+${event.points_to_reward} points!)`
: "" : ""
}`, }`,
"success", "success"
); );
// Log the check-in // Log the check-in
await logger.send( await logger.send(
"check_in", "check_in",
"events", "events",
`User ${currentUser.name} (${currentUser.graduation_year}) checked in to event ${event.event_name}`, `User ${currentUser.name} (${currentUser.graduation_year}) checked in to event ${event.event_name}`
); );
} catch (error: any) { } catch (error: any) {
createToast(error?.message || "Failed to check in to event", "error"); createToast(
error?.message || "Failed to check in to event",
"error"
);
} }
} }
@ -528,17 +564,18 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
try { try {
// Show skeletons first // Show skeletons first
const upcomingEventsContainer = document.getElementById( const upcomingEventsContainer = document.getElementById(
"upcomingEventsContainer", "upcomingEventsContainer"
); );
const pastEventsContainer = document.getElementById( const pastEventsContainer = document.getElementById(
"pastEventsContainer", "pastEventsContainer"
); );
if (!upcomingEventsContainer || !pastEventsContainer) return; if (!upcomingEventsContainer || !pastEventsContainer) return;
// Add 3 skeleton cards to each container initially // Add 3 skeleton cards to each container initially
const createSkeletonCard = () => { const createSkeletonCard = () => {
const skeletonCard = document.createElement("div"); const skeletonCard = document.createElement("div");
skeletonCard.className = "card bg-base-200 shadow-lg animate-pulse"; skeletonCard.className =
"card bg-base-200 shadow-lg animate-pulse";
skeletonCard.innerHTML = ` skeletonCard.innerHTML = `
<div class="card-body p-5"> <div class="card-body p-5">
<div class="flex flex-col h-full"> <div class="flex flex-col h-full">
@ -577,7 +614,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
const events = await get.getAll<Event>( const events = await get.getAll<Event>(
"events", "events",
"published = true", "published = true",
"-start_date", "-start_date"
); // Sort by start date descending ); // Sort by start date descending
// Clear skeletons // Clear skeletons
@ -598,21 +635,21 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
startDate.getMonth(), startDate.getMonth(),
startDate.getDate(), startDate.getDate(),
startDate.getHours(), startDate.getHours(),
startDate.getMinutes(), startDate.getMinutes()
); );
const endLocal = new Date( const endLocal = new Date(
endDate.getFullYear(), endDate.getFullYear(),
endDate.getMonth(), endDate.getMonth(),
endDate.getDate(), endDate.getDate(),
endDate.getHours(), endDate.getHours(),
endDate.getMinutes(), endDate.getMinutes()
); );
const nowLocal = new Date( const nowLocal = new Date(
now.getFullYear(), now.getFullYear(),
now.getMonth(), now.getMonth(),
now.getDate(), now.getDate(),
now.getHours(), now.getHours(),
now.getMinutes(), now.getMinutes()
); );
if (startLocal > nowLocal) { if (startLocal > nowLocal) {
@ -627,19 +664,21 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
} }
return acc; return acc;
}, },
{ upcoming: [] as Event[], past: [] as Event[] }, { upcoming: [] as Event[], past: [] as Event[] }
); );
// Sort upcoming events by start date (closest first) // Sort upcoming events by start date (closest first)
upcoming.sort( upcoming.sort(
(a, b) => (a, b) =>
new Date(a.start_date).getTime() - new Date(b.start_date).getTime(), new Date(a.start_date).getTime() -
new Date(b.start_date).getTime()
); );
// Sort past events by end date (most recent first) // Sort past events by end date (most recent first)
past.sort( past.sort(
(a, b) => (a, b) =>
new Date(b.end_date).getTime() - new Date(a.end_date).getTime(), new Date(b.end_date).getTime() -
new Date(a.end_date).getTime()
); );
upcoming.forEach((event) => { upcoming.forEach((event) => {
@ -667,7 +706,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
weekday: "short", weekday: "short",
month: "short", month: "short",
day: "numeric", day: "numeric",
}, }
)} )}
</div> </div>
<div class="text-xs mt-0.5 opacity-75"> <div class="text-xs mt-0.5 opacity-75">
@ -676,7 +715,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
{ {
hour: "numeric", hour: "numeric",
minute: "2-digit", minute: "2-digit",
}, }
)} )}
</div> </div>
</div> </div>
@ -693,7 +732,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
</div> </div>
${(() => { ${(() => {
const endDate = Get.isUTCDateString( const endDate = Get.isUTCDateString(
event.end_date, event.end_date
) )
? new Date(event.end_date) ? new Date(event.end_date)
: new Date(); : new Date();
@ -750,7 +789,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
weekday: "short", weekday: "short",
month: "short", month: "short",
day: "numeric", day: "numeric",
}, }
)} )}
</div> </div>
<div class="text-xs mt-0.5 opacity-75"> <div class="text-xs mt-0.5 opacity-75">
@ -759,7 +798,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
{ {
hour: "numeric", hour: "numeric",
minute: "2-digit", minute: "2-digit",
}, }
)} )}
</div> </div>
</div> </div>
@ -862,7 +901,8 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
} }
function backToFileList() { function backToFileList() {
const filePreviewSection = document.getElementById("filePreviewSection"); const filePreviewSection =
document.getElementById("filePreviewSection");
const filesContent = document.getElementById("filesContent"); const filesContent = document.getElementById("filesContent");
const modalTitle = document.getElementById("modalTitle"); const modalTitle = document.getElementById("modalTitle");
@ -871,8 +911,12 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
if (modalTitle) modalTitle.textContent = "Event Files"; if (modalTitle) modalTitle.textContent = "Event Files";
} }
function showFilePreview(file: { url: string; type: string; name: string }) { function showFilePreview(file: {
console.log('showFilePreview called with:', file); url: string;
type: string;
name: string;
}) {
console.log("showFilePreview called with:", file);
window.previewFileEvents(file.url, file.name); window.previewFileEvents(file.url, file.name);
} }
@ -893,13 +937,15 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Universal file preview function for events section // Universal file preview function for events section
window.previewFileEvents = function (url: string, filename: string) { window.previewFileEvents = function (url: string, filename: string) {
console.log('previewFileEvents called with:', { url, filename }); console.log("previewFileEvents called with:", { url, filename });
const modal = document.getElementById("filePreviewModal") as HTMLDialogElement; const modal = document.getElementById(
"filePreviewModal"
) as HTMLDialogElement;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
const previewContent = document.getElementById("previewContent"); const previewContent = document.getElementById("previewContent");
if (modal && previewFileName && previewContent) { if (modal && previewFileName && previewContent) {
console.log('Found all required elements'); console.log("Found all required elements");
// Update the filename display // Update the filename display
previewFileName.textContent = filename; previewFileName.textContent = filename;
@ -907,25 +953,31 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
modal.showModal(); modal.showModal();
// Dispatch state change event // Dispatch state change event
window.dispatchEvent(new CustomEvent('filePreviewStateChange', { window.dispatchEvent(
detail: { url, filename } new CustomEvent("filePreviewStateChange", {
})); detail: { url, filename },
})
);
} }
}; };
// Close file preview for events section // Close file preview for events section
window.closeFilePreviewEvents = function () { window.closeFilePreviewEvents = function () {
console.log('closeFilePreviewEvents called'); console.log("closeFilePreviewEvents called");
const modal = document.getElementById("filePreviewModal") as HTMLDialogElement; const modal = document.getElementById(
"filePreviewModal"
) as HTMLDialogElement;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
const previewContent = document.getElementById("previewContent"); const previewContent = document.getElementById("previewContent");
if (modal && previewFileName && previewContent) { if (modal && previewFileName && previewContent) {
console.log('Resetting preview and closing modal'); console.log("Resetting preview and closing modal");
// Reset the preview state // Reset the preview state
window.dispatchEvent(new CustomEvent('filePreviewStateChange', { window.dispatchEvent(
detail: { url: "", filename: "" } new CustomEvent("filePreviewStateChange", {
})); detail: { url: "", filename: "" },
})
);
// Reset the UI // Reset the UI
previewFileName.textContent = ""; previewFileName.textContent = "";
@ -936,18 +988,21 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
}; };
// Update the showFilePreview function for events section // Update the showFilePreview function for events section
window.showFilePreviewEvents = function (file: { url: string; name: string }) { window.showFilePreviewEvents = function (file: {
console.log('showFilePreviewEvents called with:', file); url: string;
name: string;
}) {
console.log("showFilePreviewEvents called with:", file);
window.previewFileEvents(file.url, file.name); window.previewFileEvents(file.url, file.name);
}; };
// Update the openDetailsModal function to use the events-specific preview // Update the openDetailsModal function to use the events-specific preview
window.openDetailsModal = function (event: any) { window.openDetailsModal = function (event: any) {
const modal = document.getElementById( const modal = document.getElementById(
"eventDetailsModal", "eventDetailsModal"
) as HTMLDialogElement; ) as HTMLDialogElement;
const filesContent = document.getElementById( const filesContent = document.getElementById(
"filesContent", "filesContent"
) as HTMLDivElement; ) as HTMLDivElement;
// Reset state // Reset state
@ -955,7 +1010,11 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
if (filesContent) filesContent.classList.remove("hidden"); if (filesContent) filesContent.classList.remove("hidden");
// Populate files content // Populate files content
if (event.files && Array.isArray(event.files) && event.files.length > 0) { if (
event.files &&
Array.isArray(event.files) &&
event.files.length > 0
) {
const baseUrl = "https://pocketbase.ieeeucsd.org"; const baseUrl = "https://pocketbase.ieeeucsd.org";
const collectionId = "events"; const collectionId = "events";
const recordId = event.id; const recordId = event.id;
@ -974,7 +1033,10 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
.map((file: string) => { .map((file: string) => {
const fileUrl = `${baseUrl}/api/files/${collectionId}/${recordId}/${file}`; const fileUrl = `${baseUrl}/api/files/${collectionId}/${recordId}/${file}`;
const fileType = getFileType(file); const fileType = getFileType(file);
const previewData = JSON.stringify({ url: fileUrl, name: file }).replace(/'/g, "\\'"); const previewData = JSON.stringify({
url: fileUrl,
name: file,
}).replace(/'/g, "\\'");
return ` return `
<tr> <tr>
<td>${file}</td> <td>${file}</td>
@ -1016,7 +1078,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Add downloadAllFiles function // Add downloadAllFiles function
window.downloadAllFiles = async function () { window.downloadAllFiles = async function () {
const downloadBtn = document.getElementById( const downloadBtn = document.getElementById(
"downloadAllBtn", "downloadAllBtn"
) as HTMLButtonElement; ) as HTMLButtonElement;
if (!downloadBtn) return; if (!downloadBtn) return;
const originalBtnContent = downloadBtn.innerHTML; const originalBtnContent = downloadBtn.innerHTML;
@ -1072,7 +1134,7 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
console.error("Failed to download files:", error); console.error("Failed to download files:", error);
createToast( createToast(
error?.message || "Failed to download files. Please try again.", error?.message || "Failed to download files. Please try again.",
"error", "error"
); );
} finally { } finally {
// Reset button state // Reset button state
@ -1083,17 +1145,19 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
// Close event details modal // Close event details modal
window.closeEventDetailsModal = function () { window.closeEventDetailsModal = function () {
const modal = document.getElementById("eventDetailsModal") as HTMLDialogElement; const modal = document.getElementById(
"eventDetailsModal"
) as HTMLDialogElement;
const filesContent = document.getElementById("filesContent"); const filesContent = document.getElementById("filesContent");
if (modal) { if (modal) {
// Reset the files content // Reset the files content
if (filesContent) { if (filesContent) {
filesContent.innerHTML = ''; filesContent.innerHTML = "";
} }
// Reset any other state if needed // Reset any other state if needed
currentEventId = ''; currentEventId = "";
// Close the modal // Close the modal
modal.close(); modal.close();
@ -1105,11 +1169,6 @@ import FilePreview from "./Officer_EventManagement/FilePreview";
window.handlePreviewError = handlePreviewError; window.handlePreviewError = handlePreviewError;
window.showLoading = showLoading; window.showLoading = showLoading;
window.hideLoading = hideLoading; window.hideLoading = hideLoading;
window.previewFileEvents = previewFileEvents;
window.closeFilePreviewEvents = closeFilePreviewEvents;
window.showFilePreviewEvents = showFilePreviewEvents;
window.openDetailsModal = openDetailsModal;
window.closeEventDetailsModal = closeEventDetailsModal;
// Add TypeScript interface for Window // Add TypeScript interface for Window
declare global { declare global {