EventsManager Component
EventsManager Component
Component: src/features/events/components/EventsManager.tsx Route: /app/fundraising/events Access: Authenticated users with Fundraising Hub access Last Updated: March 1, 2026
---
Recent Updates (March 2026)
Fix: Parent Org Event Creation Blocked (Mar 19, 2026)
- Reporter: Steven James (InFocus Ministries)
- Fixed: Parent organizations with child funds could not create events —
handleCreateEvent()had anisAdminViewguard that blocked creation and showed "Please select a specific organization" toast - Root Cause: Overly conservative guard from Jan 2026 assumed parent orgs should always select a child fund first. But
EventBuilder.handleSavealready correctly resolvesorganization_idviagetActualOrgId(selectedEntity)for parent orgs. - Solution: Removed the
isAdminView+hasChildEntitiesguard entirely. Parent orgs now proceed directly to EventBuilder. - Also Added: Optional fund selector dropdown in EventBuilder Basics step — visible only for parent_org users with child funds. Allows attributing an event to a specific fund for accounting/reporting. Defaults to parent org.
- Files Modified:
src/features/events/components/EventsManager.tsx— Removed admin-view guard + unused importssrc/features/events/components/EventBuilder.tsx— Added fund selector UI +isAdminViewimportsrc/i18n/locales/{en,es,fr,de,zh,th}/events.json— Addedbuilder.fundAttribution*keys
Fix: Timezone-Naive Timestamp Comparison (Mar 1, 2026)
- Fixed:
fetchEventsupcoming/past filters usednew Date().toISOString()(withZsuffix) against atimestamp without time zonecolumn, causing edge-case mismatches for same-day events - Solution: Strip
Zsuffix from ISO string before comparison to make intent explicit
Improvement: i18n Sweep (Mar 1, 2026)
- Fixed: 30+ hardcoded English strings in EventsManager replaced with
t()calls - Added:
manager.*keys to all 6 locale files (en, es, fr, de, zh, th)
Improvement: Shared Constants (Mar 1, 2026)
- Fixed:
EVENT_TYPE_LABELSandSTATUS_COLORSwere duplicated between EventsManager and EventBuilder - Solution: Extracted to
src/types/events.tsasEVENT_TYPE_LABELSandEVENT_STATUS_COLORS
Improvement: EventDashboard keepPreviousData (Mar 1, 2026)
- Fixed: Registrations query in EventDashboard lacked
placeholderData: keepPreviousData, causing UI flash when switching tabs - Solution: Added
keepPreviousDataconsistent with §8 caching standard
Recent Updates (February 2026)
Fix: Events Query Hardening (Feb 14, 2026)
- Fixed: Events list could show "0 events found" due to stale React Query cache
- Solution: Added
staleTime: 30_000,retry: 2,refetchOnMount: truetouseEventshook
Fix: Auction Item Creation Bug (Feb 14, 2026)
- Fixed: Auction items created during new event creation silently failed — raw
supabase.from()call was missingitem_number(NOT NULL column) - Solution: Replaced raw Supabase call with
createAuctionItemmutation in EventBuilder save handler
Fix: .single() → .maybeSingle() (Feb 14, 2026)
- Fixed:
fetchEventBySlugandvalidatePromoCodeused.single()which throws on 0 rows - Solution: Changed to
.maybeSingle()for graceful null handling
Edge Function: get-public-event v17 (Feb 14, 2026)
- Added:
collect_sales_taxfield to public event response
Migration: RLS Policy Normalization (Feb 14, 2026)
- Fixed:
event_ticket_holdsandevent_ticket_hold_itemsusedis_parent_org()instead ofis_parent_org_admin() - Solution: Normalized to match all other event table policies
Recent Updates (January 2026)
Feature: QR Code Button for Events (Jan 21, 2026)
- Added: QR Code button next to Check-In button in event list
- Feature: Opens modal with QR code for event registration URL
- Download: Users can download QR code as PNG for marketing materials
- Implementation: Uses external API (api.qrserver.com) consistent with existing QR code usage in DonorPortal and EventRegistrationSuccess
Bug Fix: Admin View Guard (Jan 13, 2026)
- Fixed: Users could enter the EventBuilder from admin view, fill out the entire form, then receive an error at save time
- Solution: Added early guard in
handleCreateEvent()that checksisAdminView(selectedEntity)and shows toast error before entering the builder
Bug Fix: Supabase Client Auth (Jan 13, 2026)
- Fixed:
EventDashboardandEventCheckInwere using raw REST API calls with anon key instead of authenticated Supabase client - Solution: Replaced
fetch()calls withsupabase.from()queries for proper JWT authentication and RLS enforcement
---
Overview
The EventsManager is the main list view for managing events within the Fundraising Hub. It provides filtering, searching, and quick actions for all organization events.
Features
- Event List - Card-based display of all events
- Status Badges - Draft, Published, Closed, Canceled
- Search - Filter by event name
- Filters - Status, event type, time period (upcoming/past)
- Quick Actions - View, Edit, Copy URL, Publish, End Registration, Delete
- Metrics Display - Registration count and revenue per event
UI Layout
┌─────────────────────────────────────────────────────────┐
│ ← Back to Fundraising Hub + Create Event │
├─────────────────────────────────────────────────────────┤
│ [Search...] [Status ▼] [Type ▼] │
│ │
│ [ Upcoming | Past ] │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Event Name [Published] │ │
│ │ Dec 25, 2025 • Location Name │ │
│ │ 45 registrations • $2,250 revenue │ │
│ │ │ │
│ │ [Check-In] [QR] [Copy] [Edit] [⋮] │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Another Event [Draft] │ │
│ │ ... │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘State Management
const [events, setEvents] = useState<Event[]>([]);
const [searchQuery, setSearchQuery] = useState('');
const [statusFilter, setStatusFilter] = useState<string>('all');
const [typeFilter, setTypeFilter] = useState<string>('all');
const [timeFilter, setTimeFilter] = useState<'upcoming' | 'past'>('upcoming');
const [view, setView] = useState<'list' | 'detail' | 'checkin' | 'builder'>('list');
const [selectedEvent, setSelectedEvent] = useState<Event | null>(null);Actions
| Action | Description | Confirmation |
|--------|-------------|--------------|
| **View** | Opens EventDashboard | No |
| **Check-In** | Opens EventCheckIn | No |
| **QR Code** | Opens modal with QR code for registration URL | No |
| **Edit** | Opens EventBuilder | Warning if published |
| **Copy URL** | Copies public URL to clipboard | Toast notification |
| **Publish** | Changes status to 'published' | No |
| **End Registration** | Changes status to 'closed' | Yes |
| **Delete** | Removes event | Yes |
View Modes
The component manages multiple views internally:
| View | Component | Trigger |
|------|-----------|---------|
| `list` | Event cards list | Default |
| `detail` | `EventDashboard` | Click event card |
| `checkin` | `EventCheckIn` | Click "Check-In" button |
| `builder` | `EventBuilder` | Click "Create Event" or "Edit" |
Filtering Logic
Filtering is done server-side via the useEvents hook which calls db.fetchEvents(). The hook passes EventFilters to Supabase:
// Server-side filters passed to fetchEvents()
const filters: EventFilters = {
status: statusFilter !== 'all' ? statusFilter : undefined,
event_type: typeFilter !== 'all' ? typeFilter : undefined,
search: searchQuery || undefined,
upcoming: timeFilter === 'upcoming',
past: timeFilter === 'past',
};The upcoming and past filters use .gte('start_date', ...) and .lt('start_date', ...) respectively, with timezone-naive timestamps to match the timestamp without time zone column type.
Related Components
EventBuilder- Create/edit eventsEventDashboard- Event metrics and reportingEventCheckIn- Check-in interfaceMarketingHub- Parent navigation hub
Related Documentation
- Main Events Doc:
../06-EVENTS-TICKETING.md - Event Builder:
./02-EVENT-BUILDER.md - Event Dashboard:
./03-EVENT-DASHBOARD.md
Synced from IFMmvp-Frontend documentation: pages/fundraising/events/01-EVENTS-MANAGER.md
Ready to Get Started?
See how Alignmint can simplify your nonprofit's operations. Schedule a free demo with our team and we'll walk you through everything.
Questions? Email us at steven@getalignmint.org