owltide/components/EventCard.vue

100 lines
2.7 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>
<p v-if="slot.assigned">
Crew:
{{ slot.assigned.map(id => idToAccount.get(id)?.name).join(", ") }}
</p>
</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);
const { data: accounts } = await useAccounts();
const idToAccount = computed(() => new Map(accounts.value?.map(a => [a.id, a])));
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>