PMB 2025 Frontend - Documentation
| Document Status | ||
|---|---|---|
| Document Owner | Product Engineering 2026 | Product Engineering 2026 |
| Contributors | ||
| Project Links | https://github.com/RistekCSUI/pmb2025-frontend | https://github.com/RistekCSUI/pmb2025-frontend |
| Project Links | https://pmb.cs.ui.ac.id | https://pmb.cs.ui.ac.id |
| Project Links | https://stg.api.pmb.cs.ui.ac.id (API) / Vercel preview deployments | https://stg.api.pmb.cs.ui.ac.id (API) / Vercel preview deployments |
| Project Links | Sentry (configured via SENTRY_DSN) | Sentry (configured via SENTRY_DSN) |
| Team | Theodore Kevin Himawan | theodore.kevin@ristek.cs.ui.ac.id |
| Team | Ari Darrell Muljono | darrell@ristek.cs.ui.ac.id |
| Team | Grace Karina | gracekarin@ristek.cs.ui.ac.id |
| Team | Yeshua Marco G. Manurung | marco@ristek.cs.ui.ac.id |
π Background
Overviewβ
The PMB 2025 Frontend is the student-facing web application for the RISTEK PMB (Penerimaan Mahasiswa Baru) platform. It provides new students with an interactive onboarding experience including SSO-based login, profile setup, friendship/invitation matching (Pansos & Katalink), puzzle games, assignment submissions, event browsing, leaderboards, badges, and QR code interactions β all wrapped in a responsive, mobile-friendly UI.
Stakeholdersβ
- Users: New students (maba), senior mentors, PMB committee (panitia)
- Upstream Dependencies: PMB 2025 Backend API (https://api.pmb.cs.ui.ac.id), UI SSO CAS (https://sso.ui.ac.id/cas2/), AWS S3 (image hosting)
- Downstream Consumers: None (this is the end-user client application)
Scope & Boundariesβ
- In Scope: User-facing pages (login, onboarding, home, friends, profile, events, assignments, leaderboard, about), SSO authentication flow, Redux state management, API integration with the PMB backend, responsive UI, QR code token system, puzzle game interface.
- Out of Scope: Admin panel (separate project: pmb2025-admin-panel), backend API logic, Data Science recommendation engine, infrastructure provisioning.
βοΈ Architecture & Design
System Diagramβ
Architecture Decisions (ADRs)β
- Language/Framework: TypeScript 4.3.2 / Next.js 12.2.4 (Pages Router) / React 17.0.2
- State Management: Redux Toolkit with redux-persist (localStorage) and async thunks
- Styling: Tailwind CSS 2.1.4 + styled-components 5.3.0 + Chakra UI 1.6.5 + Emotion
- HTTP Client: Axios with JWT interceptor (Authorization: JWT <token>)
- Form Handling: Formik + Yup (validation), react-hook-form (alternative usage)
- Animation: Framer Motion
- Error Monitoring: Sentry (@sentry/nextjs)
- Deployment: Vercel (production on master, staging preview on staging)
- Communication: Synchronous REST calls to PMB Backend API; no SSR data fetching, all API calls happen client-side.
π»Technical Specifications
API Documentationβ
The frontend communicates with the PMB Backend via an Axios-based service layer in api/services/. All requests include: Authorization: JWT <token> header (from localStorage) Timezone header (from Intl.DateTimeFormat) Base URL resolution (config.ts):
| Environment | URL |
|---|---|
| prod | https://api.pmb.cs.ui.ac.id |
| dev | https://stg.api.pmb.cs.ui.ac.id |
| local | http://localhost:5000 |
| Service Modules: | |
| Service | File |
| --- | --- |
| sso | api/services/sso.ts |
| token | api/services/token.ts |
| profile | api/services/profile.ts |
| invitations | api/services/invitations.ts |
| puzzle | api/services/puzzle.ts |
| seniors | api/services/seniors.ts |
| assignment | api/services/assignment.ts |
| events | api/services/events.ts |
| katalink | api/services/katalink.ts |
Pages & Routesβ
| Route | File | Auth | Description |
|---|---|---|---|
| / | pages/index.tsx | requireAnon | Login page (SSO UI popup / LDAP form) |
| /terms-and-conditions | pages/terms-and-conditions/index.tsx | requireAuth | Terms & conditions (pre-onboarding) |
| /onboarding | pages/onboarding.tsx | requireAuth | 3-step onboarding: personal info β interests β match |
| /home | pages/home.tsx | requireAuth | Homepage with events, FAQ, token section |
| /friends | pages/friends/index.tsx | requireAuth | Friends hub (tabs: Katalink, Puzzle, Seniors/Juniors) |
| /friends/invitations | pages/friends/invitations/index.tsx | requireAuth | Sent & received invitations list |
| /friends/invitations/[id] | pages/friends/invitations/[id].tsx | β | Invitation detail |
| /friends/[id] | pages/friends/[id].tsx | β | Friend profile detail |
| /friends/seniors/[id] | pages/friends/seniors/[id].tsx | β | Senior profile detail |
| /friends/invite/[id] | pages/friends/invite/[id].tsx | β | Send invitation flow |
| /friends/puzzle/[id] | pages/friends/puzzle/[id].tsx | β | Puzzle game interface |
| /profile | pages/profile/index.tsx | requireAuth | User profile page |
| /profile/badge | pages/profile/badge/index.tsx | β | Badge collection |
| /profile/badge/[id] | pages/profile/badge/[id].tsx | β | Badge detail |
| /assignment | pages/assignment/index.tsx | requireAuth | Assignment list (Maba only) |
| /assignment/[id] | pages/assignment/[id].tsx | β | Assignment detail with submission |
| /events | pages/events/index.tsx | requireAuth | Events list (internal/external tabs) |
| /events/[slug] | pages/events/[slug].tsx | β | Event detail |
| /leaderboard | pages/leaderboard/index.tsx | β | Leaderboard (individual & group) |
| /about | pages/about/index.tsx | β | About Fasilkom UI |
| /failed-qr | pages/failed-qr/index.tsx | β | Failed QR scan handling |
| /404 | pages/404.tsx | β | Custom 404 page |
State Management (Redux)β
The app uses Redux Toolkit with redux-persist for selective state persistence to localStorage.
| Slice | Persisted | Purpose |
|---|---|---|
| auth | Yes (token, account) | Authentication state, login/logout, new account flag |
| profile | No | Profile data, loading states, messages |
| invitations | No | Sent/received invitation lists |
| assignment | Yes | Assignment list and details |
| event | Yes | Event list |
| seniors | No | Senior list, details, loading states |
| Services are injected into thunks via extraArgument in the Redux middleware configuration. A custom logger middleware is active in development mode. |
Authentication Flowβ
- SSO UI Login: user clicks login β popup opens backend URL
GET /api/auth/loginβ backend redirects to UI SSO CAS β CAS authenticates β backend rendersindex.ejswith token β popup sends token to parent viawindow.postMessageβ frontend stores JWT in localStorage. - LDAP Fallback: username/password form β
POST /api/auth/ldapβ backend authenticates via RISTEK SSO LDAP or SSO Proxy β returns JWT β frontend stores JWT in localStorage. - Route Protection:
requireAuthHOC checks localStorage for token and redirects to/if missing. - Onboarding Guard: users without
jurusanorUser_Interestare redirected through/terms-and-conditionsβ/onboardingβ/home. - Anonymous Guard:
requireAnonHOC redirects logged-in users away from the login page to/home. - Maba vs Senior: distinguished by comparing
angkatanagainstNEXT_PUBLIC_PMB_YEAR. Maba users have access to assignments; seniors have different friend matching flows.
Data Model/Schemaβ
Core TypeScript interfaces defined in types/:
| Type File | Key Interfaces |
|---|---|
| common.d.ts | ErrorAttribute, ServerError, UserData, ProfileData |
| seniors.d.ts | Friends |
| puzzle.d.ts | Friends, PuzzleFriends, MabaReview, Question, QuestionForMaba, Puzzle, PuzzlePayload, PuzzleAnswers, Answer |
| Additional interfaces are co-located with components (e.g. match.d.ts, invitationInterface.d.ts, friend.d.ts). |
Project Structureβ
pmb2025-frontend/
βββ .github/
β βββ workflows/
β βββ deploy.yml # Production: push to master β Vercel prod
β βββ staging.yml # Staging: push/PR to staging β Vercel preview
βββ api/
β βββ services/
β βββ index.ts # Axios interceptor setup + service aggregation
β βββ sso.ts # SSO/LDAP auth calls
β βββ token.ts # Token & QR API calls
β βββ profile.ts # Profile, interests, badges, invitations
β βββ invitations.ts # Invitation CRUD
β βββ puzzle.ts # Puzzle game API
β βββ seniors.ts # Senior profiles, messaging
β βββ assignment.ts # Assignments & submissions
β βββ events.ts # Events & carousel
β βββ katalink.ts # Friendship recommendations
βββ components/
β βββ common/
β β βββ layout.tsx # Main layout wrapper with Navbar
β β βββ requireAuth.tsx # Auth guard HOC (protected routes)
β β βββ requireAnon.tsx # Anonymous-only HOC (login page)
β β βββ analytics.ts # Analytics utilities
β βββ container/ # Page-level container components
β β βββ Login/ # SSO popup + LDAP login form
β β βββ Onboarding/ # 3-step onboarding flow
β β βββ Profile/ # Profile view + edit
β β βββ Friends/ # Friends hub with tabs
β β βββ Invitations/ # Invitation management
β β βββ Events/ # Event listing + detail
β β βββ Assignments/ # Assignment listing + submission
β β βββ Leaderboard/ # Individual & group rankings
β β βββ About/ # About Fasilkom
β β βββ homepage/ # Home page sections
β β βββ Footer/ # Page footer
β β βββ Loading/ # Loading spinner
β β βββ Error/ # Error display
β β βββ TermsConditions/ # T&C page
β β βββ FailedQR/ # QR failure handling
β β βββ FloatingContactButton/ # Contact button overlay
β βββ module/ # Shared complex modules
β β βββ Navbar/ # Top navigation bar with profile dropdown
β β βββ DetailsNavbar/ # Back-navigation for detail pages
β βββ elements/ # Reusable UI primitives
β βββ Button/, Card/, Form/, Input/
β βββ Toast/, Popup/, SearchBar/, PageTab/
β βββ Token/, FriendRequestCard/, Dropzone/
β βββ InterestBadge/, InfiniteScroll/, Podium/
β βββ ModalReview/, AdminMessage/
β βββ FloatingContactButton/
βββ hooks/
β βββ windowSize.ts # useWindowSize hook
β βββ swiperRef.ts # useSwiperRef hook
βββ libs/
β βββ index.ts # Date checks, URL helpers, puzzle utilities
β βββ dateTime/ # Date/time formatting helpers
β βββ Slugify/ # URL slug generation
β βββ capitalize/ # String capitalization
β βββ Assignment/ # Assignment-specific utilities
βββ pages/
β βββ _app.tsx # App root (Redux Provider, PersistGate, ChakraProvider)
β βββ _document.tsx # Custom HTML document
β βββ _error.tsx # Error page with Sentry reporting
β βββ 404.tsx # Custom 404 page
β βββ index.tsx # Login page (root route)
β βββ onboarding.tsx # Onboarding page
β βββ home.tsx # Home dashboard
β βββ friends/ # Friends routes (index, [id], invitations, puzzle, seniors)
β βββ profile/ # Profile routes (index, badge)
β βββ assignment/ # Assignment routes (index, [id])
β βββ events/ # Events routes (index, [slug])
β βββ leaderboard/ # Leaderboard
β βββ about/ # About page
β βββ terms-and-conditions/ # T&C page
β βββ failed-qr/ # Failed QR page
βββ public/
β βββ images/ # Static images and illustrations
β βββ favicon/ # Favicon assets
β βββ fonts/ # Custom fonts (SFProDisplay, Literata, SpaceMono, Oswald)
βββ redux/
β βββ store.ts # Redux store config (RTK, persist, thunk with services)
β βββ reducers.ts # Root reducer combining all slices
β βββ middlewares/logger/ # Dev-only logging middleware
β βββ slices/
β βββ auth/ # Auth slice (login, logout, token)
β βββ profile/ # Profile slice
β βββ invitations/ # Invitations slice
β βββ assignment/ # Assignment slice
β βββ seniors/ # Seniors slice
β βββ event/ # Event slice
βββ styles/
β βββ globals.css # Global styles (font imports, Swiper overrides)
β βββ Home.module.css # CSS Module for home page
βββ types/
β βββ common.d.ts # UserData, ProfileData, errors
β βββ seniors.d.ts # Friends type
β βββ puzzle.d.ts # Puzzle, MabaReview, Question types
βββ config.ts # API base URL resolution by environment
βββ next.config.js # Next.js config (image domains, TS/ESLint ignore)
βββ tailwind.config.js # Tailwind config (custom colors, fonts, sizing)
βββ postcss.config.js # PostCSS config
βββ tsconfig.json # TypeScript config (strict mode, ES5 target)
βββ .eslintrc.js # ESLint config
βββ .prettierrc # Prettier config
βββ sentry.client.config.js # Sentry browser initialization
βββ sentry.server.config.js # Sentry server initialization
βββ package.json # Dependencies and scripts
Componentsβ
| Layer | Paths | Responsibility |
|---|---|---|
| Login | components/container/Login | Provides two auth methods β SSO UI popup (opens backend /api/auth/login in a new window, listens for postMessage with JWT) and LDAP form (username/password POST to backend). Redirects to onboarding or home based on profile completeness. |
| Onboarding | components/container/Onboarding | Three-step wizard: (1) personal information form (name, birth date, school, social media, domicile), (2) interest selection from predefined categories, (3) friend match preview. Uses Formik + Yup for validation. |
| Layout | components/common/layout.tsx | Wraps page content with the Navbar component. Navbar is hidden on / (login) and /onboarding. Includes logout popup confirmation. |
| Friends Hub | components/container/Friends | Tabbed interface with three sections β Katalink (recommendation-based friend matching), Puzzle (puzzle game matching), and Seniors/Juniors (cross-cohort connections). Each tab has its own detail views, invitation flows, and review mechanisms. |
| Token Section | components/elements/Token | QR code-based friend connection system. Users can generate QR tokens, scan others' codes, and send friend requests via token input. |
| Assignments | components/container/Assignments | Available only to Maba users. Lists assignments with due dates, supports file upload to S3 via presigned URLs using react-dropzone, and tracks submission status. |
| Events | components/container/Events | Displays PMB events separated by internal/external tabs, with carousel/banner for featured items. Uses Swiper for carousel slides. |
| Leaderboard | components/container/Leaderboard | Ranking display with individual and group (kelompok) views, featuring a podium component for top 3 and virtualized scrolling for the full list. |
| Navbar | components/module/Navbar | Top navigation with profile avatar, dropdown menu (profile, badges, logout), and responsive mobile hamburger menu. |
βοΈ Operational Playbook
Infrastructureβ
- Cloud Provider: Vercel
- Production Deployment: Push to master branch β GitHub Actions triggers Vercel production deploy (deploy.yml)
- Staging Deployment: Push/PR to staging branch β GitHub Actions triggers Vercel preview deploy (staging.yml)
- Image CDN: Next.js Image Optimization with allowed domains: images.ctfassets.net, pmb22-staging.s3.ap-southeast-1.amazonaws.com
- Link: https://pmb.cs.ui.ac.id
Environment Variablesβ
(example)
| Key | Description | Default (Dev) | Sensitive? |
|---|---|---|---|
| NEXT_PUBLIC_NODE_ENV | Environment selector for API base URL (prod / dev / local) | local | No |
| NEXT_PUBLIC_PMB_YEAR | Cohort year for Maba vs senior distinction | 2025 | No |
| NEXT_PUBLIC_BEGIN_MA | MA (Maba Activity) start date | β | No |
| NEXT_PUBLIC_BEGIN_MM | MM (Maba Matching) start date | β | No |
| NEXT_PUBLIC_DEADLINE_MA | MA deadline timestamp | β | No |
| NEXT_PUBLIC_DEADLINE_MM | MM deadline timestamp | β | No |
| NEXT_PUBLIC_DEADLINE_MM_SENIOR | Senior MM deadline timestamp | β | No |
| SENTRY_DSN | Sentry DSN (server-side) | β | Yes |
| NEXT_PUBLIC_SENTRY_DSN | Sentry DSN (client-side) | β | Yes |
| WEBDEV_VERCEL_TOKEN | Vercel deploy token (GitHub Actions secret) | β | Yes |
| ORG_ID | Vercel organization ID (GitHub Actions secret) | β | Yes |
| PROJECT_ID | Vercel project ID (GitHub Actions secret) | β | Yes |
πQuestions
π List of frequently asked questions or question that need to be answered that is related to this initiative ..