diff --git a/frontend/src/pages/Dashboard.svelte b/frontend/src/pages/Dashboard.svelte index c1ae495..9a69d10 100644 --- a/frontend/src/pages/Dashboard.svelte +++ b/frontend/src/pages/Dashboard.svelte @@ -4,13 +4,54 @@ let { session } = $props() - const attendees = liveQuery(() => db.attendees.toArray()) - const event = liveQuery(() => db.event.get(1)) + const role = $derived(session?.user?.role ?? '') + const myDeptIDs = $derived(session?.user?.department_ids ?? []) + const isTicketing = $derived(['admin', 'ticketing'].includes(role)) + const isStaffing = $derived(['admin', 'ticketing', 'staffing'].includes(role)) + const isColead = $derived(role === 'colead') - const total = $derived(($attendees ?? []).length) - const checkedIn = $derived(($attendees ?? []).filter(a => a.checked_in).length) - const remaining = $derived(total - checkedIn) - const pct = $derived(total > 0 ? Math.round((checkedIn / total) * 100) : 0) + const event = liveQuery(() => db.event.get(1)) + const allTickets = liveQuery(() => db.tickets.toArray()) + const allVolunteers = liveQuery(() => db.volunteers.filter(v => !v.deleted_at).toArray()) + const allShifts = liveQuery(() => db.shifts.filter(s => !s.deleted_at).toArray()) + const allDepts = liveQuery(() => db.departments.filter(d => !d.deleted_at).toArray()) + const allVS = liveQuery(() => db.volunteer_shifts.toArray()) + + // Ticket stats + const tickets = $derived($allTickets ?? []) + const ticketTotal = $derived(tickets.length) + const ticketCheckedIn = $derived(tickets.filter(t => t.checked_in_at).length) + const ticketRemaining = $derived(ticketTotal - ticketCheckedIn) + const ticketPct = $derived(ticketTotal > 0 ? Math.round((ticketCheckedIn / ticketTotal) * 100) : 0) + + // Volunteer stats (scoped for colead) + const volunteers = $derived.by(() => { + const vols = $allVolunteers ?? [] + if (isColead) return vols.filter(v => myDeptIDs.includes(v.department_id)) + return vols + }) + const volTotal = $derived(volunteers.length) + const volCheckedIn = $derived(volunteers.filter(v => v.checked_in).length) + const volLeads = $derived(volunteers.filter(v => v.is_lead).length) + + // Shift stats (scoped for colead) + const shifts = $derived.by(() => { + const all = $allShifts ?? [] + if (isColead) return all.filter(s => myDeptIDs.includes(s.department_id)) + return all + }) + const shiftTotal = $derived(shifts.length) + const shiftsFilled = $derived.by(() => { + const vs = $allVS ?? [] + return shifts.filter(s => vs.some(a => a.shift_id === s.id)).length + }) + const shiftFillPct = $derived(shiftTotal > 0 ? Math.round((shiftsFilled / shiftTotal) * 100) : 0) + + // Department names for colead header + const myDeptNames = $derived.by(() => { + const depts = $allDepts ?? [] + return myDeptIDs.map(id => depts.find(d => d.id === id)?.name).filter(Boolean) + })
+ Your department{myDeptNames.length > 1 ? 's' : ''}: + {myDeptNames.join(', ')} +
+ {/if} - {#if total > 0} -Add departments to organize your volunteer teams.
+Create departments to organize shifts and volunteer teams. Coleads are assigned to specific departments.
Add shifts to schedule your volunteers.
+ No shifts scheduled yet +Create departments first, then add shifts here. Volunteers can self-select shifts via the kiosk.
+ Roles: + admin — full access · + ticketing — participants, tickets, import · + staffing — volunteers, shifts, departments · + colead — manage assigned departments only · + gatekeeper — check-in only +
+ {#if loadError}The admin account was created at setup. Add users above to delegate access.
Add volunteers manually.
+Add volunteers manually above, or enable public signup in Settings.