feat: align docs with code, finish_place, registered status, UI filters, tests, CI
Some checks failed
CI / build-and-test (pull_request) Has been cancelled

- Add PLAN.md and sync backend docs, .env.example, API doc (404 details)
- Document mock DB and PORT/API_PORT in docs/backend.md; README monorepo + frontend/.env.example
- Migration 002: finish_place column, status registered; mapper and mock DB updated
- Frontend: registered status, finishPlace, calendar year/month filters, pace sparkline
- Extract createApp for tests; supertest + tsx; GitHub Actions CI

Made-with: Cursor
This commit is contained in:
Vaka.pro
2026-04-06 22:20:31 +03:00
parent 1ffc3a65eb
commit a2dcf67396
27 changed files with 1410 additions and 286 deletions

View File

@@ -89,6 +89,10 @@ export function getRaceCountdownLabel(date: string, now: Date = new Date()): str
return `через ${days} дней`;
}
export function isCloseDistance(left: number, right: number): boolean {
return Math.abs(left - right) < 0.05;
}
export function getPaceLabel(finishTime: string | null, distanceKm: number): string | null {
const totalSeconds = parseFinishTimeToSeconds(finishTime);
if (!totalSeconds || distanceKm <= 0) {
@@ -102,9 +106,23 @@ export function getPaceLabel(finishTime: string | null, distanceKm: number): str
return `${String(paceMinutes).padStart(2, "0")}:${String(paceRemainder).padStart(2, "0")} /км`;
}
export function getRaceStatusClassName(status: Race["status"]): string {
const base = "race-card__status";
if (status === "completed") {
return `${base} ${base}--completed`;
}
if (status === "registered") {
return `${base} ${base}--registered`;
}
return `${base} ${base}--planned`;
}
export function getRaceStatusLabel(status: Race["status"]): string {
if (status === "completed") {
return "пробежал";
}
if (status === "registered") {
return "зарегистрирован";
}
return "планирую";
}