Added Volunteer edit.
This commit is contained in:
parent
3eec81af7f
commit
ab3d9a0409
1 changed files with 127 additions and 68 deletions
|
|
@ -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 @@
|
|||
<tbody>
|
||||
{#each filtered as v (v.id)}
|
||||
{@const dept = deptFor(v.department_id)}
|
||||
{@const participant = participantFor(v.participant_id)}
|
||||
<tr>
|
||||
<td class="td-name">
|
||||
<strong>{v.name}</strong>
|
||||
{#if v.is_lead}
|
||||
<span class="badge badge-lead" style="margin-left:0.4rem">Co-Lead</span>
|
||||
{/if}
|
||||
{#if !v.participant_id}
|
||||
<span class="badge badge-unchecked" style="margin-left:0.4rem" title="Not linked to a participant">No ticket</span>
|
||||
{:else if !participantHasTickets(v.participant_id)}
|
||||
<span class="badge badge-partial" style="margin-left:0.4rem" title="Registered as volunteer but no ticket on file">No ticket</span>
|
||||
{/if}
|
||||
{#if v.email}
|
||||
<div class="text-muted" style="font-size:0.78rem">{v.email}</div>
|
||||
{/if}
|
||||
{#if v.note}
|
||||
<div class="text-muted" style="font-size:0.78rem">{v.note}</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-dept text-muted">
|
||||
{#if dept}
|
||||
<span class="dept-dot" style="background:{dept.color};margin-right:0.4rem"></span>{dept.name}
|
||||
{:else}
|
||||
—
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-status">
|
||||
{#if v.checked_in}
|
||||
<span class="badge badge-checked">Ready</span>
|
||||
{:else if v.confirmed}
|
||||
<span class="badge badge-confirmed">Confirmed</span>
|
||||
{:else if v.email_confirmed}
|
||||
<span class="badge badge-registered">Registered</span>
|
||||
{:else}
|
||||
<span class="badge badge-unchecked">Unconfirmed</span>
|
||||
{/if}
|
||||
{#if v.checked_in_at}
|
||||
<div class="text-muted" style="font-size:0.75rem">
|
||||
{new Date(v.checked_in_at).toLocaleTimeString()}
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-ready">
|
||||
{#if !v.checked_in}
|
||||
<CheckInButton onclick={() => checkIn(v)} />
|
||||
{/if}
|
||||
</td>
|
||||
{#if canManage}
|
||||
<td class="td-actions">
|
||||
{#if canConfirm && v.email_confirmed && !v.confirmed && v.department_id}
|
||||
<button class="btn btn-primary btn-sm" onclick={() => confirmVolunteer(v)}>Confirm</button>
|
||||
{/if}
|
||||
<button class="btn btn-ghost btn-sm" onclick={() => toggleLead(v)}
|
||||
title={v.is_lead ? 'Remove co-lead' : 'Mark as co-lead'}>
|
||||
{v.is_lead ? '− Co-Lead' : '+ Co-Lead'}
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm" onclick={() => deleteVolunteer(v)}>Delete</button>
|
||||
{#if editID === v.id}
|
||||
<tr class="edit-row">
|
||||
<td class="td-name" style="width:100%">
|
||||
<strong>{v.name}</strong>
|
||||
{#if v.email}<div class="text-muted" style="font-size:0.78rem">{v.email}</div>{/if}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
<td class="td-edit-dept">
|
||||
<select bind:value={editDeptID} style="margin:0">
|
||||
<option value="">No department</option>
|
||||
{#each $allDepts ?? [] as d}
|
||||
<option value={String(d.id)}>{d.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</td>
|
||||
<td class="td-edit-checks">
|
||||
<label style="display:flex;align-items:center;gap:0.4rem;cursor:pointer;white-space:nowrap">
|
||||
<input type="checkbox" style="width:auto" bind:checked={editIsLead} /> Co-Lead
|
||||
</label>
|
||||
</td>
|
||||
<td class="td-edit-note">
|
||||
<input bind:value={editNote} placeholder="Note" style="margin:0" />
|
||||
</td>
|
||||
<td class="td-actions">
|
||||
<button class="btn btn-primary btn-sm" onclick={() => saveVolunteer(v)} disabled={saving}>
|
||||
{saving ? '…' : 'Save'}
|
||||
</button>
|
||||
<button class="btn btn-ghost btn-sm" onclick={cancelEdit}>Cancel</button>
|
||||
</td>
|
||||
</tr>
|
||||
{:else}
|
||||
<tr>
|
||||
<td class="td-name">
|
||||
<strong>{v.name}</strong>
|
||||
{#if v.is_lead}
|
||||
<span class="badge badge-lead" style="margin-left:0.4rem">Co-Lead</span>
|
||||
{/if}
|
||||
{#if !v.participant_id}
|
||||
<span class="badge badge-unchecked" style="margin-left:0.4rem" title="Not linked to a participant">No ticket</span>
|
||||
{:else if !participantHasTickets(v.participant_id)}
|
||||
<span class="badge badge-partial" style="margin-left:0.4rem" title="No ticket on file">No ticket</span>
|
||||
{/if}
|
||||
{#if v.ticket_name && v.ticket_name !== v.name}
|
||||
<div class="text-muted" style="font-size:0.78rem">Ticket: {v.ticket_name}</div>
|
||||
{/if}
|
||||
{#if v.email}
|
||||
<div class="text-muted" style="font-size:0.78rem">{v.email}</div>
|
||||
{/if}
|
||||
{#if v.note}
|
||||
<div class="text-muted" style="font-size:0.78rem">{v.note}</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-dept text-muted">
|
||||
{#if dept}
|
||||
<span class="dept-dot" style="background:{dept.color};margin-right:0.4rem"></span>{dept.name}
|
||||
{:else}
|
||||
—
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-status">
|
||||
{#if v.checked_in}
|
||||
<span class="badge badge-checked">Ready</span>
|
||||
{:else if v.confirmed}
|
||||
<span class="badge badge-confirmed">Confirmed</span>
|
||||
{:else if v.email_confirmed}
|
||||
<span class="badge badge-registered">Registered</span>
|
||||
{:else}
|
||||
<span class="badge badge-unchecked">Unconfirmed</span>
|
||||
{/if}
|
||||
{#if v.checked_in_at}
|
||||
<div class="text-muted" style="font-size:0.75rem">
|
||||
{new Date(v.checked_in_at).toLocaleTimeString()}
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="td-ready">
|
||||
{#if !v.checked_in}
|
||||
<CheckInButton onclick={() => checkIn(v)} />
|
||||
{/if}
|
||||
</td>
|
||||
{#if canManage}
|
||||
<td class="td-actions">
|
||||
{#if canConfirm && v.email_confirmed && !v.confirmed}
|
||||
<button class="btn btn-primary btn-sm" onclick={() => confirmVolunteer(v)}>Confirm</button>
|
||||
{/if}
|
||||
<button class="btn btn-ghost btn-sm" onclick={() => startEdit(v)}>Edit</button>
|
||||
<button class="btn btn-danger btn-sm" onclick={() => deleteVolunteer(v)}>Delete</button>
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -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%; }
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue