diff options
Diffstat (limited to 'stores')
| -rw-r--r-- | stores/error.ts | 14 | ||||
| -rw-r--r-- | stores/favourites.ts | 43 | ||||
| -rw-r--r-- | stores/schedule.ts | 146 | ||||
| -rw-r--r-- | stores/selected-event.ts | 14 |
4 files changed, 217 insertions, 0 deletions
diff --git a/stores/error.ts b/stores/error.ts new file mode 100644 index 0000000..19ff289 --- /dev/null +++ b/stores/error.ts @@ -0,0 +1,14 @@ +import { type Event } from "./schedule"; +import { defineStore } from "pinia"; + +export const useErrorStore = defineStore('error', () => { + const error = ref(null as Event | null) + const setError = (event: Event) => { + error.value = event + } + const clearError = () => { + error.value = null + } + + return {error, setError, clearError} +}) diff --git a/stores/favourites.ts b/stores/favourites.ts new file mode 100644 index 0000000..2bf7257 --- /dev/null +++ b/stores/favourites.ts @@ -0,0 +1,43 @@ +import { defineStore } from "pinia"; +import { type Event } from "./schedule"; + +interface Favourite { + id: number; + eventGuid?: string; + eventId?: number; +} + +export const useFavouritesStore = defineStore('favourites', () => { + const favourites = ref([] as Favourite[]) + const status = ref('idle' as 'idle' | 'pending') + + const setFavourites = (newFavourites: Favourite[]) => { + favourites.value = newFavourites + } + const addFavourite = (favourite: Favourite) => { + favourites.value.push(favourite) + } + const removeFavourite = (favourite: { eventGuid?: string, eventId?: number }) => { + if (favourite.eventGuid) { + favourites.value = favourites.value.filter(f => f.eventGuid !== favourite.eventGuid) + } + if (favourite.eventId) { + favourites.value = favourites.value.filter(f => f.eventId !== favourite.eventId) + } + } + const isFavourite = (event: Event) => { + return favourites.value.some(f => { + if (f.eventGuid) { + return f.eventGuid === event.guid + } else if (f.eventId) { + return f.eventId === event.id + } + }) + } + + const setStatus = (newStatus: 'idle' | 'pending') => { + status.value = newStatus + } + + return {favourites, status, setFavourites, addFavourite, removeFavourite, isFavourite, setStatus} +}) diff --git a/stores/schedule.ts b/stores/schedule.ts new file mode 100644 index 0000000..5d5014c --- /dev/null +++ b/stores/schedule.ts @@ -0,0 +1,146 @@ +import { TZDate } from "@date-fns/tz"; +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) => { + schedule.value = newSchedule + + tracks.value = {} + schedule.value.tracks.forEach(track => { + track.slug = convertToSlug(track.name) + tracks.value[track.name] = track + }); + + events.value = [] + schedule.value.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() + }) + + 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) + }); + } + + return {schedule, events, eventsPerDay, eventsPerTrack, setSchedule} +}) + +function normalizeDates(event: Event, timeZone: string) { + event.start = new TZDate(event.date, timeZone) + event.end = new TZDate(event.start.getTime() + parseDuration(event.duration), 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 diff --git a/stores/selected-event.ts b/stores/selected-event.ts new file mode 100644 index 0000000..88e3a00 --- /dev/null +++ b/stores/selected-event.ts @@ -0,0 +1,14 @@ +import { type Event } from "./schedule"; +import { defineStore } from "pinia"; + +export const useSelectedEventStore = defineStore('selected-event', () => { + const selectedEvent = ref(null as Event | null) + const setSelectedEvent = (event: Event) => { + selectedEvent.value = event + } + const clearSelectedEvent = () => { + selectedEvent.value = null + } + + return {selectedEvent, setSelectedEvent, clearSelectedEvent} +}) |
