# Admin UI Redesign - Implementation Plan ## Overview This plan outlines the migration from the current scattered admin structure to a clean, hierarchy-driven navigation centered on **Tryouts**. ### Guiding Principles 1. **One main page per domain** - Features live under their parent, not as separate menu items 2. **URL reflects depth** - Path structure shows relationship (`/admin/tryout/{id}/questions`) 3. **Tree as map** - Hierarchy tree shows structure; drill-down shows details 4. **Consistent naming** - Use "Tryout" instead of "Exam" throughout --- ## 1. URL Structure ### New URL Scheme | Old Route | New Route | Description | |-----------|-----------|-------------| | `/admin/exams` | `/admin/tryouts` | Hierarchy tree (main entry) | | `/admin/student-attempts` | `/admin/tryout/{tryout_id}/attempts` | Attempts filtered by tryout | | - | `/admin/tryout/{tryout_id}/questions` | Questions filtered by tryout | | - | `/admin/tryout/{tryout_id}/questions/{question_id}/workspace` | Question workspace | | - | `/admin/tryout/{tryout_id}/questions/{question_id}/workspace/{tab}` | Workspace tabs | | - | `/admin/tryout/{tryout_id}/normalization` | Normalization settings for this tryout | | `/admin/questions` | `/admin/questions` | Global question list (kept) | | (none) | `/admin/import-tryout` | Import tryout modal/page | > **Note:** Import is tryout-level, not question-level. Import button lives on `/admin/tryouts` page header. ### Hierarchy Depth Convention ``` /admin/tryouts → Level 0: Root /admin/tryout/{tryout_id} → Level 1: Entity /admin/tryout/{tryout_id}/attempts → Level 2: Related data /admin/tryout/{tryout_id}/questions → Level 2: Related data /admin/tryout/{tryout_id}/questions/{id} → Level 3: Specific item /admin/tryout/{tryout_id}/questions/{id}/workspace → Level 4: Detail view ``` --- ## 2. Navigation Structure ### Proposed Navigation ``` Questions ├── /admin/questions # Global question list └── /admin/tryout/*/questions/*/workspace # Direct link from tree Tryouts ├── /admin/tryouts # Tree: Website → Tryout → Stat → Actions + Import button ├── /admin/tryout/*/attempts # Filtered attempts ├── /admin/tryout/*/questions # Questions in this tryout ├── /admin/tryout/*/normalization # Normalization settings └── /admin/import-tryout # Import modal/page Reports ├── /admin/reports # Dashboard ├── /admin/item-statistics └── /admin/calibration-status Settings ├── /admin/settings ├── /admin/websites └── /admin/password ``` ### Navigation Item Definition ```python ADMIN_NAV_ITEMS = ( ("Dashboard", "/admin/dashboard", ("/admin/dashboard",)), ("Questions", "/admin/questions", ( "/admin/questions", "/admin/tryout/*/questions/*/workspace", # Pattern for direct links )), ("Tryouts", "/admin/tryouts", ( "/admin/tryouts", "/admin/tryout/*/attempts", "/admin/tryout/*/questions", "/admin/tryout/*/normalization", "/admin/import-tryout", )), ("Reports", "/admin/reports", ( "/admin/reports", "/admin/item-statistics", "/admin/calibration-status", )), ("Settings", "/admin/settings", ( "/admin/settings", "/admin/websites", "/admin/password", )), ("Logout", "/admin/logout", ("/admin/logout",)), ) ``` --- ## 3. Tryouts Tree Structure ### Visual Design ``` ┌─ Tryouts ───────────────────────────────────────────────────────────────────┐ │ │ │ [+ Import Tryout] │ │ │ │ 🌐 Website A │ │ │ │ │ ├─ 📋 132380 - UTBK 2024 [●] │ │ │ └─ [Expanded on click] │ │ │ │ │ ├─ 📋 132381 - SIMAK UI [✓] │ │ │ │ │ └─ 📋 132382 - PAS Semester 1 [○] │ │ │ │ 🌐 Website B │ │ └─ ... │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Expanded Tryout View: ┌─ 📋 132380 - UTBK 2024 ─────────────────────────────────────────────────────┐ │ │ │ ┌─ Stat Card ─────────────────────────────────────────────────────────┐ │ │ │ 👥 150 participants │ NM: 672 avg │ NN: 505 avg │ │ │ │ ✓ 98% completion │ 📐 Calibration: ████████░░ 85% (17/20) │ │ │ └────────────────────────────────────────────────────────────────────┘ │ │ │ │ [📝 Questions (20)] [👥 Attempts (150)] [📐 Normalization] [⚙ Settings]│ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Legend: [●] Partial (50-89% calibrated) [✓] Ready (≥90% calibrated) [○] Needs Data (<50% calibrated) ``` ### Import Button Location - **Location:** Header of `/admin/tryouts` page - **Label:** "[+ Import Tryout]" or "[Import Tryout JSON]" - **Behavior:** Opens import modal/page - **Why:** Import is tryout-level operation (imports questions WITH tryout context) ### Stat Card Components | Field | Source | Display | |-------|--------|---------| | Participants | `TryoutStats.participant_count` | 👥 {count} | | Avg NM | `AVG(Session.NM)` where completed | 📊 {value} avg | | Avg NN | `AVG(Session.NN)` where completed | 📈 {value} avg | | Completion Rate | `completed / participants * 100` | ✓ {percentage}% | | Calibration | `calibrated_items / total_items` | 📐 Progress bar + {count}/{total} | ### Action Buttons | Action | Target URL | Icon | |--------|------------|------| | Questions | `/admin/tryout/{id}/questions` | 📝 | | Attempts | `/admin/tryout/{id}/attempts` | 👥 | | Normalization | `/admin/tryout/{id}/normalization` | 📐 | | Settings | `/admin/tryout/{id}/settings` (or modal) | ⚙ | --- ## 4. Page Specifications ### 4.1 `/admin/tryouts` (Main Tree) **Purpose:** Primary navigation entry, shows structure at a glance **Default State:** - Websites expanded - Tryouts collapsed - Shows calibration indicator dot next to each tryout **Interactions:** - Click tryout → expand/collapse - Expanded tryout shows stat card + action buttons - Actions navigate to filtered views ### 4.2 `/admin/tryout/{tryout_id}/questions` **Purpose:** View all questions in a specific tryout **Behavior:** - Shows only original/imported questions (basis items) - Pre-filtered by `tryout_id` - Links to workspace for AI variant generation **Table Columns:** | Column | Description | |--------|-------------| | ID | Question internal ID | | Stem Preview | First 100 chars of question text | | Difficulty | Current difficulty level | | Calibration | P-value or IRT-b indicator | | Variants | Count of generated variants | | Actions | [View] [Workspace] | ### 4.3 `/admin/tryout/{tryout_id}/questions/{question_id}/workspace` **Purpose:** Generate and manage question variants **Tabs:** | Tab | Purpose | |-----|---------| | Generate | AI variant generation interface | | Review | Review generated variants | | Batch | Batch generation options | **Access Pattern:** - Opens from question list or tree direct link - Context: knows parent tryout, parent question ### 4.4 `/admin/tryout/{tryout_id}/attempts` **Purpose:** View student attempts for specific tryout **Current Implementation:** Already exists at `/admin/student-attempts` → migrate URL **Enhancements:** - Pre-filtered by `tryout_id` (no dropdown needed on this page) - Stat card from parent tryout shown at top ### 4.5 `/admin/tryout/{tryout_id}/normalization` **Purpose:** Configure normalization settings for a specific tryout **Settings (per-tryout):** | Setting | Type | Default | Description | |---------|------|---------|-------------| | Mode | Select | Auto | Auto (calculate from data) or Manual (fixed values) | | Rataan | Number | 500 | Target mean for normalization | | SB | Number | 100 | Target standard deviation | | Recalculate | Button | - | Re-run normalization on existing sessions | **Formula:** `NN = 500 + 100 × ((NM - Rataan) / SB)` **UI:** - Simple form with current values - "Recalculate" button triggers normalization job - Shows last normalization timestamp ### 4.6 `/admin/import-tryout` **Purpose:** Import tryout data (questions + metadata) from JSON **Access:** Via "[+ Import Tryout]" button on `/admin/tryouts` page **Behavior:** - Opens modal or dedicated page - Upload JSON file or paste JSON content - Preview import before confirming - Creates new tryout with questions **URL Convention:** Not under specific tryout (it's creating a new one) --- ## 5. Deprecations ### Routes to Remove | Route | Reason | |-------|--------| | `/admin/exams` | Renamed to `/admin/tryouts` | | `/admin/student-attempts` | URL changed to `/admin/tryout/{id}/attempts` | | `/admin/templates` | AI uses basis items directly | | `/admin/basis-items` | Merge into question workspace | | `/admin/hierarchy` | Tree IS the hierarchy | | `/admin/question-quality` | Merged into tryout stat card | ### Legacy Redirects ```python LEGACY_URL_MAP = { "/admin/exams": "/admin/tryouts", "/admin/student-attempts": "/admin/tryouts", # Or redirect to tryouts with guidance "/admin/hierarchy": "/admin/tryouts", "/admin/question-quality": "/admin/tryouts", # Templates and basis-items: 404 (removed) } ``` --- ## 6. Implementation Phases ### Phase 1: Foundation - [ ] Rename `/admin/exams` → `/admin/tryouts` (keep old route for now) - [ ] Implement tree structure in `/admin/tryouts` - [ ] Move `TryoutStats` info into tree stat cards - [ ] Add calibration indicator dots ### Phase 2: URL Migration - [ ] Create `/admin/tryout/{id}/attempts` (redirect from old route) - [ ] Create `/admin/tryout/{id}/questions` - [ ] Update navigation items ### Phase 3: Workspace Integration - [ ] Create question workspace route - [ ] Implement workspace tabs - [ ] Connect workspace to tree and question list ### Phase 4: Cleanup - [ ] Add legacy redirects - [ ] Remove deprecated routes - [ ] Update all hardcoded links in views ### Phase 5: Polish - [ ] Review all pages for consistency - [ ] Update documentation - [ ] Test all navigation paths --- ## 7. Open Questions 1. ~~Normalization settings~~ - **RESOLVED**: Move under tryout context as `/admin/tryout/{id}/normalization` 2. ~~Import questions page~~ - **RESOLVED**: Import is tryout-level. Button on `/admin/tryouts` header, not a separate page. 3. **Tryout settings** - What settings are actually needed? (Scoring mode, time limits, selection criteria?) 4. **Global questions page** - Is `/admin/questions` (unfiltered) still useful, or should every question access go through tryout context? 5. **Templates deprecation** - Confirm that `/admin/templates` is truly unused and can be safely removed? 6. **Legacy routes for deleted pages** - Should `/admin/templates` and `/admin/basis-items` redirect somewhere or return 404? --- ## 8. Files to Modify ### Primary Changes - `app/admin_web.py` - Major route restructuring - Navigation definition in `admin_web.py` - Legacy URL map ### Likely Additions - Static assets for tree expansion/collapse (if not using existing) ### Documentation Updates - `ADMIN_UI_REDESIGN_PLAN.md` - Update to reflect final structure - `PROJECT_UNDERSTANDING.md` - Update route documentation --- ## 9. Changelog | Version | Date | Changes | |---------|------|---------| | 1.0 | 2026-06-17 | Initial draft based on discussion | | 1.1 | 2026-06-17 | - Move normalization to `/admin/tryout/{id}/normalization`
- Move import button to `/admin/tryouts` header
- Add normalization page spec (4.5)
- Rename import page spec (4.6)
- Update navigation and action buttons |