83 Commits
Author SHA1 Message Date
joshuaandClaude Sonnet 5 7eed7a01df Bump version to 1.9.2
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.2
2026-08-22 21:24:07 +02:00
joshua a7be2baab2 Merge branch 'fix/contact-only-daily-summary' into main 2026-08-22 21:23:24 +02:00
joshuaandClaude Sonnet 5 5a9137e252 Skip daily summary emails for contact-only events
Contact-only events have no registration flow, so their daily
summary (registration/payment stats) was always empty — exclude
them from the query instead of sending a pointless email.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 21:22:53 +02:00
joshuaandClaude Sonnet 5 4e63a78e8e Bump version to 1.9.1
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.1
2026-08-22 21:12:37 +02:00
joshua 2a067a3687 Merge branch 'fix/org-name-branding' into main 2026-08-22 21:11:52 +02:00
joshuaandClaude Sonnet 5 bdae0c6b08 Fix org name not showing in tab title, homepage, and backend pages
The browser tab title, homepage "Welcome to..." heading, and the
backend status/API docs pages all had the "Cross Code" default
hardcoded instead of reading the configured org_name setting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 21:09:35 +02:00
joshuaandClaude Sonnet 5 c84cc257d0 Bump version to 1.9.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.0
2026-08-21 11:51:27 +02:00
joshua 7cbb147b00 Merge branch 'feature/event-location-maps' into main 2026-08-21 11:50:31 +02:00
joshua b75be18a87 Add event/organisation location with Google Maps links
Events and the organisation profile now have an address, with a
"Directions" link and an embedded Google Maps view (no API key
required) shown on event pages, event cards, and the Contact page.
New events default their location to the org's configured address.
2026-08-21 11:47:23 +02:00
joshua 05840541c2 Merge branch 'feature/early-bird-tranches-and-contact-events' into main 2026-08-21 10:33:19 +02:00
joshuaandClaude Sonnet 5 96aa9b10cc Bump version to 1.8.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.8.0
2026-08-21 10:32:17 +02:00
joshuaandClaude Sonnet 5 bc64069021 Add PDF invoices/receipts with manual send, fix early-bird tier edit data loss
- Registration confirmations attach an invoice PDF (itemized breakdown,
  early-bird discount, balance due, Yoco pay-now link/QR) whenever a
  balance is outstanding; payment/donation confirmations attach a
  payment receipt PDF. Sent as an email attachment and, over WhatsApp,
  as the PDF itself with the existing message as its caption.
- Users can also (re)send either document on demand: an "Invoice"
  button on the registration detail popup, and a "Receipt" button next
  to each payment there and on the Payment history page, each opening
  an Email/WhatsApp choice popup, via two new endpoints restricted to
  the registration/payment's own owner.
- Fix: editing an event option's early-bird tiers deleted and
  recreated every tier for that option with brand-new ids, silently
  severing the appliedTierId link on all historical purchases (losing
  early-bird attribution and undercounting stock-limit usage) even for
  tiers the admin didn't touch. Tiers are now upserted by id.
- Update the "My Events" help content and the API docs index for the
  new endpoints.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 10:26:49 +02:00
joshuaandClaude Sonnet 5 e9cb238ce1 Fix early-bird total in notifications; group dashboard registration items
Registration/payment/reminder emails and WhatsApp messages loaded
registrations without their price tranches, so any line spanning more
than one tranche fell back to charging the full quantity at the most
recent tranche's price, silently dropping the early-bird discount from
the outstanding balance and itemized amounts shown to the user.

The user dashboard's registration detail popup also listed one raw
line per tranche; it now merges same item/price/tier lines and groups
early-bird lines separately from standard-price ones.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:57:29 +02:00
joshuaandClaude Sonnet 5 f0f8d4c242 Fix early-bird price blending and mislabeling; add contact-only events
- Early-bird pricing: RegistrationOption now tracks each purchase as a
  separate price tranche instead of overwriting a single price/quantity
  on repeat purchases, so buying more tickets after a tier expires no
  longer re-prices tickets already bought at the old price. Stock-limit
  checks, total-due calculation, and the Finance report's revenue-by-
  option are all tranche-aware; pages that showed one blended price per
  line now render/total each tranche. Viewing a pending/partially-paid
  registration (dashboard, detail page, or an event's registration
  list) now refreshes stale pricing on the spot instead of only at
  payment time.
- Fixed the "(early bird)" dashboard label incorrectly firing on any
  line priced below the base option price (e.g. a plain cheaper
  variant) — it now checks the real applied-tier flag.
- Added contact-only events (e.g. baptism): no registration/payment
  flow, shown on the public site with a "Contact us" popup instead of
  a Register button. Configurable via the admin event wizard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 17:26:35 +02:00
