Commit Graph
61 Commits
Author SHA1 Message Date
MichilisandCursor 38526f17b5 Redesign user dashboard with overview tab and i18n payment copy.
Consolidate profile and security into AccountTab, add shared dashboard components, and move awaiting-approval payment messages to translations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 07:39:52 +00:00
MichilisandCursor f5fe87613f Add stable /next and /featured URLs that redirect to the current event.
These short links always resolve to the latest upcoming or featured event so they can be shared without updating when events rotate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 05:35:52 +00:00
MichilisandCursor 613bd7be1d Refactor monolithic modules and harden booking, email, and auth infrastructure.
Split oversized frontend API client, email service, and admin/booking pages into focused modules while preserving import surfaces, and add Redis-backed queues, stale booking cleanup, stronger auth, and scale deployment configs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 07:12:59 +00:00
MichilisandCursor f0e2de2834 Fix Lightning payment UI not updating after LNbits invoice is paid.
Ensure the booking page receives payment confirmation via a streaming SSE proxy, parallel status polling, and more reliable backend event delivery.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 04:15:02 +00:00
MichilisandCursor a6840ea953 Harden auth, payments, and frontend against review findings.
Close exploitable gaps in booking/payment flows, enforce token versioning and account checks, gate sensitive payment data, and add middleware plus input validation across admin routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 19:59:02 +00:00
Michilis fc4af38e8a Add per-quantity TPago payment links for multi-ticket checkout.
Each ticket quantity (1-5) can have its own TPago link so checkout, emails, and admin config use the correct fixed-amount URL.
2026-06-18 23:59:17 +00:00
MichilisandCursor 1b2463f4bc Add human-readable event URL slugs with legacy redirect support.
Store unique slugs on events, backfill existing records, redirect old UUID and alias URLs to canonical slug pages, and expose slug editing plus alias management in the admin event modal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 04:09:05 +00:00
Michilis d09c87a5a5 Fix booking flow scroll position on mobile step changes.
Scroll to the top whenever the booking step changes so users are not left at the bottom of the page after submitting the form.
2026-06-05 02:52:14 +00:00
Michilis 69768077e5 Add search and event filters to admin email logs.
Let admins find logs by recipient or subject and narrow results by event on the Email Logs tab.
2026-06-04 23:35:53 +00:00
Michilis ecd2a7d009 fix(legal): align bullet list markers with list text
Use list-outside and left padding so ReactMarkdown and TipTap list items render markers beside text instead of on separate lines.
2026-06-04 22:58:31 +00:00
Michilis 0f7573c934 Cap event page ticket quantity at 5 per booking.
Limit the quantity stepper to five tickets or remaining spots, whichever is lower.
2026-06-04 22:53:39 +00:00
Michilis a8b72b47b1 fix(legal): show legal pages in site language with bidirectional toggle
Wire legal pages to LanguageContext, pass locale on footer/booking links,
translate layout chrome, and restore SSR content when switching back to English.
2026-06-04 22:51:32 +00:00
Michilis 22e9254f42 fix(tickets): use integer 1 for isGuest in admin guest invite
Postgres is_guest column is integer; passing JS boolean true caused
"invalid input syntax for type integer" 500 on POST /api/tickets/admin/guest.

Made-with: Cursor
2026-04-27 20:41:58 +00:00
Michilis 2cabd8c92f fix(admin): avoid rendering stray 0 for non-guest tickets on isGuest
Made-with: Love
2026-04-27 18:21:10 +00:00
Michilis 622bb5171c fix(admin): hide pending-approval payments for past events
Made-with: Cursor
2026-04-27 18:14:15 +00:00
Michilis 55516ef1e7 chore: ignore .agents directory and skills-lock.json
Made-with: Cursor
2026-04-27 18:14:15 +00:00
Michilis 3dfb1689ad Booking flow: required terms and privacy checkbox with i18n
Also includes admin, dashboard, and API updates; PWA icon assets; and
assorted layout and utility changes on dev.
2026-04-27 03:21:15 +00:00
Michilis f8ebc3760d Fix db:export ENOBUFS by streaming pg_dump output to file
Made-with: Cursor
2026-03-12 19:18:24 +00:00
Michilis 4da26e7ef1 feat(emails): add re-send for all emails, failed tab, and resend indicators
- Add resend_attempts and last_resent_at to email_logs schema and migrations
- Add POST /api/emails/logs/:id/resend and emailService.resendFromLog
- Add resendLog API and EmailLog.resendAttempts/lastResentAt
- Add All/Failed sub-tabs, resend button for all emails, re-sent indicator in logs and detail modal

