The Eboard Management section is a self-containedDocumentation 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.
EboardManagement component rendered at the bottom of the Admin Dashboard, spanning the full two-column grid width. It displays all current e-board role entries — each representing a chapter position such as “President” or “VP of Finance” — with full CRUD support. Unlike the General Members panel, which manages user accounts, the Eboard section manages display entries that appear on the public-facing Eboard page. Each entry links a chapter role (with its own role-specific email address) to a member account (via the member’s personal email). Entries are ordered by a numeric rank field that controls display sequence on the public page.
Data Model
TheEboardFacultyEntry type is exported from src/types/index.ts:
EboardManagement adds an id field (from the API or generated via crypto.randomUUID() as fallback) and remaps API fields:
Fetching Eboard Entries
EboardManagement fetches on mount via fetchResources() (confusingly named — it fetches eboard data, not file resources):
Rank Ordering
Therank field is a positive integer that controls the display sequence on the public Eboard page. A lower rank number means the entry appears earlier (e.g., President at rank 1, VP at rank 2, etc.). There is no uniqueness constraint enforced client-side — two entries can share the same rank, in which case their relative order is determined by the server.
The EboardModal enforces a positive integer for rank:
'' as a type) but the backend will reject a missing rank.
The EboardModal Form
EboardModal is used for both adding and editing entries. It is rendered inside EboardManagement (not via createPortal) and wraps the shared Modal component.
Fields
| Field | Label | Required | Type | Notes |
|---|---|---|---|---|
rank | Rank | ✅ | number | Positive integer, display order |
role | Role Name | ✅ | string | e.g., "President", "VP of Finance" |
email | Role Email | ✅ | string | Role-specific email; used as primary key for edit/delete |
memberEmail | Member Email | ✅ | string | Linked to a general-member account; searchable typeahead |
Member Email Typeahead
ThememberEmail field is a searchable typeahead backed by GET /users (full user list, filtered to role === "general-member"). As the user types, a dropdown portal renders matching members by name or email:
createPortal onto document.body and is positioned below the input using getBoundingClientRect(). Pressing Enter selects the first filtered result. Clicking outside dismisses the dropdown.
The member list is sorted alphabetically by name in
EboardManagement.fetchMembers() before being passed to EboardModal. The typeahead uses a simple toLowerCase().includes() filter, not fuzzy search (unlike the eboard entry list, which uses Fuse.js).Adding an Eboard Entry
Click '+ New Eboard Member'
handleOpenAddEntryModal resets eboardFormData to blank values and sets selectedEntry to null, indicating create mode. showEboardModal becomes true.Fill out the EboardModal form
All four fields (rank, role, role email, member email) are required. The member email field uses the typeahead to search existing general-member accounts.
Editing an Eboard Entry
Click the ⋯ icon on an entry
handleOpenEditEntryModal(entry) populates eboardFormData with the existing entry’s values and sets selectedEntry to the entry object.Modify fields in EboardModal
The modal title changes to “Edit Eboard Member” and the confirm button reads “Update”.
Deleting an Eboard Entry
Clicking theTrash2 icon on an entry sets memberToDelete to the entry’s email (role_email) and opens a ConfirmationModal:
confirmDeleteEntry posts:
fetchResources() refreshes the list.
Search
EboardManagement uses Fuse.js for fuzzy search over the name field (weight 0.7) with a threshold of 0.4:
SearchInput updates searchQuery state, and filteredEntries is derived via useMemo from the Fuse instance. When searchQuery is empty, all entries are returned unfiltered.
Unsaved Changes Guard
EboardManagement tracks changes by comparing eboardFormData against initialEntryStateRef.current. If hasEboardChanges() returns true when the user attempts to close the modal, showConfirmEboardClose is set to true, rendering a ConfirmationModal:
"Changes discarded.".
Entry Display
Each entry in the list shows:API Reference
| Operation | Method | Endpoint | Body |
|---|---|---|---|
| List all entries | GET | /eboard | — |
| Add entry | POST | /eboard/add-role | { role, role_email, email, rank } |
| Edit entry | POST | /eboard/edit-role | { role_email, role, email, rank } |
| Delete entry | POST | /eboard/delete-role | { role_email } |
| List members (typeahead) | GET | /users | — (filtered client-side to general-member) |