diff --git a/src/scripts/database/DataSyncService.ts b/src/scripts/database/DataSyncService.ts index e465316..b370121 100644 --- a/src/scripts/database/DataSyncService.ts +++ b/src/scripts/database/DataSyncService.ts @@ -601,6 +601,8 @@ export class DataSyncService { return db.users; case Collections.EVENTS: return db.events; + case Collections.EVENT_ATTENDEES: + return db.eventAttendees; case Collections.EVENT_REQUESTS: return db.eventRequests; case Collections.LOGS: @@ -619,6 +621,62 @@ export class DataSyncService { } } + /** + * Store an event code in local storage for offline check-in + * This is used when a user scans a QR code but is offline + * @param eventCode The event code to store + */ + public async storeEventCode(eventCode: string): Promise { + if (!isBrowser) return; + + try { + // Store in localStorage instead of IndexedDB for security + localStorage.setItem('pending_event_code', eventCode); + localStorage.setItem('pending_event_code_timestamp', Date.now().toString()); + console.log('Event code stored for offline check-in'); + } catch (error) { + console.error('Error storing event code:', error); + } + } + + /** + * Clear the stored event code from local storage + */ + public async clearEventCode(): Promise { + if (!isBrowser) return; + + try { + localStorage.removeItem('pending_event_code'); + localStorage.removeItem('pending_event_code_timestamp'); + console.log('Event code cleared'); + } catch (error) { + console.error('Error clearing event code:', error); + } + } + + /** + * Get the stored event code from local storage + * @returns The stored event code, or null if none exists + */ + public async getStoredEventCode(): Promise<{ code: string; timestamp: number } | null> { + if (!isBrowser) return null; + + try { + const code = localStorage.getItem('pending_event_code'); + const timestamp = localStorage.getItem('pending_event_code_timestamp'); + + if (!code || !timestamp) return null; + + return { + code, + timestamp: parseInt(timestamp) + }; + } catch (error) { + console.error('Error getting stored event code:', error); + return null; + } + } + /** * Purge event_code fields from events in IndexedDB for security * This should be called on login to ensure no event codes are stored diff --git a/src/scripts/database/DexieService.ts b/src/scripts/database/DexieService.ts index f444100..2433d4c 100644 --- a/src/scripts/database/DexieService.ts +++ b/src/scripts/database/DexieService.ts @@ -8,6 +8,7 @@ import type { Reimbursement, Receipt, Sponsor, + EventAttendee, } from "../../schemas/pocketbase/schema"; // Check if we're in a browser environment @@ -29,6 +30,7 @@ interface OfflineChange { export class DashboardDatabase extends Dexie { users!: Dexie.Table; events!: Dexie.Table; + eventAttendees!: Dexie.Table; eventRequests!: Dexie.Table; logs!: Dexie.Table; officers!: Dexie.Table; @@ -63,6 +65,12 @@ export class DashboardDatabase extends Dexie { offlineChanges: "id, collection, recordId, operation, timestamp, synced, syncAttempts", }); + + // Add version 3 with eventAttendees table and updated events table (no attendees field) + this.version(3).stores({ + events: "id, event_name, event_code, start_date, end_date, published", + eventAttendees: "id, user, event, time_checked_in", + }); } // Initialize the database with default values @@ -70,6 +78,7 @@ export class DashboardDatabase extends Dexie { const collections = [ "users", "events", + "event_attendees", "event_request", "logs", "officers", @@ -155,6 +164,7 @@ export class DexieService { const db = this.db as DashboardDatabase; await db.users.clear(); await db.events.clear(); + await db.eventAttendees.clear(); await db.eventRequests.clear(); await db.logs.clear(); await db.officers.clear(); @@ -167,6 +177,7 @@ export class DexieService { const collections = [ "users", "events", + "event_attendees", "event_request", "logs", "officers",