From 99d04f4b43f9a27afc33a22be9f33cc8dba94041 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 26 Feb 2025 23:56:19 +0100 Subject: [PATCH] Move schedule data to JSON file --- app/schedule/events.ts | 109 ----------------------------------------- app/schedule/page.tsx | 12 +++-- app/schedule/types.ts | 26 ++++++++++ schedule.json | 90 ++++++++++++++++++++++++++++++++++ ui/timetable.tsx | 21 +++++--- 5 files changed, 136 insertions(+), 122 deletions(-) delete mode 100644 app/schedule/events.ts create mode 100644 app/schedule/types.ts create mode 100644 schedule.json diff --git a/app/schedule/events.ts b/app/schedule/events.ts deleted file mode 100644 index c1ff69d..0000000 --- a/app/schedule/events.ts +++ /dev/null @@ -1,109 +0,0 @@ -export interface ScheduleEvent { - name: string, - id: string, - host?: string, - cancelled?: boolean, - description?: string, - slots: TimeSlot[], -} - -export interface ScheduleLocation { - name: string, - id: string, - description?: string, -} - -export interface TimeSlot { - id: string, - start: string, - end: string, - locations: string[], -} - -export const locations: ScheduleLocation[] = [ - { - name: "House", - id: "house", - description: "Blue building east of the camping", - }, - { - name: "Common House", - id: "common-house", - description: "That big red building in the middle", - }, - { - name: "Info Desk", - id: "info-desk", - }, - { - name: "Camping Fireplace", - id: "camping-fireplace", - }, -]; - -export const events: ScheduleEvent[] = [ - { - name: "Arcade", - id: "arcade", - description: "Play retro games!", - slots: [ - { - id: "arcade-1", - start: "2025-07-18T10:00Z", - end: "2025-07-19T01:30Z", - locations: ["house"], - }, - { - id: "arcade-2", - start: "2025-07-19T10:00Z", - end: "2025-07-20T01:00Z", - locations: ["house"], - }, - { - id: "arcade-3", - start: "2025-07-20T10:00Z", - end: "2025-07-20T18:00Z", - locations: ["house"], - }, - ], - }, - { - name: "Bonfire Stories", - description: "Share your stories as we sit cosily around the bonfire.", - id: "bonfire", - slots: [ - { - id: "bonfire-1", - start: "2025-07-19T20:00Z", - end: "2025-07-20T01:00Z", - locations: ["camping-fireplace"], - }, - ], - }, - { - name: "Fursuit Games", - description: "Playful time for the suiters.", - id: "fursuit-games", - slots: [ - { - id: "fursuit-games-1", - start: "2025-07-19T19:00Z", - end: "2025-07-19T20:00Z", - locations: ["common-house"], - }, - ], - }, - { - name: "Late Stragglers", - description: "Wait a minute, why are you still here?.", - id: "too-late", - slots: [ - { - id: "too-late-1", - start: "2025-07-22T20:00Z", - end: "2025-07-23T01:00Z", - locations: ["camping-fireplace"], - }, - ], - }, -]; diff --git a/app/schedule/page.tsx b/app/schedule/page.tsx index 0b38408..828a5c8 100644 --- a/app/schedule/page.tsx +++ b/app/schedule/page.tsx @@ -1,6 +1,7 @@ import Timetable from "@/ui/timetable" import styles from "./page.module.css" -import { ScheduleEvent, events, locations } from "./events" +import { Schedule, ScheduleEvent } from "./types" +import { readFile } from "fs/promises" function EventInfo(props: { event: ScheduleEvent }) { return
@@ -15,19 +16,20 @@ function EventInfo(props: { event: ScheduleEvent }) {
} -export default function schedule() { +export default async function schedule() { + const schedule: Schedule = JSON.parse(await readFile("schedule.json", "utf-8")); return

Schedule & Events

Study carefully, we only hold these events once a year.

Schedule

- +

Events

- {events.map(event => )} + {schedule.events.map(event => )}

Locations

    - {locations.map(location =>
  • + {schedule.locations.map(location =>
  • {location.name}

    {location.description ?? "No description provided"}
  • )} diff --git a/app/schedule/types.ts b/app/schedule/types.ts new file mode 100644 index 0000000..8ec0ddd --- /dev/null +++ b/app/schedule/types.ts @@ -0,0 +1,26 @@ +export interface ScheduleEvent { + name: string, + id: string, + host?: string, + cancelled?: boolean, + description?: string, + slots: TimeSlot[], +} + +export interface ScheduleLocation { + name: string, + id: string, + description?: string, +} + +export interface TimeSlot { + id: string, + start: string, + end: string, + locations: string[], +} + +export interface Schedule { + locations: ScheduleLocation[], + events: ScheduleEvent[], +} diff --git a/schedule.json b/schedule.json new file mode 100644 index 0000000..f936f2b --- /dev/null +++ b/schedule.json @@ -0,0 +1,90 @@ +{ + "locations": [ + { + "name": "House", + "id": "house", + "description": "Blue building east of the camping" + }, + { + "name": "Common House", + "id": "common-house", + "description": "That big red building in the middle" + }, + { + "name": "Info Desk", + "id": "info-desk", + "description": "Found at the entrance" + }, + { + "name": "Camping Fireplace", + "id": "camping-fireplace", + "description": "Next to the big tree" + } + ], + "events": [ + { + "name": "Arcade", + "id": "arcade", + "description": "Play retro games!", + "slots": [ + { + "id": "arcade-1", + "start": "2025-07-18T10:00Z", + "end": "2025-07-19T01:30Z", + "locations": ["house"] + }, + { + "id": "arcade-2", + "start": "2025-07-19T10:00Z", + "end": "2025-07-20T01:00Z", + "locations": ["house"] + }, + { + "id": "arcade-3", + "start": "2025-07-20T10:00Z", + "end": "2025-07-20T18:00Z", + "locations": ["house"] + } + ] + }, + { + "name": "Bonfire Stories", + "description": "Share your stories as we sit cosily around the bonfire.", + "id": "bonfire", + "slots": [ + { + "id": "bonfire-1", + "start": "2025-07-19T20:00Z", + "end": "2025-07-20T01:00Z", + "locations": ["camping-fireplace"] + } + ] + }, + { + "name": "Fursuit Games", + "description": "Playful time for the suiters.", + "id": "fursuit-games", + "slots": [ + { + "id": "fursuit-games-1", + "start": "2025-07-19T19:00Z", + "end": "2025-07-19T20:00Z", + "locations": ["common-house"] + } + ] + }, + { + "name": "Late Stragglers", + "description": "Wait a minute, why are you still here?.", + "id": "too-late", + "slots": [ + { + "id": "too-late-1", + "start": "2025-07-22T20:00Z", + "end": "2025-07-23T01:00Z", + "locations": ["camping-fireplace"] + } + ] + } + ] +} diff --git a/ui/timetable.tsx b/ui/timetable.tsx index 4f94f71..40e4844 100644 --- a/ui/timetable.tsx +++ b/ui/timetable.tsx @@ -1,4 +1,4 @@ -import { ScheduleEvent, TimeSlot, locations } from "@/app/schedule/events"; +import { Schedule, ScheduleEvent, ScheduleLocation, TimeSlot } from "@/app/schedule/types"; import styles from "./timetable.module.css"; const oneDayMs = 24 * 60 * 60 * 1000; @@ -100,7 +100,9 @@ function junctionsFromEdges(edges: Iterable) { return keys.map(key => junctions.get(key)!); } -function* spansFromJunctions(junctions: Iterable): Generator { +function* spansFromJunctions( + junctions: Iterable, locations: ScheduleLocation[] +): Generator { const activeLocations = new Map( locations.map(location => [location.id, new Set()]) ); @@ -211,7 +213,9 @@ function* cutSpansByHours(span: Span): Generator { } } -function tableElementsFromStretches(stretches: Iterable) { +function tableElementsFromStretches( + stretches: Iterable, locations: ScheduleLocation[] +) { type Col = { minutes?: number }; type DayHead = { span: number, content?: string } type HourHead = { span: number, content?: string } @@ -308,17 +312,18 @@ function tableElementsFromStretches(stretches: Iterable) { }; } -export default function Timetable(props: { events: ScheduleEvent[] }) { - const junctions = junctionsFromEdges(edgesFromEvents(props.events)); - const stretches = [...stretchesFromSpans(spansFromJunctions(junctions), oneHourMs * 5)]; +export default function Timetable(props: { schedule: Schedule }) { + const { locations, events } = props.schedule; + const junctions = junctionsFromEdges(edgesFromEvents(events)); + const stretches = [...stretchesFromSpans(spansFromJunctions(junctions, locations), oneHourMs * 5)]; const { columnGroups, dayHeaders, hourHeaders, locationRows, - } = tableElementsFromStretches(stretches); + } = tableElementsFromStretches(stretches, locations); const eventBySlotId = new Map( - props.events.flatMap( + events.flatMap( event => event.slots.map(slot => [slot.id, event]) ) );