Store a list of ids of events and slots that accounts have marked as being interested in, and show aggeregate counts in the schedule.
87 lines
2.2 KiB
Vue
87 lines
2.2 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">
|
|
{{ slot.start }} - {{ 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 type { ScheduleEvent } from '~/shared/types/schedule';
|
|
|
|
defineProps<{
|
|
event: ScheduleEvent
|
|
}>()
|
|
|
|
const { data: session, refresh: refreshSession } = useAccountSession();
|
|
const interestedIds = computed(() => new Set(session.value?.account.interestedIds ?? []));
|
|
|
|
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>
|