213 Commits
Author SHA1 Message Date
joshua 0bddb329e3 Merge branch 'feat/google-site-verification' v1.31.1 2026-10-22 11:43:01 +02:00
joshuaandClaude Opus 5.5 be4b6f02ea Bump to 1.31.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:43:00 +02:00
joshuaandClaude Opus 5.5 880e3206cc Add Google Search Console verification setting
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:42:56 +02:00
joshuaandClaude Opus 5.5 7b2bfc31e6 Merge branch 'feat/seo-and-traffic-sources'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.31.0
2026-10-22 09:26:17 +02:00
joshuaandClaude Opus 5.5 963c1824bf Bump to 1.31.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 09:26:15 +02:00
joshuaandClaude Opus 5.5 38262022ef Add event structured data, canonical URLs and referrer-based traffic sources
- Event pages emit schema.org Event JSON-LD (dates, venue, image,
  organizer, ZAR offers, sold-out status) for Google event results.
- Event pages, the events list and home page set a canonical URL so
  tagged and alias links don't split rankings.
- Funnel tracking falls back to the referring site (Facebook, Instagram,
  Google, ...) and fbclid/gclid when a link has no utm_source/src.
- Share and Save QR on the event page tag their links as share / qr.
- getServerSettings moves to lib/serverSettings.ts for reuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 09:26:02 +02:00
joshuaandClaude Opus 5.5 15b73d5d9e Merge branch 'feat/unified-ticket-design'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.30.1
2026-10-22 08:59:24 +02:00
joshuaandClaude Opus 5.5 c74a943709 Bump to 1.30.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:59:21 +02:00
joshuaandClaude Opus 5.5 28c8fe9715 Use the dashboard ticket design for all tickets
The emailed/WhatsApp ticket PDF and the staff and at-the-door print
views now match the user dashboard's printed tickets: rounded cards with
a light border and soft shadow. Printing goes through a shared helper in
lib/ticketPrint.ts, which also escapes names in the print HTML.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:59:07 +02:00
joshuaandClaude Opus 5.5 2e7bf263ee Merge branch 'feat/registration-donation'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.30.0
2026-10-22 08:29:17 +02:00
joshuaandClaude Opus 5.5 377630473d Bump to 1.30.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:29:11 +02:00
joshuaandClaude Opus 5.5 286cf09dd8 Add optional donation to registration; fix soldOutLines server crash
The register form now offers a "Donation amount" (suggested amounts,
custom, or none) under the ticket options. The donation is added to the
Yoco checkout as its own line and the webhook records it as a separate
donation payment linked to the registration payment.

