A graduate school application tracker that helps applicants browse programs, track application status and deadlines, and manage contacts (professors, alumni, admissions staff) tied to each application.
- Author: Shota Togawa, Daiwei Zhang
- Class Link: https://johnguerra.co/classes/webDevelopment_online_summer_2026/
- Live demo: https://zdwww.github.io/graduate-track/
- Design Doc
- Sign up and log in with an email/password account; JWT-based authentication protects all data
- Browse a paginated catalog of schools and programs, filterable by school name
- View a program's detail page with degree, field, external links, and deadlines
- Add a program to your applications with one click ("+ Add") from the catalog
- Track each application's status (Draft, Applied, Offered, Rejected), notes, and interview dates
- Edit an application's status, notes, and interview dates from a dedicated edit form
- Delete applications you no longer want to track
- Add, edit, and delete contacts (name, school, role, email, notes) linked to a specific application
Application statuses: Draft, Applied, Offered, Rejected
| Layer | Technology |
|---|---|
| Frontend | React 19 (Hooks, React Router), Vite |
| Backend | Node.js, Express 5 |
| Database | MongoDB (native driver) |
| Auth | Passport (local + JWT strategies), bcrypt |
| Hosting | GitHub Pages (frontend) · Render (backend) |
.
├── backend/
│ ├── index.js # Express app entry point
│ ├── db.js # MongoDB connection
│ ├── config/
│ │ └── passport.js # Local + JWT auth strategies
│ ├── middleware/
│ │ └── auth.js # requireAuth (JWT) middleware
│ ├── routers/
│ │ ├── auth.js
│ │ ├── applications.js
│ │ ├── contacts.js
│ │ └── schools.js
│ ├── controllers/
│ │ ├── auth.js
│ │ ├── applications.js
│ │ ├── contacts.js
│ │ └── schools.js
│ ├── models/
│ │ ├── Users.js
│ │ ├── Applications.js
│ │ ├── Contacts.js
│ │ └── Schools.js
│ └── constants/
│ └── applications.js # APPLICATION_STATUS enum
├── docs/ # Production frontend (served via GitHub Pages)
│ ├── src/
│ │ ├── pages/ # LoginPage, SignupPage, SchoolsPage, SchoolPage,
│ │ │ # ApplicationsPage, ApplicationEditPage
│ │ ├── components/ # Navigation, Contacts, ContactForm, Loading, ErrorMessage
│ │ ├── helpers/
│ │ │ ├── apis/ # fetch wrappers per resource
│ │ │ ├── constants/ # API base URL, routes, status enum
│ │ │ ├── context/ # AuthContext/AuthProvider
│ │ │ └── hooks/ # useAuth, useSchools, useApplications, useContacts...
│ │ └── App.jsx
│ └── vite.config.js
└── package.json
- Node.js 18+
- MongoDB running locally on
mongodb://localhost:27017
git clone https://github.com/zdwww/graduate-track.git
cd graduate-track
npm install # root tooling (eslint, prettier, husky)
cd backend && npm install && cd ..
cd docs && npm install && cd ..# Terminal 1 — backend (http://localhost:3000)
cd backend
npm start
# Terminal 2 — frontend (http://localhost:5174)
cd docs
npm run devThe frontend auto-detects localhost and points API requests to http://localhost:3000/api.
Set these in backend/.env (see backend/.env.sample):
| Variable | Default | Description |
|---|---|---|
MONGODB_URI |
mongodb://localhost:27017 |
MongoDB connection string |
DB_NAME |
graduate_tracker |
Database name |
JWT_SECRET |
— | Secret used to sign auth JWTs (required) |
Once the app is running locally (or on the live demo):
- Sign up / log in — create an account on the Signup page or log in on the Login page. A JWT is stored client-side and attached to all subsequent API requests.
- Browse schools — the home page lists programs from the school catalog. Filter by school name and page through results.
- View a program — click a row to see its detail page: degree, field, external links, and deadlines.
- Add an application — click + Add on a program row to start tracking it; the button becomes disabled once the program has been added.
- Manage applications — the Applications page lists everything you're tracking. Click a row to expand it and see the application date, notes, interview dates, and contacts.
- Edit an application — click Edit to change its status, notes, and interview dates, then Save.
- Delete an application — click Delete and confirm; this removes the application (its contacts remain queryable by
applicationIdbut are no longer reachable from the UI). - Manage contacts — from an expanded application row, add a contact (name, school, role, email, notes) and edit or delete existing contacts inline.
Base URL (production): https://graduate-track-api.onrender.com/api
All endpoints except /auth/register and /auth/login require an Authorization: Bearer <token> header.
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/register |
Create an account (name, email, password) |
POST |
/auth/login |
Log in with email and password, returns a JWT |
GET |
/auth/me |
Get the current authenticated user |
| Method | Endpoint | Description |
|---|---|---|
GET |
/schools |
List programs in the school catalog |
GET |
/schools/:programId |
Get a single program by ID |
| Method | Endpoint | Description |
|---|---|---|
GET |
/applications |
List applications |
POST |
/applications |
Create an application from a program |
GET |
/application/:applicationId |
Get a single application |
PATCH |
/application/:applicationId |
Update an application |
DELETE |
/application/:applicationId |
Delete an application |
| Method | Endpoint | Description |
|---|---|---|
GET |
/contacts?applicationId= |
List the current user's contacts, optionally filtered by application |
POST |
/contacts |
Add a contact to an application |
GET |
/contact/:contactId |
Get a single contact |
PATCH |
/contact/:contactId |
Update a contact (name, school, role, email, notes) |
DELETE |
/contact/:contactId |
Delete a contact |
{
"name": "Elena Diaz",
"email": "elena@example.com",
"password": "at-least-8-characters"
}Response
{
"token": "...",
"user": { "id": "...", "email": "elena@example.com", "name": "Elena Diaz" }
}{
"schoolName": "Northeastern University",
"programId": "abc123",
"programName": "MS Computer Science",
"deadlines": [{ "term": "Fall", "date": "2026-12-01" }]
}status defaults to Draft. notes, interviewDates, and applicationDate are set by the server.
{
"applicationId": "665f1...",
"name": "Dr. Jane Smith",
"school": "Northeastern University",
"role": "Admissions Committee",
"email": "jsmith@example.edu",
"notes": "Met at the virtual open house."
}applicationId and name are required; school, role, email, and notes are optional.
MIT