Made-with: Cursor
2026-03-12 19:13:24 +00:00
Michilis e09ff4ed60 Admin: stats privacy toggle, clickable event rows, fix payment method display
- Add useStatsPrivacy hook with localStorage persistence for stats visibility
- Single event page: desktop privacy button, hide capacity chip when stats hidden
- Events list: row/card click navigates to event detail; stopPropagation on actions
- Backend GET /tickets: include payment for each ticket (removes N+1)
- Bookings page: use list payment data, show — when payment method unknown

Made-with: Cursor
2026-03-10 01:10:42 +00:00
Michilis 2f45966932 Add db:export and db:import for database backups
Made-with: Cursor
2026-03-07 19:44:27 +00:00
Michilis 7c1fdbf382 Add Spanglish icon image
Made-with: Cursor
2026-03-07 19:41:16 +00:00
Michilis 596ec71191 Fix stale social media preview: revalidate next-event fetch, reject past featured events
Made-with: Cursor
2026-03-07 19:36:12 +00:00
Michilis 25b7018743 Bookings/payments/linktree: fix payment method display, event filter, logo, search
- Bookings: align payment method labels with payments page (bank_transfer, tpago, etc), add sibling fallback
- Payments: add event filter (single/multi), add search by name/email/event
- Linktree: use Spanglish logo instead of icon
- API: payments getAll supports eventId/eventIds

