diff --git a/frontend/src/components/MatchList.tsx b/frontend/src/components/MatchList.tsx index f55a90b..1e86f14 100644 --- a/frontend/src/components/MatchList.tsx +++ b/frontend/src/components/MatchList.tsx @@ -1,6 +1,6 @@ import { useNavigate } from "react-router-dom"; -import { formatDuration } from "../domain/format"; +import { formatDate, formatDuration } from "../domain/format"; import { winReasonLabel } from "../domain/winReasons"; import type { MatchListItem } from "../domain/types"; import { PlayerLink } from "./PlayerLink"; @@ -24,7 +24,7 @@ export function MatchListView({ items }: { items: MatchListItem[] }) { onClick={() => navigate(`/match/${m.id}`)} >
- {m.played_at} + {formatDate(m.played_at)} {inProgress ? ( идёт ) : ( diff --git a/frontend/src/domain/format.ts b/frontend/src/domain/format.ts index a9f93b8..8a4b6cd 100644 --- a/frontend/src/domain/format.ts +++ b/frontend/src/domain/format.ts @@ -28,6 +28,14 @@ export function formatTime(iso: string | null | undefined): string { } } +// «Дата игры» приходит date-only строкой (YYYY-MM-DD) — просто переставляем части, +// без сдвига пояса (бэкенд уже посчитал дату в поясе приложения). +export function formatDate(iso: string | null | undefined): string { + if (!iso) return "—"; + const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso); + return m ? `${m[3]}.${m[2]}.${m[1]}` : iso; +} + export function formatDateTime(iso: string | null | undefined): string { if (!iso) return "—"; try { diff --git a/frontend/src/pages/GroupPage.tsx b/frontend/src/pages/GroupPage.tsx index bb01393..8ef89ad 100644 --- a/frontend/src/pages/GroupPage.tsx +++ b/frontend/src/pages/GroupPage.tsx @@ -6,6 +6,7 @@ import { GroupSwitcher } from "../components/GroupSwitcher"; import { Leaderboard } from "../components/Leaderboard"; import { MatchListView } from "../components/MatchList"; import { Spinner } from "../components/Spinner"; +import { formatDate } from "../domain/format"; import { useMe } from "../hooks/auth"; import { useGroup, useGroupMatches, useGroupStats } from "../hooks/groups"; @@ -49,7 +50,7 @@ export function GroupPage() {

Партий: {stats?.total_matches ?? 0} - {stats?.last_match_at ? ` · последняя: ${stats.last_match_at}` : ""} + {stats?.last_match_at ? ` · последняя: ${formatDate(stats.last_match_at)}` : ""}

diff --git a/frontend/src/pages/MatchDetailPage.tsx b/frontend/src/pages/MatchDetailPage.tsx index 6e13008..d8ebc67 100644 --- a/frontend/src/pages/MatchDetailPage.tsx +++ b/frontend/src/pages/MatchDetailPage.tsx @@ -6,7 +6,7 @@ import { ConfirmDialog } from "../components/ConfirmDialog"; import { MatchMedia } from "../components/MatchMedia"; import { PlayerLink } from "../components/PlayerLink"; import { Spinner } from "../components/Spinner"; -import { formatDuration, formatTime } from "../domain/format"; +import { formatDate, formatDuration, formatTime } from "../domain/format"; import { WIN_REASONS, type WinReason, winReasonLabel } from "../domain/winReasons"; import { useToast } from "../context/ToastContext"; import { @@ -120,7 +120,7 @@ export function MatchDetailPage() {
-

{match.played_at}

+

{formatDate(match.played_at)}

{inProgress ? ( идёт ) : ( diff --git a/frontend/src/pages/admin/AdminRecordsPage.tsx b/frontend/src/pages/admin/AdminRecordsPage.tsx index 8bbab19..e4de2f4 100644 --- a/frontend/src/pages/admin/AdminRecordsPage.tsx +++ b/frontend/src/pages/admin/AdminRecordsPage.tsx @@ -3,6 +3,7 @@ import { useMemo, useState } from "react"; import { ApiError } from "../../api/client"; import { ConfirmDialog } from "../../components/ConfirmDialog"; +import { formatDate } from "../../domain/format"; import { Spinner } from "../../components/Spinner"; import { Switch } from "../../components/Switch"; import { useToast } from "../../context/ToastContext"; @@ -54,7 +55,7 @@ export function AdminRecordsPage() {
- #{m.id} · {m.played_at} + #{m.id} · {formatDate(m.played_at)} {!grouped && · {m.group_name}}
{m.player_count} игр. · автор {m.created_by}