MOPC-App/docs/claude-architecture-redesign/15-admin-ui.md

762 lines
54 KiB
Markdown
Raw Permalink Normal View History

# Admin UI Redesign
## Overview
The admin interface is the control plane for the entire MOPC competition. It must surface the redesigned Competition→Round model, jury group management, multi-round submissions, mentoring oversight, and winner confirmation — all through an intuitive, efficient interface.
### Design Principles
| Principle | Application |
|-----------|-------------|
| **Progressive disclosure** | Show essentials first; details on drill-down |
| **Linear-first navigation** | Round list is a flat, ordered timeline — not nested trees |
| **Status at a glance** | Color-coded badges, progress bars, countdowns on every card |
| **Override everywhere** | Every automated decision has an admin override within reach |
| **Audit transparency** | Every action logged; audit trail accessible from any entity |
### Tech Stack (UI)
- **Framework:** Next.js 15 App Router (Server Components default, `'use client'` where needed)
- **Styling:** Tailwind CSS 4, mobile-first breakpoints (`md:`, `lg:`)
- **Components:** shadcn/ui as base (Button, Card, Dialog, Sheet, Table, Tabs, Select, etc.)
- **Data fetching:** tRPC React Query hooks (`trpc.competition.getById.useQuery()`)
- **Brand:** Primary Red `#de0f1e`, Dark Blue `#053d57`, White `#fefefe`, Teal `#557f8c`
- **Typography:** Montserrat (600/700 headings, 300/400 body)
---
## Current Admin UI Audit
### Existing Pages
```
/admin/
├── page.tsx — Dashboard (stats cards, quick actions)
├── rounds/
│ ├── pipelines/page.tsx — Pipeline list
│ ├── new-pipeline/page.tsx — Create new pipeline
│ └── pipeline/[id]/
│ ├── page.tsx — Pipeline detail (tracks + stages)
│ ├── edit/page.tsx — Edit pipeline settings
│ ├── wizard/page.tsx — Pipeline setup wizard
│ └── advanced/page.tsx — Advanced config (JSON editor)
├── awards/
│ ├── page.tsx — Award list
│ ├── new/page.tsx — Create award
│ └── [id]/
│ ├── page.tsx — Award detail
│ └── edit/page.tsx — Edit award
├── members/
│ ├── page.tsx — User list
│ ├── invite/page.tsx — Invite user
│ └── [id]/page.tsx — User detail
├── mentors/
│ ├── page.tsx — Mentor list
│ └── [id]/page.tsx — Mentor detail
├── projects/ — Project management
├── audit/page.tsx — Audit log viewer
├── messages/
│ ├── page.tsx — Message center
│ └── templates/page.tsx — Email templates
├── programs/ — Program management
├── settings/ — System settings
├── reports/ — Reports
├── partners/ — Partner management
└── learning/ — Learning resources
```
### Current Limitations
| Page | Limitation |
|------|-----------|
| Pipeline list | Shows pipelines as opaque cards. No inline status |
| Pipeline detail | Nested Track→Stage tree is confusing. Must drill into each stage |
| Pipeline wizard | Generic JSON config per stage type. Not type-aware |
| Award management | Awards are separate from pipeline. No jury group link |
| Member management | No jury group concept. Can't see "Jury 1 members" |
| Mentor oversight | Basic list only. No workspace visibility |
| No confirmation UI | Winner confirmation doesn't exist |
---
## Redesigned Navigation
### New Admin Sitemap
```
/admin/
├── page.tsx — Dashboard (competition overview)
├── competition/
│ ├── page.tsx — Competition list
│ ├── new/page.tsx — Create competition wizard
│ └── [id]/
│ ├── page.tsx — Competition dashboard (round timeline)
│ ├── settings/page.tsx — Competition-wide settings
│ ├── rounds/
│ │ ├── page.tsx — All rounds (timeline view)
│ │ ├── new/page.tsx — Add round
│ │ └── [roundId]/
│ │ ├── page.tsx — Round detail (type-specific view)
│ │ ├── edit/page.tsx — Edit round config
│ │ ├── projects/page.tsx — Projects in this round
│ │ ├── assignments/page.tsx — Assignments (EVALUATION rounds)
│ │ ├── filtering/page.tsx — Filtering dashboard (FILTERING)
│ │ ├── submissions/page.tsx — Submission status (INTAKE/SUBMISSION)
│ │ ├── mentoring/page.tsx — Mentoring overview (MENTORING)
│ │ ├── stage-manager/page.tsx — Live stage manager (LIVE_FINAL)
│ │ └── confirmation/page.tsx — Confirmation (CONFIRMATION)
│ ├── jury-groups/
│ │ ├── page.tsx — All jury groups
│ │ ├── new/page.tsx — Create jury group
│ │ └── [groupId]/
│ │ ├── page.tsx — Jury group detail + members
│ │ └── edit/page.tsx — Edit group settings
│ ├── submission-windows/
│ │ ├── page.tsx — All submission windows
│ │ └── [windowId]/
│ │ ├── page.tsx — Window detail + requirements
│ │ └── edit/page.tsx — Edit window
│ ├── awards/
│ │ ├── page.tsx — Special awards for this competition
│ │ ├── new/page.tsx — Create award
│ │ └── [awardId]/
│ │ ├── page.tsx — Award detail
│ │ └── edit/page.tsx — Edit award
│ └── results/
│ └── page.tsx — Final results + export
├── members/ — User management (unchanged)
├── audit/page.tsx — Audit log (enhanced)
├── messages/ — Messaging (unchanged)
├── programs/ — Program management
└── settings/ — System settings
```
---
## Competition Dashboard
The central hub for managing a competition. Replaces the old Pipeline detail page.
### Layout
```
┌──────────────────────────────────────────────────────────────────────────┐
│ MOPC 2026 Competition Status: ACTIVE [Edit] │
│ Program: Monaco Ocean Protection Challenge 2026 │
├──────────────────────────────────────────────────────────────────────────┤
│ │
│ ── Quick Stats ──────────────────────────────────────────────────── │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │
│ │ 127 │ │ 23 │ │ 8 │ │ Round 3 of 8 │ │
│ │ Applications│ │ Advancing │ │ Jury Groups│ │ Jury 1 Evaluation │ │
│ │ │ │ │ │ 22 members │ │ ███████░░░ 68% │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────────────┘ │
│ │
│ ── Round Timeline ───────────────────────────────────────────────── │
│ │
│ ✓ R1 ✓ R2 ● R3 ○ R4 ○ R5 ○ R6 ○ R7 ○ R8 │
│ Intake Filter Jury 1 Submn 2 Jury 2 Mentor Finals Confirm │
│ DONE DONE ACTIVE PENDING PENDING PENDING PENDING PENDING │
│ 127 98→23 23/23 │ │
│ eval'd │ │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Round 3: Jury 1 — Semi-finalist Selection [Manage →] │ │
│ │ Type: EVALUATION | Jury: Jury 1 (8 members) │ │
│ │ Status: ACTIVE | Started: Feb 1 | Deadline: Mar 15 │ │
│ │ │ │
│ │ ████████████████████████████████████░░░░░░░░░░░░ 68% │ │
│ │ Evaluations: 186 / 276 complete │ │
│ │ │ │
│ │ ┌──────────────┬──────────────┬──────────────┬────────────┐ │ │
│ │ │ Assigned: 276│ Complete: 186│ Pending: 90 │ COI: 12 │ │ │
│ │ └──────────────┴──────────────┴──────────────┴────────────┘ │ │
│ │ │ │
│ │ [ View Assignments ] [ View Results ] [ Advance Projects ] │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ ── Sidebar: Jury Groups ─────────────────────────────────────────── │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Jury 1 (8 members) [→] │ │ Jury 2 (6 members) [→] │ │
│ │ Avg load: 15.3 / 20 │ │ Not yet assigned │ │
│ │ ████████████████░░░░ │ │ ░░░░░░░░░░░░░░░░░░░░ │ │
│ └─────────────────────────────┘ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Jury 3 (5 members) [→] │ │ Innovation Jury (4) [→] │ │
│ │ Assigned to R7 + R8 │ │ Award jury │ │
│ └─────────────────────────────┘ └─────────────────────────────┘ │
│ │
│ ── Sidebar: Special Awards ──────────────────────────────────────── │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Innovation Award STAY_IN_MAIN Jury: Innovation Jury [→] │ │
│ │ Impact Award SEPARATE_POOL Jury: Impact Jury [→] │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
```
### Key Components
| Component | Description |
|-----------|-------------|
| `<QuickStatsGrid>` | 4 stat cards showing key metrics |
| `<RoundTimeline>` | Horizontal timeline with round status badges |
| `<ActiveRoundCard>` | Expanded card for the currently active round |
| `<JuryGroupCards>` | Grid of jury group summary cards |
| `<AwardSidebar>` | List of special awards with status |
---
## Competition Setup Wizard
Replaces the old Pipeline Wizard. A multi-step form that creates the entire competition structure.
### Wizard Steps
```
Step 1: Basics → Competition name, program, categories
Step 2: Round Builder → Add/reorder rounds (type picker)
Step 3: Jury Groups → Create jury groups, assign to rounds
Step 4: Submission Windows → Define file requirements per window
Step 5: Special Awards → Configure awards (optional)
Step 6: Notifications → Deadline reminders, email settings
Step 7: Review & Create → Summary of everything, create button
```
### Step 1: Basics
```
┌──────────────────────────────────────────────────────────────────┐
│ Create Competition — Step 1 of 7: Basics │
│ ●───○───○───○───○───○───○ │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Competition Name: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ MOPC 2026 Competition │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ Program: [MOPC 2026 ▼] │
│ │
│ Category Mode: │
│ ● Shared — Both Startups and Concepts in same flow │
│ ○ Split — Separate finalist counts per category │
│ │
│ Finalist Counts: │
│ Startups: [3 ] Concepts: [3 ] │
│ │
│ [ Cancel ] [ Next → ] │
└──────────────────────────────────────────────────────────────────┘
```
### Step 2: Round Builder
The core of the wizard — a drag-and-drop round sequencer.
```
┌──────────────────────────────────────────────────────────────────┐
│ Create Competition — Step 2 of 7: Round Builder │
│ ○───●───○───○───○───○───○ │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Build your competition flow by adding rounds: │
│ │
│ ┌────┬──────────────────────────────┬──────────────┬────────┐ │
│ │ # │ Round │ Type │ Actions│ │
│ ├────┼──────────────────────────────┼──────────────┼────────┤ │
│ │ 1 │ ≡ Application Window │ INTAKE │ ✎ ✕ │ │
│ │ 2 │ ≡ AI Screening │ FILTERING │ ✎ ✕ │ │
│ │ 3 │ ≡ Jury 1 - Semi-finalist │ EVALUATION │ ✎ ✕ │ │
│ │ 4 │ ≡ Semi-finalist Documents │ SUBMISSION │ ✎ ✕ │ │
│ │ 5 │ ≡ Jury 2 - Finalist │ EVALUATION │ ✎ ✕ │ │
│ │ 6 │ ≡ Finalist Mentoring │ MENTORING │ ✎ ✕ │ │
│ │ 7 │ ≡ Live Finals │ LIVE_FINAL │ ✎ ✕ │ │
│ │ 8 │ ≡ Confirm Winners │ CONFIRMATION │ ✎ ✕ │ │
│ └────┴──────────────────────────────┴──────────────┴────────┘ │
│ │
│ [ + Add Round ] │
│ │
│ Available Round Types: │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ INTAKE │ │ FILTERING │ │ EVALUATION │ │ SUBMISSION │ │
│ │ Collect │ │ AI screen │ │ Jury score │ │ More docs │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ MENTORING │ │ LIVE_FINAL │ │ CONFIRM │ │
│ │ Workspace │ │ Live vote │ │ Cement │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ [ ← Back ] [ Next → ] │
└──────────────────────────────────────────────────────────────────┘
```
### Step 2: Round Config Sheet
When clicking ✎ on a round, a sheet slides out with type-specific config:
```
┌──────────────────────────────────────────────────────────────────┐
│ Configure Round: Jury 1 - Semi-finalist (EVALUATION) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Round Name: [Jury 1 - Semi-finalist Selection ] │
│ │
│ ── Jury Group ──────────────────────────────────────────────── │
│ Assign jury group: [Jury 1 ▼] [ + Create New ] │
│ │
│ ── Assignment ──────────────────────────────────────────────── │
│ Reviews per project: [3 ] │
│ (Caps and quotas configured on the jury group) │
│ │
│ ── Scoring ─────────────────────────────────────────────────── │
│ Evaluation form: [Standard Criteria Form ▼] │
│ Scoring mode: ● Criteria-based ○ Global score ○ Binary │
│ Score range: [1 ] to [10] │
│ │
│ ── Document Visibility ─────────────────────────────────────── │
│ This round can see docs from: │
│ ☑ Window 1: Application Documents │
│ ☐ Window 2: Semi-finalist Documents (not yet created) │
│ │
│ ── Advancement ─────────────────────────────────────────────── │
│ Advancement mode: │
│ ● Top N by score │
│ ○ Admin selection │
│ ○ AI recommended │
│ Advance top: [8 ] projects per category │
│ │
│ ── Deadline ────────────────────────────────────────────────── │
│ Start date: [Feb 1, 2026 ] │
│ End date: [Mar 15, 2026] │
│ │
│ [ Cancel ] [ Save Round ] │
└──────────────────────────────────────────────────────────────────┘
```
### Step 3: Jury Groups
```
┌──────────────────────────────────────────────────────────────────┐
│ Create Competition — Step 3 of 7: Jury Groups │
│ ○───○───●───○───○───○───○ │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Jury 1 — Semi-finalist Selection [Edit]│ │
│ │ Linked to: Round 3 │ │
│ │ Members: 0 (add after creation) │ │
│ │ Default cap: 20 (SOFT +2) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Jury 2 — Finalist Selection [Edit]│ │
│ │ Linked to: Round 5 │ │
│ │ Members: 0 (add after creation) │ │
│ │ Default cap: 15 (HARD) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Jury 3 — Live Finals + Confirmation [Edit]│ │
│ │ Linked to: Round 7, Round 8 │ │
│ │ Members: 0 (add after creation) │ │
│ │ All finalists auto-assigned │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ [ + Create Jury Group ] │
│ │
│ Note: Add members to jury groups after competition is created. │
│ │
│ [ ← Back ] [ Next → ] │
└──────────────────────────────────────────────────────────────────┘
```
### Step 4: Submission Windows
```
┌──────────────────────────────────────────────────────────────────┐
│ Create Competition — Step 4 of 7: Submission Windows │
│ ○───○───○───●───○───○───○ │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Window 1: Application Documents (linked to Round 1) │ │
│ │ │ │
│ │ File Requirements: │ │
│ │ 1. Executive Summary (PDF, max 5MB, required) │ │
│ │ 2. Business Plan (PDF, max 20MB, required) │ │
│ │ 3. Team Bios (PDF, max 5MB, required) │ │
│ │ 4. Supporting Documents (any, max 50MB, optional) │ │
│ │ │ │
│ │ Deadline: Jan 31, 2026 | Policy: GRACE (30 min) │ │
│ │ [ + Add Requirement ] [Edit] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Window 2: Semi-finalist Documents (linked to Round 4) │ │
│ │ │ │
│ │ File Requirements: │ │
│ │ 1. Updated Business Plan (PDF, max 20MB, required) │ │
│ │ 2. Video Pitch (MP4, max 500MB, required) │ │
│ │ 3. Financial Projections (PDF/XLSX, max 10MB, required) │ │
│ │ │ │
│ │ Deadline: Apr 30, 2026 | Policy: HARD │ │
│ │ [ + Add Requirement ] [Edit] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ [ + Add Submission Window ] │
│ [ ← Back ] [ Next → ] │
└──────────────────────────────────────────────────────────────────┘
```
### Step 7: Review & Create
```
┌──────────────────────────────────────────────────────────────────┐
│ Create Competition — Step 7 of 7: Review │
│ ○───○───○───○───○───○───● │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Competition: MOPC 2026 Competition │
│ Category Mode: SHARED (3 Startups + 3 Concepts) │
│ │
│ Rounds (8): │
│ 1. Application Window (INTAKE) ─── Window 1 │
│ 2. AI Screening (FILTERING) │
│ 3. Jury 1 (EVALUATION) ─── Jury 1 │
│ 4. Semi-finalist Docs (SUBMISSION) ─── Window 2 │
│ 5. Jury 2 (EVALUATION) ─── Jury 2 │
│ 6. Mentoring (MENTORING) │
│ 7. Live Finals (LIVE_FINAL) ─── Jury 3 │
│ 8. Confirm Winners (CONFIRMATION) ─── Jury 3 │
│ │
│ Jury Groups (3): Jury 1 (0 members), Jury 2 (0), Jury 3 (0) │
│ Submission Windows (2): Application Docs, Semi-finalist Docs │
│ Special Awards (2): Innovation Award, Impact Award │
│ Notifications: Reminders at 7d, 3d, 1d before deadlines │
│ │
│ ⚠ Add jury members after creation. │
│ │
│ [ ← Back ] [ Create Competition ] │
└──────────────────────────────────────────────────────────────────┘
```
---
## Round Management
### Round Detail — Type-Specific Views
Each round type renders a specialized detail page:
#### INTAKE Round Detail
```
┌──────────────────────────────────────────────────────────────────┐
│ Round 1: Application Window Status: ACTIVE │
│ Type: INTAKE | Deadline: Jan 31, 2026 (16 days) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 127 │ │ 98 │ │ 29 │ │
│ │ Submitted │ │ Complete │ │ Draft │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ Category Breakdown: 72 Startups | 55 Concepts │
│ │
│ Submission Progress (by day): │
│ ▁▂▃▃▄▅▆▇████████████▇▇▆▅▄▃▃▂▂▁ │
│ Jan 1 Jan 31 │
│ │
│ Recent Submissions: │
│ ┌─────────────────────────────┬──────────┬──────────┬────────┐ │
│ │ Team │ Category │ Status │ Files │ │
│ ├─────────────────────────────┼──────────┼──────────┼────────┤ │
│ │ OceanClean AI │ STARTUP │ Complete │ 4/4 │ │
│ │ DeepReef Monitoring │ STARTUP │ Complete │ 3/4 │ │
│ │ BlueTide Analytics │ CONCEPT │ Draft │ 1/4 │ │
│ └─────────────────────────────┴──────────┴──────────┴────────┘ │
│ │
│ [ View All Submissions ] [ Export CSV ] [ Extend Deadline ] │
└──────────────────────────────────────────────────────────────────┘
```
#### FILTERING Round Detail
```
┌──────────────────────────────────────────────────────────────────┐
│ Round 2: AI Screening Status: ACTIVE │
│ Type: FILTERING | Auto-advance: ON │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 98 │ │ 23 │ │ 67 │ │
│ │ Screened │ │ Passed │ │ Failed │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────┐ │
│ │ 8 │ │
│ │ Flagged │ ← Require manual review │
│ └──────────┘ │
│ │
│ Flagged for Review: │
│ ┌─────────────────────────┬──────────┬──────┬─────────────┐ │
│ │ Project │ AI Score │ Flag │ Action │ │
│ ├─────────────────────────┼──────────┼──────┼─────────────┤ │
│ │ WaveEnergy Solutions │ 0.55 │ EDGE │ [✓] [✗] [?] │ │
│ │ MarineData Hub │ 0.48 │ LOW │ [✓] [✗] [?] │ │
│ │ CoralMapper (dup?) │ 0.82 │ DUP │ [✓] [✗] [?] │ │
│ └─────────────────────────┴──────────┴──────┴─────────────┘ │
│ │
│ [ View All Results ] [ Re-run AI Screening ] [ Override ] │
└──────────────────────────────────────────────────────────────────┘
```
#### EVALUATION Round Detail
```
┌──────────────────────────────────────────────────────────────────┐
│ Round 3: Jury 1 — Semi-finalist Status: ACTIVE │
│ Type: EVALUATION | Jury: Jury 1 (8 members) │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ── Evaluation Progress ─────────────────────────────────────── │
│ █████████████████████████████████░░░░░░░░░░░░░░░ 68% │
│ 186 / 276 evaluations complete │
│ │
│ Per-Juror Progress: │
│ Dr. Martin ██████████████████████████████████████ 18/18 ✓ │
│ Prof. Dubois██████████████████████████████░░░░░░░ 15/20 │
│ Ms. Chen █████████████████████████████████████████ 20/20 ✓ │
│ Dr. Patel █████████████████████░░░░░░░░░░░░░░ 12/15 │
│ Mr. Silva ████████████████████████████████░░░░ 16/20 │
│ Dr. Yamada ███████████████████████████████████████ 19/20 │
│ Ms. Hansen ██████████████████████████░░░░░░░░░ 14/20 │
│ │
│ ── Actions ─────────────────────────────────────────────────── │
│ [ View Assignments ] [ View Results ] [ Send Reminder ] │
│ [ Run AI Summary ] [ Advance Top N ] [ Override Decision ] │
└──────────────────────────────────────────────────────────────────┘
```
#### LIVE_FINAL Stage Manager
```
┌──────────────────────────────────────────────────────────────────┐
│ LIVE STAGE MANAGER — Round 7: Live Finals [● RECORDING] │
│ Status: IN_PROGRESS | Category: STARTUP │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Now Presenting: OceanClean AI │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Status: Q_AND_A │ │
│ │ Presentation: 12:00 ✓ | Q&A: ██████░░ 6:23 / 10:00 │ │
│ │ │ │
│ │ [ ▶ Start Voting ] [ ⏸ Pause ] [ ⏭ Skip ] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ── Jury Votes (5 jurors) ────────────────────────────────── │
│ Dr. Martin: ○ waiting | Prof. Dubois: ○ waiting │
│ Ms. Chen: ○ waiting | Dr. Patel: ○ waiting │
│ Mr. Silva: ○ waiting | │
│ │
│ ── Audience Votes ───────────────────────────────────────── │
│ Registered: 142 | Voted: 0 (voting not yet open) │
│ │
│ ── Queue ────────────────────────────────────────────────── │
│ ┌─────┬──────────────────────┬──────────┬───────────────┐ │
│ │ Ord │ Project │ Category │ Status │ │
│ ├─────┼──────────────────────┼──────────┼───────────────┤ │
│ │ ► 1 │ OceanClean AI │ STARTUP │ Q_AND_A │ │
│ │ 2 │ DeepReef Monitoring │ STARTUP │ WAITING │ │
│ │ 3 │ CoralGuard │ STARTUP │ WAITING │ │
│ └─────┴──────────────────────┴──────────┴───────────────┘ │
│ │
│ [ Switch to CONCEPT Window ] [ End STARTUP Window ] │
└──────────────────────────────────────────────────────────────────┘
```
#### CONFIRMATION Round Detail
```
┌──────────────────────────────────────────────────────────────────┐
│ Round 8: Confirm Winners Status: ACTIVE │
│ Type: CONFIRMATION | Jury: Jury 3 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ STARTUP Proposal │ │
│ │ Status: APPROVED ✓ Approvals: 5/5 │ │
│ │ 1st: OceanClean AI (92.4) │ │
│ │ 2nd: DeepReef (88.7) │ │
│ │ 3rd: CoralGuard (85.1) │ │
│ │ [ Freeze Results ] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ CONCEPT Proposal │ │
│ │ Status: PENDING Approvals: 3/5 │ │
│ │ 1st: BlueTide Analytics (89.2) │ │
│ │ 2nd: MarineData Hub (84.6) │ │
│ │ 3rd: SeaWatch (81.3) │ │
│ │ [ Send Reminder ] [ Override ] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ [ Freeze All Approved ] [ Export Results PDF ] │
└──────────────────────────────────────────────────────────────────┘
```
---
## Component Architecture
### Shared Components
| Component | Used In | Description |
|-----------|---------|-------------|
| `<CompetitionSidebar>` | All /competition/[id]/* pages | Left sidebar with nav links |
| `<RoundTimeline>` | Dashboard, round list | Horizontal visual timeline |
| `<StatusBadge>` | Everywhere | Color-coded status chip |
| `<ProgressBar>` | Round cards, jury progress | Animated progress bar |
| `<CountdownTimer>` | Round detail, dashboard | Real-time countdown to deadline |
| `<DataTable>` | Projects, members, assignments | Sortable, filterable table |
| `<OverrideDialog>` | Filtering, evaluation, confirmation | Override modal with reason input |
| `<AuditTrailSheet>` | Any entity detail page | Slide-out audit log viewer |
| `<JuryGroupSelector>` | Wizard, round config | Dropdown with create-new option |
### Page Components (type-specific)
| Component | Round Type | Description |
|-----------|-----------|-------------|
| `<IntakeRoundView>` | INTAKE | Submission stats, file status, deadline |
| `<FilteringRoundView>` | FILTERING | AI results, flagged queue, overrides |
| `<EvaluationRoundView>` | EVALUATION | Juror progress, assignment stats, results |
| `<SubmissionRoundView>` | SUBMISSION | Upload progress, locked windows |
| `<MentoringRoundView>` | MENTORING | Workspace activity, milestone progress |
| `<LiveFinalStageManager>` | LIVE_FINAL | Full stage manager with controls |
| `<ConfirmationRoundView>` | CONFIRMATION | Proposals, approvals, freeze |
### Dynamic Round Detail Routing
```typescript
// src/app/(admin)/admin/competition/[id]/rounds/[roundId]/page.tsx
export default function RoundDetailPage({ params }) {
const { data: round } = trpc.competition.getRound.useQuery({
roundId: params.roundId,
});
if (!round) return <LoadingSkeleton />;
// Render type-specific component based on round type
switch (round.roundType) {
case 'INTAKE':
return <IntakeRoundView round={round} />;
case 'FILTERING':
return <FilteringRoundView round={round} />;
case 'EVALUATION':
return <EvaluationRoundView round={round} />;
case 'SUBMISSION':
return <SubmissionRoundView round={round} />;
case 'MENTORING':
return <MentoringRoundView round={round} />;
case 'LIVE_FINAL':
return <LiveFinalStageManager round={round} />;
case 'CONFIRMATION':
return <ConfirmationRoundView round={round} />;
}
}
```
---
## Responsive Design
| Breakpoint | Layout |
|------------|--------|
| `< md` (mobile) | Single column. Sidebar collapses to hamburger. Tables become cards. Stage manager simplified |
| `md` - `lg` (tablet) | Two column. Sidebar always visible. Tables with horizontal scroll |
| `> lg` (desktop) | Full layout. Sidebar + content + optional side panel |
### Mobile Stage Manager
The live stage manager has a simplified mobile view for admins controlling from a phone:
```
┌─────────────────────────┐
│ LIVE CONTROL [● REC]│
│ │
│ Now: OceanClean AI │
│ Status: Q_AND_A │
│ Timer: 6:23 / 10:00 │
│ │
│ ┌──────────────────────┐ │
│ │ [ Start Voting ] │ │
│ │ [ Pause ] │ │
│ │ [ Skip → Next ] │ │
│ └──────────────────────┘ │
│ │
│ Jury: 0/5 voted │
│ Audience: 0/142 voted │
│ │
│ Next: DeepReef Monitoring│
└─────────────────────────┘
```
---
## Accessibility
| Feature | Implementation |
|---------|---------------|
| **Keyboard navigation** | All actions reachable via Tab/Enter. Focus rings visible |
| **Screen reader** | Semantic HTML, `aria-label` on badges, `role="status"` on live regions |
| **Color contrast** | All text meets WCAG 2.1 AA. Status badges use icons + color |
| **Motion** | Countdown timers respect `prefers-reduced-motion` |
| **Focus management** | Dialog focus trap, return focus on close |
---
## Integration with tRPC
### Key Data-Fetching Hooks
```typescript
// Competition dashboard
const { data: competition } = trpc.competition.getById.useQuery({ id });
const { data: rounds } = trpc.competition.listRounds.useQuery({ competitionId: id });
const { data: juryGroups } = trpc.juryGroup.listByCompetition.useQuery({ competitionId: id });
// Round detail
const { data: round } = trpc.competition.getRound.useQuery({ roundId });
const { data: projects } = trpc.competition.getProjectsInRound.useQuery({ roundId });
const { data: assignments } = trpc.assignment.listByRound.useQuery({ roundId });
// Live stage manager (with polling)
const { data: ceremonyState } = trpc.liveControl.getCeremonyState.useQuery(
{ roundId },
{ refetchInterval: 1000 } // poll every second
);
// Confirmation
const { data: proposals } = trpc.winnerConfirmation.listProposals.useQuery({ competitionId: id });
```
### Mutation Patterns
```typescript
// Advance projects after evaluation
const advance = trpc.competition.advanceProjects.useMutation({
onSuccess: () => {
utils.competition.getRound.invalidate({ roundId });
utils.competition.getProjectsInRound.invalidate({ roundId });
},
});
// Freeze winner proposal
const freeze = trpc.winnerConfirmation.freezeProposal.useMutation({
onSuccess: () => {
utils.winnerConfirmation.listProposals.invalidate({ competitionId });
toast({ title: 'Results frozen', description: 'Official results are now locked.' });
},
});
```