use leptos::prelude::*; use leptos_router::{components::A, hooks::use_params_map}; use crate::api::{self, GameDetail, Participant}; use crate::i18n::*; #[component] pub fn GameDetailPage() -> impl IntoView { let i18n = use_i18n(); let params = use_params_map(); let id_str = move || params.read().get("id").unwrap_or_default(); let detail = LocalResource::new(move || { let s = id_str(); async move { let id: i64 = s.parse().map_err(|_| "invalid game id".to_string())?; api::get_game_detail(id).await } }); view! {
{move || match detail.get().map(|sw| sw.take()) { None => view! {

{t!(i18n, loading)}

}.into_any(), Some(Err(e)) => view! {

{ e }

}.into_any(), Some(Ok(g)) => view! { }.into_any(), }}
} } #[component] fn GameDetailView(game: GameDetail) -> impl IntoView { let i18n = use_i18n(); let started = api::format_ts(game.started_at); let ended = game.ended_at.map(api::format_ts) .unwrap_or_else(|| t_string!(i18n, game_ongoing).to_string()); view! {

{t!(i18n, room_detail_title)} " " { game.room_code.clone() }

{t!(i18n, started_label)} ": " { started.clone() } " · " {t!(i18n, ended_label)} ": " { ended }

{t!(i18n, players_header)}

{game.participants.iter().map(|p| { view! { } }).collect_view()}
{t!(i18n, col_player)} {t!(i18n, label_username)} {t!(i18n, col_outcome)}
{game.result.as_ref().map(|r| view! {

{t!(i18n, score_header)}

{ r.clone() }

})}
} } #[component] fn ParticipantRow(participant: Participant) -> impl IntoView { let i18n = use_i18n(); let outcome_class = match participant.outcome.as_deref() { Some("win") => "outcome-win", Some("loss") => "outcome-loss", Some("draw") => "outcome-draw", _ => "", }; let outcome_text = move || match participant.outcome.as_deref() { Some("win") => t_string!(i18n, outcome_win), Some("loss") => t_string!(i18n, outcome_loss), Some("draw") => t_string!(i18n, outcome_draw), _ => "—", }; let name = participant.username.clone(); view! { {t!(i18n, col_player)} " " { participant.player_id } {match name { Some(u) => view! { { u } }.into_any(), None => view! { {t!(i18n, anonymous_player)} }.into_any(), }} { outcome_text } } }