The scheduled-job store never persisted the channel field, so the
send worker always fell through to its email branch regardless of
what was requested. Also purges sent jobs 24h after sending instead
of keeping them forever, and surfaces who each scheduled job will go
to in the admin "manage scheduled" lists (now correctly filtered per
channel too).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Multi-phase visual facelift (design tokens, dashboards, sidebar/navbar
shell, per-page help guides, and a layout/content pass across every
remaining page) plus backend fixes to the dashboard KPI stats:
- Admin/Supervisor dashboard KPIs (revenue, donations, registrations,
tickets sold) now use a rolling trailing-month window (today back one
calendar month, e.g. 9 May - 8 June if today is 8 June) instead of
calendar month-to-date, which under-counted for most of the month.
The comparison window shifts the same way, so like is still compared
with like.
- Reports deep-links from those stat tiles now match the same window
(range=trailing_month, replacing range=this_month).
- Design tokens (brand-* Tailwind scale + shadcn CSS variables), a
site-wide contextual help button, fixed dashboard sidebar/navbar,
Admin/Supervisor/Staff/User dashboard rebuilds backed by a new
GET /api/stats/overview endpoint, a dedicated Contact page, Site
Settings restyle with WhatsApp config folded in, and an Account
activity feed backed by a new SecurityEvent model.
- Every remaining page (home, events, registration flow, auth, legal,
payment results, and every Admin/Supervisor/Staff/User tool page)
restyled onto the same design tokens, several with real layout
upgrades (home hero, events list/detail, donate page, auth pages).
- 20+ new dedicated help guides so the whole site has page-specific
help content instead of falling back to a generic guide.
- Assorted fixes surfaced along the way: donation-leg double-counting
in payment stats, donations not counting toward revenue, refund
netting in per-method report breakdowns, and donation
over-allocation after a refund.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Sidebar now shows only on each role's root landing page
(/dashboard/staff, /dashboard/supervisor, /dashboard/admin) and hides on
every sub-page beneath them, not just Reports. Navbar's "Dashboard" link
always leads back to the role root.
- Fixed two dropdown panels (EventsDropdown, the Email/WhatsApp Attendees
recipient picker) that could extend past the viewport's right edge on
narrow screens; both now stretch to their trigger's width like other
dropdowns in the app already do.
- Wrapped the Admin Cashup event-costs table in the same overflow-auto
container every sibling table on that page already uses, so it scrolls
horizontally on narrow screens instead of squeezing its columns.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Financial correctness (donation-leg model):
- Donations are no longer mutated when assigned to a registration; assignment now
creates an immutable "leg" record referencing the original donation instead.
- Fixed several places where money was double-counted once a donation was partially
or fully assigned (Payments, Revenue summary, Cashup reconciliation, Finance
report, Profit report, Master Orders, Revenue Detailed).
- Payments now record who recorded them (recordedBy), separate from who they're for.
Cashup:
- Per-user cash denomination counting (optional, any time) replaces the single
event-wide manual entry; the event's cash actual is the live sum of these counts.
- New "Payment accountability by staff member" breakdown across all methods, and a
read-only "Report" tab that opens automatically once an event is closed.
Reports page redesign:
- New shell: sidebar of universal filters (events, date range, past/inactive/closed
toggles), searchable/categorized report grid, and a popup viewer with
Print/Email/Excel/WhatsApp actions plus an in-app Reporting Guide.
- Visual pass: colored stat tiles and bar charts on most reports, matching mockups.
- PDF exports (download/Print/Email/WhatsApp) now share a branded design mirroring
the web report — colored header, stat tiles, bar chart, highlighted totals.
- Excel export now produces a styled .xlsx (via exceljs) instead of a plain CSV.
- Master Orders' "Donations made" table is now included in every export channel.
Bug fixes discovered while testing exports:
- Report emails now go through the shared, DB-configurable mail utility instead of
a one-off transporter that ignored Site Settings SMTP config.
- WhatsApp report sends now surface the actual WAWP API error and auto-recover a
disconnected session, instead of a bare axios status-code message.
Also: Admin-editable notification preference, richer Admin Registrations dashboard,
{{payment.link}} placeholder for Email/WhatsApp Attendees, and background
email/WhatsApp attendee sending.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two consistency fixes requested after the payment-method work:
1. Registration status (pending/confirmed/partial_paid/paid/cancelled)
was printed as a raw string on the user dashboard. Added
RegistrationStatusBadge mirroring the existing EventStatusBadge
pattern, using the same status colors already established on
dashboard/admin/registrations.
2. Inline success/error banners across dashboard pages persisted
indefinitely. Added a shared useDismissingState hook (drop-in
useState replacement that auto-clears a truthy value after 7s,
resetting the timer on each update) and swapped it in across ~24
dashboard files. Excluded: message-only modal dialogs (ticket-
scanning's success/error confirmations) and two states that mix
live form-validation feedback with async results inside actively-
open forms (the registration-edit modal's editError, the event
create/edit modal's error) - those keep persisting until the user
acts, since auto-hiding a "fix this field" message mid-edit would
be a regression. Also fixed at-the-door's existing bespoke
auto-dismiss timers (10s/15s, one mislabeled as "5s") to the same
consistent 7s, and removed admin/settings' manual x dismiss button
in favor of the same auto-only behavior.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>