v0.1 - макет интерфейса, аутентификация через логин, аккаунт админа, создание партии в 2 этапа, базовые настройки профиля и группы, переключение между группами, статистика
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { formatDuration } from "../domain/format";
|
||||
import { winReasonLabel } from "../domain/winReasons";
|
||||
import type { MatchListItem } from "../domain/types";
|
||||
|
||||
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 (
|
||||
<button
|
||||
key={m.id}
|
||||
className="card"
|
||||
style={{ textAlign: "left", width: "100%", margin: 0 }}
|
||||
onClick={() => navigate(`/match/${m.id}`)}
|
||||
>
|
||||
<div className="row-between">
|
||||
<b>{m.played_at}</b>
|
||||
{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) => (
|
||||
<div key={p.user_id} className="row" style={{ gap: 8 }}>
|
||||
<span className={"place-badge" + (p.place === 1 ? " first" : "")}>
|
||||
{p.place ?? "—"}
|
||||
</span>
|
||||
<span>{p.nickname}</span>
|
||||
<span className="muted small">· {p.faction_name}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user