Made-with: Cursor
2026-03-07 18:06:35 +00:00
MichilisandCursor bbfaa1172a Add unlisted event status: hidden from listings but accessible by URL
- Backend: add 'unlisted' to schema enum and Zod validation; allow booking for unlisted events
- Frontend: Event type and guards updated; unlisted events bookable, excluded from public listing/sitemap
- Admin: badge, status dropdown, Make Unlisted / Make Public / Unpublish actions; scanner/emails/tickets include unlisted

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 02:21:41 +00:00
MichilisandCursor 958181e049 Mobile-friendly admin pages, redesigned homepage Next Event card
- Extract shared mobile components (BottomSheet, MoreMenu, Dropdown, etc.) into MobileComponents.tsx
- Make admin pages mobile-friendly: bookings, emails, events, faq, payments, tickets, users
- Redesign homepage Next Event card with banner image, responsive layout, and updated styling
- Fix past events showing on homepage/linktree: use proper Date comparison, auto-unfeature expired events
- Add "Over" tag to admin events list for past events
- Fix backend FRONTEND_URL for cache revalidation

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-18 03:27:49 +00:00
MichilisandCursor 5263fa6834 Make llms.txt always fetch fresh data from the backend
- Switch from tag-based caching to cache: no-store for all backend fetches
- Add dynamic = force-dynamic to prevent Next.js static caching
- Ensures llms.txt always reflects the current featured event and FAQ data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 23:10:33 +00:00
MichilisandCursor 923c86a3b3 Fix FRONTEND_URL pointing to wrong port, breaking cache revalidation
- Update FRONTEND_URL default from localhost:3002 to localhost:3019 (actual frontend port)
- Reorder systemd service so EnvironmentFile loads before Environment overrides

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 22:53:59 +00:00
MichilisandCursor 4aaffe99c7 Fix stale featured event on homepage: revalidate cache when featured event changes
- Extract revalidateFrontendCache() to backend/src/lib/revalidate.ts
- Call revalidation from site-settings when featuredEventId is set/cleared
- Ensures homepage shows updated featured event after admin changes

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 22:42:55 +00:00
MichilisandCursor a11da5a977 Scanner: close button on valid ticket, camera lifecycle fix
- Add X close button on valid ticket screen to dismiss without check-in
- Rewrite QRScanner: full unmount when leaving Scan tab, stop MediaStream tracks
- Remount scanner via key when tab active; no hidden DOM
- Use 100dvh for mobile height; force layout reflow after camera start
- visibilitychange handler for tab suspend/resume

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 19:03:29 +00:00
MichilisandCursor 6bc7e13e78 Admin event page: redesign UI, export endpoints, mobile fixes
- Backend: Add /events/:eventId/attendees/export and /events/:eventId/tickets/export with q/status; legacy redirect for old export path
- API: exportAttendees q param, new exportTicketsCSV for tickets CSV
- Admin event page: unified tabs+content container, portal dropdowns to fix clipping, separate mobile export/add-ticket sheets (fix double menu), responsive tab bar and card layout

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 18:27:27 +00:00
MichilisandCursor c3897efd02 feat(admin): add event attendees export (CSV) with status filters
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 05:27:17 +00:00
MichilisandCursor 62bf048680 Mobile scanner redesign + backend live search
- Scanner page: fullscreen mobile-first layout, Scan/Search/Recent tabs
- Scan tab: auto-start camera, switch camera, vibration/sound feedback
- Valid/invalid fullscreen states, confirm check-in, auto-return to camera
- Search tab: live backend search (300ms debounce), tap card for detail + check-in
- Recent tab: last 20 check-ins, session counter
- Backend: GET /api/tickets/search (live search), GET /api/tickets/stats/checkin
- Admin layout: hide sidebar on scanner page; fix hooks order (no early return before useEffect)
- Back button to dashboard/events (staff → events, others → admin)
- API: searchLive, getCheckinStats, LiveSearchResult; PostgreSQL LOWER cast for UUID

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 04:26:44 +00:00
MichilisandCursor b9f46b02cc Email queue + async sending; legal settings and placeholders
- Add in-memory email queue with rate limiting (MAX_EMAILS_PER_HOUR)
- Bulk send to event attendees now queues and returns immediately
- Frontend shows 'Emails are being sent in the background'
- Legal pages, settings, and placeholders updates

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 21:03:49 +00:00
MichilisandCursor 18254c566e SEO: robots.txt, sitemap, Organization & Event schema; dashboard fmtTime fix; frontend updates
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 07:55:43 +00:00
MichilisandCursor 95ee5a5dec Improve llms.txt for AI: metadata, ISO dates, explicit status, structured events, update policy, AI summary; fix social links
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 07:12:51 +00:00
MichilisandCursor 77e92e5d96 Fix llms.txt event times: format in America/Asuncion timezone
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 05:17:47 +00:00
MichilisandCursor 07ba357194 feat: FAQ management from admin, public /faq, homepage section, llms.txt
- Backend: faq_questions table (schema + migration), CRUD + reorder API, Swagger docs
- Admin: FAQ page with create/edit, enable/disable, show on homepage, drag reorder
- Public /faq page fetches enabled FAQs from API; layout builds dynamic JSON-LD
- Homepage: FAQ section under Stay updated (homepage-enabled only) with See full FAQ link
- llms.txt: FAQ section uses homepage FAQs from API
- i18n: home.faq title/seeFull, admin FAQ nav

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 04:49:16 +00:00
MichilisandCursor 5885044369 Make next event visible to AI crawlers (SSR, JSON-LD, meta, llms.txt)
- SSR next event on homepage; pass initialEvent from server to avoid client-only content
- Add schema.org Event JSON-LD on homepage when next event exists
- Dynamic homepage metadata (description, OG, Twitter) with next event date
- Add dynamic /llms.txt route for AI-friendly plain-text event info
- Revalidation: support next-event tag; backend revalidates sitemap + next-event on event CUD
- Allow /llms.txt in robots.txt

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 04:10:49 +00:00
MichilisandCursor af94c99fd2 feat: auto-update sitemap when events are added/updated/removed
- Use tag-based cache for sitemap event list (events-sitemap)
- Add POST /api/revalidate endpoint (secret-protected) to trigger revalidation
- Backend calls revalidation after event create/update/delete
- Add REVALIDATE_SECRET to .env.example (frontend + backend)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 03:51:00 +00:00
MichilisandCursor 74464b0a7a linktree: next event links to single event page, button 'More info'
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 03:25:09 +00:00
MichilisandCursor 6a807a7cc6 Add edit user details on admin users page
- Backend: extend PUT /api/users/:id with email and accountStatus; admin-only for role/email/accountStatus; return isClaimed, rucNumber, accountStatus in user responses
- Frontend: add Edit button and modal on /admin/users to edit name, email, phone, role, language preference, account status

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 03:17:30 +00:00
MichilisandCursor fe75912f23 Fix event capacity: no negative availability, sold-out enforcement, admin override
- Backend: use calculateAvailableSeats so availableSeats is never negative
- Backend: reject public booking when confirmed >= capacity; admin create/manual bypass capacity
- Frontend: spotsLeft = max(0, capacity - bookedCount), isSoldOut when bookedCount >= capacity
- Frontend: sold-out redirect on booking page, cap quantity by spotsLeft, never show negative

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 03:01:58 +00:00
MichilisandCursor 8315029091 fix: resolve ShareButtons hydration error by deferring native share check to client
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 02:17:01 +00:00
MichilisandCursor 2b2f2cc4ed Admin event: Manual ticket + Tickets tab
- Backend: POST /api/tickets/admin/manual - creates ticket and sends confirmation + ticket email
- Frontend: Manual Ticket button and modal (email required, sends confirmation + ticket)
- New Tickets tab between Attendees and Send Email: confirmed tickets table with search (name/ticket ID), status filter, check-in actions

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 02:44:26 +00:00
Michilis 23d0325d8d feat: add payment management improvements and reminder emails
- Add option to approve/reject payments without sending notification emails
  (checkbox in review popup, default enabled)