Move soldOutLines() out of the "use client" JoinWaitlistButton module
into lib/waitlist.ts so the server-rendered event page can call it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:27:47 +02:00
joshuaandClaude Opus 5.5 27c870d46d Bump to 1.29.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.29.1
2026-10-21 16:36:17 +02:00
joshuaandClaude Opus 5.5 a0c5a6a98c Merge branch 'feat/coupons-redesign'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:36:16 +02:00
joshuaandClaude Opus 5.5 e7969429b6 Redesign the Coupon codes page to match Bundle deals
Cards instead of the table, phone-friendly sheets for the form and the uses list,
inactive codes hidden by default, and the events picker shows upcoming events only
(with search and a Show past events option).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:36:16 +02:00
joshuaandClaude Opus 5.5 4a492a8b16 Bump to 1.29.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.29.0
2026-10-21 16:21:05 +02:00
joshuaandClaude Opus 5.5 294fff0b41 Merge branch 'feat/bundle-types'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:21:05 +02:00
joshuaandClaude Opus 5.5 f33d04a57c Add bundle types: pick any, buy X get Y free, group discount
Bundles get a kind: exact (as before), mix (any setSize of the qualifying tickets for
a set price), free (cheapest freeCount in each set free) and group (setSize or more
qualifying tickets at a per-ticket price or % off, applied once). The supervisor page
has a type picker, buyers see a one-line description of each deal, and the Complete
bundle cards handle every type. Demo: Family Fun Day adds a Lunch for four deal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:21:05 +02:00
joshuaandClaude Opus 5.5 6b186b3481 Bump to 1.28.3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.28.3
2026-10-21 16:03:22 +02:00
joshuaandClaude Opus 5.5 7ba40163db Fix the bundle edit form's ticket rows
The quantity input had both w-full and w-16; w-full won, filling the row and pushing
the ticket picker off the side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:03:21 +02:00
joshuaandClaude Opus 5.5 428b438251 Bump to 1.28.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.28.2
2026-10-21 15:56:04 +02:00
joshuaandClaude Opus 5.5 6ce59af0ea Redesign the Bundle deals page
Upcoming events only by default (with a Show past events option), bundles as cards
instead of a table, and a mobile-friendly edit form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:56:03 +02:00
joshuaandClaude Opus 5.5 53ed72d032 Add bundle deals to manual registration
Lists the event's deals and shows the Complete bundle / + cards, as at the door and
on the kiosk. Part of 1.28.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.28.1
2026-10-21 15:32:17 +02:00
joshuaandClaude Opus 5.5 35d02c243b Bump to 1.28.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:22:49 +02:00
joshuaandClaude Opus 5.5 e2e6ec0e97 Merge branch 'feat/bundles-door-kiosk'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:22:48 +02:00
joshuaandClaude Opus 5.5 92ab8065ef Add bundle deals to at the door and the kiosk
Both list the event's deals and show the Complete bundle / + cards from the register
form. At the door gets the standard Back to dashboard link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:22:48 +02:00
joshuaandClaude Opus 5.5 084e3c6679 Bump to 1.28.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.28.0
2026-10-21 15:14:53 +02:00
joshuaandClaude Opus 5.5 de196e34f2 Merge branch 'feat/bundle-deals'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:14:53 +02:00
joshuaandClaude Opus 5.5 763b66ff56 Add bundle deals
Sell a set of tickets together for one price (e.g. 5 Adult + 3 Child for R500).
Bundles apply automatically, as many times as a registration's tickets allow, and
only when cheaper than the prices actually charged. Coupons come off afterwards.

- EventBundle/EventBundleItem/RegistrationBundle models and Registration.bundleDiscount
- Supervisor "Bundle deals" page, quote endpoint, bundle lines on invoices,
  receipts, emails, WhatsApp and Yoco checkout, Discounts report rows
- Register form shows started bundles with "Complete bundle" and "+" buttons
- Demo: Family Fun Day sells a Family deal bundle instead of the Family pass ticket

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:14:53 +02:00
joshuaandClaude Opus 5.5 8f92a8c3e9 Bump to 1.27.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.27.1
2026-10-21 13:39:48 +02:00
joshua 6fc6c35214 Merge branch 'chore/demo-history' 2026-10-21 13:39:47 +02:00
joshuaandClaude Opus 5.5 be1d6f2e31 Add ten completed events to the demo data
set-demo now also stages ten past events with door sales, staff cash
counts, check-ins, refunds, donations and feedback. Their cashups run
through the real cashup code after the insert and cover every path:
quick close, full settlements (card fees, deposit fee, shortfall, cash
on hand, an unaccounted amount), close-reopen-close, and pending EFT
money received later or still outstanding. One recent event is left
open with the cash counted for a live demo. Funnel sessions older than
90 days are rolled up into daily totals, as the app does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:39:47 +02:00
joshuaandClaude Opus 5.5 dc02f6b9ff Bump to 1.27.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.27.0
2026-10-21 13:29:29 +02:00
joshua 103c328a6a Merge branch 'feat/cashup-settlement' 2026-10-21 13:29:28 +02:00
joshuaandClaude Opus 5.5 7446388bfa Take cash deposit fees out of the counted cash
A bank charge on a cash deposit comes out of cash that was counted and
banked, so cash on hand is now the count less what reached the bank and
any bank-charge write-off. Before, a deposit fee showed as money "more
than expected".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:29:17 +02:00
joshuaandClaude Opus 5.5 8a4c144f6d Add cashup settlement and back links to the changelog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:25:19 +02:00
joshuaandClaude Opus 5.5 3a68b24a0f Settle cashups: where the money ended up
A full cashup now records, per payment method, how much of the expected
takings is in the bank, still on hand (cash) or pending (on the card
report or with a POP), and writes off what was lost to card fees, bank
charges or a shortfall. Whatever is left is shown as unaccounted; closing
with an unaccounted amount is allowed after a warning.

