Use the timezone configured on the account, or the default timezone if no timezone is confirude to display the timetable and events in local time.
94 lines
2.5 KiB
Vue
94 lines
2.5 KiB
Vue
<template>
|
|
<section class="event">
|
|
<h3>{{ event.name }}</h3>
|
|
<p>{{ event.description ?? "No description provided" }}</p>
|
|
<p v-if="event.interested">
|
|
{{ event.interested }} interested
|
|
</p>
|
|
<p v-if="session">
|
|
<button
|
|
class="interested"
|
|
:class="{ active: interestedIds.has(event.id) }"
|
|
@click="toggle(event.id, event.slots.map(slot => slot.id))"
|
|
>
|
|
{{ interestedIds.has(event.id) ? "✔ interested" : "🔔 interested?" }}
|
|
</button>
|
|
</p>
|
|
|
|
<h4>Timeslots</h4>
|
|
<ul>
|
|
<li v-for="slot in event.slots" :key="slot.id">
|
|
{{ formatTime(slot.start) }} - {{ formatTime(slot.end) }}
|
|
<button
|
|
v-if="session && event.slots.length > 1"
|
|
class="interested"
|
|
:disabled="interestedIds.has(event.id)"
|
|
:class="{ active: interestedIds.has(event.id) || interestedIds.has(slot.id) }"
|
|
@click="toggle(slot.id)"
|
|
>
|
|
{{ interestedIds.has(event.id) || interestedIds.has(slot.id) ? "✔ interested" : "🔔 interested?" }}
|
|
</button>
|
|
<template v-if="slot.interested">
|
|
({{ slot.interested }} interested)
|
|
</template>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { DateTime } from 'luxon';
|
|
import type { ScheduleEvent } from '~/shared/types/schedule';
|
|
|
|
defineProps<{
|
|
event: ScheduleEvent
|
|
}>()
|
|
|
|
const runtimeConfig = useRuntimeConfig();
|
|
const { data: session, refresh: refreshSession } = await useAccountSession();
|
|
const interestedIds = computed(() => new Set(session.value?.account.interestedIds ?? []));
|
|
const timezone = computed(() => session.value?.account.timezone ?? runtimeConfig.public.defaultTimezone);
|
|
|
|
function formatTime(time: string) {
|
|
return DateTime.fromISO(time, { zone: timezone.value }).toFormat("yyyy-LL-dd HH:mm");
|
|
}
|
|
|
|
async function toggle(id: string, slotIds?: string[]) {
|
|
let newIds = [...session.value!.account.interestedIds ?? []];
|
|
if (interestedIds.value.has(id)) {
|
|
newIds = newIds.filter(newId => newId !== id);
|
|
} else {
|
|
newIds.push(id);
|
|
if (slotIds) {
|
|
const filterIds = new Set(slotIds);
|
|
newIds = newIds.filter(newId => !filterIds.has(newId));
|
|
}
|
|
}
|
|
await $fetch("/api/account", {
|
|
method: "PATCH",
|
|
body: { interestedIds: newIds },
|
|
})
|
|
await refreshSession();
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.event {
|
|
background: color-mix(in oklab, var(--background), grey 20%);
|
|
padding: 0.5rem;
|
|
border-radius: 0.5rem;
|
|
}
|
|
.event h3 {
|
|
margin: 0;
|
|
}
|
|
.event + .event {
|
|
margin-block-start: 0.5rem;
|
|
}
|
|
|
|
button {
|
|
padding-inline: 0.2em;
|
|
}
|
|
button.active {
|
|
color: color-mix(in oklab, var(--foreground), green 50%);
|
|
}
|
|
</style>
|