The Sponsor Portal atDocumentation 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.
/sponsor is the private dashboard available exclusively to company sponsors of Beta Alpha Psi Beta Tau Chapter. Once a sponsor authenticates with their unique passcode, they land on SponsorHome — a two-column layout where the left column displays and edits the company profile (logo, about text, and links) and the right column manages the resource library that chapter members can browse. All data is fetched from and persisted to the backend using the sponsor’s Supabase-issued JWT, which is passed as a Bearer token on every request.
Authentication
Sponsors do not use Google OAuth. Instead they authenticate through theSponsorAuth component on the /login page, which presents a company dropdown populated from GET /sponsors/names and a passcode field.
Select company
The dropdown is populated by
GET ${VITE_BACKEND_URL}/sponsors/names. Each option contains the sponsor’s company_name.Enter passcode
The passcode is passed to Supabase as a password. Internally, the company name is slugified (
spaces → -, lowercased) to form a synthetic email: company-name@example.com.The
ProtectedRoute component’s checkRole("sponsor") helper grants access to /sponsor. It handles both the string value "sponsor" (set directly by SponsorAuth) and an object of the form { type: "sponsor", companyName: string }. Unauthenticated visitors (no session) are redirected to /login; authenticated users with the wrong role are redirected to /auth/Home.Page Structure — SponsorHome
SponsorHome is the top-level page component. It orchestrates data fetching for both the sponsor profile and the resource list, then delegates rendering to child components.
Left Column — Company Profile
Renders
SponsorDescription with the company logo, name, about text, and links. An Edit Profile button opens ProfileEditModal.Right Column — Resources
Stacks
ResourceUploadForm above ResourceList. The form uploads new files; the list shows existing ones with preview and delete actions.Fetching Sponsor Data
On mount,SponsorHome resolves the company name from three sources in priority order:
role.companyName(fromuseAuth()— most reliable)localStorage.getItem('sponsorName')- Fallback: parse the email prefix from
session.user.email
POST /sponsors/get-one-sponsor-info with { sponsor_name }:
Fetching Resources
AftersponsorData.name resolves, a second fetch fires:
SponsorResource objects:
Company Profile — SponsorDescription
SponsorDescription is a presentational component that renders the sponsor’s logo, name, about text, and links list.
profileUrl prop every time the parent updates it:
Editing the Profile — ProfileEditModal
ProfileEditModal is a full-featured modal that lets sponsors update three things simultaneously: the company logo, the about text (max 500 characters), and the links list.
Profile Picture Upload
Photo uploads happen immediately when the user selects a file — they do not wait for the Save button:DELETE /sponsors/:name/pfp and reverts currentPfpUrl to /placeholder-logo.png.
Links Management
Link validation rules
Link validation rules
Every URL must pass
new URL(urlString) with a http: or https: protocol. Invalid URLs are blocked with an inline error message. When a user clicks Save with text still in the input field, a ConfirmDialog asks whether to add the pending link or discard it.string[] in React state. Existing links can be edited inline (pencil icon) or removed (× icon, confirmed via ConfirmDialog).
Saving Changes
Clicking Save Changes callsonUpdate with { description, links, newProfilePic }. The parent SponsorHome then calls POST /sponsors/:name/details:
Unsaved-Changes Guard
ProfileEditModal registers a beforeunload listener whenever hasUnsavedChanges() returns true. Closing the modal while changes are pending triggers a ConfirmDialog (“Discard Unsaved Changes?”) — the parent SponsorHome manages this dialog via the showDiscardConfirmation callback prop.
Resource Management
Uploading — ResourceUploadForm
ResourceUploadForm accepts a file, a resource name, and an optional description, then uploads to the backend. Files larger than 4.5 MB are routed through Vercel Blob’s client-side upload path; smaller files use a direct multipart/form-data POST.
| Category | Extensions |
|---|---|
| Documents | .pdf, .doc, .docx, .txt, .rtf |
| Images | .jpg, .jpeg, .png, .gif, .webp, .svg |
| Spreadsheets | .xls, .xlsx, .csv |
| Presentations | .ppt, .pptx |
Listing Resources — ResourceList
ResourcePreviewModal), and a Delete button. The Delete button is disabled when resource.url is missing.
Deleting Resources
Clicking Delete triggers aConfirmDialog. On confirmation, the parent SponsorHome determines the deletion path:
- Vercel Blob URL (
blob.vercel-storage.comin URL):
DELETE /blob-upload/sponsor/:namewith body{ blobUrl } - Standard resource URL:
DELETE /sponsors/:name/resourceswith body{ resourceUrl, resourceId }
fetchResources() is called to refresh the list.
Route & Access Control
ProtectedRoute’s checkRole("sponsor") helper handles both the string "sponsor" (set by SponsorAuth) and the object form { type: "sponsor" }. Unauthenticated users (no session) are redirected to /login; authenticated users without the sponsor role are redirected to /auth/Home.