- Frontend: React 19, Vite, TypeScript
- Styling: Tailwind CSS 3, Gilroy font, dark mode only
- UI: Radix UI primitives, Lucide icons, CVA for variants
- Data: Firebase Auth (Google), Cloud Firestore
- Files: Google Drive API (uploads to a shared drive folder)
- Hosting: Vercel
# Install dependencies
npm install
# Copy env template and fill in values
cp .env.example .env.local
# Start dev server
npm run dev| Variable | Where to find it |
|---|---|
VITE_FIREBASE_API_KEY |
Firebase Console > Project Settings > Your apps |
VITE_FIREBASE_AUTH_DOMAIN |
Same as above |
VITE_FIREBASE_PROJECT_ID |
Same as above |
VITE_FIREBASE_STORAGE_BUCKET |
Same as above |
VITE_FIREBASE_MESSAGING_SENDER_ID |
Same as above |
VITE_FIREBASE_APP_ID |
Same as above |
VITE_GOOGLE_DRIVE_FOLDER_ID |
The folder ID from the shared drive URL |
- Create a Firebase project at console.firebase.google.com
- Register a web app and copy the config values to
.env.local - Enable Google as a sign-in provider under Authentication
- Create a Firestore Database
- Deploy security rules from
firestore.rules - Enable the Google Drive API and Identity Toolkit API in GCP Console
src/
├── components/
│ ├── ui/ # Reusable primitives (Button, Card, Dialog, etc.)
│ ├── layout/ # Navbar, Footer, PageContainer, RootLayout
│ ├── application/ # ApplicationCard, QuestionBuilder, QuestionRenderer, FileUpload
│ └── guards/ # AuthGuard, InternalGuard, ManagerGuard
├── pages/
│ ├── Home, Login, Applications, ApplicationDetail, Apply, MyApplications
│ ├── Privacy, NotFound
│ └── manage/ # Dashboard, CreateApplication, ViewSubmissions, ReviewSubmission
├── hooks/ # useAuth, useApplications, useSubmissions, useOfficerApi
├── contexts/ # AuthContext (Firebase Auth + Google OAuth token)
├── lib/ # firebase.ts, firestore.ts, drive.ts, cn.ts
└── types/ # All TypeScript types and constants
- Internal users have
@acmutd.coemail addresses and can create/manage applications - Managers are designated per-application and can review submissions
- Public applications are visible to everyone; private ones require sign-in
- Applicants see "Under Review" from the moment they submit (no "Submitted" state visible)
- File uploads go to Google Drive, text data to Firestore
- Applications can be cloned and edited through the manage dashboard