Scheduling dashboard for university student office assistants. Syncs work shifts and university timetables into a single calendar, streamlines schedule creation, and automates work document generation to replace manual spreadsheet workflows.
▶ Click to watch demo
University Portal Login
Signs in using the same RSA-encrypted login flow as the university browser portal. No separate account needed.

My Shift Schedule
Personal view of the logged-in student's own shifts with total hours for the current pay period.

All Part-time Workers Schedule
Everyone can see each other's shifts so no more than 3 workers end up scheduled on the same day.

Timetable Sync · Week View
Class blocks and work shifts on the same timeline so scheduling conflicts are caught before they happen.

Multi-day Shift Creation
Ctrl-click multiple dates to create shifts across all of them at once.

Dark Mode
Full dark theme across all views, toggled without a page reload.

Work Schedule Export
Exports the month's schedule as a formatted PDF ready to submit.

Work Log Document Generation
Auto-generates the official work log form as a PDF with personal details and work hours pre-filled, replacing what was previously done by hand.

Student Profile Card
Profile synced with the university portal and displayed as a digital student ID card.

%%{init: {'themeVariables': {'fontSize': '11px'}}}%%
graph TB
subgraph browser["Browser"]
UI["React Components\n30 custom components"]
CTX["Context API\nTheme · Auth state"]
end
subgraph vercel["Vercel · Next.js 14"]
direction TB
MW["Middleware\nAuth guard · Route protection"]
PAGES["App Router\nServer + Client Components"]
PROXY["API Route Handlers\n17 proxy endpoints"]
end
subgraph backend["FastAPI Backend\nAWS EC2"]
API["REST API"]
end
subgraph external["External"]
KLAS["KLAS Portal"]
GS["Google Sheets"]
end
UI --> MW
MW -->|"redirect /login if no cookie"| PAGES
PAGES --> PROXY
PROXY -->|"httpOnly cookie forwarding"| API
API --> KLAS
API --> GS
style browser fill:#1a1a2e,stroke:#61DAFB,color:#fff
style vercel fill:#1a1a2e,stroke:#fff,color:#fff
style backend fill:#1a1a2e,stroke:#FF9900,color:#fff
style external fill:#1a1a2e,stroke:#888,color:#fff
All auth state lives in httpOnly cookies — the browser never touches the token directly. Next.js middleware enforces protection at the edge before any component renders.
%%{init: {'themeVariables': {'fontSize': '11px'}}}%%
sequenceDiagram
autonumber
participant B as Browser
participant MW as Next.js Middleware
participant PR as API Route /api/auth/login
participant BE as FastAPI Backend
B->>MW: GET /calendar
MW->>MW: Check access_token cookie
alt cookie missing
MW-->>B: 302 → /login
end
B->>PR: POST /api/auth/login {student_id, password}
PR->>BE: POST /api/auth/login (forwarded)
BE-->>PR: {access_token, token}
Note over PR: Set httpOnly cookies<br/>access_token (JWT, 24h)<br/>session_token (KLAS session)
PR-->>B: 200 OK + Set-Cookie headers
B->>MW: GET /calendar
MW->>MW: access_token cookie ✓
MW-->>B: 200 — render calendar
%%{init: {'themeVariables': {'fontSize': '11px'}}}%%
graph TD
subgraph layout["Root Layout (layout.tsx)"]
TP["ThemeProvider\nContext · localStorage"]
end
subgraph calendar["Calendar Page (page.tsx) — state hub"]
CH["CalendarHeader\nView toggle · date nav · language"]
SB["Sidebar\nWorker list · filters · mini-calendar"]
CG["CalendarGrid\nMonth view · multi-select dates"]
WG["WeeklyCalendarGrid\nWeek/day view · time slots"]
MC["MobileDayCalendar\nMobile week strip"]
SEM["ShiftEditorModal\nCreate/edit · conflict detection"]
SDP["ShiftDetailPanel\nDesktop shift info"]
PC["ProfileCard\nProfile · settings · work hours"]
end
TP --> calendar
CH --> calendar
SB --> calendar
CG --> SEM
WG --> SEM
SEM --> calendar
app/
├── api/ # 17 API proxy route handlers (auth, shifts, holidays, users…)
├── calendar/ # Main protected page — calendar orchestrator
├── login/ # Auth page with error state from URL params
├── globals.css # 60+ CSS custom properties (dual theme)
└── layout.tsx # Root layout with ThemeProvider
components/ # 30 fully custom components
lib/
├── api.ts # Typed fetch wrapper — all 18 endpoint functions
├── types.ts # 20+ TypeScript interfaces (Shift, User, Holiday, TimetableEntry…)
├── i18n.ts # Bilingual Ko/En translation system
├── workMonth.ts # 25th–24th payroll cycle date math
└── theme.ts # Theme persistence + DOM application
middleware.ts # Edge auth guard — protects /calendar/* routes
npm install
cp .env.example .env.local # set BACKEND_URL
npm run dev| Variable | Description |
|---|---|
BACKEND_URL |
FastAPI backend URL (e.g. http://localhost:8000) |
| Script | Description |
|---|---|
npm run dev |
Start dev server on port 3000 |
npm run build |
Production build |
npm run lint |
ESLint check |