Pending money can be marked received or written off after the event is
closed, without reopening it. Reopening starts the next cashup from the
last one. Write-offs come off net profit and show as "Bank & card
charges" in the cashup, finance and profit reports.

The reports page also moves to the shared back link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:25:04 +02:00
joshuaandClaude Opus 5.5 9be78c3c34 Use one back link style across the dashboards
Every dashboard page now uses the shared BackLink, the small
"← Back to dashboard" link above the page title that the Waitlist page
already had, instead of a mix of grey Back buttons in different places.
Pages that had no way back (site settings, profile, donate, manual
registration) get one too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 13:25:04 +02:00
joshuaandClaude Opus 5.5 d268236686 Bump to 1.26.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.26.1
2026-10-21 12:23:51 +02:00
joshua 95a8bd0796 Merge branch 'chore/demo-data' 2026-10-21 12:21:03 +02:00
joshuaandClaude Opus 5.5 101632e758 Add set-demo script for staging demo data
npm run set-demo wipes the database, keeping the site settings and the
admin account, and stages six upcoming events with registrations,
payments, tickets, a waitlist, camp cabins, coupons, costs and funnel
stats for showing the platform to other churches. Documented in
backend/DEMO_DATA.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:21:03 +02:00
joshuaandClaude Opus 5.5 7cf5f79d01 Merge branch 'chore/frontend-lint'
Includes chore/deps-security-prisma7 (Prisma 7 upgrade and npm audit fixes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.26.0
2026-10-21 11:16:38 +02:00
joshuaandClaude Opus 5.5 00464c086d Bump to 1.26.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:16:38 +02:00
joshuaandClaude Opus 5.5 4e07034bbd Add frontend lint cleanup to the changelog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:11:49 +02:00
joshuaandClaude Opus 5.5 2d6c840614 Type the reports page and turn lint back on in builds
ReportsV2 gets typed API responses (funnel, feedback summary, coupon
redemptions, cashup audit, consent) and derived rows. Master-order
quantities move into a per-row map, so an option name can no longer
overwrite a fixed column. Consent row types move to src/types. Removes
unused export helpers and state.

With the frontend now at zero lint errors and warnings, next build runs
ESLint again (eslint.ignoreDuringBuilds is gone).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00
joshuaandClaude Opus 5.5 235da5bf61 Type the at-the-door page and share pricing helpers
Each door panel and modal gets typed props; unused setError/setInfo/
onCreated props are dropped. The current early-bird price helpers move
to src/lib/pricing.ts (shared with manual registration), dead fallbacks
for a legacy registration 'options' field are removed, and the refund
history now shows a refund's reason (stored in its status field) instead
of a 'reason' field that never exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00
joshuaandClaude Opus 5.5 f6581eb441 Type payments and user dashboard pages
Moves the duplicated registration-option pricing helper into
src/lib/pricing.ts and drops an unused users list from payments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00
joshuaandClaude Opus 5.5 0a8788afff Type supervisor forms, manual registration and events pages
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00
joshuaandClaude Opus 5.5 b560d0d340 Type registrations, email and WhatsApp messaging pages
Adds typed payloads and results for the email/WhatsApp attendee and
broadcast endpoints. The WhatsApp page's messageDirty flag becomes a ref
(it only gated the template effect), and a no-op branch in the email
template effect is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00
joshuaandClaude Opus 5.5 b2439a781e Type more frontend pages and fix their hook dependencies
Cashup, users, profile, consent, allocations, event options, forms,
event tickets, ticket scanning and manual registration now use real
types. Data loaders are wrapped in useCallback and listed as effect
dependencies. Also adds shared Attendee, Section and form response
types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:10:01 +02:00