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.
This commit is contained in:
Hornwitser 2025-09-06 19:25:20 +02:00
parent adeef4f629
commit 5898a46a1b
5 changed files with 70 additions and 2 deletions

View file

@ -8,6 +8,14 @@
<p v-if=event.host> <p v-if=event.host>
Host: {{ event.host }} Host: {{ event.host }}
</p> </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 class="preWrap">{{ event.description ?? "No description provided" }}</p>
<p v-if="event.interested"> <p v-if="event.interested">
{{ event.interested }} interested {{ event.interested }} interested
@ -79,6 +87,22 @@ async function toggle(type: "event" | "slot", id: number, slotIds?: number[]) {
margin-block-start: 0.5rem; 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 { button {
padding-inline: 0.2em; padding-inline: 0.2em;
} }

View file

@ -13,6 +13,14 @@
<p v-if=event?.host> <p v-if=event?.host>
Host: {{ event.host }} Host: {{ event.host }}
</p> </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 class="preWrap">{{ event?.description ?? "No description provided" }}</p>
<p v-if="locations.length"> <p v-if="locations.length">
At {{ locations.map(location => location?.name ?? "unknown").join(" + ") }} At {{ locations.map(location => location?.name ?? "unknown").join(" + ") }}
@ -62,6 +70,22 @@ function formatTime(time: DateTime) {
margin-block-start: 0.5rem; 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 { button {
padding-inline: 0.2em; padding-inline: 0.2em;
} }

View file

@ -10,6 +10,7 @@
<th>id</th> <th>id</th>
<th>name</th> <th>name</th>
<th>host</th> <th>host</th>
<th>notice</th>
<th>description</th> <th>description</th>
<th>p</th> <th>p</th>
<th>s</th> <th>s</th>
@ -38,6 +39,13 @@
v-model="event.host" v-model="event.host"
> >
</td> </td>
<td>
<textarea
rows="1"
:disabled="!canEdit(event)"
v-model="event.notice"
/>
</td>
<td> <td>
<textarea <textarea
rows="1" rows="1"
@ -81,6 +89,12 @@
v-model="newEventHost" v-model="newEventHost"
> >
</td> </td>
<td>
<textarea
rows="1"
v-model="newEventNotice"
/>
</td>
<td> <td>
<textarea <textarea
rows="1" rows="1"
@ -116,6 +130,7 @@
<td>{{ event.id }}</td> <td>{{ event.id }}</td>
<td>{{ event.name }}</td> <td>{{ event.name }}</td>
<td>{{ event.host }}</td> <td>{{ event.host }}</td>
<td class="preWrap">{{ event.notice }}</td>
<td class="preWrap">{{ event.description }}</td> <td class="preWrap">{{ event.description }}</td>
<td>{{ event.crew ? "" : "Yes"}}</td> <td>{{ event.crew ? "" : "Yes"}}</td>
<td>{{ event.slots.size ? event.slots.size : "" }}</td> <td>{{ event.slots.size ? event.slots.size : "" }}</td>
@ -143,6 +158,7 @@ function canEdit(event: ClientScheduleEvent) {
const newEventName = ref(""); const newEventName = ref("");
const newEventHost = ref(""); const newEventHost = ref("");
const newEventNotice = ref("");
const newEventDescription = ref(""); const newEventDescription = ref("");
const newEventPublic = ref(false); const newEventPublic = ref(false);
function eventExists(name: string) { function eventExists(name: string) {
@ -165,7 +181,7 @@ function newEvent() {
!newEventPublic.value, !newEventPublic.value,
newEventHost.value, newEventHost.value,
false, false,
"", newEventNotice.value,
newEventDescription.value, newEventDescription.value,
0, 0,
new Set(), new Set(),
@ -174,6 +190,7 @@ function newEvent() {
schedule.value.events.add(event); schedule.value.events.add(event);
newEventName.value = ""; newEventName.value = "";
newEventHost.value = ""; newEventHost.value = "";
newEventNotice.value = "";
newEventDescription.value = ""; newEventDescription.value = "";
newEventPublic.value = false; newEventPublic.value = false;
} }

View file

@ -105,6 +105,7 @@
:class='{"event": cell.slot, "crew": cell.event?.crew }' :class='{"event": cell.slot, "crew": cell.event?.crew }'
:title="cell.event?.name" :title="cell.event?.name"
> >
{{ cell.event?.notice ? "⚠️" : undefined }}
{{ cell.event?.name }} {{ cell.event?.name }}
</td> </td>
</tr> </tr>

View file

@ -43,6 +43,7 @@ let eventId = 1;
const events = [ const events = [
{ {
name: "Arcade", name: "Arcade",
notice: "No food or drinks allowed!\n\nClosed drinking containers are okay.",
description: "Play retro games!\n\nWe have anything from C64 to PS5.", description: "Play retro games!\n\nWe have anything from C64 to PS5.",
slots: [ slots: [
"d1 12:00 4h clubhouse", "d1 12:00 4h clubhouse",
@ -339,10 +340,11 @@ export function generateDemoSchedule(): ApiSchedule {
id: 111, id: 111,
updatedAt: toIso(toDate(origin, "d-2", "10:01")), updatedAt: toIso(toDate(origin, "d-2", "10:01")),
events: events.map( events: events.map(
({ id, name, crew, description, slots }) => ({ ({ id, name, crew, notice, description, slots }) => ({
id, id,
name, name,
crew, crew,
notice,
description, description,
interested: eventCounts.get(id), interested: eventCounts.get(id),
slots: slots.map(shorthand => toSlot(origin, shorthand, slotCounts, eventSlotIdToAssigned)), slots: slots.map(shorthand => toSlot(origin, shorthand, slotCounts, eventSlotIdToAssigned)),