# Phase 6: Event Browsing UI **Status:** ⬜ Not Started **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** frontend **Implementer:** Opus + frontend-design skill **Depends on:** Phase 4 (use cases) + Phase 5 (UI shell) ## Objective Build the user-facing browsing experience: pre-match list, live list (auto-refreshing), event-detail view with odds-over-time chart, plus an Excel export trigger. Visual quality must match the design system established in Phase 5 — distinctive, accessible, information-dense without being cluttered. ## Tasks - [ ] Create `Marathon.UI/Pages/PreMatch/EventsList.razor`: - Server-paginated table of upcoming `Event`s (use `IEventRepository` via injected use case wrapper) - Filters: sport (multi-select), country (multi-select), date range, free-text search (league/team) - Sort: scheduled time, sport, country, league - Each row shows compact odds preview (Match Win-1 / Draw / Win-2) - Click row → navigate to `Pages/Events/Detail.razor?id=...` - [ ] Create `Marathon.UI/Pages/Live/LiveList.razor`: - Same shell as PreMatch but data source is live snapshots - Auto-refresh every `Scraping:PollingIntervalSeconds` (use a timer + state subscription pattern; do NOT poll the scraper directly — read from snapshot repo) - Visual indicator when odds change since last refresh (subtle pulse / arrow) - [ ] Create `Marathon.UI/Pages/Events/Detail.razor`: - Event header: sport icon, league, scheduled time, sides 1 & 2 - Tabs: "Match" | "Period 1" | "Period 2" | ... - For each scope, show all bet types in a tabular layout - Charts panel: odds-over-time using Plotly.Blazor — three traces for Win-1/Draw/Win-2, secondary axis for handicap value - Snapshot history table beneath the chart - Excel export button (single event or full date range) - [ ] Create `Marathon.UI/Components/SportIcon.razor` — small SVG-based component with recognizable icons per sport (basketball, football, hockey, tennis, volleyball, etc.). - [ ] Create `Marathon.UI/Components/OddsCell.razor` — formats `OddsRate` with delta arrow (↑ green, ↓ red) when value changes from previous render. - [ ] Create `Marathon.UI/Components/OddsTimeline.razor` — wraps Plotly.Blazor with consistent theming and tooltip behavior. - [ ] Create `Marathon.UI/Components/ExportDialog.razor` — modal: pick `DateRange`, pick `ExportKind`, click Export → calls `ExportToExcelUseCase`. Show success toast with output file path. - [ ] State management: small `EventBrowsingState` service (singleton scoped to UI) holding active filters per page. Inject via DI in pages. No Redux/Fluxor — keep simple. - [ ] Add packages to `Marathon.UI`: - `Plotly.Blazor` - [ ] Update `Marathon.UI/Resources/SharedResource.{ru,en}.resx` with all new strings. Establish key naming convention from Phase 5 handoff notes. - [ ] Performance: - Virtualized rows for large event lists (`MudVirtualize` or `MudTable` virtual pagination) - Debounce filter inputs (300ms) - Memoize chart data — recompute only when snapshot list changes - [ ] Accessibility: - Table semantics with proper headers + ARIA labels - Keyboard navigation for row selection - Focus visible on all interactive elements - Charts include data table fallback for screen readers ## Files to Modify/Create - `src/Marathon.UI/Pages/PreMatch/EventsList.razor` - `src/Marathon.UI/Pages/Live/LiveList.razor` - `src/Marathon.UI/Pages/Events/Detail.razor` - `src/Marathon.UI/Components/SportIcon.razor`, `OddsCell.razor`, `OddsTimeline.razor`, `ExportDialog.razor` - `src/Marathon.UI/Services/EventBrowsingState.cs` - `src/Marathon.UI/Resources/SharedResource.{ru,en}.resx` — append new keys - `src/Marathon.UI/Components/_Imports.razor` — register Plotly.Blazor - Tests: `tests/Marathon.UI.Tests/Pages/**`, `Components/**` ## Acceptance Criteria - Compiles (Big Bang). - Live list visually conveys odds changes between refreshes. - Detail page chart renders 3 traces (Win-1/Draw/Win-2) with smooth interpolation and clear tooltip showing exact rate at any point in time. - Excel export from the dialog reaches `ExportToExcelUseCase` correctly. - Both RU and EN render correctly across all new UI. - Distinctive visual identity — implementer should follow frontend-design guidance. ## Notes - The frontend-design skill content is provided to the agent in `FRONTEND_DESIGN_SKILL`. Apply its principles — typography, color, motion, spatial composition. - Use Plotly.Blazor for charts (smooth, themable, professional look). - Keep components small (<200 lines) and composable. - Big Bang: compile-only smoke check. ## Review Checklist - [ ] Compiles - [ ] No mutation of domain types in UI components - [ ] Filters/sort persist within page session via `EventBrowsingState` - [ ] Chart accessible (data table fallback) - [ ] All new strings localized in RU + EN - [ ] Visual consistency with Phase 5 theme tokens ## Handoff to Next Phase