- 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
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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)
- 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)
- 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
- Add dbGet/dbAll helper functions for database-agnostic queries
- Add toDbBool/convertBooleansForDb for boolean type conversion
- Add toDbDate/getNow for timestamp type handling
- Add generateId that returns UUID for Postgres, nanoid for SQLite
- Update all routes to use compatibility helpers
- Add normalizeEvent to return clean number types from Postgres decimal
- Add formatPrice utility for consistent price display
- Add legal pages admin interface with RichTextEditor
- Update carousel images
- Add drizzle migration files for PostgreSQL
- Add ticket validation and check-in API endpoints
- Add PDF ticket generation with QR codes (pdfkit)
- Add admin QR scanner page with camera support
- Add admin site settings page
- Update email templates with PDF ticket download link
- Add checked_in_by_admin_id field for audit tracking
- Update booking success page with ticket download
- Various UI improvements to events and booking pages
Display past event photos in an auto-playing carousel between the
"What is Spanglish?" and "Stay Updated" sections. Images are loaded
dynamically from /images/carrousel/ folder with support for jpg, png,
and webp formats.
- Replace text logo with logo-spanglish.png in Header and Footer
- Update email templates to use logo image instead of styled text
- Add new HeroSection and EventHighlight components
- Update homepage layout and event detail pages
- Adjust Tailwind config and global styles
- Add comprehensive metadata to root layout with Open Graph, Twitter cards
- Create dynamic sitemap.ts for all pages and events
- Create robots.ts with proper allow/disallow rules
- Add JSON-LD Event structured data to event detail pages
- Add page-specific metadata to events, community, contact, FAQ pages
- Add FAQ structured data schema
- Update footer with local SEO text for Asunción, Paraguay
- Add web manifest for mobile SEO
- Create 404 page with proper noindex
- Optimize image alt text and add lazy loading
- Add NEXT_PUBLIC_SITE_URL env variable
- Add about/ folder to gitignore
- Dashboard community links now use .env values like community page
- Removed hardcoded social media URLs from dashboard
- Added deploy folder with nginx and systemd service configs
- Moved linktree page to public route
- Various backend and auth context updates
- Add PORT=3002 to frontend .env.example
- Use dotenv-cli to load env vars for next dev/start
- Add package-lock.json to .gitignore and remove from tracking