diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2025-08-14 18:07:12 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2025-08-14 18:07:12 +0100 |
| commit | 4697556cac819c47d068819b9fc9c3b4ea84e279 (patch) | |
| tree | b832d8fc6b643a8b9d0eeca35c1268e1649da731 /web/stores/schedule.ts | |
| parent | dd49c9205bb04844b686b9c3396c40eb49d25826 (diff) | |
Merge confplanner-web and replace fiber with native net/http
Diffstat (limited to 'web/stores/schedule.ts')
| -rw-r--r-- | web/stores/schedule.ts | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/web/stores/schedule.ts b/web/stores/schedule.ts new file mode 100644 index 0000000..d5f4b4c --- /dev/null +++ b/web/stores/schedule.ts @@ -0,0 +1,168 @@ +import { TZDate } from "@date-fns/tz"; +import { addDays } from "date-fns"; +import { defineStore } from "pinia"; + +interface Schedule { + conference: Conference; + tracks: Track[]; + days: Day[]; +} + +interface Conference { + title: string; + venue: string; + city: string; + start: Date; + end: Date; + days: number; + dayChange: string; + timeslotDuration: string; + baseUrl: string; + timeZoneName: string; +} + +interface Track { + name: string; + slug: string; +} + +interface Day { + date: string; + start: Date; + end: Date; + rooms: Room[]; +} + +interface Room { + name: string; + events: Event[]; +} + +export interface Event { + id: number; + guid: string; + date: string; + start: Date; + end: Date; + duration: string; + room: string; + url: string; + track: Track; + type: string; + title: string; + abstract: string; + persons: Person[]; + attachments: Attachment[]; + links: Link[]; +} + +interface Person { + id: number; + name: string; +} + +interface Attachment { + type: string; + href: string; + name: string; +} + +interface Link { + href: string; + name: string; +} + +export const useScheduleStore = defineStore('schedule', () => { + const schedule = ref(null as Schedule | null) + + const events = ref([] as Event[]) + const eventsPerDay = ref({} as { [key: string]: Event[] }) + const eventsPerTrack = ref({} as { [key: string]: Event[] }) + + const tracks = ref({} as { [key: string]: Track }) + + const setSchedule = (newSchedule: Schedule) => { + tracks.value = {} + newSchedule.tracks.forEach(track => { + track.slug = convertToSlug(track.name) + tracks.value[track.name] = track + }); + + newSchedule.conference.start = new TZDate(newSchedule.conference.start, newSchedule.conference.timeZoneName) + newSchedule.conference.end = addDays(new TZDate(newSchedule.conference.end, newSchedule.conference.timeZoneName), 1) + + events.value = [] + newSchedule.days.forEach(day => { + day.start = new TZDate(day.start, newSchedule.conference.timeZoneName) + day.end = new TZDate(day.end, newSchedule.conference.timeZoneName) + day.rooms.forEach(room => { + room.events.forEach(event => { + normalizeDates(event, newSchedule.conference.timeZoneName) + + events.value.push(event) + + event.track = tracks.value[event.track as unknown as string] + }) + }) + }) + events.value.sort((a, b) => { + return a.start.getTime() - b.start.getTime() + }) + + schedule.value = newSchedule + + eventsPerDay.value = {} + events.value.forEach(event => { + const date = event.date.split('T')[0] + if (!eventsPerDay.value[date]) { + eventsPerDay.value[date] = [] + } + eventsPerDay.value[date].push(event) + }) + + eventsPerTrack.value = {} + events.value.forEach(event => { + if (!eventsPerTrack.value[event.track.name]) { + eventsPerTrack.value[event.track.name] = [] + } + eventsPerTrack.value[event.track.name].push(event) + }); + } + + const isConferenceOngoing = () => { + if (!schedule.value) { + return false + } + return new Date() >= schedule.value.conference.start && new Date() < schedule.value.conference.end + } + + const isConferenceFinished = () => { + if (!schedule.value) { + return false + } + return new Date() > schedule.value.conference.end + } + + const getStartDate = () => { + return schedule.value?.conference.start || 0 + } + + return {schedule, events, eventsPerDay, eventsPerTrack, setSchedule, isConferenceOngoing, isConferenceFinished, getStartDate} +}) + +function normalizeDates(event: Event, timeZone: string) { + event.start = new TZDate(event.start, timeZone) + event.end = new TZDate(event.end, timeZone) +} + +function parseDuration(duration: string) { + const [hours, minutes] = duration.split(':').map(Number) + return hours * 60 * 60 * 1000 + minutes * 60 * 1000 +} + +function convertToSlug(text: string) { + return text + .toLowerCase() + .replace(/ /g, '-') + .replace(/[^\w-]+/g, '') +}
\ No newline at end of file |
