Files
ForbiddenStarsApp/frontend/src/components/MatchList.tsx
T
NotBigGhostandClaude Fable 5 002c657855 UI: даты игр в едином формате ДД.ММ.ГГГГ вместо сырых ISO-строк
Новый formatDate в domain/format.ts для date-only строк (played_at,
last_match_at). Применён: список партий, заголовок страницы партии
(раньше там было «2026-07-13»), записи в админке, «последняя партия»
на странице группы.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:42:05 +03:00

59 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useNavigate } from "react-router-dom";
import { formatDate, formatDuration } from "../domain/format";
import { winReasonLabel } from "../domain/winReasons";
import type { MatchListItem } from "../domain/types";
import { PlayerLink } from "./PlayerLink";
export function MatchListView({ items }: { items: MatchListItem[] }) {
const navigate = useNavigate();
if (items.length === 0) return <div className="muted small">Партий пока нет.</div>;
return (
<div className="stack">
{items.map((m) => {
const inProgress = m.status === "in_progress";
const sorted = [...m.participants].sort((a, b) => (a.place ?? 99) - (b.place ?? 99));
return (
// div, а не button: внутри карточки лежат ссылки на профили игроков,
// а интерактивные элементы внутри <button> — невалидная разметка.
<div
key={m.id}
className="card"
style={{ textAlign: "left", width: "100%", margin: 0, cursor: "pointer" }}
onClick={() => navigate(`/match/${m.id}`)}
>
<div className="row-between">
<span className="muted small">{formatDate(m.played_at)}</span>
{inProgress ? (
<span className="badge" style={{ color: "var(--accent-2)" }}>идёт</span>
) : (
<span className="muted small">
{formatDuration(m.duration_minutes)} · {winReasonLabel(m.win_reason)}
</span>
)}
</div>
<div className="stack" style={{ marginTop: 6, gap: 4 }}>
{sorted.map((p) => (
<PlayerLink key={p.user_id} userId={p.user_id} className="row" style={{ gap: 8 }}>
<span
className={
"place-badge" +
(p.place === 1 && !p.eliminated ? " first" : "") +
(p.eliminated ? " eliminated" : "")
}
>
{p.eliminated ? "✕" : (p.place ?? "—")}
</span>
<span>{p.nickname}</span>
<span className="muted small">· {p.faction_name}</span>
</PlayerLink>
))}
</div>
</div>
);
})}
</div>
);
}