diff --git a/frontend/src/pages/Volunteers.svelte b/frontend/src/pages/Volunteers.svelte
index e26ee6a..c8521e1 100644
--- a/frontend/src/pages/Volunteers.svelte
+++ b/frontend/src/pages/Volunteers.svelte
@@ -18,6 +18,12 @@
let newIsLead = $state(false)
let newNote = $state('')
+ let editID = $state(null)
+ let editDeptID = $state('')
+ let editIsLead = $state(false)
+ let editNote = $state('')
+ let saving = $state(false)
+
const role = $derived(session?.user?.role ?? '')
const canManage = $derived(['admin', 'ticketing', 'staffing', 'colead'].includes(role))
const canConfirm = $derived(['admin', 'staffing', 'colead'].includes(role))
@@ -100,15 +106,6 @@
}
}
- async function toggleLead(v) {
- try {
- const updated = await api.volunteers.update(v.id, { ...v, is_lead: !v.is_lead })
- await db.volunteers.put(updated)
- } catch (err) {
- error = err.message
- }
- }
-
async function deleteVolunteer(v) {
if (!confirm(`Delete volunteer "${v.name}"?`)) return
try {
@@ -119,6 +116,36 @@
}
}
+ function startEdit(v) {
+ editID = v.id
+ editDeptID = v.department_id ? String(v.department_id) : ''
+ editIsLead = v.is_lead
+ editNote = v.note ?? ''
+ }
+
+ function cancelEdit() {
+ editID = null
+ }
+
+ async function saveVolunteer(v) {
+ saving = true
+ error = ''
+ try {
+ const updated = await api.volunteers.update(v.id, {
+ ...v,
+ department_id: editDeptID ? parseInt(editDeptID) : null,
+ is_lead: editIsLead,
+ note: editNote,
+ })
+ await db.volunteers.put(updated)
+ editID = null
+ } catch (err) {
+ error = err.message
+ } finally {
+ saving = false
+ }
+ }
+
function deptFor(id) {
return ($allDepts ?? []).find(d => d.id === id)
}
@@ -231,66 +258,96 @@
{#each filtered as v (v.id)}
{@const dept = deptFor(v.department_id)}
- {@const participant = participantFor(v.participant_id)}
-
- |
- {v.name}
- {#if v.is_lead}
- Co-Lead
- {/if}
- {#if !v.participant_id}
- No ticket
- {:else if !participantHasTickets(v.participant_id)}
- No ticket
- {/if}
- {#if v.email}
- {v.email}
- {/if}
- {#if v.note}
- {v.note}
- {/if}
- |
-
- {#if dept}
- {dept.name}
- {:else}
- —
- {/if}
- |
-
- {#if v.checked_in}
- Ready
- {:else if v.confirmed}
- Confirmed
- {:else if v.email_confirmed}
- Registered
- {:else}
- Unconfirmed
- {/if}
- {#if v.checked_in_at}
-
- {new Date(v.checked_in_at).toLocaleTimeString()}
-
- {/if}
- |
-
- {#if !v.checked_in}
- checkIn(v)} />
- {/if}
- |
- {#if canManage}
-
- {#if canConfirm && v.email_confirmed && !v.confirmed && v.department_id}
-
- {/if}
-
-
+ {#if editID === v.id}
+ |
+ |
+ {v.name}
+ {#if v.email} {v.email} {/if}
|
- {/if}
-
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+ {:else}
+
+ |
+ {v.name}
+ {#if v.is_lead}
+ Co-Lead
+ {/if}
+ {#if !v.participant_id}
+ No ticket
+ {:else if !participantHasTickets(v.participant_id)}
+ No ticket
+ {/if}
+ {#if v.ticket_name && v.ticket_name !== v.name}
+ Ticket: {v.ticket_name}
+ {/if}
+ {#if v.email}
+ {v.email}
+ {/if}
+ {#if v.note}
+ {v.note}
+ {/if}
+ |
+
+ {#if dept}
+ {dept.name}
+ {:else}
+ —
+ {/if}
+ |
+
+ {#if v.checked_in}
+ Ready
+ {:else if v.confirmed}
+ Confirmed
+ {:else if v.email_confirmed}
+ Registered
+ {:else}
+ Unconfirmed
+ {/if}
+ {#if v.checked_in_at}
+
+ {new Date(v.checked_in_at).toLocaleTimeString()}
+
+ {/if}
+ |
+
+ {#if !v.checked_in}
+ checkIn(v)} />
+ {/if}
+ |
+ {#if canManage}
+
+ {#if canConfirm && v.email_confirmed && !v.confirmed}
+
+ {/if}
+
+
+ |
+ {/if}
+
+ {/if}
{/each}
@@ -305,5 +362,7 @@
.td-dept { width: 100%; order: 3; }
.td-status { width: 100%; order: 4; }
.td-actions { width: 100%; order: 5; display: flex; justify-content: flex-end; }
+ .edit-row td { width: 100%; }
+ .td-edit-dept, .td-edit-checks, .td-edit-note { width: 100%; }
}