joshua f2c3172e16 Merge branch 'feature/site-branding-customization' into main 2026-08-20 14:57:44 +02:00
joshuaandClaude Sonnet 5 fd9e917b62 Bump version to 1.7.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.7.0
2026-08-20 14:57:23 +02:00
joshuaandClaude Sonnet 5 86af7093ac Add admin-configurable branding (colors, logo, favicon) and generic default fallbacks
Site Settings -> Branding now supports a Primary/Secondary/Accent brand color
system applied site-wide (buttons, nav, hover states, links) and to outgoing
email header/CTA colors, plus a favicon upload alongside the existing logo
upload, a live preview panel (website/email x desktop/mobile), and
logo-based color suggestions. The setup wizard's Branding step got the same
treatment. Fixes two related bugs found along the way: the setup wizard's
logo/favicon upload was missing its auth token, and a static favicon.ico in
Next's special app/ convention path was silently overriding the dynamic one.

Also replaces every "Hope Events"/"Hope Family Church" default (org name,
email subjects, WhatsApp messages, report metadata, API docs) with a neutral
"Cross Code" placeholder, and the optional legal settings (operator name, IO
details, website URL, effective date) with obviously-generic placeholders
instead of defaulting to real personal/organisational details -- since this
platform is deployed for multiple organisations. Adds SETTINGS.md documenting
every setting's default behaviour.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 14:49:51 +02:00
joshua 2d99b7cafe Merge branch 'feature/supervisor-payments-improvements' into main 2026-08-08 01:24:52 +02:00
joshuaandClaude Sonnet 5 906c79a8e8 Bump version to 1.6.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.6.0
2026-08-08 01:19:49 +02:00
joshuaandClaude Sonnet 5 47b79181b7 Add search and event filter to the Assigned donations list
Finding a specific leg to unassign meant scanning the whole list by
eye. Adds a text search (matches registrant, donor, or event) and an
event dropdown (built from events that actually have assigned legs)
above the list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 01:15:45 +02:00
joshuaandClaude Sonnet 5 34f9826829 Fix donation-assignment admin email reading as a real payment
The internal admin notice for applying a donation to a registration
reused buildPaymentAdminNotice as-is, so it read "Payment recorded" /
"Registration payment" — indistinguishable from an actual incoming
payment even though no new money changed hands. Adds a dedicated
buildDonationAssignmentAdminNotice wrapper (mirroring the one already
added for unassignment) so the subject, heading, and Type field all
say "Donation applied" instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 00:59:24 +02:00
joshuaandClaude Sonnet 5 252f80fadb Add ability to unassign a donation from a registration
Assigning a donation to a registration was one-way: the refund flow
could reverse the money but left the donation's "leg" payment in
place, permanently locking that portion of the donation as used even
though it had been refunded back out. Adds POST
/api/payments/unassign-donation, which deletes the leg, reverts the
registration's status/tickets the same way a refund downgrade already
does, and notifies the registrant. New "Assigned donations" list on
the supervisor Payments page surfaces existing legs with an Unassign
action, since no such list existed before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 00:53:21 +02:00
joshuaandClaude Sonnet 5 0a5b08020f Speed up payment/refund processing on the supervisor dashboard
Reconciling a Yoco payment and sending payment links blocked the HTTP
response on ticket-PDF generation and email/WhatsApp sends; they now
run in the background like the other payment flows already did.
Registration/payment option loops (pricing, stock checks, ticket
generation) now resolve concurrently instead of sequentially. The
Payments page dropped a per-registration N+1 fetch and now refreshes
its lists in parallel after each action. Added missing indexes for
dashboard stats and donation-leg lookups, and made GET
/api/registrations optionally paginated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 00:00:29 +02:00
joshua 6759e9c2d3 Merge branch 'fix/join-us-button-logged-in' into main v1.5.4 2026-08-07 01:57:23 +02:00
joshuaandClaude Sonnet 5 8799eec717 Bump version to 1.5.4
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 01:57:02 +02:00
joshuaandClaude Sonnet 5 56e0c8a31f Fix Join Us button linking logged-in users to register page
Send logged-in users to their dashboard instead of the registration
form, matching how the Navbar already treats logged-in vs guest users.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 01:52:35 +02:00
joshua 4bcb07f9d1 Merge branch 'fix/help-modal-mobile-overflow' into main v1.5.3 2026-08-07 01:17:08 +02:00
joshuaandClaude Sonnet 5 a0a3dc2416 Bump version to 1.5.3
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 01:16:53 +02:00
joshuaandClaude Sonnet 5 51639322e2 Fix help guide popups overflowing the screen on mobile
The popup card had no overall height cap, only the tab content area
did, so the header/quick-links/footer could push the close button off
screen on short mobile viewports. The card is now capped to the
screen height with the header and footer pinned in place, and only
the tab content scrolls internally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 01:14:44 +02:00
joshuaandClaude Sonnet 5 1f186d6d2a Bump version to 1.5.2
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.5.2
2026-08-07 00:47:54 +02:00
joshua 55e7ca9546 Merge branch 'fix/dashboard-mobile-styling' into main 2026-08-07 00:47:14 +02:00
joshua 8f69e58aa2 Add tab icons and fix mobile dashboard styling issues
- Add matching lucide-react icons to tab/mode switcher buttons on
  payments, at-the-door, manual, email-attendees, whatsapp-attendees,
  and admin cashup pages, mirroring icons already used in their help menus
- Fix navbar Logout button sitting lower than other nav links (missing
  border/padding classes that other links use for their active-underline)
