diff --git a/frontend/src/app.css b/frontend/src/app.css index f10e75b..5727e4d 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -131,6 +131,7 @@ tr:hover td { background: rgba(255,255,255,0.02); } } .badge-checked { background: rgba(34,197,94,0.15); color: var(--c-success); } .badge-unchecked { background: rgba(122,127,150,0.15); color: var(--c-muted); } +.badge-partial { background: rgba(245,158,11,0.15); color: var(--c-warn); } .badge-role { background: rgba(99,102,241,0.15); color: var(--c-accent-h); } .badge-lead { background: rgba(245,158,11,0.15); color: var(--c-warn); } diff --git a/frontend/src/pages/Participants.svelte b/frontend/src/pages/Participants.svelte index 726851c..0003bf0 100644 --- a/frontend/src/pages/Participants.svelte +++ b/frontend/src/pages/Participants.svelte @@ -24,6 +24,15 @@ let newPronouns = $state('') let newNote = $state('') + // Edit participant + let editId = $state(null) + let editName = $state('') + let editEmail = $state('') + let editPhone = $state('') + let editPronouns = $state('') + let editNote = $state('') + let saving = $state(false) + // Add ticket form (per participant) let addTicketFor = $state(null) // participant id let addingTicket = $state(false) @@ -57,14 +66,8 @@ return ticketsFor(participantId).filter(t => t.checked_in_at).length } - async function toggleExpand(id) { - if (expandedId === id) { - expandedId = null - expandedTickets = [] - return - } - expandedId = id - expandedTickets = ticketsFor(id) + function toggleExpand(id) { + expandedId = expandedId === id ? null : id } async function generateCodes() { @@ -148,6 +151,32 @@ } } + function startEdit(p) { + editId = p.id + editName = p.preferred_name + editEmail = p.email + editPhone = p.phone + editPronouns = p.pronouns + editNote = p.note + } + + async function saveEdit(e) { + e.preventDefault() + saving = true; error = '' + try { + const p = await api.participants.update(editId, { + preferred_name: editName, email: editEmail, phone: editPhone, + pronouns: editPronouns, note: editNote, + }) + await db.participants.put(p) + editId = null + } catch (err) { + error = err.message + } finally { + saving = false + } + } + async function addTicket(e, participantId) { e.preventDefault() addingTicket = true; error = '' @@ -283,6 +312,26 @@ {@const ci = checkedInCount(p.id)} {@const isExpanded = expandedId === p.id} {@const isMergeTarget = mergeMode && mergeSource?.id !== p.id} + {@const isEditing = editId === p.id} + {#if isEditing} + + +
+
+ + + + + +
+
+ + +
+
+ + + {:else} { mergeTarget = p } : null} @@ -297,7 +346,12 @@
{p.note}
{/if} - {p.email || '—'} + + {p.email || '—'} + {#if p.phone} +
{p.phone}
+ {/if} + {#if pts.length > 0} {/if} {/if} - {#if isExpanded} + {/if} + {#if isExpanded && !isEditing}
@@ -417,12 +474,9 @@ font-size: 0.825rem; padding: 0.3rem 0.5rem; } - .badge-partial { - background: rgba(245,158,11,0.15); - color: var(--c-warn); - padding: 0.15rem 0.5rem; - border-radius: 99px; - font-size: 0.75rem; - font-weight: 600; - } + .edit-row td { padding: 0.5rem 1rem; background: var(--c-bg); } + .participant-edit-form { display: flex; flex-direction: column; gap: 0.25rem; } + .edit-fields { display: flex; gap: 0.4rem; flex-wrap: wrap; } + .edit-fields input { flex: 1; min-width: 120px; font-size: 0.825rem; padding: 0.3rem 0.5rem; width: auto; } + diff --git a/frontend/src/pages/Settings.svelte b/frontend/src/pages/Settings.svelte index 72d6b5b..5caf2ee 100644 --- a/frontend/src/pages/Settings.svelte +++ b/frontend/src/pages/Settings.svelte @@ -232,8 +232,8 @@ Permanently delete all records of a given type. This cannot be undone.

-