feat: русский UI, версии в футере, даты и устойчивость загрузки API
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
- API: дата старта всегда YYYY-MM-DD; фронт: parseRaceDate без двойного T00:00:00 - GET /health с version из package.json; Vite define __FRONTEND_VERSION__ - Футер с версиями клиента/сервера (BEM), сетка app-shell на три ряда - AbortController для карточки старта; ретраи GET при 502–504 и понятные ошибки шлюза - Русские подписи навигации/страниц, lang=ru, без английских фраз в интерфейсе
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
export interface RaceRow {
|
||||
id: string;
|
||||
race_date: string;
|
||||
race_date: string | Date;
|
||||
title: string;
|
||||
distance_km: string;
|
||||
status: string | null;
|
||||
@@ -43,11 +43,23 @@ function toISOString(value: Date | string): string {
|
||||
return value instanceof Date ? value.toISOString() : String(value);
|
||||
}
|
||||
|
||||
/** DATE column may arrive as string or Date; API always exposes YYYY-MM-DD for the calendar day. */
|
||||
function raceDateToApiValue(value: string | Date): string {
|
||||
if (typeof value === "string") {
|
||||
const m = value.match(/^(\d{4}-\d{2}-\d{2})/);
|
||||
return m ? m[1]! : value;
|
||||
}
|
||||
const y = value.getFullYear();
|
||||
const mo = String(value.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(value.getDate()).padStart(2, "0");
|
||||
return `${y}-${mo}-${day}`;
|
||||
}
|
||||
|
||||
/** Convert a DB row to the API DTO (camelCase). */
|
||||
export function rowToDto(row: RaceRow): RaceDto {
|
||||
return {
|
||||
id: row.id,
|
||||
date: row.race_date,
|
||||
date: raceDateToApiValue(row.race_date),
|
||||
title: row.title,
|
||||
distanceKm: parseFloat(row.distance_km),
|
||||
status: row.status,
|
||||
|
||||
Reference in New Issue
Block a user