From 01c0f792484f8f52606eae0e58abe528acef3086 Mon Sep 17 00:00:00 2001 From: Leo Goetz Date: Thu, 22 Jan 2026 09:10:15 +0100 Subject: feat: completed course, added some types and changed output to dist folder --- frontend/src/components/Events.ts | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 frontend/src/components/Events.ts (limited to 'frontend/src/components/Events.ts') diff --git a/frontend/src/components/Events.ts b/frontend/src/components/Events.ts new file mode 100644 index 0000000..a92cf83 --- /dev/null +++ b/frontend/src/components/Events.ts @@ -0,0 +1,129 @@ +import { Calendar } from "./Icons"; + +const API_URL = import.meta.env.VITE_API_URL; + +interface Event { + id: number; + title: string; + description?: string; + date: Date; + host_id: number; + image_url?: string; + host: { + id: number; + name: string; + email: string; + }; + rsvps: { + id: number; + name: string; + email: string; + }[]; +} + +const loadEventsData = async (): Promise => { + try { + const response = await fetch(`${API_URL}/events`); + return response.json(); + } catch (e) { + console.error(e); + return []; + } +}; + +export const EventModal = (event: Event) => { + const formId = `rsvp-form-${event.id}`; + const modalId = `modal-event-${event.id}`; + return ` +
+
+ +

RSVP to ${event.title}

+
+
+ + + +
+
+ + + + +
+
+
`; +}; + +export const EventCard = (e: Event) => { + const eventDate = new Date(e.date); + const isPast = eventDate < new Date(); + return ` +
+
+ ${e.image_url && `${e.title} thumbnail`} +
+
+

${e.title}

+

${Calendar} ${eventDate.toLocaleDateString()}

+

Host: ${e.host?.name || `User ${e.host_id}`}

+ + ${e.description ? `

${e.description}

` : ""} +
+
+ + ${e.rsvps?.length || 0} ${isPast ? "went" : "going"} + + ${ + !isPast + ? ` + ` + : "" + } +
+ ${EventModal(e)} +
+ `; +}; + +export const EventsSection = (title: string, events: Event[]) => { + return ` +
+

${title} events

+
+ ${events.map((e) => EventCard(e)).join("") || "No events"} +
+
`; +}; + +// IIFE to asynchronously load the Event data before exporting the component +// https://developer.mozilla.org/en-US/docs/Glossary/IIFE +export const Events = await (async () => { + const all = await loadEventsData(); + const past = all.filter((e) => new Date(e.date) < new Date()); + const upcoming = all.filter((e) => new Date(e.date) > new Date()); + return ` + ${EventsSection("Upcoming", upcoming)} + ${EventsSection("Past", past)} +`; +})(); -- cgit v1.3