Files
maraphon-app/plans/initial-implementation/phase-6-event-browsing-ui.md
T

5.0 KiB

Phase 6: Event Browsing UI

Status: Not Started Parent plan: 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 Events (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