Skip to content

Commit 6d5644d

Browse files
committed
fix(events): UI improvements for event management
- Toggle Add Event button to Cancel (red) when creating new event - Remove redundant X cancel button from inline row - Reduce table cell padding (p-3 → p-2) for compact layout - Toggle expanded roster on row click (click again to collapse) - Clear checkInCode when Open is unchecked to prevent stale codes - Use $state for DOM element references (Svelte 5 pattern)
1 parent 16ca5d5 commit 6d5644d

File tree

1 file changed

+48
-41
lines changed

1 file changed

+48
-41
lines changed

src/routes/admin/events/+page.svelte

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@
255255
256256
// Inline event creation state
257257
let isAddingEvent = $state(false);
258-
let tableContainer: HTMLDivElement;
258+
let tableContainer = $state<HTMLDivElement | null>(null);
259259
// svelte-ignore state_referenced_locally
260260
let newEvent = $state({
261261
name: '',
@@ -283,12 +283,15 @@
283283
}
284284
});
285285
286-
// Auto-generate check-in code when isPublic is checked
286+
// Auto-generate check-in code when isPublic is checked, clear when unchecked
287287
let prevNewEventIsPublic = $state(false);
288288
$effect(() => {
289289
if (newEvent.isPublic && !prevNewEventIsPublic) {
290290
newEvent.checkInCode = generateCheckInCode();
291291
}
292+
else if (!newEvent.isPublic && prevNewEventIsPublic) {
293+
newEvent.checkInCode = '';
294+
}
292295
prevNewEventIsPublic = newEvent.isPublic;
293296
});
294297
@@ -329,12 +332,15 @@
329332
}
330333
});
331334
332-
// Auto-generate check-in code when isPublic is checked (only if no existing code)
335+
// Auto-generate check-in code when isPublic is checked (only if no existing code), clear when unchecked
333336
let prevEditEventIsPublic = $state(false);
334337
$effect(() => {
335338
if (editEvent.isPublic && !prevEditEventIsPublic && !editEvent.checkInCode) {
336339
editEvent.checkInCode = generateCheckInCode();
337340
}
341+
else if (!editEvent.isPublic && prevEditEventIsPublic) {
342+
editEvent.checkInCode = '';
343+
}
338344
prevEditEventIsPublic = editEvent.isPublic;
339345
});
340346
@@ -436,8 +442,10 @@
436442
}
437443
438444
async function toggleEventRow(eventId: string, eventDateTime: string) {
439-
// If same row clicked, do nothing (don't collapse)
445+
// If same row clicked, collapse it
440446
if (expandedEventId === eventId) {
447+
expandedEventId = null;
448+
rosterData = [];
441449
return;
442450
}
443451
@@ -943,18 +951,26 @@
943951
Hide past events
944952
</label>
945953
</div>
946-
<button
947-
onclick={async () => {
948-
newEvent.date = getTodayDate();
949-
isAddingEvent = true;
950-
await tick();
951-
tableContainer?.scrollTo({ top: 0, behavior: 'smooth' });
952-
}}
953-
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
954-
disabled={isAddingEvent}
955-
>
956-
+ Add Event
957-
</button>
954+
{#if isAddingEvent}
955+
<button
956+
onclick={cancelAddEvent}
957+
class="bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700"
958+
>
959+
Cancel
960+
</button>
961+
{:else}
962+
<button
963+
onclick={async () => {
964+
newEvent.date = getTodayDate();
965+
isAddingEvent = true;
966+
await tick();
967+
tableContainer?.scrollTo({ top: 0, behavior: 'smooth' });
968+
}}
969+
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
970+
>
971+
+ Add Event
972+
</button>
973+
{/if}
958974
</div>
959975

960976
{#if markedForDelete.size > 0}
@@ -989,7 +1005,7 @@
9891005
<table class="w-full border-collapse">
9901006
<thead class="sticky top-0 z-10">
9911007
<tr class="bg-gray-100 text-left">
992-
<th class="p-3 border-b font-semibold">
1008+
<th class="p-2 border-b font-semibold">
9931009
<button
9941010
onclick={() => toggleSort('name')}
9951011
class="inline-flex items-center gap-1 hover:text-blue-600"
@@ -1010,7 +1026,7 @@
10101026
{/if}
10111027
</button>
10121028
</th>
1013-
<th class="p-3 border-b font-semibold">
1029+
<th class="p-2 border-b font-semibold">
10141030
<button
10151031
onclick={() => toggleSort('dateTime')}
10161032
class="inline-flex items-center gap-1 hover:text-blue-600"
@@ -1031,7 +1047,7 @@
10311047
{/if}
10321048
</button>
10331049
</th>
1034-
<th class="p-3 border-b font-semibold">
1050+
<th class="p-2 border-b font-semibold">
10351051
<button
10361052
onclick={() => toggleSort('eventType')}
10371053
class="inline-flex items-center gap-1 hover:text-blue-600"
@@ -1052,7 +1068,7 @@
10521068
{/if}
10531069
</button>
10541070
</th>
1055-
<th class="p-3 border-b font-semibold w-32">
1071+
<th class="p-2 border-b font-semibold w-32">
10561072
<button
10571073
onclick={() => toggleSort('cohort')}
10581074
class="inline-flex items-center gap-1 hover:text-blue-600"
@@ -1073,7 +1089,7 @@
10731089
{/if}
10741090
</button>
10751091
</th>
1076-
<th class="p-3 border-b font-semibold">
1092+
<th class="p-2 border-b font-semibold">
10771093
<button
10781094
onclick={() => toggleSort('attendance')}
10791095
class="inline-flex items-center gap-1 hover:text-blue-600"
@@ -1094,9 +1110,9 @@
10941110
{/if}
10951111
</button>
10961112
</th>
1097-
<th class="p-3 border-b font-semibold">Code</th>
1098-
<th class="p-3 border-b font-semibold">Survey</th>
1099-
<th class="p-3 border-b font-semibold w-16"></th>
1113+
<th class="p-2 border-b font-semibold">Code</th>
1114+
<th class="p-2 border-b font-semibold">Survey</th>
1115+
<th class="p-2 border-b font-semibold w-16"></th>
11001116
</tr>
11011117
</thead>
11021118
<tbody>
@@ -1254,15 +1270,6 @@
12541270
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
12551271
</svg>
12561272
</button>
1257-
<button
1258-
onclick={cancelAddEvent}
1259-
class="text-red-600 hover:text-red-800"
1260-
title="Cancel"
1261-
>
1262-
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
1263-
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
1264-
</svg>
1265-
</button>
12661273
</div>
12671274
</td>
12681275
</tr>
@@ -1491,7 +1498,7 @@
14911498
if (hasRoster) toggleEventRow(event.id, event.dateTime);
14921499
}}
14931500
>
1494-
<td class="p-3">
1501+
<td class="p-2">
14951502
<span class="inline-flex items-center gap-2">
14961503
{#if hasRoster}
14971504
<svg
@@ -1509,13 +1516,13 @@
15091516
{event.name || '(Untitled)'}
15101517
</span>
15111518
</td>
1512-
<td class="p-3">
1519+
<td class="p-2">
15131520
<div>{formatDateOnly(event.dateTime)}</div>
15141521
<div class="text-gray-500 text-sm">
15151522
{formatTimeOnly(event.dateTime)}{#if event.endDateTime}&nbsp;–&nbsp;{formatTimeOnly(event.endDateTime)}{/if}
15161523
</div>
15171524
</td>
1518-
<td class="p-3">
1525+
<td class="p-2">
15191526
{#if event.eventType}
15201527
<span class="{EVENT_TYPE_COLORS[event.eventType].tailwind} font-medium">
15211528
{event.eventType}
@@ -1524,7 +1531,7 @@
15241531
<span class="text-gray-400">—</span>
15251532
{/if}
15261533
</td>
1527-
<td class="p-3 w-32">
1534+
<td class="p-2 w-32">
15281535
{#if event.isPublic || event.cohortIds.length > 0}
15291536
{@const cohortNames = getCohortNames(event.cohortIds).join(', ')}
15301537
{@const displayText = event.isPublic ? (cohortNames ? `Open, ${cohortNames}` : 'Open') : cohortNames}
@@ -1535,21 +1542,21 @@
15351542
<span class="text-gray-400">—</span>
15361543
{/if}
15371544
</td>
1538-
<td class="p-3">
1545+
<td class="p-2">
15391546
{#if expectedAttendance !== null}
15401547
<span class="font-mono text-sm">{event.attendanceCount ?? 0}/{expectedAttendance}</span>
15411548
{:else}
15421549
<span class="text-gray-400">{event.attendanceCount ?? 0}</span>
15431550
{/if}
15441551
</td>
1545-
<td class="p-3">
1552+
<td class="p-2">
15461553
{#if event.checkInCode}
15471554
<span class="font-mono text-sm">{event.checkInCode}</span>
15481555
{:else}
15491556
<span class="text-gray-400">—</span>
15501557
{/if}
15511558
</td>
1552-
<td class="p-3">
1559+
<td class="p-2">
15531560
{#if event.surveyUrl}
15541561
<a
15551562
href={event.surveyUrl /* eslint-disable-line svelte/no-navigation-without-resolve -- external URL */}
@@ -1573,7 +1580,7 @@
15731580
</span>
15741581
{/if}
15751582
</td>
1576-
<td class="p-3">
1583+
<td class="p-2">
15771584
<div class="flex gap-1">
15781585
<button
15791586
onclick={(e) => {

0 commit comments

Comments
 (0)