From 50ec7e94bc6c3c221b5ae004c4306edfcc5ee03b Mon Sep 17 00:00:00 2001 From: Marcus Pascual Date: Sun, 10 May 2026 19:57:53 +0800 Subject: [PATCH 1/8] feat: use Supabase to pull events data instead of JSON imports --- src/lib/data/events/index.ts | 73 +++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/src/lib/data/events/index.ts b/src/lib/data/events/index.ts index ab119018..ec364f0c 100644 --- a/src/lib/data/events/index.ts +++ b/src/lib/data/events/index.ts @@ -3,27 +3,55 @@ import { parse } from 'valibot'; import { type Event, Event as EventSchema } from '$lib/models/event'; import type { State } from '$lib/types/state'; +import { supabase } from '$lib/supabaseClient'; + import { type EventSession, dummy_session } from '$lib/types/event_session'; export async function getEvents() { - const imports = import.meta.glob('./json/*.json'); - - const promises = Object.entries(imports).map(async ([_, asset]) => { - const event = parse(EventSchema, await asset()); - - const parsed_sessions: EventSession[] = []; - for (const detail of event.sessions) { - const [type, start, end, description] = detail.split('|'); - if ((type === 'Internal' || type === 'External') && start && end) { - const new_session: EventSession = { - type, - start: new Date(start), - end: new Date(end), - description: description ?? null, - }; - parsed_sessions.push(new_session); - } - } + const { data: eventsData, error: eventsError } = await supabase + .from('events') + .select('id, name, tag, description, slug') + .order('id'); + + if (eventsError) throw new Error('events data fetching error'); + + const { data: sessionsData, error: sessionsError } = await supabase + .from('event_sessions') + .select('event_id, audience_type, start_time, end_time, session_desc') + + if (sessionsError) throw new Error('event_sessions data fetching error'); + + const sessionsByEventId: Record< + number, + { audience_type: string; start_time: string; end_time: string; session_desc: string | null }[] + > = {}; + + // checking jic sessionsData is null + for (const s of sessionsData ?? []) { + const event_id = s.event_id; + + // init the value for records + if (!sessionsByEventId[event_id]) sessionsByEventId[event_id] = []; + sessionsByEventId[event_id]!.push({ + audience_type: s.audience_type, + start_time: s.start_time, + end_time: s.end_time, + session_desc: s.session_desc + }) + } + + const events: Event[] = []; + for (const eventData of eventsData ?? []) { + const event = parse(EventSchema, eventData); + + const currEventSessions = sessionsByEventId[eventData.id] ?? []; + + const parsed_sessions: EventSession[] = currEventSessions.map(s => ({ + type: s.audience_type as 'Internal' | 'External', + start: new Date(s.start_time), + end: new Date(s.end_time), + description: s.session_desc ?? null + })) parsed_sessions.sort((a, b) => b.end.getTime() - a.end.getTime()); @@ -47,8 +75,9 @@ export async function getEvents() { if (state === 'Past') current_session = parsed_sessions[parsed_sessions.length - 1] ?? dummy_session; - return { ...event, parsed_sessions, current_session, state } as Event; - }); - - return await Promise.all(promises); + + events.push({ ...event, parsed_sessions, current_session, state } as Event); + } + + return events; } From 198a26b4efb8adf9f5929ba88ea30656e72eb209 Mon Sep 17 00:00:00 2001 From: Marcus Pascual Date: Sun, 10 May 2026 20:11:46 +0800 Subject: [PATCH 2/8] fix: update event model to remove sessions --- src/lib/models/event.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/models/event.ts b/src/lib/models/event.ts index 3565bce6..103f8d52 100644 --- a/src/lib/models/event.ts +++ b/src/lib/models/event.ts @@ -1,4 +1,4 @@ -import { type InferOutput, array, object, picklist, string } from 'valibot'; +import { type InferOutput, object, picklist, string } from 'valibot'; import type { EventSession } from '$lib/types/event_session'; import type { State } from '$lib/types/state'; @@ -17,7 +17,6 @@ export const Event = object({ tag: picklist(TAGS), name: string(), description: string(), - sessions: array(string()), slug: string(), }); From 55726ecbbc951966d5e564afb37c4270bb125f1f Mon Sep 17 00:00:00 2001 From: Marcus Pascual Date: Sun, 10 May 2026 20:30:14 +0800 Subject: [PATCH 3/8] fix: update TAGS in the event model --- src/lib/models/event.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/models/event.ts b/src/lib/models/event.ts index 103f8d52..6d40461f 100644 --- a/src/lib/models/event.ts +++ b/src/lib/models/event.ts @@ -11,6 +11,7 @@ export const TAGS = [ 'Partnership', 'Workshop', 'Other', + 'Hackathon' ] as const; export const Event = object({ From dcf5d7a94e06034cd99b1beb9b3e44238a548e40 Mon Sep 17 00:00:00 2001 From: Marcus Pascual Date: Sun, 10 May 2026 21:52:59 +0800 Subject: [PATCH 4/8] refactor: use a single query for events and sessions --- src/lib/data/events/index.ts | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/lib/data/events/index.ts b/src/lib/data/events/index.ts index ec364f0c..2137bf32 100644 --- a/src/lib/data/events/index.ts +++ b/src/lib/data/events/index.ts @@ -8,43 +8,27 @@ import { supabase } from '$lib/supabaseClient'; import { type EventSession, dummy_session } from '$lib/types/event_session'; export async function getEvents() { - const { data: eventsData, error: eventsError } = await supabase + const { data, error } = await supabase .from('events') - .select('id, name, tag, description, slug') + .select(` + id, name, tag, description, slug, + event_sessions (audience_type, start_time, end_time, session_desc) + `) .order('id'); - if (eventsError) throw new Error('events data fetching error'); - - const { data: sessionsData, error: sessionsError } = await supabase - .from('event_sessions') - .select('event_id, audience_type, start_time, end_time, session_desc') - - if (sessionsError) throw new Error('event_sessions data fetching error'); + if (error) throw new Error('events data fetching error'); const sessionsByEventId: Record< number, { audience_type: string; start_time: string; end_time: string; session_desc: string | null }[] > = {}; - // checking jic sessionsData is null - for (const s of sessionsData ?? []) { - const event_id = s.event_id; - - // init the value for records - if (!sessionsByEventId[event_id]) sessionsByEventId[event_id] = []; - sessionsByEventId[event_id]!.push({ - audience_type: s.audience_type, - start_time: s.start_time, - end_time: s.end_time, - session_desc: s.session_desc - }) - } - + const events: Event[] = []; - for (const eventData of eventsData ?? []) { + for (const eventData of data ?? []) { const event = parse(EventSchema, eventData); - const currEventSessions = sessionsByEventId[eventData.id] ?? []; + const currEventSessions = eventData.event_sessions ?? []; const parsed_sessions: EventSession[] = currEventSessions.map(s => ({ type: s.audience_type as 'Internal' | 'External', From dbf8f1a0ae0ef3a2f5f8830443e37faad8aec104 Mon Sep 17 00:00:00 2001 From: Marcus Pascual Date: Sun, 10 May 2026 22:28:07 +0800 Subject: [PATCH 5/8] feat: use img_url field from db --- src/lib/components/cards/EventCard.svelte | 25 +++++++++++---------- src/lib/components/modals/EventModal.svelte | 4 ++-- src/lib/data/events/index.ts | 8 +------ src/lib/models/event.ts | 3 ++- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/lib/components/cards/EventCard.svelte b/src/lib/components/cards/EventCard.svelte index 6ed419fb..7a812c46 100644 --- a/src/lib/components/cards/EventCard.svelte +++ b/src/lib/components/cards/EventCard.svelte @@ -1,12 +1,14 @@