fix frontend calendar race states
Some checks failed
CI / build-and-test (pull_request) Has been cancelled

This commit is contained in:
Anton
2026-04-27 12:31:29 +03:00
parent 0b7ad23252
commit dffbb48d99
5 changed files with 186 additions and 34 deletions

View File

@@ -1,14 +1,14 @@
import { useCallback, useMemo, useRef, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import type { Race } from "../api";
import { buildMonthCells, groupRacesByYmd, toYmd, WEEKDAY_LABELS_SHORT_RU } from "../lib";
import { buildMonthCells, groupRacesByYmd, isRaceDateInPast, toYmd, WEEKDAY_LABELS_SHORT_RU } from "../lib";
const MONTH_NAMES_RU_SHORT = [
"янв.",
"февр.",
"мар.",
"апр.",
"мая",
"май",
"июн.",
"июл.",
"авг.",
@@ -20,6 +20,13 @@ const MONTH_NAMES_RU_SHORT = [
const POPOVER_LEAVE_MS = 140;
function toLocalYmd(date: Date): string {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
}
interface RacesCalendarProps {
displayYear: number;
monthFilter: string;
@@ -77,6 +84,8 @@ function CalendarMonthBlock(props: {
setOpenYmd: (v: string | null) => void;
scheduleClose: () => void;
cancelClose: () => void;
onMonthSelect?: (monthIndex: number) => void;
todayYmd: string;
}): JSX.Element {
const {
year,
@@ -88,6 +97,8 @@ function CalendarMonthBlock(props: {
setOpenYmd,
scheduleClose,
cancelClose,
onMonthSelect,
todayYmd,
} = props;
const cells = useMemo(() => buildMonthCells(year, monthIndex), [year, monthIndex]);
const title = `${MONTH_NAMES_RU_SHORT[monthIndex]} ${year}`;
@@ -96,7 +107,21 @@ function CalendarMonthBlock(props: {
return (
<div className={blockClass}>
<h3 className="races-cal__month-title">{title}</h3>
<h3 className="races-cal__month-title">
{onMonthSelect ? (
<button
type="button"
className="races-cal__month-title-button"
onClick={() => {
onMonthSelect(monthIndex);
}}
>
{title}
</button>
) : (
title
)}
</h3>
<div className="races-cal__weekdays" aria-hidden>
{WEEKDAY_LABELS_SHORT_RU.map((d) => (
<span key={d} className="races-cal__weekday">
@@ -113,11 +138,22 @@ function CalendarMonthBlock(props: {
const dayRaces = racesByYmd.get(ymd) ?? [];
const hasRaces = dayRaces.length > 0;
const isOpen = openYmd === ymd;
const isPast = isRaceDateInPast(ymd);
const isToday = ymd === todayYmd;
const cellClassName = [
"races-cal__cell",
hasRaces ? "races-cal__cell--has-race" : "",
isOpen ? "races-cal__cell--open" : "",
isPast ? "races-cal__cell--past" : "",
isToday ? "races-cal__cell--today" : "",
]
.filter(Boolean)
.join(" ");
return (
<div
key={ymd}
className={`races-cal__cell${hasRaces ? " races-cal__cell--has-race" : ""}${isOpen ? " races-cal__cell--open" : ""}`}
className={cellClassName}
onMouseEnter={() => {
cancelClose();
setOpenYmd(hasRaces ? ymd : null);
@@ -182,6 +218,7 @@ export function RacesCalendar(props: RacesCalendarProps): JSX.Element {
}, [cancelClose]);
const racesByYmd = useMemo(() => groupRacesByYmd(races), [races]);
const todayYmd = useMemo(() => toLocalYmd(new Date()), []);
const focusedMonthIndex = monthFilter === "" ? null : parseInt(monthFilter, 10) - 1;
@@ -202,6 +239,11 @@ export function RacesCalendar(props: RacesCalendarProps): JSX.Element {
setOpenYmd={setOpenYmd}
scheduleClose={scheduleClose}
cancelClose={cancelClose}
onMonthSelect={(mi) => {
onMonthFilterChange(String(mi + 1));
setOpenYmd(null);
}}
todayYmd={todayYmd}
/>
))}
</div>
@@ -240,6 +282,7 @@ export function RacesCalendar(props: RacesCalendarProps): JSX.Element {
setOpenYmd={setOpenYmd}
scheduleClose={scheduleClose}
cancelClose={cancelClose}
todayYmd={todayYmd}
/>
</div>
)}