Event management for e-board users lives on the Events page (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/asubap/website/llms.txt
Use this file to discover all available pages before exploring further.
EventsPage.tsx, route /events) — not inside the Admin Dashboard at /admin. When the authenticated user’s role is "e-board", the Events page renders additional controls: a + New Event button above the Upcoming Events list, and per-card Edit, Delete, and Announce icon buttons. Creating events opens CreateEventModal; editing opens EditEventModal. Both modals are mounted via React.createPortal onto document.body. A toggle pill bar (Standard / Hidden) lets e-board users switch between the public-facing event feed and the hidden administrative bucket. All event data is typed as AdminEvent for e-board sessions and MemberEvent for general-member sessions, both extending the shared BaseEvent base type from src/types/index.ts.
The AdminEvent Type
TheAdminEvent type is defined in src/types/index.ts and is the authoritative shape for events viewed by e-board users. It extends BaseEvent with fields that are only exposed to admins.
isAdminEvent type guard checks for the is_hidden property:
EventsPage and EditEventModal to safely branch logic that only applies to the admin-facing event shape.
View Modes: Standard vs. Hidden Buckets
EventsPage maintains a local showHidden boolean. A pill-style toggle at the top of the page switches between the two modes when the user is e-board.
- Standard Events
Shows three sub-sections:
- Events In-Session — events currently active based on
event_date,event_time, andevent_hours - Upcoming Events — events with a future
event_datenot yet in-session - Past Events — events with a past
event_date, paginated with a “Load More” button (3 per page)
Hidden events participate in the same hours-granting system as standard events. The
event_hours and event_hours_type fields are still required when creating a bucket so that the backend correctly credits the right hours category when members are manually added.Creating an Event
CreateEventModal is mounted via React.createPortal onto document.body (z-index 9999). It owns all form state locally and uses useScrollLock(true) to prevent background scroll while open. The + New Event button is only visible to e-board users in the Upcoming Events header.
Form Fields
Required Fields
Required Fields
| Field | State Variable | Type | API Key | Notes |
|---|---|---|---|---|
| Event Title | eventTitle | string | event_name | Plain text, trimmed on submit |
| Description | description | string | event_description | Plain text <textarea>, 3 rows |
| Location | location.name | string | event_location | Set by LocationPicker component |
| Date | date | string | event_date | HTML date input (YYYY-MM-DD) |
| Time | time | string | event_time | HTML time input (HH:MM) |
| Event Hours | hours | string | event_hours | Numeric, parsed with parseFloat, step 0.5 |
| Hours Type | hoursType | string | event_hours_type | Select: professional, social, service, development, n/a |
| Check-in Window | checkInWindow | number | check_in_window | Minutes, default 15 |
| Check-in Radius | checkInRadius | number | check_in_radius | Meters, default 50 |
| Event Limit | eventLimit | number | event_limit | Max attendees, default 100 |
Optional Fields
Optional Fields
| Field | State Variable | Type | API Key | Notes |
|---|---|---|---|---|
| Dress Code | dressCode | string | dress_code | Free-text, e.g., "Business Professional" |
| Sponsors Attending | sponsors | string[] | sponsors_attending | Multi-select via SponsorMultiSelect component |
| Latitude | location.latitude | number | event_lat | Set by LocationPicker, default 33.4242 (ASU) |
| Longitude | location.longitude | number | event_long | Set by LocationPicker, default -111.9281 (ASU) |
| Hidden | isHidden | boolean | is_hidden | Checkbox; makes event invisible in member feed |
Request Payload
Validation
All required fields are validated client-side before the request is sent. Errors are stored per-field in aFormErrors object and displayed inline below the relevant input. The form does not submit if any required field is empty or if hours is not a non-negative number.
Unsaved Changes Guard
CreateEventModal computes hasChanges() by JSON-serializing current state vs. the initialStateRef. If the user attempts to close with unsaved changes, a ConfirmationModal prompts:
Editing an Event
EditEventModal mirrors CreateEventModal but pre-populates its form from the eventToEdit prop. It additionally persists draft edits to localStorage under the key modal-event-edit-{eventId} whenever formData differs from initialStateRef. On successful save or deliberate discard, the key is cleared.
Edit Endpoint
EventsPage re-fetches the full event list from GET /events to refresh the UI.
Deleting an Event
EachEventCard rendered for e-board users has a Delete icon button. Clicking it sets eventToDelete and opens a ConfirmationModal:
allEvents[] local state immediately.
Announcing an Event
E-board users can send an email announcement for an event via the Announce button on eachEventCard. Clicking it opens a ConfirmationModal:
Location Picker
Both create and edit modals use theLocationPicker component (src/components/common/LocationPicker.tsx), which wraps Leaflet + leaflet-geosearch. It exposes a LocationObject:
(33.4242, -111.9281) correspond to Arizona State University’s main campus.
Sponsor Multi-Select
TheSponsorMultiSelect component (src/components/common/SponsorMultiSelect.tsx) lets e-board users tag which sponsors are attending an event. Selected values are stored as an array of company name strings that maps to the sponsors_attending API field.
Check-In Configuration
Thecheck_in_window and check_in_radius fields control the geo-fenced mobile check-in feature:
| Field | Unit | Default | Purpose |
|---|---|---|---|
check_in_window | Minutes | 15 | How many minutes before/after event_time the check-in button is active |
check_in_radius | Meters | 50 | Maximum GPS distance from event_lat/event_long for a valid check-in |
AdminEvent type — MemberEvent only receives check_in_window and check_in_radius if the member has RSVP’d, and only exposes a boolean can_check_in rather than the raw values.
RSVP and Attendance Data
AdminEvent carries the full user ID arrays:
EventParticipants:
API Reference
| Operation | Method | Endpoint | Key Body Fields |
|---|---|---|---|
| List events (authed) | GET | /events | — |
| List events (public) | GET | /events/public | — |
| Create event | POST | /events/add-event | event_name, event_date, event_time, event_hours, event_hours_type, is_hidden, check_in_window, check_in_radius, event_limit |
| Edit event | POST | /events/edit-event | event_id, name, date, location, is_hidden, check_in_window, check_in_radius |
| Delete event | POST | /events/delete-event | event_id |
| Announce event | POST | /events/send-event | event_id, recipient_filter |
| Get participants | GET | /events/:eventId/participants | — |