- Add payment reminder email template and send functionality
- Track when reminder emails are sent (reminderSentAt field)
- Display reminder sent timestamp in payment review popup
- Make payment review popup scrollable for better UX
- Add payment-reminder template to email system (available in admin emails)
2026-02-05 04:13:42 +00:00
Michilis 0c142884c7 feat: add featured event with automatic fallback
- Add featured_event_id to site_settings (schema + migration)
- Backend: featured event logic in /events/next/upcoming with auto-unset when event ends
- Site settings: PUT supports featuredEventId, add PUT /featured-event for admin
- Admin events: Set as featured checkbox in editor, star toggle in list, featured badge
- Admin settings: Featured Event section with current event and remove/change links
- API: siteSettingsApi.setFeaturedEvent(), Event.isFeatured, SiteSettings.featuredEventId
- Homepage/linktree unchanged: still use getNextUpcoming (now returns featured or fallback)
2026-02-03 19:24:00 +00:00
Michilis 0fd8172e04 Use admin timezone for emails and ticket PDFs
- Email: formatDate/formatTime use site timezone from settings
- PDF tickets: date/time formatted in site timezone
- Tickets routes: fetch timezone and pass to PDF generation
2026-02-03 18:40:39 +00:00
Michilis 9090d7bad2 Add .npm-cache to gitignore; users route and mobile header updates 2026-02-02 21:16:50 +00:00
Michilis 4a84ad22c7 Backend and frontend updates: auth, email, payments, events, tickets; carrousel images; mobile event detail layout; i18n 2026-02-02 20:58:21 +00:00