MM LNK 2025 — Real-time Pageant Scoring System
Published on 2025-08-27
Reading time: 4 min read
Description: A Next.js + MongoDB real-time scoring system built for Mister & Miss Linggo ng Kabataan 2025 — admin controls, judge panels, live tallying, and printable reports.
Link: https://mrandmisslnk2025.vercel.app/
Github repo: https://github.com/Exzort567/scoringSystem

This project is a full-stack scoring system built for Mister & Miss Linggo ng Kabataan 2025.
It’s designed to be reliable in a live event setting: admins control the competition flow, judges enter scores on separate devices, and results update in real time for the admin dashboard and final reports.
Below I’ll walk through the main pages and explain what each part does, why it matters, and the technical choices behind them.
Login Page

The Admin Dashboard is the event control center. Admins manage contestants and judges, control rounds, monitor scoring progress, and finalize results.
Key features showcased
- Email & password fields
- Password visibility toggle (eye icon)
- Role-based redirect after successful sign-in
Why this matters
Securing access and clearly separating roles prevents unauthorized actions (e.g., a judge accessing admin controls). The UX elements (eye icon, loading, friendly errors) improve usability during a high-pressure event.
Admin Dashboard

The Admin Dashboard is the event control center. Admins manage contestants and judges, control rounds, monitor scoring progress, and finalize results.
Core capabilities
• Contestant Management — create / edit / delete contestants, upload photo (Cloudinary), set contestant number and metadata.
• Judge Management — create judge accounts, reset passwords, see online status.
• Round Control — lock/unlock segments (Production, Sportswear, Q&A, Formal). Unlocking a round immediately notifies judges and makes the scoring UI visible to them.
• Live Score Monitor — live average and weighted totals for each contestant, submission status per judge (✓/✗).
• Top 5 & Finalization — the system auto-ranks contestants after rounds and can mark the Top 5 for the final judging stage.
• Export — PDF/Excel export of raw scores and final tallies.
Why this matters
Centralized control with live visibility is essential for transparency and fairness. Admins can monitor who submitted scores and intervene if corrections are needed.

Contestant creation includes an image uploader (Cloudinary). Images are stored there and the returned URL saved in MongoDB. The form validates inputs and shows previews so the admin can confirm before saving.
Judge Panel

Purpose
The Judge Panel is intentionally minimal and focused: judges see only the currently unlocked round and the list of contestants assigned. The scoring form includes each criterion and auto-calculates the weighted score live (so judges see the impact of their inputs before submitting).
Judging flow (example)
Production Number — criteria:
• Synchronization & Energy — 1–10 (10% weight)
• Stage Presence & Confidence — 1–10 (10% weight)
• Showmanship — 1–10 (5% weight)
Total for the round = 25% of final score.
Once a judge submits:
- The score is persisted to MongoDB.
- An Ably (realtime) event is broadcast so the admin dashboard updates instantly.
- The judge’s submission becomes locked (admin can re-open if edits are allowed).
Top 5 Final Round

Final round specifics
• Only Top 5 contestants are displayed.
• Criteria are scored 1–10 (Poise, Walk, Eye contact, Facial expression, X-factor).
• Scores are tallied in real time and reflect immediately on the admin live ranking.
Technical summary (why these tools)
• Next.js (App Router) — fast, server/client rendering, easy API routes.
• MongoDB — flexible document model for contestants, judges, rounds, and scores.
• NextAuth (Credentials) — role-based authentication (admin, judge).
• Ably — real-time pub/sub to broadcast round lock/unlock and score updates.
• Cloudinary — secure image upload and optimized delivery for contestant photos.
• pdfmake (or jsPDF) & xlsx — generate printable PDF and Excel reports.
Data model (high level)
users (judges, admins) — { email, name, passwordHash, role } contestants — { name, number, barangay, photoUrl, ... } rounds — { name, weights, isLocked } scores — { judgeId, contestantId, roundId, criteria: {..}, totalScore }