no more console logs

This commit is contained in:
chark1es 2025-03-08 22:23:30 -08:00
parent 16d9ec9e1d
commit 27bc2f4e70
32 changed files with 3752 additions and 4000 deletions

View file

@ -1,18 +1,22 @@
<script> <script>
const observer = new IntersectionObserver((entries) => { const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
entry.target.classList.add("in-view"); entry.target.classList.add("in-view");
entry.target.classList.remove("opacity-0"); entry.target.classList.remove("opacity-0");
console.log("Added 'in-view' class to:", entry.target); // console.log("Added 'in-view' class to:", entry.target);
} else { } else {
entry.target.classList.remove("in-view"); entry.target.classList.remove("in-view");
entry.target.classList.add("opacity-0"); entry.target.classList.add("opacity-0");
console.log("Removed 'in-view' class from:", entry.target); // console.log("Removed 'in-view' class from:", entry.target);
} }
}); });
}, { threshold: 0.2 }); },
{ threshold: 0.2 },
);
document.querySelectorAll("[data-inview]").forEach((el) => observer.observe(el)); document
.querySelectorAll("[data-inview]")
.forEach((el) => observer.observe(el));
</script> </script>

View file

@ -28,8 +28,7 @@ import EventLoad from "./EventsSection/EventLoad";
<div <div
class="absolute inset-0 bg-base-100 opacity-0 group-hover:opacity-90 transition-opacity duration-300 flex items-center justify-center z-10" class="absolute inset-0 bg-base-100 opacity-0 group-hover:opacity-90 transition-opacity duration-300 flex items-center justify-center z-10"
> >
<span <span class="text-base-content font-medium text-sm sm:text-base"
class="text-base-content font-medium text-sm sm:text-base"
>Coming Soon</span >Coming Soon</span
> >
</div> </div>
@ -49,12 +48,8 @@ import EventLoad from "./EventsSection/EventLoad";
disabled disabled
> >
<option disabled selected>Pick an event</option> <option disabled selected>Pick an event</option>
<option <option>Technical Workshop - Web Development</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>
<button <button
@ -94,9 +89,8 @@ import EventLoad from "./EventsSection/EventLoad";
class="btn btn-circle btn-ghost btn-sm sm:btn-md" class="btn btn-circle btn-ghost btn-sm sm:btn-md"
onclick="window.closeEventDetailsModal()" onclick="window.closeEventDetailsModal()"
> >
<iconify-icon <iconify-icon icon="heroicons:x-mark" className="h-4 w-4 sm:h-6 sm:w-6"
icon="heroicons:x-mark" ></iconify-icon>
className="h-4 w-4 sm:h-6 sm:w-6"></iconify-icon>
</button> </button>
</div> </div>
@ -130,8 +124,7 @@ import EventLoad from "./EventsSection/EventLoad";
id="previewLoadingSpinner" id="previewLoadingSpinner"
class="absolute inset-0 flex items-center justify-center bg-base-200 bg-opacity-50 hidden" class="absolute inset-0 flex items-center justify-center bg-base-200 bg-opacity-50 hidden"
> >
<span class="loading loading-spinner loading-md sm:loading-lg" <span class="loading loading-spinner loading-md sm:loading-lg"></span>
></span>
</div> </div>
<div id="previewContent" class="w-full"> <div id="previewContent" class="w-full">
<FilePreview client:load isModal={true} /> <FilePreview client:load isModal={true} />
@ -191,14 +184,14 @@ import EventLoad from "./EventsSection/EventLoad";
// 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 });
console.log("URL type:", typeof url, "URL length:", url?.length || 0); // console.log("URL type:", typeof url, "URL length:", url?.length || 0);
console.log( // console.log(
"Filename type:", // "Filename type:",
typeof filename, // typeof filename,
"Filename length:", // "Filename length:",
filename?.length || 0 // filename?.length || 0
); // );
// Validate inputs // Validate inputs
if (!url || typeof url !== "string") { if (!url || typeof url !== "string") {
@ -210,7 +203,7 @@ import EventLoad from "./EventsSection/EventLoad";
if (!filename || typeof filename !== "string") { if (!filename || typeof filename !== "string") {
console.error( console.error(
"Invalid filename provided to previewFileEvents:", "Invalid filename provided to previewFileEvents:",
filename filename,
); );
toast.error("Cannot preview file: Invalid filename"); toast.error("Cannot preview file: Invalid filename");
return; return;
@ -218,27 +211,24 @@ import EventLoad from "./EventsSection/EventLoad";
// Ensure URL is properly formatted // Ensure URL is properly formatted
if (!url.startsWith("http")) { if (!url.startsWith("http")) {
console.warn( console.warn("URL doesn't start with http, attempting to fix:", url);
"URL doesn't start with http, attempting to fix:",
url
);
if (url.startsWith("/")) { if (url.startsWith("/")) {
url = `https://pocketbase.ieeeucsd.org${url}`; url = `https://pocketbase.ieeeucsd.org${url}`;
} else { } else {
url = `https://pocketbase.ieeeucsd.org/${url}`; url = `https://pocketbase.ieeeucsd.org/${url}`;
} }
console.log("Fixed URL:", url); // console.log("Fixed URL:", url);
} }
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
const previewContent = document.getElementById("previewContent"); const previewContent = document.getElementById("previewContent");
const loadingSpinner = document.getElementById("previewLoadingSpinner"); const loadingSpinner = document.getElementById("previewLoadingSpinner");
if (modal && previewFileName && previewContent) { if (modal && previewFileName && previewContent) {
console.log("Found all required elements"); // console.log("Found all required elements");
// Show loading spinner // Show loading spinner
if (loadingSpinner) { if (loadingSpinner) {
@ -254,11 +244,11 @@ import EventLoad from "./EventsSection/EventLoad";
// Test the URL with a fetch before dispatching the event // Test the URL with a fetch before dispatching the event
fetch(url, { method: "HEAD" }) fetch(url, { method: "HEAD" })
.then((response) => { .then((response) => {
console.log( // console.log(
"URL test response:", // "URL test response:",
response.status, // response.status,
response.ok // response.ok
); // );
if (!response.ok) { if (!response.ok) {
console.warn("URL might not be accessible:", url); console.warn("URL might not be accessible:", url);
toast( toast(
@ -270,7 +260,7 @@ import EventLoad from "./EventsSection/EventLoad";
background: "#FFC107", background: "#FFC107",
color: "#000", color: "#000",
}, },
} },
); );
} }
}) })
@ -279,14 +269,14 @@ import EventLoad from "./EventsSection/EventLoad";
}) })
.finally(() => { .finally(() => {
// Dispatch state change event to update the FilePreview component // Dispatch state change event to update the FilePreview component
console.log( // console.log(
"Dispatching filePreviewStateChange event with:", // "Dispatching filePreviewStateChange event with:",
{ url, filename } // { url, filename }
); // );
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("filePreviewStateChange", { new CustomEvent("filePreviewStateChange", {
detail: { url, filename }, detail: { url, filename },
}) }),
); );
}); });
@ -304,9 +294,9 @@ import EventLoad from "./EventsSection/EventLoad";
// 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( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
const previewContent = document.getElementById("previewContent"); const previewContent = document.getElementById("previewContent");
@ -317,14 +307,14 @@ import EventLoad from "./EventsSection/EventLoad";
} }
if (modal && previewFileName && previewContent) { if (modal && previewFileName && previewContent) {
console.log("Resetting preview and closing modal"); // console.log("Resetting preview and closing modal");
// First reset the preview state by dispatching an event with empty values // First reset the preview state by dispatching an event with empty values
// This ensures the FilePreview component clears its internal state // This ensures the FilePreview component clears its internal state
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("filePreviewStateChange", { new CustomEvent("filePreviewStateChange", {
detail: { url: "", filename: "" }, detail: { url: "", filename: "" },
}) }),
); );
// Reset the UI // Reset the UI
@ -333,7 +323,7 @@ import EventLoad from "./EventsSection/EventLoad";
// Close the modal // Close the modal
modal.close(); modal.close();
console.log("File preview modal closed and state reset"); // console.log("File preview modal closed and state reset");
} else { } else {
console.error("Could not find elements to close file preview"); console.error("Could not find elements to close file preview");
} }
@ -344,7 +334,7 @@ import EventLoad from "./EventsSection/EventLoad";
url: string; url: string;
name: string; name: string;
}) { }) {
console.log("showFilePreviewEvents called with:", file); // console.log("showFilePreviewEvents called with:", file);
if (!file || !file.url || !file.name) { if (!file || !file.url || !file.name) {
console.error("Invalid file data:", file); console.error("Invalid file data:", file);
toast.error("Could not preview file: missing file information"); toast.error("Could not preview file: missing file information");
@ -356,10 +346,10 @@ import EventLoad from "./EventsSection/EventLoad";
// 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;
// Check if event has ended // Check if event has ended
@ -383,11 +373,7 @@ import EventLoad from "./EventsSection/EventLoad";
if (filesContent) filesContent.classList.remove("hidden"); if (filesContent) filesContent.classList.remove("hidden");
// Populate files content // Populate files content
if ( if (event.files && Array.isArray(event.files) && event.files.length > 0) {
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;
@ -446,7 +432,7 @@ import EventLoad from "./EventsSection/EventLoad";
// 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;
@ -501,7 +487,7 @@ import EventLoad from "./EventsSection/EventLoad";
} catch (error: any) { } catch (error: any) {
console.error("Failed to download files:", error); console.error("Failed to download files:", error);
toast.error( toast.error(
error?.message || "Failed to download files. Please try again." error?.message || "Failed to download files. Please try again.",
); );
} finally { } finally {
// Reset button state // Reset button state
@ -513,7 +499,7 @@ import EventLoad from "./EventsSection/EventLoad";
// Close event details modal // Close event details modal
window.closeEventDetailsModal = function () { window.closeEventDetailsModal = function () {
const modal = document.getElementById( const modal = document.getElementById(
"eventDetailsModal" "eventDetailsModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const filesContent = document.getElementById("filesContent"); const filesContent = document.getElementById("filesContent");

View file

@ -249,8 +249,6 @@ const EventCheckIn = () => {
// Create the attendee record in PocketBase // Create the attendee record in PocketBase
const newAttendee = await update.create(Collections.EVENT_ATTENDEES, attendeeData); const newAttendee = await update.create(Collections.EVENT_ATTENDEES, attendeeData);
console.log("Successfully created attendance record");
// Update user's total points // Update user's total points
// First, get all the user's attendance records to calculate total points // First, get all the user's attendance records to calculate total points
const userAttendance = await get.getList<EventAttendee>( const userAttendance = await get.getList<EventAttendee>(
@ -267,7 +265,7 @@ const EventCheckIn = () => {
}); });
// Log the points update // Log the points update
console.log(`Updating user points to: ${totalPoints}`); // console.log(`Updating user points to: ${totalPoints}`);
// Update the user record with the new total points // Update the user record with the new total points
await update.updateFields(Collections.USERS, userId, { await update.updateFields(Collections.USERS, userId, {

View file

@ -74,9 +74,9 @@ const EventLoad = () => {
// Clear events table // Clear events table
if (db && db.events) { if (db && db.events) {
console.log("Clearing events cache..."); // console.log("Clearing events cache...");
await db.events.clear(); await db.events.clear();
console.log("Events cache cleared successfully"); // console.log("Events cache cleared successfully");
} }
// Reset sync timestamp for events by updating it to 0 // Reset sync timestamp for events by updating it to 0
@ -84,7 +84,7 @@ const EventLoad = () => {
const currentInfo = await dexieService.getLastSync(Collections.EVENTS); const currentInfo = await dexieService.getLastSync(Collections.EVENTS);
// Then update it with a timestamp of 0 (forcing a fresh sync) // Then update it with a timestamp of 0 (forcing a fresh sync)
await dexieService.updateLastSync(Collections.EVENTS); await dexieService.updateLastSync(Collections.EVENTS);
console.log("Events sync timestamp reset"); // console.log("Events sync timestamp reset");
// Reload events // Reload events
setLoading(true); setLoading(true);
@ -245,7 +245,7 @@ const EventLoad = () => {
const dataSync = DataSyncService.getInstance(); const dataSync = DataSyncService.getInstance();
const auth = Authentication.getInstance(); const auth = Authentication.getInstance();
console.log("Starting to load events..."); // console.log("Starting to load events...");
// Check if user is authenticated // Check if user is authenticated
if (!auth.isAuthenticated()) { if (!auth.isAuthenticated()) {
@ -255,7 +255,7 @@ const EventLoad = () => {
} }
// Force sync to ensure we have the latest data // Force sync to ensure we have the latest data
console.log("Syncing events collection..."); // console.log("Syncing events collection...");
let syncSuccess = false; let syncSuccess = false;
let retryCount = 0; let retryCount = 0;
const maxRetries = 3; const maxRetries = 3;
@ -263,13 +263,13 @@ const EventLoad = () => {
while (!syncSuccess && retryCount < maxRetries) { while (!syncSuccess && retryCount < maxRetries) {
try { try {
if (retryCount > 0) { if (retryCount > 0) {
console.log(`Retry attempt ${retryCount} of ${maxRetries}...`); // console.log(`Retry attempt ${retryCount} of ${maxRetries}...`);
// Add a small delay between retries // Add a small delay between retries
await new Promise(resolve => setTimeout(resolve, 1000 * retryCount)); await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
} }
await dataSync.syncCollection(Collections.EVENTS, "published = true", "-start_date"); await dataSync.syncCollection(Collections.EVENTS, "published = true", "-start_date");
console.log("Events collection synced successfully"); // console.log("Events collection synced successfully");
syncSuccess = true; syncSuccess = true;
} catch (syncError) { } catch (syncError) {
retryCount++; retryCount++;
@ -282,7 +282,7 @@ const EventLoad = () => {
} }
// Get events from IndexedDB // Get events from IndexedDB
console.log("Fetching events from IndexedDB..."); // console.log("Fetching events from IndexedDB...");
const allEvents = await dataSync.getData<Event>( const allEvents = await dataSync.getData<Event>(
Collections.EVENTS, Collections.EVENTS,
false, // Don't force sync again false, // Don't force sync again
@ -290,27 +290,27 @@ const EventLoad = () => {
"-start_date" "-start_date"
); );
console.log(`Retrieved ${allEvents.length} events from IndexedDB`); // console.log(`Retrieved ${allEvents.length} events from IndexedDB`);
// Filter out invalid events // Filter out invalid events
const validEvents = allEvents.filter(event => isValidEvent(event)); const validEvents = allEvents.filter(event => isValidEvent(event));
console.log(`Filtered out ${allEvents.length - validEvents.length} invalid events`); // console.log(`Filtered out ${allEvents.length - validEvents.length} invalid events`);
// If no valid events found in IndexedDB, try fetching directly from PocketBase as fallback // If no valid events found in IndexedDB, try fetching directly from PocketBase as fallback
let eventsToProcess = validEvents; let eventsToProcess = validEvents;
if (allEvents.length === 0) { if (allEvents.length === 0) {
console.log("No events found in IndexedDB, trying direct PocketBase fetch..."); // console.log("No events found in IndexedDB, trying direct PocketBase fetch...");
try { try {
const pbEvents = await get.getAll<Event>( const pbEvents = await get.getAll<Event>(
Collections.EVENTS, Collections.EVENTS,
"published = true", "published = true",
"-start_date" "-start_date"
); );
console.log(`Retrieved ${pbEvents.length} events directly from PocketBase`); // console.log(`Retrieved ${pbEvents.length} events directly from PocketBase`);
// Filter out invalid events from PocketBase results // Filter out invalid events from PocketBase results
const validPbEvents = pbEvents.filter(event => isValidEvent(event)); const validPbEvents = pbEvents.filter(event => isValidEvent(event));
console.log(`Filtered out ${pbEvents.length - validPbEvents.length} invalid events from PocketBase`); // console.log(`Filtered out ${pbEvents.length - validPbEvents.length} invalid events from PocketBase`);
eventsToProcess = validPbEvents; eventsToProcess = validPbEvents;
@ -319,7 +319,7 @@ const EventLoad = () => {
const dexieService = DexieService.getInstance(); const dexieService = DexieService.getInstance();
const db = dexieService.getDB(); const db = dexieService.getDB();
if (db && db.events) { if (db && db.events) {
console.log(`Storing ${validPbEvents.length} valid PocketBase events in IndexedDB...`); // console.log(`Storing ${validPbEvents.length} valid PocketBase events in IndexedDB...`);
await db.events.bulkPut(validPbEvents); await db.events.bulkPut(validPbEvents);
} }
} }
@ -329,7 +329,7 @@ const EventLoad = () => {
} }
// Split events into upcoming, ongoing, and past based on start and end dates // Split events into upcoming, ongoing, and past based on start and end dates
console.log("Categorizing events..."); // console.log("Categorizing events...");
const now = new Date(); const now = new Date();
const { upcoming, ongoing, past } = eventsToProcess.reduce( const { upcoming, ongoing, past } = eventsToProcess.reduce(
(acc, event) => { (acc, event) => {
@ -382,7 +382,7 @@ const EventLoad = () => {
} }
); );
console.log(`Categorized events: ${upcoming.length} upcoming, ${ongoing.length} ongoing, ${past.length} past`); // console.log(`Categorized events: ${upcoming.length} upcoming, ${ongoing.length} ongoing, ${past.length} past`);
// Sort events // Sort events
upcoming.sort((a, b) => new Date(a.start_date).getTime() - new Date(b.start_date).getTime()); upcoming.sort((a, b) => new Date(a.start_date).getTime() - new Date(b.start_date).getTime());
@ -409,16 +409,16 @@ const EventLoad = () => {
// Try to load from IndexedDB only as a last resort // Try to load from IndexedDB only as a last resort
try { try {
console.log("Attempting to load events from IndexedDB only..."); // console.log("Attempting to load events from IndexedDB only...");
const dexieService = DexieService.getInstance(); const dexieService = DexieService.getInstance();
const db = dexieService.getDB(); const db = dexieService.getDB();
if (db && db.events) { if (db && db.events) {
const allCachedEvents = await db.events.filter(event => event.published === true).toArray(); const allCachedEvents = await db.events.filter(event => event.published === true).toArray();
console.log(`Found ${allCachedEvents.length} cached events in IndexedDB`); // console.log(`Found ${allCachedEvents.length} cached events in IndexedDB`);
// Filter out invalid events // Filter out invalid events
const cachedEvents = allCachedEvents.filter(event => isValidEvent(event)); const cachedEvents = allCachedEvents.filter(event => isValidEvent(event));
console.log(`Filtered out ${allCachedEvents.length - cachedEvents.length} invalid cached events`); // console.log(`Filtered out ${allCachedEvents.length - cachedEvents.length} invalid cached events`);
if (cachedEvents.length > 0) { if (cachedEvents.length > 0) {
// Process these events // Process these events
@ -458,7 +458,7 @@ const EventLoad = () => {
ongoing: ongoing.slice(0, 50), ongoing: ongoing.slice(0, 50),
past: past.slice(0, 50) past: past.slice(0, 50)
}); });
console.log("Successfully loaded events from cache"); // console.log("Successfully loaded events from cache");
} }
} }
} catch (cacheError) { } catch (cacheError) {

View file

@ -34,13 +34,7 @@ let upcomingEvents: Event[] = [];
// Fetch events // Fetch events
try { try {
if (auth.isAuthenticated()) { if (auth.isAuthenticated()) {
eventResponse = await get.getList<Event>( eventResponse = await get.getList<Event>("events", 1, 5, "", "-start_date");
"events",
1,
5,
"",
"-start_date"
);
upcomingEvents = eventResponse.items; upcomingEvents = eventResponse.items;
} }
} catch (error) { } catch (error) {
@ -72,9 +66,7 @@ const currentPage = eventResponse.page;
class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-primary transition-all duration-300 hover:-translate-y-1 transform" class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-primary transition-all duration-300 hover:-translate-y-1 transform"
> >
<div class="stat p-4 md:p-6"> <div class="stat p-4 md:p-6">
<div <div class="stat-title text-sm md:text-base font-medium opacity-80">
class="stat-title text-sm md:text-base font-medium opacity-80"
>
Total Events Total Events
</div> </div>
<div <div
@ -94,9 +86,7 @@ const currentPage = eventResponse.page;
class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-secondary transition-all duration-300 hover:-translate-y-1 transform" class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-secondary transition-all duration-300 hover:-translate-y-1 transform"
> >
<div class="stat p-4 md:p-6"> <div class="stat p-4 md:p-6">
<div <div class="stat-title text-sm md:text-base font-medium opacity-80">
class="stat-title text-sm md:text-base font-medium opacity-80"
>
Unique Attendees Unique Attendees
</div> </div>
<div <div
@ -116,9 +106,7 @@ const currentPage = eventResponse.page;
class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-accent transition-all duration-300 hover:-translate-y-1 transform sm:col-span-2 md:col-span-1" class="stats shadow-lg bg-base-100 rounded-2xl border border-base-200 hover:border-accent transition-all duration-300 hover:-translate-y-1 transform sm:col-span-2 md:col-span-1"
> >
<div class="stat p-4 md:p-6"> <div class="stat p-4 md:p-6">
<div <div class="stat-title text-sm md:text-base font-medium opacity-80">
class="stat-title text-sm md:text-base font-medium opacity-80"
>
Recurring Attendees Recurring Attendees
</div> </div>
<div <div
@ -155,20 +143,14 @@ const currentPage = eventResponse.page;
class="btn btn-ghost btn-sm md:btn-md gap-2" class="btn btn-ghost btn-sm md:btn-md gap-2"
onclick="window.refreshEvents()" onclick="window.refreshEvents()"
> >
<Icon <Icon name="heroicons:arrow-path" class="h-4 w-4 md:h-5 md:w-5" />
name="heroicons:arrow-path"
class="h-4 w-4 md:h-5 md:w-5"
/>
Refresh Refresh
</button> </button>
<button <button
class="btn btn-primary btn-sm md:btn-md gap-2" class="btn btn-primary btn-sm md:btn-md gap-2"
onclick="window.openEditModal()" onclick="window.openEditModal()"
> >
<Icon <Icon name="heroicons:plus" class="h-4 w-4 md:h-5 md:w-5" />
name="heroicons:plus"
class="h-4 w-4 md:h-5 md:w-5"
/>
Add New Event Add New Event
</button> </button>
</div> </div>
@ -182,8 +164,7 @@ const currentPage = eventResponse.page;
<div class="flex flex-wrap gap-4"> <div class="flex flex-wrap gap-4">
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Time Filter</span >Time Filter</span
> >
</label> </label>
@ -223,8 +204,7 @@ const currentPage = eventResponse.page;
<!-- Other filters with similar responsive adjustments --> <!-- Other filters with similar responsive adjustments -->
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Year</span >Year</span
> >
</label> </label>
@ -254,8 +234,7 @@ const currentPage = eventResponse.page;
> >
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text">All Years</span <span class="label-text">All Years</span>
>
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
@ -273,8 +252,7 @@ const currentPage = eventResponse.page;
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Quarter</span >Quarter</span
> >
</label> </label>
@ -284,9 +262,7 @@ const currentPage = eventResponse.page;
class="btn btn-sm m-1 w-[180px] justify-between items-center" class="btn btn-sm m-1 w-[180px] justify-between items-center"
> >
<div class="flex-1 text-left truncate"> <div class="flex-1 text-left truncate">
<span id="quarterFilterLabel" <span id="quarterFilterLabel">All Quarters</span>
>All Quarters</span
>
</div> </div>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -307,9 +283,7 @@ const currentPage = eventResponse.page;
> >
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text" <span class="label-text">All Quarters</span>
>All Quarters</span
>
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
@ -321,41 +295,25 @@ const currentPage = eventResponse.page;
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text">Fall</span> <span class="label-text">Fall</span>
<input <input type="checkbox" class="checkbox" value="fall" />
type="checkbox"
class="checkbox"
value="fall"
/>
</label> </label>
</div> </div>
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text">Winter</span> <span class="label-text">Winter</span>
<input <input type="checkbox" class="checkbox" value="winter" />
type="checkbox"
class="checkbox"
value="winter"
/>
</label> </label>
</div> </div>
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text">Spring</span> <span class="label-text">Spring</span>
<input <input type="checkbox" class="checkbox" value="spring" />
type="checkbox"
class="checkbox"
value="spring"
/>
</label> </label>
</div> </div>
<div class="form-control"> <div class="form-control">
<label class="label cursor-pointer"> <label class="label cursor-pointer">
<span class="label-text">Summer</span> <span class="label-text">Summer</span>
<input <input type="checkbox" class="checkbox" value="summer" />
type="checkbox"
class="checkbox"
value="summer"
/>
</label> </label>
</div> </div>
</div> </div>
@ -364,8 +322,7 @@ const currentPage = eventResponse.page;
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Published</span >Published</span
> >
</label> </label>
@ -431,8 +388,7 @@ const currentPage = eventResponse.page;
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Has Files</span >Has Files</span
> >
</label> </label>
@ -498,8 +454,7 @@ const currentPage = eventResponse.page;
<div class="form-control w-full sm:w-auto"> <div class="form-control w-full sm:w-auto">
<label class="label"> <label class="label">
<span <span class="label-text text-sm md:text-base font-medium"
class="label-text text-sm md:text-base font-medium"
>Has Food</span >Has Food</span
> >
</label> </label>
@ -569,9 +524,7 @@ const currentPage = eventResponse.page;
<div class="flex flex-col sm:flex-row gap-4 mb-4"> <div class="flex flex-col sm:flex-row gap-4 mb-4">
<div class="form-control flex-1"> <div class="form-control flex-1">
<div class="join w-full"> <div class="join w-full">
<div <div class="join-item bg-base-200 flex items-center px-3">
class="join-item bg-base-200 flex items-center px-3"
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4 md:h-5 md:w-5 opacity-70" class="h-4 w-4 md:h-5 md:w-5 opacity-70"
@ -618,29 +571,22 @@ const currentPage = eventResponse.page;
</div> </div>
<!-- Pagination --> <!-- Pagination -->
<div <div class="flex justify-center mt-4 md:mt-6" id="paginationContainer">
class="flex justify-center mt-4 md:mt-6"
id="paginationContainer"
>
<div class="join"> <div class="join">
<button <button class="join-item btn btn-xs md:btn-sm" id="firstPageBtn"
class="join-item btn btn-xs md:btn-sm" >«</button
id="firstPageBtn">«</button
> >
<button <button class="join-item btn btn-xs md:btn-sm" id="prevPageBtn"
class="join-item btn btn-xs md:btn-sm" ></button
id="prevPageBtn"></button
> >
<button class="join-item btn btn-xs md:btn-sm" <button class="join-item btn btn-xs md:btn-sm"
>Page <span id="currentPageNumber">1</span></button >Page <span id="currentPageNumber">1</span></button
> >
<button <button class="join-item btn btn-xs md:btn-sm" id="nextPageBtn"
class="join-item btn btn-xs md:btn-sm" ></button
id="nextPageBtn"></button
> >
<button <button class="join-item btn btn-xs md:btn-sm" id="lastPageBtn"
class="join-item btn btn-xs md:btn-sm" >»</button
id="lastPageBtn">»</button
> >
</div> </div>
</div> </div>
@ -735,10 +681,7 @@ const currentPage = eventResponse.page;
<div class="modal-box max-w-4xl"> <div class="modal-box max-w-4xl">
<div class="flex justify-between items-center mb-4"> <div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-lg" id="attendeesModalTitle"></h3> <h3 class="font-bold text-lg" id="attendeesModalTitle"></h3>
<button <button class="btn btn-circle btn-ghost" onclick="attendeesModal.close()">
class="btn btn-circle btn-ghost"
onclick="attendeesModal.close()"
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6" class="h-6 w-6"
@ -840,9 +783,7 @@ const currentPage = eventResponse.page;
) { ) {
auth.setUpdating(true); auth.setUpdating(true);
const response = await get.getAll<Event>("events"); const response = await get.getAll<Event>("events");
cachedEvents = response.map((event) => cachedEvents = response.map((event) => Get.convertUTCToLocal(event));
Get.convertUTCToLocal(event)
);
lastCacheUpdate = now; lastCacheUpdate = now;
// Initialize year filter options from cache // Initialize year filter options from cache
@ -852,8 +793,7 @@ const currentPage = eventResponse.page;
years.add(year); years.add(year);
}); });
const yearCheckboxes = const yearCheckboxes = document.getElementById("yearCheckboxes");
document.getElementById("yearCheckboxes");
if (yearCheckboxes) { if (yearCheckboxes) {
const sortedYears = Array.from(years).sort((a, b) => b - a); const sortedYears = Array.from(years).sort((a, b) => b - a);
yearCheckboxes.innerHTML = sortedYears yearCheckboxes.innerHTML = sortedYears
@ -863,18 +803,16 @@ const currentPage = eventResponse.page;
<span class="label-text">${year}</span> <span class="label-text">${year}</span>
<input type="checkbox" class="checkbox" value="${year}" /> <input type="checkbox" class="checkbox" value="${year}" />
</label> </label>
` `,
) )
.join(""); .join("");
// Add event listeners to checkboxes // Add event listeners to checkboxes
const allYearsCheckbox = document.querySelector( const allYearsCheckbox = document.querySelector(
'input[type="checkbox"][value="all"]' 'input[type="checkbox"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
const yearInputs = Array.from( const yearInputs = Array.from(
yearCheckboxes.querySelectorAll( yearCheckboxes.querySelectorAll('input[type="checkbox"]'),
'input[type="checkbox"]'
)
) as HTMLInputElement[]; ) as HTMLInputElement[];
if (allYearsCheckbox) { if (allYearsCheckbox) {
@ -885,9 +823,8 @@ const currentPage = eventResponse.page;
input.checked = false; input.checked = false;
}); });
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById( document.getElementById("yearFilterLabel")!.textContent =
"yearFilterLabel" "All Years";
)!.textContent = "All Years";
} }
currentPage = 1; currentPage = 1;
fetchEvents(); fetchEvents();
@ -903,15 +840,12 @@ const currentPage = eventResponse.page;
if (checkedYears.length === 0) { if (checkedYears.length === 0) {
allYearsCheckbox.checked = true; allYearsCheckbox.checked = true;
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById( document.getElementById("yearFilterLabel")!.textContent =
"yearFilterLabel" "All Years";
)!.textContent = "All Years";
} else { } else {
allYearsCheckbox.checked = false; allYearsCheckbox.checked = false;
filterState.year = checkedYears; filterState.year = checkedYears;
document.getElementById( document.getElementById("yearFilterLabel")!.textContent =
"yearFilterLabel"
)!.textContent =
checkedYears.length === 1 checkedYears.length === 1
? checkedYears[0] ? checkedYears[0]
: `${checkedYears.length} Years Selected`; : `${checkedYears.length} Years Selected`;
@ -1010,8 +944,7 @@ const currentPage = eventResponse.page;
const eventEnd = new Date(event.end_date).toISOString(); const eventEnd = new Date(event.end_date).toISOString();
// Time filter // Time filter
if (filterState.time === "upcoming" && eventStart <= now) if (filterState.time === "upcoming" && eventStart <= now) return false;
return false;
if (filterState.time === "past" && eventEnd >= now) return false; if (filterState.time === "past" && eventEnd >= now) return false;
if ( if (
filterState.time === "ongoing" && filterState.time === "ongoing" &&
@ -1028,7 +961,7 @@ const currentPage = eventResponse.page;
// Check if either the start year or end year matches any selected year // Check if either the start year or end year matches any selected year
const yearMatches = filterState.year.some( const yearMatches = filterState.year.some(
(year) => year === eventStartYear || year === eventEndYear (year) => year === eventStartYear || year === eventEndYear,
); );
if (!yearMatches) return false; if (!yearMatches) return false;
} }
@ -1065,8 +998,7 @@ const currentPage = eventResponse.page;
// Published filter // Published filter
if (filterState.published !== "all") { if (filterState.published !== "all") {
if ((filterState.published === "yes") !== event.published) if ((filterState.published === "yes") !== event.published) return false;
return false;
} }
// Has Files filter // Has Files filter
@ -1077,8 +1009,7 @@ const currentPage = eventResponse.page;
// Has Food filter // Has Food filter
if (filterState.hasFood !== "all") { if (filterState.hasFood !== "all") {
if ((filterState.hasFood === "yes") !== event.has_food) if ((filterState.hasFood === "yes") !== event.has_food) return false;
return false;
} }
// Search query // Search query
@ -1093,7 +1024,7 @@ const currentPage = eventResponse.page;
event.event_name.toLowerCase().includes(term) || event.event_name.toLowerCase().includes(term) ||
event.event_code.toLowerCase().includes(term) || event.event_code.toLowerCase().includes(term) ||
event.location.toLowerCase().includes(term) || event.location.toLowerCase().includes(term) ||
event.event_description.toLowerCase().includes(term) event.event_description.toLowerCase().includes(term),
) )
); );
} }
@ -1105,9 +1036,7 @@ const currentPage = eventResponse.page;
// Fetch and display events using cached data // Fetch and display events using cached data
async function fetchEvents() { async function fetchEvents() {
const eventsList = document.getElementById("eventsList"); const eventsList = document.getElementById("eventsList");
const paginationContainer = document.getElementById( const paginationContainer = document.getElementById("paginationContainer");
"paginationContainer"
);
if (!eventsList || !paginationContainer) return; if (!eventsList || !paginationContainer) return;
try { try {
@ -1133,8 +1062,7 @@ const currentPage = eventResponse.page;
// Sort events by start date (newest first) // Sort events by start date (newest first)
filteredEvents.sort( filteredEvents.sort(
(a, b) => (a, b) =>
new Date(b.start_date).getTime() - new Date(b.start_date).getTime() - new Date(a.start_date).getTime(),
new Date(a.start_date).getTime()
); );
// Calculate pagination // Calculate pagination
@ -1146,19 +1074,18 @@ const currentPage = eventResponse.page;
// Update pagination UI // Update pagination UI
const firstPageBtn = document.getElementById( const firstPageBtn = document.getElementById(
"firstPageBtn" "firstPageBtn",
) as HTMLButtonElement; ) as HTMLButtonElement;
const prevPageBtn = document.getElementById( const prevPageBtn = document.getElementById(
"prevPageBtn" "prevPageBtn",
) as HTMLButtonElement; ) as HTMLButtonElement;
const nextPageBtn = document.getElementById( const nextPageBtn = document.getElementById(
"nextPageBtn" "nextPageBtn",
) as HTMLButtonElement; ) as HTMLButtonElement;
const lastPageBtn = document.getElementById( const lastPageBtn = document.getElementById(
"lastPageBtn" "lastPageBtn",
) as HTMLButtonElement; ) as HTMLButtonElement;
const currentPageNumber = const currentPageNumber = document.getElementById("currentPageNumber");
document.getElementById("currentPageNumber");
if (firstPageBtn) firstPageBtn.disabled = currentPage <= 1; if (firstPageBtn) firstPageBtn.disabled = currentPage <= 1;
if (prevPageBtn) prevPageBtn.disabled = currentPage <= 1; if (prevPageBtn) prevPageBtn.disabled = currentPage <= 1;
@ -1206,12 +1133,8 @@ const currentPage = eventResponse.page;
console.error("Error formatting date:", e); console.error("Error formatting date:", e);
} }
const locationStr = event.location const locationStr = event.location ? `${event.location}` : "";
? `${event.location}` const codeStr = event.event_code ? `${event.event_code}` : "";
: "";
const codeStr = event.event_code
? `${event.event_code}`
: "";
const detailsStr = [locationStr, codeStr] const detailsStr = [locationStr, codeStr]
.filter(Boolean) .filter(Boolean)
.join(" | code: "); .join(" | code: ");
@ -1276,8 +1199,7 @@ const currentPage = eventResponse.page;
async function calculateQuarterlyStats() { async function calculateQuarterlyStats() {
try { try {
const { start: termStart, end: termEnd } = getCurrentTerm(); const { start: termStart, end: termEnd } = getCurrentTerm();
const { start: quarterStart, end: quarterEnd } = const { start: quarterStart, end: quarterEnd } = getCurrentQuarter();
getCurrentQuarter();
// Update quarter name in UI // Update quarter name in UI
const quarterNameEl = document.getElementById("quarterName"); const quarterNameEl = document.getElementById("quarterName");
@ -1318,19 +1240,17 @@ const currentPage = eventResponse.page;
}); });
quarterlyStats.recurringAttendees = Array.from( quarterlyStats.recurringAttendees = Array.from(
quarterAttendees.values() quarterAttendees.values(),
).filter((count) => count > 1).length; ).filter((count) => count > 1).length;
// Update the UI // Update the UI
const totalEventsEl = document.getElementById("totalEvents"); const totalEventsEl = document.getElementById("totalEvents");
const uniqueAttendeesEl = const uniqueAttendeesEl = document.getElementById("uniqueAttendees");
document.getElementById("uniqueAttendees");
const recurringAttendeesEl = const recurringAttendeesEl =
document.getElementById("recurringAttendees"); document.getElementById("recurringAttendees");
if (totalEventsEl) if (totalEventsEl)
totalEventsEl.textContent = totalEventsEl.textContent = quarterlyStats.totalEvents.toString();
quarterlyStats.totalEvents.toString();
if (uniqueAttendeesEl) if (uniqueAttendeesEl)
uniqueAttendeesEl.textContent = uniqueAttendeesEl.textContent =
quarterlyStats.uniqueAttendees.toString(); quarterlyStats.uniqueAttendees.toString();
@ -1383,24 +1303,20 @@ const currentPage = eventResponse.page;
}); });
// Year filter // Year filter
document document.getElementById("yearCheckboxes")?.addEventListener("change", (e) => {
.getElementById("yearCheckboxes")
?.addEventListener("change", (e) => {
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
if (!target.matches('input[type="checkbox"]')) return; if (!target.matches('input[type="checkbox"]')) return;
const allYearsCheckbox = target const allYearsCheckbox = target
.closest(".dropdown-content") .closest(".dropdown-content")
?.querySelector( ?.querySelector(
'input[type="checkbox"][value="all"]' 'input[type="checkbox"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
const yearInputs = Array.from( const yearInputs = Array.from(
target target
.closest(".dropdown-content") .closest(".dropdown-content")
?.querySelectorAll( ?.querySelectorAll('#yearCheckboxes input[type="checkbox"]') || [],
'#yearCheckboxes input[type="checkbox"]'
) || []
) as HTMLInputElement[]; ) as HTMLInputElement[];
if (target.value === "all" && target.checked) { if (target.value === "all" && target.checked) {
@ -1408,8 +1324,7 @@ const currentPage = eventResponse.page;
input.checked = false; input.checked = false;
}); });
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById("yearFilterLabel")!.textContent = document.getElementById("yearFilterLabel")!.textContent = "All Years";
"All Years";
} else { } else {
const checkedYears = yearInputs const checkedYears = yearInputs
.filter((inp) => inp.checked) .filter((inp) => inp.checked)
@ -1418,8 +1333,7 @@ const currentPage = eventResponse.page;
if (checkedYears.length === 0) { if (checkedYears.length === 0) {
allYearsCheckbox.checked = true; allYearsCheckbox.checked = true;
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById("yearFilterLabel")!.textContent = document.getElementById("yearFilterLabel")!.textContent = "All Years";
"All Years";
} else { } else {
allYearsCheckbox.checked = false; allYearsCheckbox.checked = false;
filterState.year = checkedYears; filterState.year = checkedYears;
@ -1439,9 +1353,7 @@ const currentPage = eventResponse.page;
?.addEventListener("change", (e) => { ?.addEventListener("change", (e) => {
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
const yearInputs = Array.from( const yearInputs = Array.from(
document.querySelectorAll( document.querySelectorAll('#yearCheckboxes input[type="checkbox"]'),
'#yearCheckboxes input[type="checkbox"]'
)
) as HTMLInputElement[]; ) as HTMLInputElement[];
if (target.checked) { if (target.checked) {
@ -1449,8 +1361,7 @@ const currentPage = eventResponse.page;
input.checked = false; input.checked = false;
}); });
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById("yearFilterLabel")!.textContent = document.getElementById("yearFilterLabel")!.textContent = "All Years";
"All Years";
currentPage = 1; currentPage = 1;
fetchEvents(); fetchEvents();
} }
@ -1466,15 +1377,15 @@ const currentPage = eventResponse.page;
const allQuartersCheckbox = target const allQuartersCheckbox = target
.closest("#quarterDropdownContent") .closest("#quarterDropdownContent")
?.querySelector( ?.querySelector(
'input[type="checkbox"][value="all"]' 'input[type="checkbox"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
const quarterInputs = Array.from( const quarterInputs = Array.from(
target target
.closest("#quarterDropdownContent") .closest("#quarterDropdownContent")
?.querySelectorAll('input[type="checkbox"]') || [] ?.querySelectorAll('input[type="checkbox"]') || [],
).filter( ).filter(
(inp) => (inp as HTMLInputElement).value !== "all" (inp) => (inp as HTMLInputElement).value !== "all",
) as HTMLInputElement[]; ) as HTMLInputElement[];
if (target.value === "all" && target.checked) { if (target.value === "all" && target.checked) {
@ -1516,8 +1427,8 @@ const currentPage = eventResponse.page;
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
filterState.published = target.value; filterState.published = target.value;
document.getElementById("publishedFilterLabel")!.textContent = document.getElementById("publishedFilterLabel")!.textContent =
target.parentElement?.querySelector(".label-text") target.parentElement?.querySelector(".label-text")?.textContent ||
?.textContent || "All"; "All";
currentPage = 1; currentPage = 1;
fetchEvents(); fetchEvents();
}); });
@ -1531,8 +1442,8 @@ const currentPage = eventResponse.page;
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
filterState.hasFiles = target.value; filterState.hasFiles = target.value;
document.getElementById("hasFilesFilterLabel")!.textContent = document.getElementById("hasFilesFilterLabel")!.textContent =
target.parentElement?.querySelector(".label-text") target.parentElement?.querySelector(".label-text")?.textContent ||
?.textContent || "All"; "All";
currentPage = 1; currentPage = 1;
fetchEvents(); fetchEvents();
}); });
@ -1546,8 +1457,8 @@ const currentPage = eventResponse.page;
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
filterState.hasFood = target.value; filterState.hasFood = target.value;
document.getElementById("hasFoodFilterLabel")!.textContent = document.getElementById("hasFoodFilterLabel")!.textContent =
target.parentElement?.querySelector(".label-text") target.parentElement?.querySelector(".label-text")?.textContent ||
?.textContent || "All"; "All";
currentPage = 1; currentPage = 1;
fetchEvents(); fetchEvents();
}); });
@ -1576,9 +1487,7 @@ const currentPage = eventResponse.page;
} }
// Per page select // Per page select
document document.getElementById("perPageSelect")?.addEventListener("change", (e) => {
.getElementById("perPageSelect")
?.addEventListener("change", (e) => {
const target = e.target as HTMLSelectElement; const target = e.target as HTMLSelectElement;
perPage = parseInt(target.value); perPage = parseInt(target.value);
currentPage = 1; currentPage = 1;
@ -1590,7 +1499,7 @@ const currentPage = eventResponse.page;
window.addEventListener("DOMContentLoaded", () => { window.addEventListener("DOMContentLoaded", () => {
// Reset all filters to defaults // Reset all filters to defaults
const timeFilterAll = document.querySelector( const timeFilterAll = document.querySelector(
'input[name="timeFilter"][value="all"]' 'input[name="timeFilter"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
if (timeFilterAll) { if (timeFilterAll) {
// Ensure the radio button is properly checked // Ensure the radio button is properly checked
@ -1600,10 +1509,10 @@ const currentPage = eventResponse.page;
// Reset year filter // Reset year filter
const yearAllCheckbox = document.querySelector( const yearAllCheckbox = document.querySelector(
'input[type="checkbox"][value="all"]' 'input[type="checkbox"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
const yearCheckboxes = document.querySelectorAll( const yearCheckboxes = document.querySelectorAll(
'#yearCheckboxes input[type="checkbox"]' '#yearCheckboxes input[type="checkbox"]',
); );
if (yearAllCheckbox && yearCheckboxes) { if (yearAllCheckbox && yearCheckboxes) {
yearAllCheckbox.checked = true; yearAllCheckbox.checked = true;
@ -1611,16 +1520,15 @@ const currentPage = eventResponse.page;
(checkbox as HTMLInputElement).checked = false; (checkbox as HTMLInputElement).checked = false;
}); });
filterState.year = ["all"]; filterState.year = ["all"];
document.getElementById("yearFilterLabel")!.textContent = document.getElementById("yearFilterLabel")!.textContent = "All Years";
"All Years";
} }
// Reset quarter filter // Reset quarter filter
const quarterAllCheckbox = document.querySelector( const quarterAllCheckbox = document.querySelector(
'#quarterDropdownContent input[type="checkbox"][value="all"]' '#quarterDropdownContent input[type="checkbox"][value="all"]',
) as HTMLInputElement; ) as HTMLInputElement;
const quarterCheckboxes = document.querySelectorAll( const quarterCheckboxes = document.querySelectorAll(
'#quarterDropdownContent input[type="checkbox"]:not([value="all"])' '#quarterDropdownContent input[type="checkbox"]:not([value="all"])',
); );
if (quarterAllCheckbox && quarterCheckboxes) { if (quarterAllCheckbox && quarterCheckboxes) {
quarterAllCheckbox.checked = true; quarterAllCheckbox.checked = true;
@ -1633,27 +1541,27 @@ const currentPage = eventResponse.page;
} }
const publishedFilter = document.getElementById( const publishedFilter = document.getElementById(
"publishedFilter" "publishedFilter",
) as HTMLSelectElement; ) as HTMLSelectElement;
if (publishedFilter) publishedFilter.value = "all"; if (publishedFilter) publishedFilter.value = "all";
const hasFilesFilter = document.getElementById( const hasFilesFilter = document.getElementById(
"hasFilesFilter" "hasFilesFilter",
) as HTMLSelectElement; ) as HTMLSelectElement;
if (hasFilesFilter) hasFilesFilter.value = "all"; if (hasFilesFilter) hasFilesFilter.value = "all";
const hasFoodFilter = document.getElementById( const hasFoodFilter = document.getElementById(
"hasFoodFilter" "hasFoodFilter",
) as HTMLSelectElement; ) as HTMLSelectElement;
if (hasFoodFilter) hasFoodFilter.value = "all"; if (hasFoodFilter) hasFoodFilter.value = "all";
const searchInput = document.getElementById( const searchInput = document.getElementById(
"searchInput" "searchInput",
) as HTMLInputElement; ) as HTMLInputElement;
if (searchInput) searchInput.value = ""; if (searchInput) searchInput.value = "";
const perPageSelect = document.getElementById( const perPageSelect = document.getElementById(
"perPageSelect" "perPageSelect",
) as HTMLSelectElement; ) as HTMLSelectElement;
if (perPageSelect) perPageSelect.value = "5"; if (perPageSelect) perPageSelect.value = "5";
@ -1683,12 +1591,10 @@ const currentPage = eventResponse.page;
// Update the previewFileInEditModal function // Update the previewFileInEditModal function
window.previewFileInEditModal = async function ( window.previewFileInEditModal = async function (
url: string, url: string,
filename: string filename: string,
) { ) {
const editFormSection = document.getElementById("editFormSection"); const editFormSection = document.getElementById("editFormSection");
const previewSection = document.getElementById( const previewSection = document.getElementById("editModalPreviewSection");
"editModalPreviewSection"
);
const editFilePreview = document.getElementById("editFilePreview"); const editFilePreview = document.getElementById("editFilePreview");
const previewFileName = document.getElementById("editPreviewFileName"); const previewFileName = document.getElementById("editPreviewFileName");
const loadingSpinner = document.getElementById("editLoadingSpinner"); const loadingSpinner = document.getElementById("editLoadingSpinner");
@ -1724,16 +1630,14 @@ const currentPage = eventResponse.page;
// Update the showFilePreview function // Update the showFilePreview function
window.showFilePreview = function (file: { url: string; name: string }) { window.showFilePreview = function (file: { url: string; name: string }) {
console.log("showFilePreview called with:", file); // console.log("showFilePreview called with:", file);
window.previewFile(file.url, file.name); window.previewFile(file.url, file.name);
}; };
// Add backToEditForm function // Add backToEditForm function
window.backToEditForm = function () { window.backToEditForm = function () {
const editFormSection = document.getElementById("editFormSection"); const editFormSection = document.getElementById("editFormSection");
const previewSection = document.getElementById( const previewSection = document.getElementById("editModalPreviewSection");
"editModalPreviewSection"
);
const editFilePreview = document.getElementById("editFilePreview"); const editFilePreview = document.getElementById("editFilePreview");
const previewFileName = document.getElementById("editPreviewFileName"); const previewFileName = document.getElementById("editPreviewFileName");
@ -1756,17 +1660,15 @@ const currentPage = eventResponse.page;
// Universal file preview function // Universal file preview function
window.previewFile = function (url: string, filename: string) { window.previewFile = function (url: string, filename: string) {
console.log("previewFile called with:", { url, filename }); // console.log("previewFile called with:", { url, filename });
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const filePreview = document.getElementById( const filePreview = document.getElementById("officerFilePreview") as any;
"officerFilePreview"
) as any;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
if (filePreview && modal && previewFileName) { if (filePreview && modal && previewFileName) {
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;
@ -1774,7 +1676,7 @@ const currentPage = eventResponse.page;
modal.showModal(); modal.showModal();
// Update the preview component // Update the preview component
console.log("Dispatching updateFilePreview event"); // console.log("Dispatching updateFilePreview event");
const event = new CustomEvent("updateFilePreview", { const event = new CustomEvent("updateFilePreview", {
detail: { url, filename }, detail: { url, filename },
}); });
@ -1790,17 +1692,15 @@ const currentPage = eventResponse.page;
// Close file preview // Close file preview
window.closeFilePreview = function () { window.closeFilePreview = function () {
console.log("closeFilePreview called"); // console.log("closeFilePreview called");
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const filePreview = document.getElementById( const filePreview = document.getElementById("officerFilePreview") as any;
"officerFilePreview"
) as any;
const previewFileName = document.getElementById("previewFileName"); const previewFileName = document.getElementById("previewFileName");
if (modal && filePreview && previewFileName) { if (modal && filePreview && previewFileName) {
console.log("Resetting preview and closing modal"); // console.log("Resetting preview and closing modal");
// Reset the preview // Reset the preview
const event = new CustomEvent("updateFilePreview", { const event = new CustomEvent("updateFilePreview", {
detail: { url: "", filename: "" }, detail: { url: "", filename: "" },
@ -1814,7 +1714,7 @@ const currentPage = eventResponse.page;
// Close event details modal // Close event details modal
window.closeEventDetailsModal = function () { window.closeEventDetailsModal = function () {
const modal = document.getElementById( const modal = document.getElementById(
"eventDetailsModal" "eventDetailsModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const filesContent = document.getElementById("filesContent"); const filesContent = document.getElementById("filesContent");
const attendeesContent = document.getElementById("attendeesContent"); const attendeesContent = document.getElementById("attendeesContent");
@ -1835,11 +1735,7 @@ const currentPage = eventResponse.page;
function updateFilePreviewButtons(files: string[], eventId: string) { function updateFilePreviewButtons(files: string[], eventId: string) {
return files return files
.map((filename) => { .map((filename) => {
const fileUrl = fileManager.getFileUrl( const fileUrl = fileManager.getFileUrl("events", eventId, filename);
"events",
eventId,
filename
);
const previewData = JSON.stringify({ const previewData = JSON.stringify({
url: fileUrl, url: fileUrl,
name: filename, name: filename,
@ -1884,12 +1780,10 @@ const currentPage = eventResponse.page;
if (newFiles && fileInput.files) { if (newFiles && fileInput.files) {
// Get existing files if any // Get existing files if any
const existingFiles = newFiles.querySelectorAll(".file-item"); const existingFiles = newFiles.querySelectorAll(".file-item");
const existingFilesArray = Array.from(existingFiles).map( const existingFilesArray = Array.from(existingFiles).map((item) => {
(item) => {
const nameSpan = item.querySelector(".file-name"); const nameSpan = item.querySelector(".file-name");
return nameSpan ? nameSpan.textContent : ""; return nameSpan ? nameSpan.textContent : "";
} });
);
// Store new files in the storage and update UI // Store new files in the storage and update UI
Array.from(fileInput.files) Array.from(fileInput.files)
@ -1936,12 +1830,11 @@ const currentPage = eventResponse.page;
const currentFiles = document.getElementById("currentFiles"); const currentFiles = document.getElementById("currentFiles");
if (currentFiles) { if (currentFiles) {
const fileElement = currentFiles.querySelector( const fileElement = currentFiles.querySelector(
`[data-filename="${filename}"]` `[data-filename="${filename}"]`,
); );
if (fileElement) { if (fileElement) {
fileElement.classList.add("opacity-50"); fileElement.classList.add("opacity-50");
const deleteButton = const deleteButton = fileElement.querySelector(".text-error");
fileElement.querySelector(".text-error");
if (deleteButton) { if (deleteButton) {
deleteButton.innerHTML = ` deleteButton.innerHTML = `
<button type="button" class="btn btn-ghost btn-xs" onclick="window.undoDeleteFile('${eventId}', '${filename}')"> <button type="button" class="btn btn-ghost btn-xs" onclick="window.undoDeleteFile('${eventId}', '${filename}')">
@ -1957,7 +1850,7 @@ const currentPage = eventResponse.page;
`File "${filename}" marked for deletion. Save changes to confirm.`, `File "${filename}" marked for deletion. Save changes to confirm.`,
{ {
icon: "🗑️", icon: "🗑️",
} },
); );
} catch (error) { } catch (error) {
console.error("Failed to stage file deletion:", error); console.error("Failed to stage file deletion:", error);
@ -1973,7 +1866,7 @@ const currentPage = eventResponse.page;
const currentFiles = document.getElementById("currentFiles"); const currentFiles = document.getElementById("currentFiles");
if (currentFiles) { if (currentFiles) {
const fileElement = currentFiles.querySelector( const fileElement = currentFiles.querySelector(
`[data-filename="${filename}"]` `[data-filename="${filename}"]`,
); );
if (fileElement) { if (fileElement) {
fileElement.classList.remove("opacity-50"); fileElement.classList.remove("opacity-50");
@ -2002,7 +1895,7 @@ const currentPage = eventResponse.page;
// Universal file preview function for officer section // Universal file preview function for officer section
window.previewFileOfficer = function (url: string, filename: string) { window.previewFileOfficer = function (url: string, filename: string) {
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
if (!modal) { if (!modal) {
@ -2014,7 +1907,7 @@ const currentPage = eventResponse.page;
window.dispatchEvent( window.dispatchEvent(
new CustomEvent(FILE_PREVIEW_STATE_CHANGE, { new CustomEvent(FILE_PREVIEW_STATE_CHANGE, {
detail: { url, filename }, detail: { url, filename },
}) }),
); );
// Show modal after event dispatch // Show modal after event dispatch
@ -2026,7 +1919,7 @@ const currentPage = eventResponse.page;
// Close file preview for officer section // Close file preview for officer section
window.closeFilePreviewOfficer = function () { window.closeFilePreviewOfficer = function () {
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const previewContent = document.getElementById("previewContent"); const previewContent = document.getElementById("previewContent");
@ -2049,7 +1942,7 @@ const currentPage = eventResponse.page;
window.dispatchEvent( window.dispatchEvent(
new CustomEvent(FILE_PREVIEW_STATE_CHANGE, { new CustomEvent(FILE_PREVIEW_STATE_CHANGE, {
detail: { url: "", filename: "" }, detail: { url: "", filename: "" },
}) }),
); );
// Close modal after cleanup // Close modal after cleanup
@ -2083,18 +1976,14 @@ const currentPage = eventResponse.page;
} }
// Get fresh URL from FileManager to ensure we have the latest // Get fresh URL from FileManager to ensure we have the latest
const freshUrl = fileManager.getFileUrl( const freshUrl = fileManager.getFileUrl("events", eventId, file.name);
"events",
eventId,
file.name
);
// Show the preview with fresh URL // Show the preview with fresh URL
window.previewFileOfficer(freshUrl, file.name); window.previewFileOfficer(freshUrl, file.name);
} catch (error) { } catch (error) {
console.error("Failed to fetch fresh file data:", error); console.error("Failed to fetch fresh file data:", error);
toast.error( toast.error(
"Failed to load file preview. The file may have been deleted or modified." "Failed to load file preview. The file may have been deleted or modified.",
); );
} }
}; };
@ -2104,10 +1993,10 @@ const currentPage = eventResponse.page;
// Add openAttendeesModal function // Add openAttendeesModal function
window.openAttendeesModal = function (event: Event) { window.openAttendeesModal = function (event: Event) {
console.log("Opening attendees modal for event:", event.id); // console.log("Opening attendees modal for event:", event.id);
const modal = document.getElementById( const modal = document.getElementById(
"attendeesModal" "attendeesModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
const modalTitle = document.getElementById("attendeesModalTitle"); const modalTitle = document.getElementById("attendeesModalTitle");
@ -2126,7 +2015,7 @@ const currentPage = eventResponse.page;
eventId: event.id, eventId: event.id,
eventName: event.event_name, eventName: event.event_name,
}, },
}) }),
); );
// Show modal // Show modal
@ -2136,7 +2025,7 @@ const currentPage = eventResponse.page;
// Add event listeners when the document loads // Add event listeners when the document loads
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
const modal = document.getElementById( const modal = document.getElementById(
"filePreviewModal" "filePreviewModal",
) as HTMLDialogElement; ) as HTMLDialogElement;
if (modal) { if (modal) {
// Handle modal close via backdrop // Handle modal close via backdrop

View file

@ -287,7 +287,7 @@ export default function Attendees() {
const fetchEventData = async () => { const fetchEventData = async () => {
if (!eventId || !auth.isAuthenticated()) { if (!eventId || !auth.isAuthenticated()) {
if (!auth.isAuthenticated()) { if (!auth.isAuthenticated()) {
console.log('User not authenticated'); // console.log('User not authenticated');
setError('Authentication required'); setError('Authentication required');
} }
return; return;

View file

@ -631,7 +631,7 @@ export default function EventEditor({ onEventSaved }: EventEditorProps) {
has_food: eventData.has_food || false has_food: eventData.has_food || false
}); });
console.log("Event data loaded successfully:", eventData); // console.log("Event data loaded successfully:", eventData);
} else { } else {
setEvent({ setEvent({
id: '', id: '',
@ -784,7 +784,7 @@ export default function EventEditor({ onEventSaved }: EventEditorProps) {
// 1. Remove files marked for deletion // 1. Remove files marked for deletion
if (filesToDelete.size > 0) { if (filesToDelete.size > 0) {
console.log(`Removing ${filesToDelete.size} files from event ${event.id}`); // console.log(`Removing ${filesToDelete.size} files from event ${event.id}`);
currentFiles = currentFiles.filter(file => !filesToDelete.has(file)); currentFiles = currentFiles.filter(file => !filesToDelete.has(file));
// Update the files field first to remove deleted files // Update the files field first to remove deleted files
@ -797,7 +797,7 @@ export default function EventEditor({ onEventSaved }: EventEditorProps) {
// 2. Add new files one by one to preserve existing ones // 2. Add new files one by one to preserve existing ones
if (selectedFiles.size > 0) { if (selectedFiles.size > 0) {
console.log(`Adding ${selectedFiles.size} new files to event ${event.id}`); // console.log(`Adding ${selectedFiles.size} new files to event ${event.id}`);
// Convert Map to array of File objects // Convert Map to array of File objects
const newFiles = Array.from(selectedFiles.values()); const newFiles = Array.from(selectedFiles.values());
@ -849,7 +849,7 @@ export default function EventEditor({ onEventSaved }: EventEditorProps) {
// Then upload files if any // Then upload files if any
if (selectedFiles.size > 0 && newEvent?.id) { if (selectedFiles.size > 0 && newEvent?.id) {
console.log(`Adding ${selectedFiles.size} files to new event ${newEvent.id}`); // console.log(`Adding ${selectedFiles.size} files to new event ${newEvent.id}`);
// Convert Map to array of File objects // Convert Map to array of File objects
const newFiles = Array.from(selectedFiles.values()); const newFiles = Array.from(selectedFiles.values());

View file

@ -31,7 +31,7 @@ if (auth.isAuthenticated()) {
userEventRequests = await get.getAll<EventRequest>( userEventRequests = await get.getAll<EventRequest>(
Collections.EVENT_REQUESTS, Collections.EVENT_REQUESTS,
`requested_user="${userId}"`, `requested_user="${userId}"`,
"-created" "-created",
); );
} }
} catch (err) { } catch (err) {
@ -46,8 +46,8 @@ if (auth.isAuthenticated()) {
<h1 class="text-3xl font-bold text-white mb-2">Event Request Form</h1> <h1 class="text-3xl font-bold text-white mb-2">Event Request Form</h1>
<p class="text-gray-300 mb-4"> <p class="text-gray-300 mb-4">
Submit your event request at least 6 weeks before your event. After Submit your event request at least 6 weeks before your event. After
submitting, please notify PR and/or Coordinators in the #-events submitting, please notify PR and/or Coordinators in the #-events Slack
Slack channel. channel.
</p> </p>
<div class="bg-base-300/50 p-4 rounded-lg text-sm text-gray-300"> <div class="bg-base-300/50 p-4 rounded-lg text-sm text-gray-300">
<p class="font-medium mb-2">This form includes sections for:</p> <p class="font-medium mb-2">This form includes sections for:</p>
@ -109,10 +109,7 @@ if (auth.isAuthenticated()) {
{ {
!error && ( !error && (
<UserEventRequests <UserEventRequests client:load eventRequests={userEventRequests} />
client:load
eventRequests={userEventRequests}
/>
) )
} }
</div> </div>
@ -171,10 +168,10 @@ if (auth.isAuthenticated()) {
<script is:inline> <script is:inline>
// Define the global function immediately to ensure it's available // Define the global function immediately to ensure it's available
window.showEventRequestFormPreview = function (formData) { window.showEventRequestFormPreview = function (formData) {
console.log( // console.log(
"Global showEventRequestFormPreview called with data", // "Global showEventRequestFormPreview called with data",
formData // formData
); // );
// Remove any elements that might be obstructing the view // Remove any elements that might be obstructing the view
const removeObstructions = () => { const removeObstructions = () => {
@ -204,12 +201,12 @@ if (auth.isAuthenticated()) {
// Dispatch event to show modal // Dispatch event to show modal
document.dispatchEvent(event); document.dispatchEvent(event);
console.log("showEventRequestPreviewModal event dispatched"); // console.log("showEventRequestPreviewModal event dispatched");
// Ensure modal container is visible // Ensure modal container is visible
setTimeout(() => { setTimeout(() => {
const modalContainer = document.getElementById( const modalContainer = document.getElementById(
"event-request-preview-modal-container" "event-request-preview-modal-container",
); );
if (modalContainer) { if (modalContainer) {
modalContainer.style.zIndex = "99999"; modalContainer.style.zIndex = "99999";
@ -226,8 +223,7 @@ if (auth.isAuthenticated()) {
document.body.style.overflow = "auto"; document.body.style.overflow = "auto";
// Ensure the modal content is properly sized // Ensure the modal content is properly sized
const modalContent = const modalContent = modalContainer.querySelector("div > div > div");
modalContainer.querySelector("div > div > div");
if (modalContent) { if (modalContent) {
modalContent.style.maxWidth = "90vw"; modalContent.style.maxWidth = "90vw";
modalContent.style.width = "100%"; modalContent.style.width = "100%";
@ -261,30 +257,26 @@ if (auth.isAuthenticated()) {
await dataSync.syncCollection( await dataSync.syncCollection(
Collections.EVENT_REQUESTS, Collections.EVENT_REQUESTS,
`requested_user="${userId}"`, `requested_user="${userId}"`,
"-created" "-created",
);
console.log(
"Initial data sync complete for user event requests"
); );
// console.log("Initial data sync complete for user event requests");
} }
} catch (err) { } catch (err) {
console.error("Error during initial data sync:", err); // console.error("Error during initial data sync:", err);
} }
} }
const formTab = document.getElementById("form-tab"); const formTab = document.getElementById("form-tab");
const submissionsTab = document.getElementById("submissions-tab"); const submissionsTab = document.getElementById("submissions-tab");
const formContent = document.getElementById("form-content"); const formContent = document.getElementById("form-content");
const submissionsContent = document.getElementById( const submissionsContent = document.getElementById("submissions-content");
"submissions-content"
);
// Function to switch tabs // Function to switch tabs
const switchTab = ( const switchTab = (
activeTab: HTMLElement, activeTab: HTMLElement,
activeContent: HTMLElement, activeContent: HTMLElement,
inactiveTab: HTMLElement, inactiveTab: HTMLElement,
inactiveContent: HTMLElement inactiveContent: HTMLElement,
) => { ) => {
// Update tab classes // Update tab classes
activeTab.classList.add("tab-active"); activeTab.classList.add("tab-active");
@ -305,24 +297,14 @@ if (auth.isAuthenticated()) {
formTab?.addEventListener("click", (e) => { formTab?.addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
if (formContent && submissionsContent && submissionsTab) { if (formContent && submissionsContent && submissionsTab) {
switchTab( switchTab(formTab, formContent, submissionsTab, submissionsContent);
formTab,
formContent,
submissionsTab,
submissionsContent
);
} }
}); });
submissionsTab?.addEventListener("click", (e) => { submissionsTab?.addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
if (formContent && submissionsContent && formTab) { if (formContent && submissionsContent && formTab) {
switchTab( switchTab(submissionsTab, submissionsContent, formTab, formContent);
submissionsTab,
submissionsContent,
formTab,
formContent
);
} }
}); });

View file

@ -12,7 +12,7 @@ export const EventRequestFormPreviewModal: React.FC = () => {
// Function to handle showing the modal // Function to handle showing the modal
const showModal = (data: any) => { const showModal = (data: any) => {
console.log('showModal called with data', data); // console.log('showModal called with data', data);
setFormData(data); setFormData(data);
setIsOpen(true); setIsOpen(true);
}; };
@ -24,23 +24,23 @@ export const EventRequestFormPreviewModal: React.FC = () => {
// Define the global function // Define the global function
window.showEventRequestFormPreview = (data: any) => { window.showEventRequestFormPreview = (data: any) => {
console.log('Global showEventRequestFormPreview called with data', data); // console.log('Global showEventRequestFormPreview called with data', data);
showModal(data); showModal(data);
}; };
// Listen for the custom event as a fallback // Listen for the custom event as a fallback
const handleShowModal = (event: CustomEvent) => { const handleShowModal = (event: CustomEvent) => {
console.log('Received showEventRequestPreviewModal event', event.detail); // console.log('Received showEventRequestPreviewModal event', event.detail);
if (event.detail && event.detail.formData) { if (event.detail && event.detail.formData) {
showModal(event.detail.formData); showModal(event.detail.formData);
} else { } else {
console.error('Event detail or formData is missing', event.detail); // console.error('Event detail or formData is missing', event.detail);
} }
}; };
// Add event listener // Add event listener
document.addEventListener('showEventRequestPreviewModal', handleShowModal as EventListener); document.addEventListener('showEventRequestPreviewModal', handleShowModal as EventListener);
console.log('Event listener for showEventRequestPreviewModal added'); // console.log('Event listener for showEventRequestPreviewModal added');
// Clean up // Clean up
return () => { return () => {
@ -53,12 +53,12 @@ export const EventRequestFormPreviewModal: React.FC = () => {
} }
document.removeEventListener('showEventRequestPreviewModal', handleShowModal as EventListener); document.removeEventListener('showEventRequestPreviewModal', handleShowModal as EventListener);
console.log('Event listener for showEventRequestPreviewModal removed'); // console.log('Event listener for showEventRequestPreviewModal removed');
}; };
}, []); // Empty dependency array - only run once on mount }, []); // Empty dependency array - only run once on mount
const handleClose = () => { const handleClose = () => {
console.log('Modal closed'); // console.log('Modal closed');
setIsOpen(false); setIsOpen(false);
}; };
@ -122,7 +122,7 @@ const EventRequestFormPreview: React.FC<EventRequestFormPreviewProps> = ({
const parsedData = JSON.parse(savedData); const parsedData = JSON.parse(savedData);
setFormData(parsedData); setFormData(parsedData);
} catch (e) { } catch (e) {
console.error('Error parsing saved form data:', e); // console.error('Error parsing saved form data:', e);
} }
} }
setLoading(false); setLoading(false);

View file

@ -69,7 +69,7 @@ const UserEventRequests: React.FC<UserEventRequestsProps> = ({ eventRequests: in
// Listen for tab visibility changes and refresh data when tab becomes visible // Listen for tab visibility changes and refresh data when tab becomes visible
useEffect(() => { useEffect(() => {
const handleTabVisible = () => { const handleTabVisible = () => {
console.log("Tab became visible, refreshing event requests..."); // console.log("Tab became visible, refreshing event requests...");
refreshEventRequests(); refreshEventRequests();
}; };
@ -411,19 +411,19 @@ const UserEventRequests: React.FC<UserEventRequestsProps> = ({ eventRequests: in
className="btn btn-sm btn-primary" className="btn btn-sm btn-primary"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
console.log('Full Preview button clicked', selectedRequest); // console.log('Full Preview button clicked', selectedRequest);
try { try {
// Direct call to the global function // Direct call to the global function
if (typeof window.showEventRequestFormPreview === 'function') { if (typeof window.showEventRequestFormPreview === 'function') {
window.showEventRequestFormPreview(selectedRequest); window.showEventRequestFormPreview(selectedRequest);
} else { } else {
console.error('showEventRequestFormPreview is not a function', window.showEventRequestFormPreview); // console.log('Fallback: showEventRequestPreviewModal event dispatched');
// Fallback to event dispatch if function is not available // Fallback to event dispatch if function is not available
const event = new CustomEvent("showEventRequestPreviewModal", { const event = new CustomEvent("showEventRequestPreviewModal", {
detail: { formData: selectedRequest } detail: { formData: selectedRequest }
}); });
document.dispatchEvent(event); document.dispatchEvent(event);
console.log('Fallback: showEventRequestPreviewModal event dispatched'); // console.log('Fallback: showEventRequestPreviewModal event dispatched');
} }
} catch (error) { } catch (error) {
console.error('Error showing full preview:', error); console.error('Error showing full preview:', error);

View file

@ -37,7 +37,7 @@ try {
// Don't check authentication here - let the client component handle it // Don't check authentication here - let the client component handle it
// The server-side check is causing issues when the token is valid client-side but not server-side // The server-side check is causing issues when the token is valid client-side but not server-side
console.log("Fetching event requests in Astro component..."); // console.log("Fetching event requests in Astro component...");
// Expand the requested_user field to get user details // Expand the requested_user field to get user details
allEventRequests = await get allEventRequests = await get
.getAll<ExtendedEventRequest>(Collections.EVENT_REQUESTS, "", "-created", { .getAll<ExtendedEventRequest>(Collections.EVENT_REQUESTS, "", "-created", {
@ -49,9 +49,9 @@ try {
return []; return [];
}); });
console.log( // console.log(
`Fetched ${allEventRequests.length} event requests in Astro component`, // `Fetched ${allEventRequests.length} event requests in Astro component`,
); // );
// Process the event requests to add the requested_user_expand property // Process the event requests to add the requested_user_expand property
allEventRequests = allEventRequests.map((request) => { allEventRequests = allEventRequests.map((request) => {
@ -172,9 +172,9 @@ try {
"-created", "-created",
{ expand: "requested_user" }, { expand: "requested_user" },
); );
console.log("Initial data sync complete"); // console.log("Initial data sync complete");
} catch (err) { } catch (err) {
console.error("Error during initial data sync:", err); // console.error("Error during initial data sync:", err);
} }
// Check for error message in the UI // Check for error message in the UI
@ -183,9 +183,9 @@ try {
errorElement && errorElement &&
errorElement.textContent?.includes("Authentication error") errorElement.textContent?.includes("Authentication error")
) { ) {
console.log( // console.log(
"Authentication error detected in UI, redirecting to login...", // "Authentication error detected in UI, redirecting to login...",
); // );
// Redirect to login page after a short delay // Redirect to login page after a short delay
setTimeout(() => { setTimeout(() => {
window.location.href = "/login"; window.location.href = "/login";
@ -196,13 +196,13 @@ try {
// Also check if we have any event requests // Also check if we have any event requests
const tableContainer = document.querySelector(".event-table-container"); const tableContainer = document.querySelector(".event-table-container");
if (tableContainer) { if (tableContainer) {
console.log( // console.log(
"Event table container found, component should load normally", // "Event table container found, component should load normally",
); // );
} else { } else {
console.log( // console.log(
"Event table container not found, might be an issue with rendering", // "Event table container not found, might be an issue with rendering",
); // );
} }
}); });
</script> </script>

View file

@ -56,7 +56,7 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
// Don't check authentication here - try to fetch anyway // Don't check authentication here - try to fetch anyway
// The token might be valid for the API even if isAuthenticated() returns false // The token might be valid for the API even if isAuthenticated() returns false
console.log("Fetching event requests..."); // console.log("Fetching event requests...");
// Use DataSyncService to get data from IndexedDB with forced sync // Use DataSyncService to get data from IndexedDB with forced sync
const updatedRequests = await dataSync.getData<ExtendedEventRequest>( const updatedRequests = await dataSync.getData<ExtendedEventRequest>(
@ -67,12 +67,12 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
'requested_user' 'requested_user'
); );
console.log(`Fetched ${updatedRequests.length} event requests`); // console.log(`Fetched ${updatedRequests.length} event requests`);
setEventRequests(updatedRequests); setEventRequests(updatedRequests);
applyFilters(updatedRequests); applyFilters(updatedRequests);
} catch (error) { } catch (error) {
console.error('Error refreshing event requests:', error); // console.error('Error refreshing event requests:', error);
toast.error('Failed to refresh event requests'); toast.error('Failed to refresh event requests');
} finally { } finally {
setIsRefreshing(false); setIsRefreshing(false);
@ -169,7 +169,7 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
const eventRequest = eventRequests.find(req => req.id === id); const eventRequest = eventRequests.find(req => req.id === id);
const eventName = eventRequest?.name || 'Event'; const eventName = eventRequest?.name || 'Event';
console.error('Error updating status:', error); // console.error('Error updating status:', error);
toast.error(`Failed to update status for "${eventName}"`); toast.error(`Failed to update status for "${eventName}"`);
throw error; // Re-throw the error to be caught by the caller throw error; // Re-throw the error to be caught by the caller
} }
@ -242,7 +242,7 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
// Toast is now shown in updateEventRequestStatus // Toast is now shown in updateEventRequestStatus
closeUpdateModal(); closeUpdateModal();
} catch (error) { } catch (error) {
console.error('Error in handleUpdateStatus:', error); // console.error('Error in handleUpdateStatus:', error);
// Toast is now shown in updateEventRequestStatus // Toast is now shown in updateEventRequestStatus
// Keep modal open so user can try again // Keep modal open so user can try again
} }
@ -273,14 +273,14 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
// Check if we're authenticated // Check if we're authenticated
if (!auth.isAuthenticated()) { if (!auth.isAuthenticated()) {
console.log("Authentication check failed - attempting to continue anyway"); // console.log("Authentication check failed - attempting to continue anyway");
// Don't show error or redirect immediately - try to refresh first // Don't show error or redirect immediately - try to refresh first
try { try {
// Try to refresh event requests anyway - the token might be valid // Try to refresh event requests anyway - the token might be valid
await refreshEventRequests(); await refreshEventRequests();
} catch (err) { } catch (err) {
console.error("Failed to refresh after auth check:", err); // console.error("Failed to refresh after auth check:", err);
toast.error("Authentication error. Please log in again."); toast.error("Authentication error. Please log in again.");
// Only redirect if refresh fails // Only redirect if refresh fails
@ -289,7 +289,7 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
}, 2000); }, 2000);
} }
} else { } else {
console.log("Authentication check passed"); // console.log("Authentication check passed");
} }
}; };
@ -304,7 +304,7 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
// Listen for tab visibility changes and refresh data when tab becomes visible // Listen for tab visibility changes and refresh data when tab becomes visible
useEffect(() => { useEffect(() => {
const handleTabVisible = () => { const handleTabVisible = () => {
console.log("Tab became visible, refreshing event requests..."); // console.log("Tab became visible, refreshing event requests...");
refreshEventRequests(); refreshEventRequests();
}; };

View file

@ -49,7 +49,7 @@ export default function ShowProfileLogs() {
try { try {
setIsFetchingAll(true); setIsFetchingAll(true);
console.log("Fetching logs for user:", userId); // console.log("Fetching logs for user:", userId);
// Use DataSyncService to fetch logs // Use DataSyncService to fetch logs
const dataSync = DataSyncService.getInstance(); const dataSync = DataSyncService.getInstance();
@ -70,15 +70,15 @@ export default function ShowProfileLogs() {
"-created" "-created"
); );
console.log("Fetched logs:", fetchedLogs.length); // console.log("Fetched logs:", fetchedLogs.length);
if (fetchedLogs.length === 0) { if (fetchedLogs.length === 0) {
// If no logs found, try to fetch directly from PocketBase // If no logs found, try to fetch directly from PocketBase
console.log("No logs found in IndexedDB, trying direct fetch from PocketBase"); // console.log("No logs found in IndexedDB, trying direct fetch from PocketBase");
try { try {
const sendLog = SendLog.getInstance(); const sendLog = SendLog.getInstance();
const directLogs = await sendLog.getUserLogs(userId); const directLogs = await sendLog.getUserLogs(userId);
console.log("Direct fetch logs:", directLogs.length); // console.log("Direct fetch logs:", directLogs.length);
if (directLogs.length > 0) { if (directLogs.length > 0) {
setAllLogs(directLogs); setAllLogs(directLogs);
@ -90,7 +90,7 @@ export default function ShowProfileLogs() {
setTotalLogs(fetchedLogs.length); setTotalLogs(fetchedLogs.length);
} }
} catch (directError) { } catch (directError) {
console.error("Failed to fetch logs directly:", directError); // console.error("Failed to fetch logs directly:", directError);
setAllLogs(fetchedLogs); setAllLogs(fetchedLogs);
setTotalPages(Math.ceil(fetchedLogs.length / LOGS_PER_PAGE)); setTotalPages(Math.ceil(fetchedLogs.length / LOGS_PER_PAGE));
setTotalLogs(fetchedLogs.length); setTotalLogs(fetchedLogs.length);
@ -101,7 +101,7 @@ export default function ShowProfileLogs() {
setTotalLogs(fetchedLogs.length); setTotalLogs(fetchedLogs.length);
} }
} catch (error) { } catch (error) {
console.error("Failed to fetch logs:", error); // console.error("Failed to fetch logs:", error);
setError("Error loading activity"); setError("Error loading activity");
} finally { } finally {
setLoading(false); setLoading(false);
@ -134,7 +134,7 @@ export default function ShowProfileLogs() {
// Update displayed logs whenever filtered results change // Update displayed logs whenever filtered results change
useEffect(() => { useEffect(() => {
setLogs(filteredLogs); setLogs(filteredLogs);
console.log("Filtered logs updated:", filteredLogs.length, "logs"); // console.log("Filtered logs updated:", filteredLogs.length, "logs");
}, [filteredLogs]); }, [filteredLogs]);
// Debounced search handler // Debounced search handler
@ -178,12 +178,12 @@ export default function ShowProfileLogs() {
setTimeout(async () => { setTimeout(async () => {
// Check if logs were loaded // Check if logs were loaded
if (allLogs.length === 0) { if (allLogs.length === 0) {
console.log("No logs found after initial fetch, trying direct fetch"); // console.log("No logs found after initial fetch, trying direct fetch");
await directFetchLogs(); await directFetchLogs();
} }
}, 1000); }, 1000);
} catch (error) { } catch (error) {
console.error("Failed to load logs with retry:", error); // console.error("Failed to load logs with retry:", error);
} }
}; };
@ -200,14 +200,14 @@ export default function ShowProfileLogs() {
// Check if the logs collection exists and has any records // Check if the logs collection exists and has any records
const result = await pb.collection(Collections.LOGS).getList(1, 1); const result = await pb.collection(Collections.LOGS).getList(1, 1);
console.log("Logs collection check:", { // console.log("Logs collection check:", {
totalItems: result.totalItems, // totalItems: result.totalItems,
page: result.page, // page: result.page,
perPage: result.perPage, // perPage: result.perPage,
totalPages: result.totalPages // totalPages: result.totalPages
}); // });
} catch (error) { } catch (error) {
console.error("Failed to check logs collection:", error); // console.error("Failed to check logs collection:", error);
} }
}; };
@ -255,7 +255,7 @@ export default function ShowProfileLogs() {
return; return;
} }
console.log("Direct fetching logs for user:", userId); // console.log("Direct fetching logs for user:", userId);
// Fetch logs directly from PocketBase // Fetch logs directly from PocketBase
const result = await pb.collection(Collections.LOGS).getList<Log>(1, 100, { const result = await pb.collection(Collections.LOGS).getList<Log>(1, 100, {
@ -264,10 +264,10 @@ export default function ShowProfileLogs() {
expand: "user" expand: "user"
}); });
console.log("Direct fetch result:", { // console.log("Direct fetch result:", {
totalItems: result.totalItems, // totalItems: result.totalItems,
items: result.items.length // items: result.items.length
}); // });
if (result.items.length > 0) { if (result.items.length > 0) {
setAllLogs(result.items); setAllLogs(result.items);
@ -275,7 +275,7 @@ export default function ShowProfileLogs() {
setTotalLogs(result.items.length); setTotalLogs(result.items.length);
} }
} catch (error) { } catch (error) {
console.error("Failed to direct fetch logs:", error); // console.error("Failed to direct fetch logs:", error);
setError("Error loading activity"); setError("Error loading activity");
} finally { } finally {
setLoading(false); setLoading(false);
@ -315,13 +315,13 @@ export default function ShowProfileLogs() {
} }
// Debug logs // Debug logs
console.log("Render state:", { // console.log("Render state:", {
logsLength: logs.length, // logsLength: logs.length,
allLogsLength: allLogs.length, // allLogsLength: allLogs.length,
searchQuery, // searchQuery,
loading, // loading,
currentPage // currentPage
}); // });
if (allLogs.length === 0 && !searchQuery && !loading) { if (allLogs.length === 0 && !searchQuery && !loading) {
return ( return (
@ -348,10 +348,10 @@ export default function ShowProfileLogs() {
"Test log created for debugging", "Test log created for debugging",
userId userId
); );
console.log("Created test log"); // console.log("Created test log");
setTimeout(() => fetchLogs(true), 1000); setTimeout(() => fetchLogs(true), 1000);
} catch (error) { } catch (error) {
console.error("Failed to create test log:", error); // console.error("Failed to create test log:", error);
} }
}} }}
> >

View file

@ -13,14 +13,6 @@ const logtoEndpoint = import.meta.env.LOGTO_ENDPOINT;
const logtoTokenEndpoint = import.meta.env.LOGTO_TOKEN_ENDPOINT; const logtoTokenEndpoint = import.meta.env.LOGTO_TOKEN_ENDPOINT;
const logtoApiEndpoint = import.meta.env.LOGTO_API_ENDPOINT; const logtoApiEndpoint = import.meta.env.LOGTO_API_ENDPOINT;
// Log environment variables for debugging
console.log("Environment variables in Astro file:");
console.log("LOGTO_APP_ID:", logtoAppId);
console.log("LOGTO_APP_SECRET:", logtoAppSecret);
console.log("LOGTO_ENDPOINT:", logtoEndpoint);
console.log("LOGTO_TOKEN_ENDPOINT:", logtoTokenEndpoint);
console.log("LOGTO_API_ENDPOINT:", logtoApiEndpoint);
// Define fallback values if environment variables are not set // Define fallback values if environment variables are not set
const safeLogtoAppId = logtoAppId || "missing_app_id"; const safeLogtoAppId = logtoAppId || "missing_app_id";
const safeLogtoAppSecret = logtoAppSecret || "missing_app_secret"; const safeLogtoAppSecret = logtoAppSecret || "missing_app_secret";

View file

@ -162,7 +162,7 @@ export default function DisplaySettings() {
if (Object.keys(updateData).length > 0) { if (Object.keys(updateData).length > 0) {
await update.updateFields(Collections.USERS, userId, updateData); await update.updateFields(Collections.USERS, userId, updateData);
console.log('Initialized default display and accessibility settings'); // console.log('Initialized default display and accessibility settings');
} }
} catch (error) { } catch (error) {
console.error('Error initializing default settings:', error); console.error('Error initializing default settings:', error);

View file

@ -67,7 +67,7 @@ export default function NotificationSettings() {
{ notification_preferences: JSON.stringify(DEFAULT_NOTIFICATION_PREFERENCES) } { notification_preferences: JSON.stringify(DEFAULT_NOTIFICATION_PREFERENCES) }
); );
setPreferences(DEFAULT_NOTIFICATION_PREFERENCES); setPreferences(DEFAULT_NOTIFICATION_PREFERENCES);
console.log('Initialized default notification preferences'); // console.log('Initialized default notification preferences');
} catch (error) { } catch (error) {
console.error('Error initializing default notification preferences:', error); console.error('Error initializing default notification preferences:', error);
} }

View file

@ -45,29 +45,7 @@ export default function PasswordChangeSettings({
const logtoTokenEndpoint = envLogtoTokenEndpoint || propLogtoTokenEndpoint; const logtoTokenEndpoint = envLogtoTokenEndpoint || propLogtoTokenEndpoint;
const logtoApiEndpoint = envLogtoApiEndpoint || propLogtoApiEndpoint; const logtoApiEndpoint = envLogtoApiEndpoint || propLogtoApiEndpoint;
// Log props and environment variables for debugging
useEffect(() => {
console.log("PasswordChangeSettings props and env vars:");
console.log("Props - logtoAppId:", propLogtoAppId);
console.log("Props - logtoAppSecret:", propLogtoAppSecret);
console.log("Props - logtoEndpoint:", propLogtoEndpoint);
console.log("Props - logtoTokenEndpoint:", propLogtoTokenEndpoint);
console.log("Props - logtoApiEndpoint:", propLogtoApiEndpoint);
console.log("Env - LOGTO_APP_ID:", envLogtoAppId);
console.log("Env - LOGTO_APP_SECRET:", envLogtoAppSecret);
console.log("Env - LOGTO_ENDPOINT:", envLogtoEndpoint);
console.log("Env - LOGTO_TOKEN_ENDPOINT:", envLogtoTokenEndpoint);
console.log("Env - LOGTO_API_ENDPOINT:", envLogtoApiEndpoint);
console.log("Using - logtoAppId:", logtoAppId);
console.log("Using - logtoAppSecret:", logtoAppSecret);
console.log("Using - logtoEndpoint:", logtoEndpoint);
console.log("Using - logtoTokenEndpoint:", logtoTokenEndpoint);
console.log("Using - logtoApiEndpoint:", logtoApiEndpoint);
}, [
propLogtoAppId, propLogtoAppSecret, propLogtoEndpoint, propLogtoTokenEndpoint, propLogtoApiEndpoint,
envLogtoAppId, envLogtoAppSecret, envLogtoEndpoint, envLogtoTokenEndpoint, envLogtoApiEndpoint,
logtoAppId, logtoAppSecret, logtoEndpoint, logtoTokenEndpoint, logtoApiEndpoint
]);
// Get the user's Logto ID on component mount // Get the user's Logto ID on component mount
useEffect(() => { useEffect(() => {
@ -80,17 +58,17 @@ export default function PasswordChangeSettings({
return; return;
} }
console.log("Current user:", user); // console.log("Current user:", user);
const pb = auth.getPocketBase(); const pb = auth.getPocketBase();
try { try {
const externalAuthRecord = await pb.collection('_externalAuths').getFirstListItem(`recordRef="${user.id}" && provider="oidc"`); const externalAuthRecord = await pb.collection('_externalAuths').getFirstListItem(`recordRef="${user.id}" && provider="oidc"`);
console.log("Found external auth record:", externalAuthRecord); // console.log("Found external auth record:", externalAuthRecord);
const userId = externalAuthRecord.providerId; const userId = externalAuthRecord.providerId;
if (userId) { if (userId) {
setLogtoUserId(userId); setLogtoUserId(userId);
console.log("Set Logto user ID:", userId); // console.log("Set Logto user ID:", userId);
} else { } else {
console.error("No providerId found in external auth record"); console.error("No providerId found in external auth record");
toast.error("Could not determine your user ID. Please try again later or contact support."); toast.error("Could not determine your user ID. Please try again later or contact support.");
@ -153,7 +131,7 @@ export default function PasswordChangeSettings({
try { try {
const response = await fetch('/api/check-env'); const response = await fetch('/api/check-env');
const data = await response.json(); const data = await response.json();
console.log("Environment variables status:", data); // console.log("Environment variables status:", data);
// Check if all required environment variables are set // Check if all required environment variables are set
const { envStatus } = data; const { envStatus } = data;
@ -244,7 +222,7 @@ export default function PasswordChangeSettings({
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document; const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
if (iframeDocument) { if (iframeDocument) {
const responseText = iframeDocument.body.innerText; const responseText = iframeDocument.body.innerText;
console.log("Response from iframe:", responseText); // console.log("Response from iframe:", responseText);
if (responseText) { if (responseText) {
try { try {
@ -308,7 +286,7 @@ export default function PasswordChangeSettings({
} else { } else {
// Use the fetch API with JSON // Use the fetch API with JSON
const endpoint = '/api/change-password'; const endpoint = '/api/change-password';
console.log(`Calling server-side API endpoint: ${endpoint}`); // console.log(`Calling server-side API endpoint: ${endpoint}`);
// Ensure we have the Logto user ID // Ensure we have the Logto user ID
if (!logtoUserId) { if (!logtoUserId) {
@ -317,13 +295,13 @@ export default function PasswordChangeSettings({
} }
// Log the values we're about to use // Log the values we're about to use
console.log("Values being used for API call:"); // console.log("Values being used for API call:");
console.log("- logtoUserId:", logtoUserId); // console.log("- logtoUserId:", logtoUserId);
console.log("- newPassword:", formData.newPassword ? "[PRESENT]" : "[MISSING]"); // console.log("- newPassword:", formData.newPassword ? "[PRESENT]" : "[MISSING]");
console.log("- logtoAppId:", logtoAppId); // console.log("- logtoAppId:", logtoAppId);
console.log("- logtoAppSecret:", logtoAppSecret ? "[PRESENT]" : "[MISSING]"); // console.log("- logtoAppSecret:", logtoAppSecret ? "[PRESENT]" : "[MISSING]");
console.log("- logtoTokenEndpoint:", logtoTokenEndpoint); // console.log("- logtoTokenEndpoint:", logtoTokenEndpoint);
console.log("- logtoApiEndpoint:", logtoApiEndpoint); // console.log("- logtoApiEndpoint:", logtoApiEndpoint);
// Prepare request data with explicit values (not relying on variable references that might be undefined) // Prepare request data with explicit values (not relying on variable references that might be undefined)
const requestData = { const requestData = {
@ -336,12 +314,12 @@ export default function PasswordChangeSettings({
logtoApiEndpoint: logtoApiEndpoint || logtoEndpoint logtoApiEndpoint: logtoApiEndpoint || logtoEndpoint
}; };
console.log("Request data:", { // console.log("Request data:", {
...requestData, // ...requestData,
currentPassword: "[REDACTED]", // currentPassword: "[REDACTED]",
newPassword: "[REDACTED]", // newPassword: "[REDACTED]",
logtoAppSecret: "[REDACTED]" // logtoAppSecret: "[REDACTED]"
}); // });
// Validate request data before sending // Validate request data before sending
if (!requestData.userId) { if (!requestData.userId) {
@ -368,7 +346,7 @@ export default function PasswordChangeSettings({
// Stringify the request data to ensure it's valid JSON // Stringify the request data to ensure it's valid JSON
const requestBody = JSON.stringify(requestData); const requestBody = JSON.stringify(requestData);
console.log("Request body (stringified):", requestBody); // console.log("Request body (stringified):", requestBody);
// Create a debug object to display in the UI // Create a debug object to display in the UI
const debugObj = { const debugObj = {
@ -394,13 +372,13 @@ export default function PasswordChangeSettings({
body: requestBody body: requestBody
}); });
console.log("Response status:", response.status); // console.log("Response status:", response.status);
// Process the response // Process the response
let result: any; let result: any;
try { try {
const responseText = await response.text(); const responseText = await response.text();
console.log("Raw response:", responseText); // console.log("Raw response:", responseText);
if (responseText) { if (responseText) {
result = JSON.parse(responseText); result = JSON.parse(responseText);
@ -408,7 +386,7 @@ export default function PasswordChangeSettings({
result = { success: false, message: 'Empty response from server' }; result = { success: false, message: 'Empty response from server' };
} }
console.log("API response:", result); // console.log("API response:", result);
// Add response to debug info // Add response to debug info
setDebugInfo((prev: any) => ({ setDebugInfo((prev: any) => ({
@ -470,13 +448,13 @@ export default function PasswordChangeSettings({
type="button" type="button"
className="btn btn-sm btn-warning" className="btn btn-sm btn-warning"
onClick={() => { onClick={() => {
console.log("Debug Info:"); // console.log("Debug Info:");
console.log("- logtoUserId:", logtoUserId); // console.log("- logtoUserId:", logtoUserId);
console.log("- Environment Variables:"); // console.log("- Environment Variables:");
console.log(" - LOGTO_APP_ID:", import.meta.env.LOGTO_APP_ID); // console.log(" - LOGTO_APP_ID:", import.meta.env.LOGTO_APP_ID);
console.log(" - LOGTO_ENDPOINT:", import.meta.env.LOGTO_ENDPOINT); // console.log(" - LOGTO_ENDPOINT:", import.meta.env.LOGTO_ENDPOINT);
console.log(" - LOGTO_TOKEN_ENDPOINT:", import.meta.env.LOGTO_TOKEN_ENDPOINT); // console.log(" - LOGTO_TOKEN_ENDPOINT:", import.meta.env.LOGTO_TOKEN_ENDPOINT);
console.log(" - LOGTO_API_ENDPOINT:", import.meta.env.LOGTO_API_ENDPOINT); // console.log(" - LOGTO_API_ENDPOINT:", import.meta.env.LOGTO_API_ENDPOINT);
toast.success("Debug info logged to console"); toast.success("Debug info logged to console");
}} }}

View file

@ -104,17 +104,17 @@ export default function ResumeSettings() {
const loadingToast = toast.loading('Uploading resume...'); const loadingToast = toast.loading('Uploading resume...');
// Log the file being uploaded for debugging // Log the file being uploaded for debugging
console.log('Uploading file:', { // console.log('Uploading file:', {
name: resumeFile.name, // name: resumeFile.name,
size: resumeFile.size, // size: resumeFile.size,
type: resumeFile.type // type: resumeFile.type
}); // });
let updatedUserData: User; let updatedUserData: User;
try { try {
// Use the FileManager to upload the file directly // Use the FileManager to upload the file directly
console.log('Using FileManager to upload resume file'); // console.log('Using FileManager to upload resume file');
// Upload the file using the FileManager's uploadFile method // Upload the file using the FileManager's uploadFile method
const result = await fileManager.uploadFile<User>( const result = await fileManager.uploadFile<User>(
@ -130,18 +130,18 @@ export default function ResumeSettings() {
throw new Error('Resume was not properly saved to the user record'); throw new Error('Resume was not properly saved to the user record');
} }
console.log('Resume upload successful:', result.resume); // console.log('Resume upload successful:', result.resume);
// Store the updated user data // Store the updated user data
updatedUserData = result; updatedUserData = result;
// Fetch the updated user record to ensure we have the latest data // Fetch the updated user record to ensure we have the latest data
const refreshedUser = await get.getOne<User>(Collections.USERS, user.id); const refreshedUser = await get.getOne<User>(Collections.USERS, user.id);
console.log('Refreshed user data:', refreshedUser); // console.log('Refreshed user data:', refreshedUser);
// Double check that the resume field is populated // Double check that the resume field is populated
if (!refreshedUser.resume) { if (!refreshedUser.resume) {
console.warn('Resume field is missing in the refreshed user data'); // console.warn('Resume field is missing in the refreshed user data');
} }
} catch (uploadError) { } catch (uploadError) {
console.error('Error in file upload process:', uploadError); console.error('Error in file upload process:', uploadError);
@ -173,7 +173,7 @@ export default function ResumeSettings() {
toast.success('Resume uploaded successfully'); toast.success('Resume uploaded successfully');
// Log the successful upload // Log the successful upload
console.log('Resume uploaded successfully:', updatedUserData.resume); // console.log('Resume uploaded successfully:', updatedUserData.resume);
// Dispatch a custom event to notify the dashboard about the resume upload // Dispatch a custom event to notify the dashboard about the resume upload
const event = new CustomEvent('resumeUploaded', { const event = new CustomEvent('resumeUploaded', {
@ -223,14 +223,14 @@ export default function ResumeSettings() {
const loadingToast = toast.loading('Deleting resume...'); const loadingToast = toast.loading('Deleting resume...');
// Log the deletion attempt // Log the deletion attempt
console.log('Attempting to delete resume for user:', user.id); // console.log('Attempting to delete resume for user:', user.id);
// Create a FormData with empty resume field to remove the file // Create a FormData with empty resume field to remove the file
const formData = new FormData(); const formData = new FormData();
formData.append('resume', ''); formData.append('resume', '');
try { try {
console.log('Using FileManager to delete resume file'); // console.log('Using FileManager to delete resume file');
// Use the FileManager's deleteFile method to remove the file // Use the FileManager's deleteFile method to remove the file
const result = await fileManager.deleteFile<User>( const result = await fileManager.deleteFile<User>(
@ -241,22 +241,22 @@ export default function ResumeSettings() {
// Verify the file was deleted // Verify the file was deleted
if (result.resume) { if (result.resume) {
console.warn('Resume field still exists after deletion attempt:', result.resume); // console.warn('Resume field still exists after deletion attempt:', result.resume);
toast.dismiss(loadingToast); toast.dismiss(loadingToast);
toast.error('Failed to completely remove the resume. Please try again.'); toast.error('Failed to completely remove the resume. Please try again.');
setUploading(false); setUploading(false);
return; return;
} }
console.log('Resume deletion successful for user:', user.id); // console.log('Resume deletion successful for user:', user.id);
// Fetch the updated user record to ensure we have the latest data // Fetch the updated user record to ensure we have the latest data
const refreshedUser = await get.getOne<User>(Collections.USERS, user.id); const refreshedUser = await get.getOne<User>(Collections.USERS, user.id);
console.log('Refreshed user data after deletion:', refreshedUser); // console.log('Refreshed user data after deletion:', refreshedUser);
// Double check that the resume field is empty // Double check that the resume field is empty
if (refreshedUser.resume) { if (refreshedUser.resume) {
console.warn('Resume field is still present in the refreshed user data:', refreshedUser.resume); // console.warn('Resume field is still present in the refreshed user data:', refreshedUser.resume);
} }
} catch (deleteError) { } catch (deleteError) {
console.error('Error in file deletion process:', deleteError); console.error('Error in file deletion process:', deleteError);
@ -275,7 +275,7 @@ export default function ResumeSettings() {
toast.success('Resume deleted successfully'); toast.success('Resume deleted successfully');
// Log the successful deletion // Log the successful deletion
console.log('Resume deleted successfully for user:', user.id); // console.log('Resume deleted successfully for user:', user.id);
// Dispatch a custom event to notify the dashboard about the resume deletion // Dispatch a custom event to notify the dashboard about the resume deletion
const event = new CustomEvent('resumeUploaded', { const event = new CustomEvent('resumeUploaded', {
@ -356,11 +356,11 @@ export default function ResumeSettings() {
const loadingToast = toast.loading('Replacing resume...'); const loadingToast = toast.loading('Replacing resume...');
// Log the file being uploaded for debugging // Log the file being uploaded for debugging
console.log('Replacing resume with file:', { // console.log('Replacing resume with file:', {
name: file.name, // name: file.name,
size: file.size, // size: file.size,
type: file.type // type: file.type
}); // });
// Create a FormData object for the file upload // Create a FormData object for the file upload
const formData = new FormData(); const formData = new FormData();

View file

@ -112,27 +112,27 @@ export default function ReimbursementList() {
const fileManager = FileManager.getInstance(); const fileManager = FileManager.getInstance();
useEffect(() => { useEffect(() => {
console.log('Component mounted'); // console.log('Component mounted');
fetchReimbursements(); fetchReimbursements();
}, []); }, []);
// Add effect to monitor requests state // Add effect to monitor requests state
useEffect(() => { useEffect(() => {
console.log('Requests state updated:', requests); // console.log('Requests state updated:', requests);
console.log('Number of requests:', requests.length); // console.log('Number of requests:', requests.length);
}, [requests]); }, [requests]);
// Add a useEffect to log preview URL and filename changes // Add a useEffect to log preview URL and filename changes
useEffect(() => { useEffect(() => {
console.log('Preview URL changed:', previewUrl); // console.log('Preview URL changed:', previewUrl);
console.log('Preview filename changed:', previewFilename); // console.log('Preview filename changed:', previewFilename);
}, [previewUrl, previewFilename]); }, [previewUrl, previewFilename]);
// Add a useEffect to log when the preview modal is shown/hidden // Add a useEffect to log when the preview modal is shown/hidden
useEffect(() => { useEffect(() => {
console.log('Show preview changed:', showPreview); // console.log('Show preview changed:', showPreview);
if (showPreview) { if (showPreview) {
console.log('Selected receipt:', selectedReceipt); // console.log('Selected receipt:', selectedReceipt);
} }
}, [showPreview, selectedReceipt]); }, [showPreview, selectedReceipt]);
@ -167,7 +167,7 @@ export default function ReimbursementList() {
'-created' '-created'
); );
console.log('Reimbursement records from IndexedDB:', reimbursementRecords); // console.log('Reimbursement records from IndexedDB:', reimbursementRecords);
// Process the records // Process the records
const processedRecords = reimbursementRecords.map(record => { const processedRecords = reimbursementRecords.map(record => {
@ -183,7 +183,7 @@ export default function ReimbursementList() {
auditNotes = record.audit_notes; auditNotes = record.audit_notes;
} }
} catch (e) { } catch (e) {
console.error('Error parsing audit notes:', e); // console.error('Error parsing audit notes:', e);
} }
} }
@ -217,7 +217,7 @@ export default function ReimbursementList() {
itemizedExpenses = receiptRecord.itemized_expenses as ItemizedExpense[]; itemizedExpenses = receiptRecord.itemized_expenses as ItemizedExpense[];
} }
} catch (e) { } catch (e) {
console.error('Error parsing itemized expenses:', e); // console.error('Error parsing itemized expenses:', e);
} }
} }
@ -241,13 +241,13 @@ export default function ReimbursementList() {
})); }));
} }
} catch (e) { } catch (e) {
console.error(`Error fetching receipt ${receiptId}:`, e); // console.error(`Error fetching receipt ${receiptId}:`, e);
} }
} }
} }
} }
} catch (err) { } catch (err) {
console.error('Error fetching reimbursements:', err); // console.error('Error fetching reimbursements:', err);
setError('Failed to load reimbursements. Please try again.'); setError('Failed to load reimbursements. Please try again.');
} finally { } finally {
setLoading(false); setLoading(false);
@ -256,7 +256,7 @@ export default function ReimbursementList() {
const handlePreviewFile = async (request: ReimbursementRequest, receiptId: string) => { const handlePreviewFile = async (request: ReimbursementRequest, receiptId: string) => {
try { try {
console.log('Previewing file for receipt ID:', receiptId); // console.log('Previewing file for receipt ID:', receiptId);
const pb = auth.getPocketBase(); const pb = auth.getPocketBase();
const fileManager = FileManager.getInstance(); const fileManager = FileManager.getInstance();
@ -265,13 +265,13 @@ export default function ReimbursementList() {
// Check if we already have the receipt details in our map // Check if we already have the receipt details in our map
if (receiptDetailsMap[receiptId]) { if (receiptDetailsMap[receiptId]) {
console.log('Using cached receipt details'); // console.log('Using cached receipt details');
// Use the cached receipt details // Use the cached receipt details
setSelectedReceipt(receiptDetailsMap[receiptId]); setSelectedReceipt(receiptDetailsMap[receiptId]);
// Check if the receipt has a file // Check if the receipt has a file
if (!receiptDetailsMap[receiptId].file) { if (!receiptDetailsMap[receiptId].file) {
console.error('Receipt has no file attached'); // console.error('Receipt has no file attached');
toast.error('This receipt has no file attached'); toast.error('This receipt has no file attached');
setPreviewUrl(''); setPreviewUrl('');
setPreviewFilename(''); setPreviewFilename('');
@ -280,7 +280,7 @@ export default function ReimbursementList() {
} }
// Get the file URL with token for protected files // Get the file URL with token for protected files
console.log('Getting file URL with token'); // console.log('Getting file URL with token');
const url = await fileManager.getFileUrlWithToken( const url = await fileManager.getFileUrlWithToken(
'receipts', 'receipts',
receiptId, receiptId,
@ -290,7 +290,7 @@ export default function ReimbursementList() {
// Check if the URL is empty // Check if the URL is empty
if (!url) { if (!url) {
console.error('Failed to get file URL: Empty URL returned'); // console.error('Failed to get file URL: Empty URL returned');
toast.error('Failed to load receipt: Could not generate file URL'); toast.error('Failed to load receipt: Could not generate file URL');
// Still show the preview modal but with empty URL to display the error message // Still show the preview modal but with empty URL to display the error message
setPreviewUrl(''); setPreviewUrl('');
@ -299,7 +299,7 @@ export default function ReimbursementList() {
return; return;
} }
console.log('Got URL:', url.substring(0, 50) + '...'); // console.log('Got URL:', url.substring(0, 50) + '...');
// Set the preview URL and filename // Set the preview URL and filename
setPreviewUrl(url); setPreviewUrl(url);
@ -309,28 +309,28 @@ export default function ReimbursementList() {
setShowPreview(true); setShowPreview(true);
// Log the current state // Log the current state
console.log('Current state after setting:', { // console.log('Current state after setting:', {
previewUrl: url, // previewUrl: url,
previewFilename: receiptDetailsMap[receiptId].file, // previewFilename: receiptDetailsMap[receiptId].file,
showPreview: true // showPreview: true
}); // });
return; return;
} }
// If not in the map, get the receipt record using its ID // If not in the map, get the receipt record using its ID
console.log('Fetching receipt details from server'); // console.log('Fetching receipt details from server');
const receiptRecord = await pb.collection('receipts').getOne(receiptId, { const receiptRecord = await pb.collection('receipts').getOne(receiptId, {
$autoCancel: false $autoCancel: false
}); });
if (receiptRecord) { if (receiptRecord) {
console.log('Receipt record found:', receiptRecord.id); // console.log('Receipt record found:', receiptRecord.id);
console.log('Receipt file:', receiptRecord.file); // console.log('Receipt file:', receiptRecord.file);
// Check if the receipt has a file // Check if the receipt has a file
if (!receiptRecord.file) { if (!receiptRecord.file) {
console.error('Receipt has no file attached'); // console.error('Receipt has no file attached');
toast.error('This receipt has no file attached'); toast.error('This receipt has no file attached');
setPreviewUrl(''); setPreviewUrl('');
setPreviewFilename(''); setPreviewFilename('');
@ -367,7 +367,7 @@ export default function ReimbursementList() {
setSelectedReceipt(receiptDetails); setSelectedReceipt(receiptDetails);
// Get the file URL with token for protected files // Get the file URL with token for protected files
console.log('Getting file URL with token for new receipt'); // console.log('Getting file URL with token for new receipt');
const url = await fileManager.getFileUrlWithToken( const url = await fileManager.getFileUrlWithToken(
'receipts', 'receipts',
receiptRecord.id, receiptRecord.id,
@ -377,7 +377,7 @@ export default function ReimbursementList() {
// Check if the URL is empty // Check if the URL is empty
if (!url) { if (!url) {
console.error('Failed to get file URL: Empty URL returned'); // console.error('Failed to get file URL: Empty URL returned');
toast.error('Failed to load receipt: Could not generate file URL'); toast.error('Failed to load receipt: Could not generate file URL');
// Still show the preview modal but with empty URL to display the error message // Still show the preview modal but with empty URL to display the error message
setPreviewUrl(''); setPreviewUrl('');
@ -386,7 +386,7 @@ export default function ReimbursementList() {
return; return;
} }
console.log('Got URL:', url.substring(0, 50) + '...'); // console.log('Got URL:', url.substring(0, 50) + '...');
// Set the preview URL and filename // Set the preview URL and filename
setPreviewUrl(url); setPreviewUrl(url);
@ -396,16 +396,16 @@ export default function ReimbursementList() {
setShowPreview(true); setShowPreview(true);
// Log the current state // Log the current state
console.log('Current state after setting:', { // console.log('Current state after setting:', {
previewUrl: url, // previewUrl: url,
previewFilename: receiptRecord.file, // previewFilename: receiptRecord.file,
showPreview: true // showPreview: true
}); // });
} else { } else {
throw new Error('Receipt not found'); throw new Error('Receipt not found');
} }
} catch (error) { } catch (error) {
console.error('Error loading receipt:', error); // console.error('Error loading receipt:', error);
toast.error('Failed to load receipt. Please try again.'); toast.error('Failed to load receipt. Please try again.');
// Show the preview modal with empty URL to display the error message // Show the preview modal with empty URL to display the error message
setPreviewUrl(''); setPreviewUrl('');
@ -423,7 +423,7 @@ export default function ReimbursementList() {
}; };
if (loading) { if (loading) {
console.log('Rendering loading state'); // console.log('Rendering loading state');
return ( return (
<motion.div <motion.div
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
@ -437,7 +437,7 @@ export default function ReimbursementList() {
} }
if (error) { if (error) {
console.log('Rendering error state:', error); // console.log('Rendering error state:', error);
return ( return (
<motion.div <motion.div
initial={{ opacity: 0, y: -20 }} initial={{ opacity: 0, y: -20 }}
@ -450,8 +450,8 @@ export default function ReimbursementList() {
); );
} }
console.log('Rendering main component. Requests:', requests); // console.log('Rendering main component. Requests:', requests);
console.log('Requests length:', requests.length); // console.log('Requests length:', requests.length);
return ( return (
<> <>
@ -482,7 +482,7 @@ export default function ReimbursementList() {
> >
<AnimatePresence mode="popLayout"> <AnimatePresence mode="popLayout">
{requests.map((request, index) => { {requests.map((request, index) => {
console.log('Rendering request:', request); // console.log('Rendering request:', request);
return ( return (
<motion.div <motion.div
key={request.id} key={request.id}

View file

@ -134,7 +134,6 @@ export default function ReimbursementManagementPortal() {
} }
const records = await get.getAll<ExtendedReimbursement>('reimbursement', filter, sort); const records = await get.getAll<ExtendedReimbursement>('reimbursement', filter, sort);
console.log('Loaded reimbursements:', records);
// Load user data for submitters // Load user data for submitters
const userIds = new Set(records.map(r => r.submitted_by)); const userIds = new Set(records.map(r => r.submitted_by));
@ -165,11 +164,9 @@ export default function ReimbursementManagementPortal() {
// Load associated receipts // Load associated receipts
const receiptIds = enrichedRecords.flatMap(r => r.receipts || []); const receiptIds = enrichedRecords.flatMap(r => r.receipts || []);
console.log('Extracted receipt IDs:', receiptIds, 'from reimbursements:', enrichedRecords.map(r => ({ id: r.id, receipts: r.receipts })));
if (receiptIds.length > 0) { if (receiptIds.length > 0) {
try { try {
console.log('Attempting to load receipts with IDs:', receiptIds);
const receiptRecords = await Promise.all( const receiptRecords = await Promise.all(
receiptIds.map(async id => { receiptIds.map(async id => {
try { try {
@ -202,12 +199,10 @@ export default function ReimbursementManagementPortal() {
); );
const validReceipts = receiptRecords.filter((r): r is ExtendedReceipt => r !== null); const validReceipts = receiptRecords.filter((r): r is ExtendedReceipt => r !== null);
console.log('Successfully loaded receipt records:', validReceipts);
const receiptMap = Object.fromEntries( const receiptMap = Object.fromEntries(
validReceipts.map(receipt => [receipt.id, receipt]) validReceipts.map(receipt => [receipt.id, receipt])
); );
console.log('Created receipt map:', receiptMap);
setReceipts(receiptMap); setReceipts(receiptMap);
} catch (error: any) { } catch (error: any) {
console.error('Error loading receipts:', error); console.error('Error loading receipts:', error);
@ -219,7 +214,7 @@ export default function ReimbursementManagementPortal() {
toast.error('Failed to load receipts: ' + (error?.message || 'Unknown error')); toast.error('Failed to load receipts: ' + (error?.message || 'Unknown error'));
} }
} else { } else {
console.log('No receipt IDs found in reimbursements'); // console.log('No receipt IDs found in reimbursements');
setReceipts({}); setReceipts({});
} }
} catch (error) { } catch (error) {

View file

@ -29,7 +29,7 @@ const ImageWithFallback = ({ url, filename, onError }: ImageWithFallbackProps) =
try { try {
// Try to fetch the image as a blob and create an object URL // Try to fetch the image as a blob and create an object URL
console.log('Trying to fetch image as blob:', url); // console.log('Trying to fetch image as blob:', url);
const response = await fetch(url, { mode: 'cors' }); const response = await fetch(url, { mode: 'cors' });
if (!response.ok) { if (!response.ok) {
@ -38,7 +38,7 @@ const ImageWithFallback = ({ url, filename, onError }: ImageWithFallbackProps) =
const blob = await response.blob(); const blob = await response.blob();
const objectUrl = URL.createObjectURL(blob); const objectUrl = URL.createObjectURL(blob);
console.log('Created object URL:', objectUrl); // console.log('Created object URL:', objectUrl);
// Update the image source with the object URL // Update the image source with the object URL
setImgSrc(objectUrl); setImgSrc(objectUrl);
@ -48,10 +48,10 @@ const ImageWithFallback = ({ url, filename, onError }: ImageWithFallbackProps) =
onError('Failed to load image. This might be due to permission issues or the file may not exist.'); onError('Failed to load image. This might be due to permission issues or the file may not exist.');
// Log additional details // Log additional details
console.log('Image URL that failed:', url); // console.log('Image URL that failed:', url);
console.log('Current auth status:', // console.log('Current auth status:',
Authentication.getInstance().isAuthenticated() ? 'Authenticated' : 'Not authenticated' // Authentication.getInstance().isAuthenticated() ? 'Authenticated' : 'Not authenticated'
); // );
} }
}; };

View file

@ -76,26 +76,26 @@ const Calendar = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
const loadGapiAndListEvents = async () => { const loadGapiAndListEvents = async () => {
try { try {
console.log("Starting to load events..."); // console.log("Starting to load events...");
if (typeof window.gapi === "undefined") { if (typeof window.gapi === "undefined") {
console.log("Loading GAPI script..."); // console.log("Loading GAPI script...");
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
const script = document.createElement("script"); const script = document.createElement("script");
script.src = "https://apis.google.com/js/api.js"; script.src = "https://apis.google.com/js/api.js";
document.body.appendChild(script); document.body.appendChild(script);
script.onload = () => { script.onload = () => {
console.log("GAPI script loaded"); // console.log("GAPI script loaded");
window.gapi.load("client", resolve); window.gapi.load("client", resolve);
}; };
script.onerror = () => { script.onerror = () => {
console.error("Failed to load GAPI script"); // console.error("Failed to load GAPI script");
reject(new Error("Failed to load the Google API script.")); reject(new Error("Failed to load the Google API script."));
}; };
}); });
} }
console.log("Initializing GAPI client..."); // console.log("Initializing GAPI client...");
await window.gapi.client.init({ await window.gapi.client.init({
apiKey: CALENDAR_API_KEY, apiKey: CALENDAR_API_KEY,
discoveryDocs: [ discoveryDocs: [
@ -115,7 +115,7 @@ const Calendar = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
0, 0,
); );
console.log("Fetching events..."); // console.log("Fetching events...");
const response = await window.gapi.client.calendar.events.list({ const response = await window.gapi.client.calendar.events.list({
calendarId: calendarId, calendarId: calendarId,
timeZone: userTimeZone, timeZone: userTimeZone,
@ -125,13 +125,13 @@ const Calendar = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
orderBy: "startTime", orderBy: "startTime",
}); });
console.log("Response received:", response); // console.log("Response received:", response);
if (response.result.items) { if (response.result.items) {
setEvents(response.result.items); setEvents(response.result.items);
} }
} catch (error) { } catch (error) {
console.error("Detailed Error: ", error); // console.error("Detailed Error: ", error);
setError(error.message || "Failed to load events"); setError(error.message || "Failed to load events");
} finally { } finally {
setLoading(false); setLoading(false);

View file

@ -48,16 +48,16 @@ const EventList = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
const loadGapiAndListEvents = async () => { const loadGapiAndListEvents = async () => {
try { try {
console.log("Starting to load events..."); // console.log("Starting to load events...");
if (typeof window.gapi === "undefined") { if (typeof window.gapi === "undefined") {
console.log("Loading GAPI script..."); // console.log("Loading GAPI script...");
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
const script = document.createElement("script"); const script = document.createElement("script");
script.src = "https://apis.google.com/js/api.js"; script.src = "https://apis.google.com/js/api.js";
document.body.appendChild(script); document.body.appendChild(script);
script.onload = () => { script.onload = () => {
console.log("GAPI script loaded"); // console.log("GAPI script loaded");
window.gapi.load("client", resolve); window.gapi.load("client", resolve);
}; };
script.onerror = () => { script.onerror = () => {
@ -67,7 +67,7 @@ const EventList = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
}); });
} }
console.log("Initializing GAPI client..."); // console.log("Initializing GAPI client...");
await window.gapi.client.init({ await window.gapi.client.init({
apiKey: apiKey, apiKey: apiKey,
discoveryDocs: [ discoveryDocs: [
@ -75,7 +75,7 @@ const EventList = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
], ],
}); });
console.log("Fetching events..."); // console.log("Fetching events...");
const response = await window.gapi.client.calendar.events.list({ const response = await window.gapi.client.calendar.events.list({
calendarId: calendarId, calendarId: calendarId,
timeZone: userTimeZone, timeZone: userTimeZone,
@ -85,7 +85,7 @@ const EventList = ({ CALENDAR_API_KEY, EVENT_CALENDAR_ID }) => {
orderBy: "startTime", orderBy: "startTime",
}); });
console.log("Response received:", response); // console.log("Response received:", response);
if (response.result.items) { if (response.result.items) {
setEvents(response.result.items); setEvents(response.result.items);

View file

@ -11,8 +11,6 @@ async function getLogtoAccessToken(
scope: string = "all", scope: string = "all",
): Promise<string | null> { ): Promise<string | null> {
try { try {
console.log("Attempting to get access token from Logto");
// Create Basic auth string // Create Basic auth string
const authString = Buffer.from(`${clientId}:${clientSecret}`).toString( const authString = Buffer.from(`${clientId}:${clientSecret}`).toString(
"base64", "base64",
@ -59,8 +57,6 @@ async function verifyUserPassword(
accessToken: string, accessToken: string,
): Promise<boolean> { ): Promise<boolean> {
try { try {
console.log("Verifying current password");
const response = await fetch( const response = await fetch(
`${logtoApiEndpoint}/api/users/${userId}/password/verify`, `${logtoApiEndpoint}/api/users/${userId}/password/verify`,
{ {
@ -75,7 +71,6 @@ async function verifyUserPassword(
// 204 means password matches, 422 means it doesn't match // 204 means password matches, 422 means it doesn't match
if (response.status === 204) { if (response.status === 204) {
console.log("Current password verified successfully");
return true; return true;
} }
@ -101,8 +96,6 @@ async function verifyUserPassword(
export const POST: APIRoute = async ({ request }) => { export const POST: APIRoute = async ({ request }) => {
try { try {
console.log("Received change password request");
// Parse request body // Parse request body
const contentType = request.headers.get("content-type"); const contentType = request.headers.get("content-type");
const rawBody = await request.text(); const rawBody = await request.text();
@ -161,6 +154,7 @@ export const POST: APIRoute = async ({ request }) => {
} }
// Get access token // Get access token
// console.log("Attempting to get access token from Logto");
const accessToken = await getLogtoAccessToken( const accessToken = await getLogtoAccessToken(
logtoTokenEndpoint, logtoTokenEndpoint,
logtoAppId, logtoAppId,
@ -181,6 +175,7 @@ export const POST: APIRoute = async ({ request }) => {
} }
// Verify current password before proceeding // Verify current password before proceeding
// console.log("Verifying current password");
const isPasswordValid = await verifyUserPassword( const isPasswordValid = await verifyUserPassword(
logtoApiEndpoint, logtoApiEndpoint,
userId, userId,
@ -202,6 +197,7 @@ export const POST: APIRoute = async ({ request }) => {
} }
// Change password using Logto Management API // Change password using Logto Management API
// console.log("Current password verified successfully");
const changePasswordResponse = await fetch( const changePasswordResponse = await fetch(
`${logtoApiEndpoint}/api/users/${userId}/password`, `${logtoApiEndpoint}/api/users/${userId}/password`,
{ {

View file

@ -26,13 +26,13 @@ const components = Object.fromEntries(
const component = await import( const component = await import(
`../components/dashboard/${section.component}.astro` `../components/dashboard/${section.component}.astro`
); );
console.log(`Loaded component: ${section.component}`); // Debug log // console.log(`Loaded component: ${section.component}`); // Debug log
return [section.component, component.default]; return [section.component, component.default];
}) }),
) ),
); );
console.log("Available components:", Object.keys(components)); // Debug log // console.log("Available components:", Object.keys(components)); // Debug log
--- ---
<!doctype html> <!doctype html>
@ -65,33 +65,19 @@ console.log("Available components:", Object.keys(components)); // Debug log
<!-- User Profile --> <!-- User Profile -->
<div class="p-6 border-b border-base-200"> <div class="p-6 border-b border-base-200">
<!-- Loading State --> <!-- Loading State -->
<div <div id="userProfileSkeleton" class="flex items-center gap-4">
id="userProfileSkeleton"
class="flex items-center gap-4"
>
<div class="avatar flex items-center justify-center"> <div class="avatar flex items-center justify-center">
<div <div class="w-12 h-12 rounded-xl bg-base-300 animate-pulse"></div>
class="w-12 h-12 rounded-xl bg-base-300 animate-pulse"
>
</div>
</div> </div>
<div class="flex-1"> <div class="flex-1">
<div <div class="h-6 w-32 bg-base-300 animate-pulse rounded mb-2">
class="h-6 w-32 bg-base-300 animate-pulse rounded mb-2"
>
</div>
<div
class="h-5 w-20 bg-base-300 animate-pulse rounded"
>
</div> </div>
<div class="h-5 w-20 bg-base-300 animate-pulse rounded"></div>
</div> </div>
</div> </div>
<!-- Signed Out State --> <!-- Signed Out State -->
<div <div id="userProfileSignedOut" class="flex items-center gap-4 hidden">
id="userProfileSignedOut"
class="flex items-center gap-4 hidden"
>
<div class="avatar flex items-center justify-center"> <div class="avatar flex items-center justify-center">
<div <div
class="w-12 h-12 rounded-xl bg-base-300 text-base-content/30 flex items-center justify-center" class="w-12 h-12 rounded-xl bg-base-300 text-base-content/30 flex items-center justify-center"
@ -100,22 +86,15 @@ console.log("Available components:", Object.keys(components)); // Debug log
</div> </div>
</div> </div>
<div> <div>
<h3 <h3 class="font-medium text-lg text-base-content/70">
class="font-medium text-lg text-base-content/70"
>
Signed Out Signed Out
</h3> </h3>
<div class="badge badge-outline mt-1 opacity-50"> <div class="badge badge-outline mt-1 opacity-50">Guest</div>
Guest
</div>
</div> </div>
</div> </div>
<!-- Actual Profile --> <!-- Actual Profile -->
<div <div id="userProfileSummary" class="flex items-center gap-4 hidden">
id="userProfileSummary"
class="flex items-center gap-4 hidden"
>
<div class="avatar flex items-center justify-center"> <div class="avatar flex items-center justify-center">
<div <div
class="w-12 h-12 rounded-xl bg-[#06659d] text-white ring ring-base-200 ring-offset-base-100 ring-offset-2 inline-flex items-center justify-center" class="w-12 h-12 rounded-xl bg-[#06659d] text-white ring ring-base-200 ring-offset-base-100 ring-offset-2 inline-flex items-center justify-center"
@ -127,9 +106,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
</div> </div>
</div> </div>
<div> <div>
<h3 class="font-medium text-lg" id="userName"> <h3 class="font-medium text-lg" id="userName">Loading...</h3>
Loading...
</h3>
<div <div
class="badge badge-outline mt-1 border-[#06659d] text-[#06659d]" class="badge badge-outline mt-1 border-[#06659d] text-[#06659d]"
id="userRole" id="userRole"
@ -168,64 +145,41 @@ console.log("Available components:", Object.keys(components)); // Debug log
<div id="actualMenu" class="hidden"> <div id="actualMenu" class="hidden">
{ {
Object.entries(dashboardConfig.categories).map( Object.entries(dashboardConfig.categories).map(
([categoryKey, category]: [ ([categoryKey, category]: [string, any]) => (
string,
any,
]) => (
<> <>
<li <li
class={`menu-title font-medium opacity-70 ${ class={`menu-title font-medium opacity-70 ${
category.role && category.role && category.role !== "none"
category.role !== "none"
? "hidden" ? "hidden"
: "" : ""
}`} }`}
data-role-required={ data-role-required={category.role || "none"}
category.role || "none"
}
> >
<span>{category.title}</span> <span>{category.title}</span>
</li> </li>
{category.sections.map( {category.sections.map((sectionKey: string) => {
(sectionKey: string) => { const section = dashboardConfig.sections[sectionKey];
const section =
dashboardConfig
.sections[
sectionKey
];
return ( return (
<li <li
class={ class={
section.role && section.role && section.role !== "none"
section.role !==
"none"
? "hidden" ? "hidden"
: "" : ""
} }
data-role-required={ data-role-required={section.role}
section.role
}
> >
<button <button
class={`dashboard-nav-btn gap-4 transition-all duration-200 outline-none focus:outline-none hover:bg-opacity-5 ${section.class || ""}`} class={`dashboard-nav-btn gap-4 transition-all duration-200 outline-none focus:outline-none hover:bg-opacity-5 ${section.class || ""}`}
data-section={ data-section={sectionKey}
sectionKey
}
> >
<Icon <Icon name={section.icon} class="h-5 w-5" />
name={
section.icon
}
class="h-5 w-5"
/>
{section.title} {section.title}
</button> </button>
</li> </li>
); );
} })}
)}
</> </>
) ),
) )
} }
</div> </div>
@ -238,15 +192,10 @@ console.log("Available components:", Object.keys(components)); // Debug log
class="flex-1 overflow-x-hidden overflow-y-auto bg-base-200 w-full xl:w-[calc(100%-20rem)]" class="flex-1 overflow-x-hidden overflow-y-auto bg-base-200 w-full xl:w-[calc(100%-20rem)]"
> >
<!-- Mobile Header --> <!-- Mobile Header -->
<header <header class="bg-base-100 p-4 shadow-md xl:hidden sticky top-0 z-40">
class="bg-base-100 p-4 shadow-md xl:hidden sticky top-0 z-40"
>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<button <button id="mobileSidebarToggle" class="btn btn-square btn-ghost">
id="mobileSidebarToggle"
class="btn btn-square btn-ghost"
>
<Icon name="heroicons:bars-3" class="h-6 w-6" /> <Icon name="heroicons:bars-3" class="h-6 w-6" />
</button> </button>
<h1 class="text-xl font-bold">IEEE UCSD</h1> <h1 class="text-xl font-bold">IEEE UCSD</h1>
@ -258,11 +207,8 @@ console.log("Available components:", Object.keys(components)); // Debug log
<div class="p-4 md:p-6 max-w-[1600px] mx-auto"> <div class="p-4 md:p-6 max-w-[1600px] mx-auto">
<!-- Loading State --> <!-- Loading State -->
<div id="pageLoadingState" class="w-full"> <div id="pageLoadingState" class="w-full">
<div <div class="flex flex-col items-center justify-center p-4 sm:p-8">
class="flex flex-col items-center justify-center p-4 sm:p-8" <div class="loading loading-spinner loading-lg"></div>
>
<div class="loading loading-spinner loading-lg">
</div>
<p class="mt-4 opacity-70">Loading dashboard...</p> <p class="mt-4 opacity-70">Loading dashboard...</p>
</div> </div>
</div> </div>
@ -288,9 +234,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
<!-- Not Authenticated State --> <!-- Not Authenticated State -->
<div id="notAuthenticatedState" class="hidden w-full"> <div id="notAuthenticatedState" class="hidden w-full">
<div class="card bg-base-100 shadow-xl mx-2 sm:mx-0"> <div class="card bg-base-100 shadow-xl mx-2 sm:mx-0">
<div <div class="card-body items-center text-center p-4 sm:p-8">
class="card-body items-center text-center p-4 sm:p-8"
>
<div class="mb-4 sm:mb-6"> <div class="mb-4 sm:mb-6">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -307,11 +251,9 @@ console.log("Available components:", Object.keys(components)); // Debug log
<h2 class="card-title text-xl sm:text-2xl mb-2"> <h2 class="card-title text-xl sm:text-2xl mb-2">
Sign in to Access Dashboard Sign in to Access Dashboard
</h2> </h2>
<p <p class="opacity-70 mb-4 sm:mb-6 text-sm sm:text-base">
class="opacity-70 mb-4 sm:mb-6 text-sm sm:text-base" Please sign in with your IEEE UCSD account to access the
> dashboard.
Please sign in with your IEEE UCSD account
to access the dashboard.
</p> </p>
<button <button
class="login-button btn btn-primary btn-lg gap-2 w-full sm:w-auto" class="login-button btn btn-primary btn-lg gap-2 w-full sm:w-auto"
@ -343,14 +285,12 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Skip if no component is defined // Skip if no component is defined
if (!section.component) return null; if (!section.component) return null;
const Component = const Component = components[section.component];
components[section.component];
return ( return (
<div <div
id={`${sectionKey}Section`} id={`${sectionKey}Section`}
class={`dashboard-section hidden ${ class={`dashboard-section hidden ${
section.role && section.role && section.role !== "none"
section.role !== "none"
? "role-restricted" ? "role-restricted"
: "" : ""
}`} }`}
@ -359,7 +299,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
<Component /> <Component />
</div> </div>
); );
} },
) )
} }
</div> </div>
@ -383,11 +323,10 @@ console.log("Available components:", Object.keys(components)); // Debug log
const logger = SendLog.getInstance(); const logger = SendLog.getInstance();
// Initialize page state // Initialize page state
const pageLoadingState = const pageLoadingState = document.getElementById("pageLoadingState");
document.getElementById("pageLoadingState");
const pageErrorState = document.getElementById("pageErrorState"); const pageErrorState = document.getElementById("pageErrorState");
const notAuthenticatedState = document.getElementById( const notAuthenticatedState = document.getElementById(
"notAuthenticatedState" "notAuthenticatedState",
); );
const mainContent = document.getElementById("mainContent"); const mainContent = document.getElementById("mainContent");
const sidebar = document.querySelector("aside"); const sidebar = document.querySelector("aside");
@ -418,11 +357,9 @@ console.log("Available components:", Object.keys(components)); // Debug log
} }
// For non-sponsor roles, handle normally // For non-sponsor roles, handle normally
document document.querySelectorAll("[data-role-required]").forEach((element) => {
.querySelectorAll("[data-role-required]")
.forEach((element) => {
const requiredRole = element.getAttribute( const requiredRole = element.getAttribute(
"data-role-required" "data-role-required",
) as OfficerStatus; ) as OfficerStatus;
// Skip elements that don't have a role requirement // Skip elements that don't have a role requirement
@ -432,10 +369,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
} }
// Check if user has permission for this role // Check if user has permission for this role
const hasPermission = hasAccess( const hasPermission = hasAccess(officerStatus, requiredRole);
officerStatus,
requiredRole
);
// Only show elements if user has permission // Only show elements if user has permission
element.classList.toggle("hidden", !hasPermission); element.classList.toggle("hidden", !hasPermission);
@ -444,10 +378,8 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Handle navigation // Handle navigation
const handleNavigation = () => { const handleNavigation = () => {
const navButtons = const navButtons = document.querySelectorAll(".dashboard-nav-btn");
document.querySelectorAll(".dashboard-nav-btn"); const sections = document.querySelectorAll(".dashboard-section");
const sections =
document.querySelectorAll(".dashboard-section");
const mainContentDiv = document.getElementById("mainContent"); const mainContentDiv = document.getElementById("mainContent");
// Ensure mainContent is visible // Ensure mainContent is visible
@ -481,19 +413,17 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Show selected section // Show selected section
const sectionId = `${sectionKey}Section`; const sectionId = `${sectionKey}Section`;
const targetSection = const targetSection = document.getElementById(sectionId);
document.getElementById(sectionId);
if (targetSection) { if (targetSection) {
targetSection.classList.remove("hidden"); targetSection.classList.remove("hidden");
console.log(`Showing section: ${sectionId}`); // Debug log // console.log(`Showing section: ${sectionId}`); // Debug log
} }
// Close mobile sidebar if needed // Close mobile sidebar if needed
if (window.innerWidth < 1024 && sidebar) { if (window.innerWidth < 1024 && sidebar) {
sidebar.classList.add("-translate-x-full"); sidebar.classList.add("-translate-x-full");
document.body.classList.remove("overflow-hidden"); document.body.classList.remove("overflow-hidden");
const overlay = const overlay = document.getElementById("sidebarOverlay");
document.getElementById("sidebarOverlay");
overlay?.remove(); overlay?.remove();
} }
}); });
@ -537,7 +467,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
"", "",
{ {
fields: ["id", "type", "role"], fields: ["id", "type", "role"],
} },
); );
if (officerRecords && officerRecords.items.length > 0) { if (officerRecords && officerRecords.items.length > 0) {
@ -579,7 +509,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
"", "",
{ {
fields: ["id", "company"], fields: ["id", "company"],
} },
); );
if (sponsorRecords && sponsorRecords.items.length > 0) { if (sponsorRecords && sponsorRecords.items.length > 0) {
@ -613,8 +543,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
if (userName) userName.textContent = fallbackValues.name; if (userName) userName.textContent = fallbackValues.name;
if (userRole) userRole.textContent = fallbackValues.role; if (userRole) userRole.textContent = fallbackValues.role;
if (userInitials) if (userInitials) userInitials.textContent = fallbackValues.initials;
userInitials.textContent = fallbackValues.initials;
updateSectionVisibility("" as OfficerStatus); updateSectionVisibility("" as OfficerStatus);
} }
@ -622,18 +551,16 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Mobile sidebar toggle // Mobile sidebar toggle
const mobileSidebarToggle = document.getElementById( const mobileSidebarToggle = document.getElementById(
"mobileSidebarToggle" "mobileSidebarToggle",
); );
if (mobileSidebarToggle && sidebar) { if (mobileSidebarToggle && sidebar) {
const toggleSidebar = () => { const toggleSidebar = () => {
const isOpen = const isOpen = !sidebar.classList.contains("-translate-x-full");
!sidebar.classList.contains("-translate-x-full");
if (isOpen) { if (isOpen) {
sidebar.classList.add("-translate-x-full"); sidebar.classList.add("-translate-x-full");
document.body.classList.remove("overflow-hidden"); document.body.classList.remove("overflow-hidden");
const overlay = const overlay = document.getElementById("sidebarOverlay");
document.getElementById("sidebarOverlay");
overlay?.remove(); overlay?.remove();
} else { } else {
sidebar.classList.remove("-translate-x-full"); sidebar.classList.remove("-translate-x-full");
@ -658,38 +585,35 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Check if user is authenticated // Check if user is authenticated
if (!auth.isAuthenticated()) { if (!auth.isAuthenticated()) {
console.log("User not authenticated"); // console.log("User not authenticated");
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.add("hidden");
pageLoadingState.classList.add("hidden");
if (notAuthenticatedState) if (notAuthenticatedState)
notAuthenticatedState.classList.remove("hidden"); notAuthenticatedState.classList.remove("hidden");
return; return;
} }
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.remove("hidden");
pageLoadingState.classList.remove("hidden");
if (pageErrorState) pageErrorState.classList.add("hidden"); if (pageErrorState) pageErrorState.classList.add("hidden");
if (notAuthenticatedState) if (notAuthenticatedState)
notAuthenticatedState.classList.add("hidden"); notAuthenticatedState.classList.add("hidden");
// Show loading states // Show loading states
const userProfileSkeleton = document.getElementById( const userProfileSkeleton = document.getElementById(
"userProfileSkeleton" "userProfileSkeleton",
); );
const userProfileSignedOut = document.getElementById( const userProfileSignedOut = document.getElementById(
"userProfileSignedOut" "userProfileSignedOut",
); );
const userProfileSummary = const userProfileSummary =
document.getElementById("userProfileSummary"); document.getElementById("userProfileSummary");
const menuLoadingSkeleton = document.getElementById( const menuLoadingSkeleton = document.getElementById(
"menuLoadingSkeleton" "menuLoadingSkeleton",
); );
const actualMenu = document.getElementById("actualMenu"); const actualMenu = document.getElementById("actualMenu");
if (userProfileSkeleton) if (userProfileSkeleton)
userProfileSkeleton.classList.remove("hidden"); userProfileSkeleton.classList.remove("hidden");
if (userProfileSummary) if (userProfileSummary) userProfileSummary.classList.add("hidden");
userProfileSummary.classList.add("hidden");
if (userProfileSignedOut) if (userProfileSignedOut)
userProfileSignedOut.classList.add("hidden"); userProfileSignedOut.classList.add("hidden");
if (menuLoadingSkeleton) if (menuLoadingSkeleton)
@ -700,15 +624,11 @@ console.log("Available components:", Object.keys(components)); // Debug log
await updateUserProfile(user); await updateUserProfile(user);
// Show actual profile and hide skeleton // Show actual profile and hide skeleton
if (userProfileSkeleton) if (userProfileSkeleton) userProfileSkeleton.classList.add("hidden");
userProfileSkeleton.classList.add("hidden"); if (userProfileSummary) userProfileSummary.classList.remove("hidden");
if (userProfileSummary)
userProfileSummary.classList.remove("hidden");
// Hide all sections first // Hide all sections first
document document.querySelectorAll(".dashboard-section").forEach((section) => {
.querySelectorAll(".dashboard-section")
.forEach((section) => {
section.classList.add("hidden"); section.classList.add("hidden");
}); });
@ -725,7 +645,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
"", "",
{ {
fields: ["id", "type", "role"], fields: ["id", "type", "role"],
} },
); );
if (officerRecords && officerRecords.items.length > 0) { if (officerRecords && officerRecords.items.length > 0) {
@ -763,23 +683,17 @@ console.log("Available components:", Object.keys(components)); // Debug log
"", "",
{ {
fields: ["id", "company"], fields: ["id", "company"],
} },
); );
if ( if (sponsorRecords && sponsorRecords.items.length > 0) {
sponsorRecords &&
sponsorRecords.items.length > 0
) {
officerStatus = "sponsor"; officerStatus = "sponsor";
} else { } else {
officerStatus = "none"; officerStatus = "none";
} }
} }
} catch (error) { } catch (error) {
console.error( console.error("Error determining officer status:", error);
"Error determining officer status:",
error
);
officerStatus = "none"; officerStatus = "none";
} }
@ -790,24 +704,17 @@ console.log("Available components:", Object.keys(components)); // Debug log
// Only sponsors get a different default view // Only sponsors get a different default view
if (officerStatus === "sponsor") { if (officerStatus === "sponsor") {
// For sponsors, show the sponsor dashboard // For sponsors, show the sponsor dashboard
defaultSection = document.getElementById( defaultSection = document.getElementById("sponsorDashboardSection");
"sponsorDashboardSection"
);
defaultButton = document.querySelector( defaultButton = document.querySelector(
'[data-section="sponsorDashboard"]' '[data-section="sponsorDashboard"]',
); );
} else { } else {
// For all other users (including administrators), show the profile section // For all other users (including administrators), show the profile section
defaultSection = defaultSection = document.getElementById("profileSection");
document.getElementById("profileSection"); defaultButton = document.querySelector('[data-section="profile"]');
defaultButton = document.querySelector(
'[data-section="profile"]'
);
// Log the default section for debugging // Log the default section for debugging
console.log( // console.log(`Setting default section to profile for user with role: ${officerStatus}`);
`Setting default section to profile for user with role: ${officerStatus}`
);
} }
if (defaultSection) { if (defaultSection) {
@ -821,20 +728,16 @@ console.log("Available components:", Object.keys(components)); // Debug log
handleNavigation(); handleNavigation();
// Show actual menu and hide skeleton // Show actual menu and hide skeleton
if (menuLoadingSkeleton) if (menuLoadingSkeleton) menuLoadingSkeleton.classList.add("hidden");
menuLoadingSkeleton.classList.add("hidden");
if (actualMenu) actualMenu.classList.remove("hidden"); if (actualMenu) actualMenu.classList.remove("hidden");
// Show main content and hide loading // Show main content and hide loading
if (mainContent) mainContent.classList.remove("hidden"); if (mainContent) mainContent.classList.remove("hidden");
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.add("hidden");
pageLoadingState.classList.add("hidden");
} catch (error) { } catch (error) {
console.error("Error initializing dashboard:", error); console.error("Error initializing dashboard:", error);
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.add("hidden");
pageLoadingState.classList.add("hidden"); if (pageErrorState) pageErrorState.classList.remove("hidden");
if (pageErrorState)
pageErrorState.classList.remove("hidden");
} }
}; };
@ -846,24 +749,19 @@ console.log("Available components:", Object.keys(components)); // Debug log
.querySelector(".login-button") .querySelector(".login-button")
?.addEventListener("click", async () => { ?.addEventListener("click", async () => {
try { try {
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.remove("hidden");
pageLoadingState.classList.remove("hidden");
if (notAuthenticatedState) if (notAuthenticatedState)
notAuthenticatedState.classList.add("hidden"); notAuthenticatedState.classList.add("hidden");
await auth.login(); await auth.login();
} catch (error) { } catch (error) {
console.error("Login error:", error); console.error("Login error:", error);
if (pageLoadingState) if (pageLoadingState) pageLoadingState.classList.add("hidden");
pageLoadingState.classList.add("hidden"); if (pageErrorState) pageErrorState.classList.remove("hidden");
if (pageErrorState)
pageErrorState.classList.remove("hidden");
} }
}); });
// Handle logout button click // Handle logout button click
document document.getElementById("logoutButton")?.addEventListener("click", () => {
.getElementById("logoutButton")
?.addEventListener("click", () => {
auth.logout(); auth.logout();
window.location.reload(); window.location.reload();
}); });
@ -876,8 +774,7 @@ console.log("Available components:", Object.keys(components)); // Debug log
window.addEventListener("resize", () => { window.addEventListener("resize", () => {
if (window.innerWidth >= 1024) { if (window.innerWidth >= 1024) {
const overlay = const overlay = document.getElementById("sidebarOverlay");
document.getElementById("sidebarOverlay");
if (overlay) { if (overlay) {
overlay.remove(); overlay.remove();
document.body.classList.remove("overflow-hidden"); document.body.classList.remove("overflow-hidden");

View file

@ -60,7 +60,7 @@ export class RedirectHandler {
{ emailVisibility: false }, { emailVisibility: false },
); );
console.log("Auth successful:", authData); // console.log("Auth successful:", authData);
this.contentEl.innerHTML = ` this.contentEl.innerHTML = `
<p class="text-3xl font-bold text-green-500 mb-4">Authentication Successful!</p> <p class="text-3xl font-bold text-green-500 mb-4">Authentication Successful!</p>
<p class="text-2xl font-medium">Initializing your data...</p> <p class="text-2xl font-medium">Initializing your data...</p>
@ -99,19 +99,15 @@ export class RedirectHandler {
private async initializeDataSync(): Promise<void> { private async initializeDataSync(): Promise<void> {
try { try {
// Dynamically import the AuthSyncService to avoid circular dependencies // Dynamically import the AuthSyncService to avoid circular dependencies
const { AuthSyncService } = await import('../database/AuthSyncService'); const { AuthSyncService } = await import("../database/AuthSyncService");
// Get the instance and trigger a full sync // Get the instance and trigger a full sync
const authSync = AuthSyncService.getInstance(); const authSync = AuthSyncService.getInstance();
const syncResult = await authSync.handleLogin(); const syncResult = await authSync.handleLogin();
if (syncResult) { // console.log('Initial data sync completed successfully');
console.log('Initial data sync completed successfully');
} else {
console.warn('Initial data sync completed with issues');
}
} catch (error) { } catch (error) {
console.error('Failed to initialize data sync:', error); console.error("Failed to initialize data sync:", error);
// Continue with login process even if sync fails // Continue with login process even if sync fails
} }
} }

View file

@ -78,7 +78,7 @@ export class AuthSyncService {
if (!isBrowser) return true; if (!isBrowser) return true;
if (this.isSyncing) { if (this.isSyncing) {
console.log("Sync already in progress, queueing login sync"); // console.log("Sync already in progress, queueing login sync");
if (this.syncPromise) { if (this.syncPromise) {
this.syncPromise = this.syncPromise.then(() => this.performLoginSync()); this.syncPromise = this.syncPromise.then(() => this.performLoginSync());
} else { } else {
@ -100,7 +100,7 @@ export class AuthSyncService {
if (!isBrowser) return; if (!isBrowser) return;
if (!this.auth.isAuthenticated()) { if (!this.auth.isAuthenticated()) {
console.log("Not authenticated, skipping login sync"); // console.log("Not authenticated, skipping login sync");
return; return;
} }
@ -108,7 +108,7 @@ export class AuthSyncService {
this.syncErrors = {}; this.syncErrors = {};
try { try {
console.log("Starting login sync process..."); // console.log("Starting login sync process...");
// Display sync notification if in browser environment // Display sync notification if in browser environment
this.showSyncNotification("Syncing your data..."); this.showSyncNotification("Syncing your data...");
@ -123,7 +123,7 @@ export class AuthSyncService {
); );
// Log the sync operation // Log the sync operation
console.log("User data synchronized on login"); // console.log("User data synchronized on login");
} }
// Sync all collections in parallel with conflict resolution // Sync all collections in parallel with conflict resolution
@ -131,9 +131,9 @@ export class AuthSyncService {
this.collectionsToSync.map(async (collection) => { this.collectionsToSync.map(async (collection) => {
try { try {
await this.dataSync.syncCollection(collection); await this.dataSync.syncCollection(collection);
console.log(`Successfully synced ${collection}`); // console.log(`Successfully synced ${collection}`);
} catch (error) { } catch (error) {
console.error(`Error syncing ${collection}:`, error); // console.error(`Error syncing ${collection}:`, error);
this.syncErrors[collection] = error as Error; this.syncErrors[collection] = error as Error;
} }
}), }),
@ -146,17 +146,17 @@ export class AuthSyncService {
const syncVerification = await this.verifySyncSuccess(); const syncVerification = await this.verifySyncSuccess();
if (syncVerification.success) { if (syncVerification.success) {
console.log("Login sync completed successfully"); // console.log("Login sync completed successfully");
this.showSyncNotification("Data sync complete!", "success"); this.showSyncNotification("Data sync complete!", "success");
} else { } else {
console.warn( // console.warn(
"Login sync completed with issues:", // "Login sync completed with issues:",
syncVerification.errors, // syncVerification.errors,
); // );
this.showSyncNotification("Some data could not be synced", "warning"); this.showSyncNotification("Some data could not be synced", "warning");
} }
} catch (error) { } catch (error) {
console.error("Error during login sync:", error); // console.error("Error during login sync:", error);
this.showSyncNotification("Failed to sync data", "error"); this.showSyncNotification("Failed to sync data", "error");
} finally { } finally {
this.isSyncing = false; this.isSyncing = false;
@ -180,7 +180,7 @@ export class AuthSyncService {
if (!isBrowser) return true; if (!isBrowser) return true;
if (this.isSyncing) { if (this.isSyncing) {
console.log("Sync already in progress, queueing logout cleanup"); // console.log("Sync already in progress, queueing logout cleanup");
this.syncQueue.push("logout"); this.syncQueue.push("logout");
return true; return true;
} }
@ -188,7 +188,7 @@ export class AuthSyncService {
this.isSyncing = true; this.isSyncing = true;
try { try {
console.log("Starting logout cleanup process..."); // console.log("Starting logout cleanup process...");
// Ensure any pending changes are synced before logout // Ensure any pending changes are synced before logout
await this.syncPendingChanges(); await this.syncPendingChanges();
@ -196,10 +196,10 @@ export class AuthSyncService {
// Clear all data from IndexedDB // Clear all data from IndexedDB
await this.dexieService.clearAllData(); await this.dexieService.clearAllData();
console.log("Logout cleanup completed successfully"); // console.log("Logout cleanup completed successfully");
return true; return true;
} catch (error) { } catch (error) {
console.error("Error during logout cleanup:", error); // console.error("Error during logout cleanup:", error);
return false; return false;
} finally { } finally {
this.isSyncing = false; this.isSyncing = false;
@ -224,7 +224,7 @@ export class AuthSyncService {
// This would be implemented if we had offline capabilities // This would be implemented if we had offline capabilities
// For now, we just log that we would sync pending changes // For now, we just log that we would sync pending changes
console.log("Checking for pending changes to sync before logout..."); // console.log("Checking for pending changes to sync before logout...");
// In a real implementation, this would sync any offline changes // In a real implementation, this would sync any offline changes
} }
@ -284,7 +284,7 @@ export class AuthSyncService {
window.toast(message, { type }); window.toast(message, { type });
} else { } else {
// Fallback to console // Fallback to console
console.log(`[${type.toUpperCase()}] ${message}`); // console.log(`[${type.toUpperCase()}] ${message}`);
} }
} }
@ -293,7 +293,7 @@ export class AuthSyncService {
*/ */
public async forceSyncAll(): Promise<boolean> { public async forceSyncAll(): Promise<boolean> {
if (this.isSyncing) { if (this.isSyncing) {
console.log("Sync already in progress, queueing full sync"); // console.log("Sync already in progress, queueing full sync");
this.syncQueue.push("login"); // Reuse login sync logic this.syncQueue.push("login"); // Reuse login sync logic
return true; return true;
} }

View file

@ -83,7 +83,7 @@ export class DataSyncService {
private async handleOnline(): Promise<void> { private async handleOnline(): Promise<void> {
if (!isBrowser) return; if (!isBrowser) return;
console.log("Device is online, syncing pending changes..."); // console.log("Device is online, syncing pending changes...");
this.offlineMode = false; this.offlineMode = false;
await this.syncOfflineChanges(); await this.syncOfflineChanges();
} }
@ -94,7 +94,7 @@ export class DataSyncService {
private handleOffline(): void { private handleOffline(): void {
if (!isBrowser) return; if (!isBrowser) return;
console.log("Device is offline, enabling offline mode..."); // console.log("Device is offline, enabling offline mode...");
this.offlineMode = true; this.offlineMode = true;
} }
@ -109,13 +109,13 @@ export class DataSyncService {
): Promise<T[]> { ): Promise<T[]> {
// Skip in non-browser environments // Skip in non-browser environments
if (!isBrowser) { if (!isBrowser) {
console.log(`Skipping sync for ${collection} in non-browser environment`); // console.log(`Skipping sync for ${collection} in non-browser environment`);
return []; return [];
} }
// Prevent multiple syncs of the same collection at the same time // Prevent multiple syncs of the same collection at the same time
if (this.syncInProgress[collection]) { if (this.syncInProgress[collection]) {
console.log(`Sync already in progress for ${collection}`); // console.log(`Sync already in progress for ${collection}`);
return []; return [];
} }
@ -124,19 +124,19 @@ export class DataSyncService {
try { try {
// Check if we're authenticated // Check if we're authenticated
if (!this.auth.isAuthenticated()) { if (!this.auth.isAuthenticated()) {
console.log(`Not authenticated, skipping sync for ${collection}`); // console.log(`Not authenticated, skipping sync for ${collection}`);
return []; return [];
} }
// Check if we're offline // Check if we're offline
if (this.offlineMode) { if (this.offlineMode) {
console.log(`Device is offline, using cached data for ${collection}`); // console.log(`Device is offline, using cached data for ${collection}`);
const db = this.dexieService.getDB(); const db = this.dexieService.getDB();
const table = this.getTableForCollection(collection); const table = this.getTableForCollection(collection);
return table ? ((await table.toArray()) as T[]) : []; return table ? ((await table.toArray()) as T[]) : [];
} }
console.log(`Syncing ${collection}...`); // console.log(`Syncing ${collection}...`);
// Normalize expand parameter to be an array of strings // Normalize expand parameter to be an array of strings
let normalizedExpand: string[] | undefined; let normalizedExpand: string[] | undefined;
@ -158,7 +158,7 @@ export class DataSyncService {
const items = await this.get.getAll<T>(collection, filter, sort, { const items = await this.get.getAll<T>(collection, filter, sort, {
expand: normalizedExpand, expand: normalizedExpand,
}); });
console.log(`Fetched ${items.length} items from ${collection}`); // console.log(`Fetched ${items.length} items from ${collection}`);
// Get the database table // Get the database table
const db = this.dexieService.getDB(); const db = this.dexieService.getDB();
@ -181,11 +181,11 @@ export class DataSyncService {
const existingItem = existingItemsMap.get(item.id); const existingItem = existingItemsMap.get(item.id);
// SECURITY FIX: Remove event_code from events before storing in IndexedDB // SECURITY FIX: Remove event_code from events before storing in IndexedDB
if (collection === Collections.EVENTS && 'event_code' in item) { if (collection === Collections.EVENTS && "event_code" in item) {
// Keep the event_code but ensure files array is properly handled // Keep the event_code but ensure files array is properly handled
if ('files' in item && Array.isArray((item as any).files)) { if ("files" in item && Array.isArray((item as any).files)) {
// Ensure files array is properly stored // Ensure files array is properly stored
console.log(`Event ${item.id} has ${(item as any).files.length} files`); // console.log(`Event ${item.id} has ${(item as any).files.length} files`);
} else { } else {
// Initialize empty files array if not present // Initialize empty files array if not present
(item as any).files = []; (item as any).files = [];
@ -232,18 +232,21 @@ export class DataSyncService {
// For events, ensure we handle the files field properly // For events, ensure we handle the files field properly
if (collection === Collections.EVENTS) { if (collection === Collections.EVENTS) {
// Ensure files array is properly handled // Ensure files array is properly handled
if ('files' in serverItem && Array.isArray((serverItem as any).files)) { if ("files" in serverItem && Array.isArray((serverItem as any).files)) {
console.log(`Server event ${serverItem.id} has ${(serverItem as any).files.length} files`); // console.log(`Server event ${serverItem.id} has ${(serverItem as any).files.length} files`);
} else { } else {
// Initialize empty files array if not present // Initialize empty files array if not present
(serverItem as any).files = []; (serverItem as any).files = [];
} }
// If local item has files but server doesn't, preserve local files // If local item has files but server doesn't, preserve local files
if ('files' in localItem && Array.isArray((localItem as any).files) && if (
"files" in localItem &&
Array.isArray((localItem as any).files) &&
(localItem as any).files.length > 0 && (localItem as any).files.length > 0 &&
(!('files' in serverItem) || !(serverItem as any).files.length)) { (!("files" in serverItem) || !(serverItem as any).files.length)
console.log(`Preserving local files for event ${localItem.id}`); ) {
// console.log(`Preserving local files for event ${localItem.id}`);
(serverItem as any).files = (localItem as any).files; (serverItem as any).files = (localItem as any).files;
} }
} }
@ -255,9 +258,9 @@ export class DataSyncService {
); );
if (pendingChanges.length > 0) { if (pendingChanges.length > 0) {
console.log( // console.log(
`Found ${pendingChanges.length} pending changes for ${collection}:${localItem.id}`, // `Found ${pendingChanges.length} pending changes for ${collection}:${localItem.id}`,
); // );
// Server-wins strategy by default, but preserve local changes that haven't been synced // Server-wins strategy by default, but preserve local changes that haven't been synced
const mergedItem = { ...serverItem }; const mergedItem = { ...serverItem };
@ -268,12 +271,16 @@ export class DataSyncService {
// Apply each field change individually // Apply each field change individually
Object.entries(change.data).forEach(([key, value]) => { Object.entries(change.data).forEach(([key, value]) => {
// Special handling for files array // Special handling for files array
if (key === 'files' && Array.isArray(value)) { if (key === "files" && Array.isArray(value)) {
// Merge files arrays, removing duplicates // Merge files arrays, removing duplicates
const existingFiles = Array.isArray((mergedItem as any)[key]) ? (mergedItem as any)[key] : []; const existingFiles = Array.isArray((mergedItem as any)[key])
? (mergedItem as any)[key]
: [];
const newFiles = value as string[]; const newFiles = value as string[];
(mergedItem as any)[key] = [...new Set([...existingFiles, ...newFiles])]; (mergedItem as any)[key] = [
console.log(`Merged files for ${collection}:${localItem.id}`, (mergedItem as any)[key]); ...new Set([...existingFiles, ...newFiles]),
];
// console.log(`Merged files for ${collection}:${localItem.id}`, (mergedItem as any)[key]);
} else { } else {
(mergedItem as any)[key] = value; (mergedItem as any)[key] = value;
} }
@ -326,11 +333,11 @@ export class DataSyncService {
.toArray(); .toArray();
if (pendingChanges.length === 0) { if (pendingChanges.length === 0) {
console.log("No pending offline changes to sync"); // console.log("No pending offline changes to sync");
return true; return true;
} }
console.log(`Syncing ${pendingChanges.length} offline changes...`); // console.log(`Syncing ${pendingChanges.length} offline changes...`);
// Group changes by collection for more efficient processing // Group changes by collection for more efficient processing
const changesByCollection = pendingChanges.reduce( const changesByCollection = pendingChanges.reduce(
@ -411,9 +418,9 @@ export class DataSyncService {
}; };
const id = await this.offlineChangesTable.add(change as OfflineChange); const id = await this.offlineChangesTable.add(change as OfflineChange);
console.log( // console.log(
`Recorded offline change: ${operation} on ${collection}:${recordId}`, // `Recorded offline change: ${operation} on ${collection}:${recordId}`,
); // );
// Try to sync immediately if we're online // Try to sync immediately if we're online
if (!this.offlineMode) { if (!this.offlineMode) {
@ -500,7 +507,7 @@ export class DataSyncService {
// SECURITY FIX: Remove event_code from events before returning them // SECURITY FIX: Remove event_code from events before returning them
if (collection === Collections.EVENTS) { if (collection === Collections.EVENTS) {
data = data.map((item: any) => { data = data.map((item: any) => {
if ('event_code' in item) { if ("event_code" in item) {
const { event_code, ...rest } = item; const { event_code, ...rest } = item;
return rest; return rest;
} }
@ -538,14 +545,19 @@ export class DataSyncService {
// For events, ensure we handle the files field properly // For events, ensure we handle the files field properly
if (collection === Collections.EVENTS) { if (collection === Collections.EVENTS) {
// Ensure files array is properly handled // Ensure files array is properly handled
if (!('files' in pbItem) || !Array.isArray((pbItem as any).files)) { if (!("files" in pbItem) || !Array.isArray((pbItem as any).files)) {
(pbItem as any).files = []; (pbItem as any).files = [];
} }
// If we already have a local item with files, preserve them if server has none // If we already have a local item with files, preserve them if server has none
if (item && 'files' in item && Array.isArray((item as any).files) && if (
(item as any).files.length > 0 && !(pbItem as any).files.length) { item &&
console.log(`Preserving local files for event ${id}`); "files" in item &&
Array.isArray((item as any).files) &&
(item as any).files.length > 0 &&
!(pbItem as any).files.length
) {
// console.log(`Preserving local files for event ${id}`);
(pbItem as any).files = (item as any).files; (pbItem as any).files = (item as any).files;
} }
@ -587,8 +599,8 @@ export class DataSyncService {
} }
// Special handling for files field in events // Special handling for files field in events
if (collection === Collections.EVENTS && 'files' in data) { if (collection === Collections.EVENTS && "files" in data) {
console.log(`Updating files for event ${id}`, (data as any).files); // console.log(`Updating files for event ${id}`, (data as any).files);
// Ensure files is an array // Ensure files is an array
if (!Array.isArray((data as any).files)) { if (!Array.isArray((data as any).files)) {
@ -596,12 +608,12 @@ export class DataSyncService {
} }
// If we're updating files, make sure we're not losing any // If we're updating files, make sure we're not losing any
if ('files' in currentItem && Array.isArray((currentItem as any).files)) { if ("files" in currentItem && Array.isArray((currentItem as any).files)) {
// Merge files arrays, removing duplicates // Merge files arrays, removing duplicates
const existingFiles = (currentItem as any).files as string[]; const existingFiles = (currentItem as any).files as string[];
const newFiles = (data as any).files as string[]; const newFiles = (data as any).files as string[];
(data as any).files = [...new Set([...existingFiles, ...newFiles])]; (data as any).files = [...new Set([...existingFiles, ...newFiles])];
console.log(`Merged files for event ${id}`, (data as any).files); // console.log(`Merged files for event ${id}`, (data as any).files);
} }
} }
@ -689,11 +701,14 @@ export class DataSyncService {
try { try {
// Store in localStorage instead of IndexedDB for security // Store in localStorage instead of IndexedDB for security
localStorage.setItem('pending_event_code', eventCode); localStorage.setItem("pending_event_code", eventCode);
localStorage.setItem('pending_event_code_timestamp', Date.now().toString()); localStorage.setItem(
console.log('Event code stored for offline check-in'); "pending_event_code_timestamp",
Date.now().toString(),
);
// console.log('Event code stored for offline check-in');
} catch (error) { } catch (error) {
console.error('Error storing event code:', error); console.error("Error storing event code:", error);
} }
} }
@ -704,11 +719,11 @@ export class DataSyncService {
if (!isBrowser) return; if (!isBrowser) return;
try { try {
localStorage.removeItem('pending_event_code'); localStorage.removeItem("pending_event_code");
localStorage.removeItem('pending_event_code_timestamp'); localStorage.removeItem("pending_event_code_timestamp");
console.log('Event code cleared'); // console.log('Event code cleared');
} catch (error) { } catch (error) {
console.error('Error clearing event code:', error); console.error("Error clearing event code:", error);
} }
} }
@ -716,21 +731,24 @@ export class DataSyncService {
* Get the stored event code from local storage * Get the stored event code from local storage
* @returns The stored event code, or null if none exists * @returns The stored event code, or null if none exists
*/ */
public async getStoredEventCode(): Promise<{ code: string; timestamp: number } | null> { public async getStoredEventCode(): Promise<{
code: string;
timestamp: number;
} | null> {
if (!isBrowser) return null; if (!isBrowser) return null;
try { try {
const code = localStorage.getItem('pending_event_code'); const code = localStorage.getItem("pending_event_code");
const timestamp = localStorage.getItem('pending_event_code_timestamp'); const timestamp = localStorage.getItem("pending_event_code_timestamp");
if (!code || !timestamp) return null; if (!code || !timestamp) return null;
return { return {
code, code,
timestamp: parseInt(timestamp) timestamp: parseInt(timestamp),
}; };
} catch (error) { } catch (error) {
console.error('Error getting stored event code:', error); console.error("Error getting stored event code:", error);
return null; return null;
} }
} }
@ -747,7 +765,7 @@ export class DataSyncService {
const table = this.getTableForCollection(Collections.EVENTS); const table = this.getTableForCollection(Collections.EVENTS);
if (!table) { if (!table) {
console.error('Events table not found'); console.error("Events table not found");
return; return;
} }
@ -755,8 +773,8 @@ export class DataSyncService {
const events = await table.toArray(); const events = await table.toArray();
// Remove event_code from each event // Remove event_code from each event
const updatedEvents = events.map(event => { const updatedEvents = events.map((event) => {
if ('event_code' in event) { if ("event_code" in event) {
const { event_code, ...rest } = event; const { event_code, ...rest } = event;
return rest; return rest;
} }
@ -767,9 +785,9 @@ export class DataSyncService {
await table.clear(); await table.clear();
await table.bulkAdd(updatedEvents); await table.bulkAdd(updatedEvents);
console.log('Successfully purged event codes from IndexedDB'); // console.log('Successfully purged event codes from IndexedDB');
} catch (error) { } catch (error) {
console.error('Error purging event codes:', error); console.error("Error purging event codes:", error);
} }
} }
} }

View file

@ -74,7 +74,8 @@ export class DashboardDatabase extends Dexie {
// Add version 4 with files field in events table // Add version 4 with files field in events table
this.version(4).stores({ this.version(4).stores({
events: "id, event_name, event_code, start_date, end_date, published, files", events:
"id, event_name, event_code, start_date, end_date, published, files",
}); });
} }
@ -125,7 +126,7 @@ export class DexieService {
this.db.initialize(); this.db.initialize();
} else { } else {
// Use a mock database in non-browser environments // Use a mock database in non-browser environments
console.log("Running in Node.js environment, using mock database"); // console.log("Running in Node.js environment, using mock database");
this.db = new MockDashboardDatabase() as any; this.db = new MockDashboardDatabase() as any;
} }
} }

View file

@ -1,4 +1,4 @@
import { Authentication } from '../pocketbase/Authentication'; import { Authentication } from "../pocketbase/Authentication";
/** /**
* Initialize authentication synchronization * Initialize authentication synchronization
@ -13,23 +13,23 @@ export async function initAuthSync(): Promise<void> {
// This will trigger the lazy loading of AuthSyncService // This will trigger the lazy loading of AuthSyncService
// through the onAuthStateChange mechanism // through the onAuthStateChange mechanism
auth.onAuthStateChange(() => { auth.onAuthStateChange(() => {
console.log('Auth sync initialized and listening for auth state changes'); // console.log('Auth sync initialized and listening for auth state changes');
}); });
console.log('Auth sync initialization complete'); // console.log('Auth sync initialization complete');
} catch (error) { } catch (error) {
console.error('Failed to initialize auth sync:', error); console.error("Failed to initialize auth sync:", error);
} }
} }
// Export a function to manually trigger a full sync // Export a function to manually trigger a full sync
export async function forceFullSync(): Promise<boolean> { export async function forceFullSync(): Promise<boolean> {
try { try {
const { AuthSyncService } = await import('./AuthSyncService'); const { AuthSyncService } = await import("./AuthSyncService");
const authSync = AuthSyncService.getInstance(); const authSync = AuthSyncService.getInstance();
return await authSync.forceSyncAll(); return await authSync.forceSyncAll();
} catch (error) { } catch (error) {
console.error('Failed to force full sync:', error); console.error("Failed to force full sync:", error);
return false; return false;
} }
} }

View file

@ -89,7 +89,7 @@ export class Authentication {
await this.initAuthSyncService(); await this.initAuthSyncService();
// Get AuthSyncService instance // Get AuthSyncService instance
const { AuthSyncService } = await import('../database/AuthSyncService'); const { AuthSyncService } = await import("../database/AuthSyncService");
const authSync = AuthSyncService.getInstance(); const authSync = AuthSyncService.getInstance();
// Handle data cleanup before actual logout // Handle data cleanup before actual logout
@ -98,9 +98,9 @@ export class Authentication {
// Clear auth store // Clear auth store
this.pb.authStore.clear(); this.pb.authStore.clear();
console.log('Logout completed successfully with data cleanup'); // console.log('Logout completed successfully with data cleanup');
} catch (error) { } catch (error) {
console.error('Error during logout:', error); console.error("Error during logout:", error);
// Fallback to basic logout if sync fails // Fallback to basic logout if sync fails
this.pb.authStore.clear(); this.pb.authStore.clear();
} }
@ -135,7 +135,10 @@ export class Authentication {
this.authChangeCallbacks.push(callback); this.authChangeCallbacks.push(callback);
// Initialize AuthSyncService when first callback is registered // Initialize AuthSyncService when first callback is registered
if (!this.authSyncServiceInitialized && this.authChangeCallbacks.length === 1) { if (
!this.authSyncServiceInitialized &&
this.authChangeCallbacks.length === 1
) {
this.initAuthSyncService(); this.initAuthSyncService();
} }
} }
@ -173,23 +176,23 @@ export class Authentication {
try { try {
// Dynamically import AuthSyncService to avoid circular dependencies // Dynamically import AuthSyncService to avoid circular dependencies
const { AuthSyncService } = await import('../database/AuthSyncService'); const { AuthSyncService } = await import("../database/AuthSyncService");
// Initialize the service // Initialize the service
AuthSyncService.getInstance(); AuthSyncService.getInstance();
this.authSyncServiceInitialized = true; this.authSyncServiceInitialized = true;
console.log('AuthSyncService initialized successfully'); // console.log('AuthSyncService initialized successfully');
// If user is already authenticated, trigger initial sync // If user is already authenticated, trigger initial sync
if (this.isAuthenticated()) { if (this.isAuthenticated()) {
const authSync = AuthSyncService.getInstance(); const authSync = AuthSyncService.getInstance();
authSync.handleLogin().catch(err => { authSync.handleLogin().catch((err) => {
console.error('Error during initial data sync:', err); console.error("Error during initial data sync:", err);
}); });
} }
} catch (error) { } catch (error) {
console.error('Failed to initialize AuthSyncService:', error); console.error("Failed to initialize AuthSyncService:", error);
} }
} }
} }

View file

@ -3,7 +3,7 @@ import { Authentication } from "./Authentication";
export class FileManager { export class FileManager {
private auth: Authentication; private auth: Authentication;
private static instance: FileManager; private static instance: FileManager;
private static UNSUPPORTED_EXTENSIONS = ['afdesign', 'psd', 'ai', 'sketch']; private static UNSUPPORTED_EXTENSIONS = ["afdesign", "psd", "ai", "sketch"];
private constructor() { private constructor() {
this.auth = Authentication.getInstance(); this.auth = Authentication.getInstance();
@ -25,12 +25,15 @@ export class FileManager {
* @returns Object with validation result and reason if invalid * @returns Object with validation result and reason if invalid
*/ */
public validateFileType(file: File): { valid: boolean; reason?: string } { public validateFileType(file: File): { valid: boolean; reason?: string } {
const fileExtension = file.name.split('.').pop()?.toLowerCase(); const fileExtension = file.name.split(".").pop()?.toLowerCase();
if (fileExtension && FileManager.UNSUPPORTED_EXTENSIONS.includes(fileExtension)) { if (
fileExtension &&
FileManager.UNSUPPORTED_EXTENSIONS.includes(fileExtension)
) {
return { return {
valid: false, valid: false,
reason: `File type .${fileExtension} is not supported. Please convert to PDF or image format.` reason: `File type .${fileExtension} is not supported. Please convert to PDF or image format.`,
}; };
} }
@ -51,7 +54,7 @@ export class FileManager {
recordId: string, recordId: string,
field: string, field: string,
file: File, file: File,
append: boolean = false append: boolean = false,
): Promise<T> { ): Promise<T> {
if (!this.auth.isAuthenticated()) { if (!this.auth.isAuthenticated()) {
throw new Error("User must be authenticated to upload files"); throw new Error("User must be authenticated to upload files");
@ -64,11 +67,13 @@ export class FileManager {
// Validate file size // Validate file size
const maxSize = 200 * 1024 * 1024; // 200MB const maxSize = 200 * 1024 * 1024; // 200MB
if (file.size > maxSize) { if (file.size > maxSize) {
throw new Error(`File size ${(file.size / 1024 / 1024).toFixed(2)}MB exceeds 200MB limit`); throw new Error(
`File size ${(file.size / 1024 / 1024).toFixed(2)}MB exceeds 200MB limit`,
);
} }
// Check for potentially problematic file types // Check for potentially problematic file types
const fileExtension = file.name.split('.').pop()?.toLowerCase(); const fileExtension = file.name.split(".").pop()?.toLowerCase();
// Validate file type // Validate file type
const validation = this.validateFileType(file); const validation = this.validateFileType(file);
@ -77,16 +82,16 @@ export class FileManager {
} }
// Log upload attempt // Log upload attempt
console.log('Attempting file upload:', { // console.log('Attempting file upload:', {
name: file.name, // name: file.name,
size: file.size, // size: file.size,
type: file.type, // type: file.type,
extension: fileExtension, // extension: fileExtension,
collection: collectionName, // collection: collectionName,
recordId: recordId, // recordId: recordId,
field: field, // field: field,
append: append // append: append
}); // });
// Create FormData for the upload // Create FormData for the upload
const formData = new FormData(); const formData = new FormData();
@ -104,20 +109,21 @@ export class FileManager {
existingFiles = existingRecord[field] || []; existingFiles = existingRecord[field] || [];
} }
} catch (error) { } catch (error) {
console.warn('Could not fetch existing record:', error); // console.warn('Could not fetch existing record:', error);
} }
// Check if the file already exists // Check if the file already exists
const fileExists = existingFiles.some(existingFile => const fileExists = existingFiles.some(
existingFile.toLowerCase() === file.name.toLowerCase() (existingFile) =>
existingFile.toLowerCase() === file.name.toLowerCase(),
); );
if (fileExists) { if (fileExists) {
console.warn(`File with name ${file.name} already exists. Renaming to avoid conflicts.`); // console.warn(`File with name ${file.name} already exists. Renaming to avoid conflicts.`);
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();
const nameParts = file.name.split('.'); const nameParts = file.name.split(".");
const extension = nameParts.pop(); const extension = nameParts.pop();
const baseName = nameParts.join('.'); const baseName = nameParts.join(".");
const newFileName = `${baseName}_${timestamp}.${extension}`; const newFileName = `${baseName}_${timestamp}.${extension}`;
// Create a new file with the modified name // Create a new file with the modified name
@ -128,59 +134,70 @@ export class FileManager {
} }
try { try {
const result = await pb.collection(collectionName).update<T>(recordId, formData); const result = await pb
console.log('Upload successful:', { .collection(collectionName)
result, .update<T>(recordId, formData);
fileInfo: { // console.log('Upload successful:', {
name: file.name, // result,
size: file.size, // fileInfo: {
type: file.type // name: file.name,
}, // size: file.size,
collection: collectionName, // type: file.type
recordId: recordId // },
}); // collection: collectionName,
// recordId: recordId
// });
// Verify the file was actually added to the record // Verify the file was actually added to the record
try { try {
const updatedRecord = await pb.collection(collectionName).getOne(recordId); const updatedRecord = await pb
console.log('Updated record files:', { .collection(collectionName)
files: updatedRecord.files, .getOne(recordId);
recordId: recordId // console.log('Updated record files:', {
}); // files: updatedRecord.files,
// recordId: recordId
// });
} catch (verifyError) { } catch (verifyError) {
console.warn('Could not verify file upload:', verifyError); // console.warn('Could not verify file upload:', verifyError);
} }
return result; return result;
} catch (pbError: any) { } catch (pbError: any) {
// Log detailed PocketBase error // Log detailed PocketBase error
console.error('PocketBase upload error:', { // console.error('PocketBase upload error:', {
status: pbError?.status, // status: pbError?.status,
response: pbError?.response, // response: pbError?.response,
data: pbError?.data, // data: pbError?.data,
message: pbError?.message // message: pbError?.message
}); // });
// More specific error message based on file type // More specific error message based on file type
if (fileExtension && FileManager.UNSUPPORTED_EXTENSIONS.includes(fileExtension)) { if (
throw new Error(`Upload failed: File type .${fileExtension} is not supported. Please convert to PDF or image format.`); fileExtension &&
FileManager.UNSUPPORTED_EXTENSIONS.includes(fileExtension)
) {
throw new Error(
`Upload failed: File type .${fileExtension} is not supported. Please convert to PDF or image format.`,
);
} }
throw new Error(`Upload failed: ${pbError?.message || 'Unknown PocketBase error'}`); throw new Error(
`Upload failed: ${pbError?.message || "Unknown PocketBase error"}`,
);
} }
} catch (err) { } catch (err) {
console.error(`Failed to upload file to ${collectionName}:`, { // console.error(`Failed to upload file to ${collectionName}:`, {
error: err, // error: err,
fileInfo: { // fileInfo: {
name: file.name, // name: file.name,
size: file.size, // size: file.size,
type: file.type // type: file.type
}, // },
auth: { // auth: {
isAuthenticated: this.auth.isAuthenticated(), // isAuthenticated: this.auth.isAuthenticated(),
userId: this.auth.getUserId() // userId: this.auth.getUserId()
} // }
}); // });
if (err instanceof Error) { if (err instanceof Error) {
throw err; throw err;
@ -241,7 +258,7 @@ export class FileManager {
.getOne<T>(recordId); .getOne<T>(recordId);
existingFiles = (record as any)[field] || []; existingFiles = (record as any)[field] || [];
} catch (error) { } catch (error) {
console.warn("Failed to fetch existing record:", error); // console.warn("Failed to fetch existing record:", error);
} }
} }
@ -260,7 +277,7 @@ export class FileManager {
processedFile = await this.compressImageIfNeeded(file, 50); // 50MB max size processedFile = await this.compressImageIfNeeded(file, 50); // 50MB max size
} }
} catch (error) { } catch (error) {
console.warn(`Failed to process file ${file.name}:`, error); // console.warn(`Failed to process file ${file.name}:`, error);
processedFile = file; // Use original file if processing fails processedFile = file; // Use original file if processing fails
} }
@ -298,7 +315,7 @@ export class FileManager {
.getOne<T>(recordId); .getOne<T>(recordId);
return finalRecord; return finalRecord;
} catch (err) { } catch (err) {
console.error(`Failed to upload files to ${collectionName}:`, err); // console.error(`Failed to upload files to ${collectionName}:`, err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -324,7 +341,7 @@ export class FileManager {
const record = await pb.collection(collectionName).getOne(recordId); const record = await pb.collection(collectionName).getOne(recordId);
existingFiles = record[field] || []; existingFiles = record[field] || [];
} catch (error) { } catch (error) {
console.warn("Failed to fetch existing record for duplicate check:", error); // console.warn("Failed to fetch existing record for duplicate check:", error);
} }
// Add new files, renaming duplicates if needed // Add new files, renaming duplicates if needed
@ -334,15 +351,15 @@ export class FileManager {
// Check if filename already exists // Check if filename already exists
if (Array.isArray(existingFiles) && existingFiles.includes(file.name)) { if (Array.isArray(existingFiles) && existingFiles.includes(file.name)) {
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();
const nameParts = file.name.split('.'); const nameParts = file.name.split(".");
const extension = nameParts.pop(); const extension = nameParts.pop();
const baseName = nameParts.join('.'); const baseName = nameParts.join(".");
const newFileName = `${baseName}_${timestamp}.${extension}`; const newFileName = `${baseName}_${timestamp}.${extension}`;
// Create a new file with the modified name // Create a new file with the modified name
fileToUpload = new File([file], newFileName, { type: file.type }); fileToUpload = new File([file], newFileName, { type: file.type });
console.log(`Renamed duplicate file from ${file.name} to ${newFileName}`); // console.log(`Renamed duplicate file from ${file.name} to ${newFileName}`);
} }
formData.append(field, fileToUpload); formData.append(field, fileToUpload);
@ -350,7 +367,7 @@ export class FileManager {
// Tell PocketBase to keep existing files // Tell PocketBase to keep existing files
if (existingFiles.length > 0) { if (existingFiles.length > 0) {
formData.append(`${field}@`, ''); // This tells PocketBase to keep existing files formData.append(`${field}@`, ""); // This tells PocketBase to keep existing files
} }
try { try {
@ -398,7 +415,7 @@ export class FileManager {
const formData = new FormData(); const formData = new FormData();
// Tell PocketBase to keep existing files // Tell PocketBase to keep existing files
formData.append(`${field}@`, ''); formData.append(`${field}@`, "");
// Append new files, renaming if needed to avoid duplicates // Append new files, renaming if needed to avoid duplicates
for (const file of files) { for (const file of files) {
@ -407,15 +424,15 @@ export class FileManager {
// Check if filename already exists // Check if filename already exists
if (existingFilenames.has(file.name)) { if (existingFilenames.has(file.name)) {
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();
const nameParts = file.name.split('.'); const nameParts = file.name.split(".");
const extension = nameParts.pop(); const extension = nameParts.pop();
const baseName = nameParts.join('.'); const baseName = nameParts.join(".");
const newFileName = `${baseName}_${timestamp}.${extension}`; const newFileName = `${baseName}_${timestamp}.${extension}`;
// Create a new file with the modified name // Create a new file with the modified name
fileToUpload = new File([file], newFileName, { type: file.type }); fileToUpload = new File([file], newFileName, { type: file.type });
console.log(`Renamed duplicate file from ${file.name} to ${newFileName}`); // console.log(`Renamed duplicate file from ${file.name} to ${newFileName}`);
} }
formData.append(field, fileToUpload); formData.append(field, fileToUpload);
@ -426,7 +443,7 @@ export class FileManager {
.update<T>(recordId, formData); .update<T>(recordId, formData);
return result; return result;
} catch (err) { } catch (err) {
console.error(`Failed to append files to ${collectionName}:`, err); // console.error(`Failed to append files to ${collectionName}:`, err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -477,7 +494,7 @@ export class FileManager {
.update<T>(recordId, data); .update<T>(recordId, data);
return result; return result;
} catch (err) { } catch (err) {
console.error(`Failed to delete file from ${collectionName}:`, err); // console.error(`Failed to delete file from ${collectionName}:`, err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -512,7 +529,7 @@ export class FileManager {
const result = await response.blob(); const result = await response.blob();
return result; return result;
} catch (err) { } catch (err) {
console.error(`Failed to download file from ${collectionName}:`, err); // console.error(`Failed to download file from ${collectionName}:`, err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -552,7 +569,7 @@ export class FileManager {
return fileUrls; return fileUrls;
} catch (err) { } catch (err) {
console.error(`Failed to get files from ${collectionName}:`, err); // console.error(`Failed to get files from ${collectionName}:`, err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -643,22 +660,22 @@ export class FileManager {
public async getFileToken(): Promise<string> { public async getFileToken(): Promise<string> {
// Check authentication status // Check authentication status
if (!this.auth.isAuthenticated()) { if (!this.auth.isAuthenticated()) {
console.warn("User is not authenticated when trying to get file token"); // console.warn("User is not authenticated when trying to get file token");
// Try to refresh the auth if possible // Try to refresh the auth if possible
try { try {
const pb = this.auth.getPocketBase(); const pb = this.auth.getPocketBase();
if (pb.authStore.isValid) { if (pb.authStore.isValid) {
console.log( // console.log(
"Auth store is valid, but auth check failed. Trying to refresh token.", // "Auth store is valid, but auth check failed. Trying to refresh token.",
); // );
await pb.collection("users").authRefresh(); await pb.collection("users").authRefresh();
console.log("Auth refreshed successfully"); // console.log("Auth refreshed successfully");
} else { } else {
throw new Error("User must be authenticated to get a file token"); throw new Error("User must be authenticated to get a file token");
} }
} catch (refreshError) { } catch (refreshError) {
console.error("Failed to refresh authentication:", refreshError); // console.error("Failed to refresh authentication:", refreshError);
throw new Error("User must be authenticated to get a file token"); throw new Error("User must be authenticated to get a file token");
} }
} }
@ -668,19 +685,19 @@ export class FileManager {
const pb = this.auth.getPocketBase(); const pb = this.auth.getPocketBase();
// Log auth status // Log auth status
console.log("Auth status before getting token:", { // console.log("Auth status before getting token:", {
isValid: pb.authStore.isValid, // isValid: pb.authStore.isValid,
token: pb.authStore.token // token: pb.authStore.token
? pb.authStore.token.substring(0, 10) + "..." // ? pb.authStore.token.substring(0, 10) + "..."
: "none", // : "none",
model: pb.authStore.model ? pb.authStore.model.id : "none", // model: pb.authStore.model ? pb.authStore.model.id : "none",
}); // });
const result = await pb.files.getToken(); const result = await pb.files.getToken();
console.log("Got file token:", result.substring(0, 10) + "..."); // console.log("Got file token:", result.substring(0, 10) + "...");
return result; return result;
} catch (err) { } catch (err) {
console.error("Failed to get file token:", err); // console.error("Failed to get file token:", err);
throw err; throw err;
} finally { } finally {
this.auth.setUpdating(false); this.auth.setUpdating(false);
@ -705,25 +722,25 @@ export class FileManager {
// Check if filename is empty // Check if filename is empty
if (!filename) { if (!filename) {
console.error( // console.error(
`Empty filename provided for ${collectionName}/${recordId}`, // `Empty filename provided for ${collectionName}/${recordId}`,
); // );
return ""; return "";
} }
// Check if user is authenticated // Check if user is authenticated
if (!this.auth.isAuthenticated()) { if (!this.auth.isAuthenticated()) {
console.warn("User is not authenticated when trying to get file URL"); // console.warn("User is not authenticated when trying to get file URL");
} }
// Always try to use token for protected files // Always try to use token for protected files
if (useToken) { if (useToken) {
try { try {
console.log( // console.log(
`Getting file token for ${collectionName}/${recordId}/${filename}`, // `Getting file token for ${collectionName}/${recordId}/${filename}`,
); // );
const token = await this.getFileToken(); const token = await this.getFileToken();
console.log(`Got token: ${token.substring(0, 10)}...`); // console.log(`Got token: ${token.substring(0, 10)}...`);
// Make sure to pass the token as a query parameter // Make sure to pass the token as a query parameter
const url = pb.files.getURL( const url = pb.files.getURL(
@ -731,16 +748,16 @@ export class FileManager {
filename, filename,
{ token }, { token },
); );
console.log(`Generated URL with token: ${url.substring(0, 50)}...`); // console.log(`Generated URL with token: ${url.substring(0, 50)}...`);
return url; return url;
} catch (error) { } catch (error) {
console.error("Error getting file token:", error); // console.error("Error getting file token:", error);
// Fall back to URL without token // Fall back to URL without token
const url = pb.files.getURL( const url = pb.files.getURL(
{ id: recordId, collectionId: collectionName }, { id: recordId, collectionId: collectionName },
filename, filename,
); );
console.log(`Fallback URL without token: ${url.substring(0, 50)}...`); // console.log(`Fallback URL without token: ${url.substring(0, 50)}...`);
return url; return url;
} }
} }
@ -750,7 +767,7 @@ export class FileManager {
{ id: recordId, collectionId: collectionName }, { id: recordId, collectionId: collectionName },
filename, filename,
); );
console.log(`Generated URL without token: ${url.substring(0, 50)}...`); // console.log(`Generated URL without token: ${url.substring(0, 50)}...`);
return url; return url;
} }
} }