- Fix stat card labels getting truncated on mobile by removing the
  ellipsis-cut label and widening the mobile grid to one column
- Fix Revenue trend / Top performing events rendering outside the
  viewport on mobile by containing horizontal overflow and truncating
  long event titles in the table
2026-08-07 00:41:52 +02:00
joshuaandClaude Sonnet 5 1b2f2a7c79 Stop tracking banner.json runtime data store
Same reasoning as scheduled-emails.json: it's mutated by the running
app (site banner content), not source. readBanner() already falls
back to sane defaults when the file is missing, so untracking it is
safe for fresh checkouts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 00:04:45 +02:00
joshuaandClaude Sonnet 5 7906248c67 Stop tracking scheduled-emails.json runtime data store
It's mutated by the running app (scheduled job queue), not source -
committing it churns the repo with live recipient/message content.
Kept on disk, just untracked; a fresh checkout will get an empty
store created on demand by ensureStore().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 00:03:04 +02:00
joshua 22ffbf201e Merge branch 'fix/whatsapp-scheduling-channel-bug' into main (1.5.1) v1.5.1 2026-08-07 00:01:01 +02:00
joshuaandClaude Sonnet 5 be499f0d66 Fix scheduled job list/edit dropping message content
toClient() never returned the message body (html/text for email,
message for WhatsApp), so "Manage scheduled" showed nothing to view
or edit even though the content existed in storage. Editing a
scheduled WhatsApp message also saved to the wrong payload field
(text instead of message), silently discarding the edit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 00:00:43 +02:00
joshuaandClaude Sonnet 5 75b2f8ccc5 Bump version to 1.5.1
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 23:41:43 +02:00
joshua 4f003f1628 Merge branch 'fix/whatsapp-scheduling-channel-bug' 2026-08-06 23:40:32 +02:00
joshuaandClaude Sonnet 5 b3ff2b9c5e Fix scheduled WhatsApp messages sending as email; add 24h cleanup and recipient display
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>
2026-08-06 23:37:35 +02:00
joshuaandClaude Sonnet 5 0833888eaa Bump version to 1.5.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.5.0
2026-08-06 15:29:17 +02:00
joshuaandClaude Sonnet 5 b626404640 Merge branch 'feature/site-redesign' (1.5.0)
Full site visual redesign, site-wide contextual help system, dashboard
KPI overhaul (rolling trailing-month window), and assorted fixes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 15:27:39 +02:00
joshuaandClaude Sonnet 5 0f2b5afa74 Help guide opens on demand only; add At the door to admin quick actions
- The site-wide help guide no longer auto-opens on first visit to a page
  — it only opens when the help button is clicked. Removed the
  now-pointless "Don't show this again" checkbox and the per-page
  dismissal tracking it drove.
- Admin dashboard quick actions was missing "At the door" (walk-in
  registration, payments, ticket printing), which Supervisor already had.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 15:17:12 +02:00
joshuaandClaude Sonnet 5 8e6cb542d9 Full site redesign, help system, and dashboard stats fixes
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>
2026-08-06 15:00:10 +02:00
joshuaandClaude Sonnet 5 d74fec3a5c Bump version to 1.4.2
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.4.2
2026-08-06 09:13:04 +02:00
joshuaandClaude Sonnet 5 4bee1b24f7 Fix supervisor payments mobile tabs, reconcile donor, report method buckets, and refund/donation accounting
- Supervisor Payments: mode tabs now wrap on mobile instead of overflowing off-screen.
- Reconciling a Yoco transaction as a donation now lets staff pick who it's from.
- Reports payment-method breakdown now buckets into Cash/Card/EFT/Other everywhere,
  folding Apple Pay, Google Pay, and Yoco-portal payments into Card.
- Refunds now net against their original method's bucket (Cashup/Finance/Profit reports,
  My Payments filtering/display) instead of vanishing or falling into "Other".
- Refund form's method dropdown mirrors the real payment methods and auto-fills from the
  payment being refunded, replacing an ambiguous generic "Refund" option.
- Fixed donation remaining/unallocated balance inflating instead of shrinking when a
  donation is refunded (assign-donation endpoint, cashup reports, donations reports,
  and the Assign Donation panel all summed refund legs with the wrong sign).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 09:08:53 +02:00
joshuaandClaude Sonnet 5 70605923bf Bump version to 1.4.1
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.4.1
2026-08-05 15:00:44 +02:00
joshuaandClaude Sonnet 5 424141f216 Fix Reports mobile layout overflow and desktop date range overflow
Report popup buttons and the page's search/Back controls overflowed
off-screen on mobile instead of wrapping, and the sidebar's custom
date range inputs spilled outside the filter box on desktop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 14:57:09 +02:00
joshuaandClaude Sonnet 5 d6ea4c37d7 Sync root package.json version to 1.4.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.4.0
2026-08-04 15:49:03 +02:00
joshua ebf521e64e Merge branch 'feature/reports-and-cashup-overhaul' (1.4.0) 2026-08-04 15:46:55 +02:00
joshuaandClaude Sonnet 5 e5fbcc2222 Bump version to 1.4.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 15:46:09 +02:00