owltide/components/CardEvent.vue
Hornwitser 5898a46a1b Add UI to edit and display event notices
Add a warning like display of event notices to the event card and the
event slot card and indicate in the timesheet that an event has a
notice.  Also includes the input controls needed to edit the notice.
2025-09-06 23:54:42 +02:00

112 lines
2.8 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<section class="event">
<h3>{{ event.name }}</h3>
<p v-if=event.host>
Host: {{ event.host }}
</p>
<div v-if="event.notice" class="notice preWrap">
<div class="noticeIcon">
</div>
<p>
{{ event.notice }}
</p>
</div>
<p class="preWrap">{{ event.description ?? "No description provided" }}</p>
<p v-if="event.interested">
{{ event.interested }} interested
</p>
<p v-if="accountStore.valid">
<button
class="interested"
:class="{ active: accountStore.interestedEventIds.has(event.id) }"
@click="toggle('event', event.id, [...event.slots.keys()])"
>
{{ accountStore.interestedEventIds.has(event.id) ? "✔ interested" : "🔔 interested?" }}
</button>
</p>
<h4>Timeslots</h4>
<ul>
<li v-for="slot in event.slots.values()" :key="slot.id">
{{ formatTime(slot.start) }} - {{ formatTime(slot.end) }}
<button
v-if="accountStore.valid && event.slots.size > 1"
class="interested"
:disabled="accountStore.interestedEventIds.has(event.id)"
:class="{ active: accountStore.interestedEventIds.has(event.id) || accountStore.interestedEventSlotIds.has(slot.id) }"
@click="toggle('slot', slot.id)"
>
{{ accountStore.interestedEventIds.has(event.id) || accountStore.interestedEventSlotIds.has(slot.id) ? "✔ interested" : "🔔 interested?" }}
</button>
<template v-if="slot.interested">
({{ slot.interested }} interested)
</template>
<p v-if="slot.assigned.size">
Crew:
{{ [...slot.assigned].map(id => usersStore.users.get(id)?.name).join(", ") }}
</p>
</li>
</ul>
</section>
</template>
<script lang="ts" setup>
import { DateTime } from '~/shared/utils/luxon';
defineProps<{
event: ClientScheduleEvent
}>()
const accountStore = useAccountStore();
const usersStore = useUsersStore();
function formatTime(time: DateTime) {
return time.toFormat("yyyy-LL-dd HH:mm");
}
async function toggle(type: "event" | "slot", id: number, slotIds?: number[]) {
await accountStore.toggleInterestedId(type, id, slotIds);
}
</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;
}
.notice {
display: flex;
width: fit-content;
gap: 0.5rem;
padding: 0.5rem;
margin-block: 0.5rem;
border-radius: 0.25rem;
border: 1px solid color-mix(in oklab, CanvasText, orange 50%);
background-color: color-mix(in oklab, Canvas, orange 40%);
}
.noticeIcon {
flex: 0 0 auto;
align-self: center;
font-size: 1rem;
}
button {
padding-inline: 0.2em;
}
button.active {
color: color-mix(in oklab, var(--foreground), green 50%);
}
</style>