Fix Schedule UI regressions and complete non-RU/EN locale translations
- Duration now sums segments + transfers (last arrival − first departure) for multi-leg/connecting in Schedule, matching TZ §4.1.14.3 and Angular. - Default day auto-expands per TZ §4.1.14: current-week today, future-week first valid day, last-valid-day fallback when earlier days are out of window. - Aircraft model no longer leaks into collapsed rows; shown only when expanded AND direct, mirroring Angular's operator-logo-and-model [showModel]="expanded && direct". - Week tabs use MONTH-SHORT.* translation table so Russian renders "27 апр. - 3 май." instead of genitive "мая" from Intl. - "Ранее искали" → "Вы искали" across all 9 locales (TZ §4.1.9.5). - Sort-arrow headers compacted (inline-flex nowrap, zero gap) so labels stay on one line next to the chevrons. - robots.txt allows Yandex/Googlebot/* with no Disallow (TZ §4.1.20). - 6 non-RU/EN locales (de/es/fr/it/ja/ko) + zh were missing ~45 strings each; translated from Angular where present, hand-translated otherwise so every locale is down to the two intentional `.undefined` stubs.
This commit is contained in:
@@ -34,22 +34,27 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__sort-group {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
gap: 0;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
&__sort {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 1px 2px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
color: colors.$border-blue;
|
||||
line-height: 0;
|
||||
border-radius: 2px;
|
||||
display: block;
|
||||
|
||||
svg { display: block; }
|
||||
|
||||
&:hover { color: colors.$blue; }
|
||||
&--active { color: colors.$blue; }
|
||||
|
||||
@@ -143,21 +143,25 @@ export const DayGroupedFlightList: FC<DayGroupedFlightListProps> = ({
|
||||
return g.map((day) => ({ ...day, flights: sortFlights(day.flights, sortMode) }));
|
||||
}, [flights, sortMode]);
|
||||
|
||||
// Auto-open today's day group on first render (and when the visible
|
||||
// window shifts). The user can collapse it; we never re-open after
|
||||
// Auto-open the default day per TZ §4.1.14: current week expands today;
|
||||
// future weeks expand the first valid day (week where only Sunday is
|
||||
// valid → Sunday). The user can collapse it; we never re-open after
|
||||
// that for the same date.
|
||||
const [autoOpenedFor, setAutoOpenedFor] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
if (groups.length === 0) return;
|
||||
const now = new Date();
|
||||
const todayIso = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
||||
const todayInScope = groups.some((g) => g.date === todayIso);
|
||||
if (!todayInScope || autoOpenedFor === todayIso) return;
|
||||
const defaultDate = groups.some((g) => g.date === todayIso)
|
||||
? todayIso
|
||||
: (groups[0]?.date ?? null);
|
||||
if (!defaultDate || autoOpenedFor === defaultDate) return;
|
||||
setExpandedDays((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.add(todayIso);
|
||||
next.add(defaultDate);
|
||||
return next;
|
||||
});
|
||||
setAutoOpenedFor(todayIso);
|
||||
setAutoOpenedFor(defaultDate);
|
||||
}, [groups, autoOpenedFor]);
|
||||
|
||||
// Mirror Angular `ScheduleDaysComponent.expandDefaultFlight`: once a
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
* - Clicking a tab auto-scrolls (page jumps) to show the selected week.
|
||||
*/
|
||||
|
||||
import { type FC, useEffect, useMemo, useState } from "react";
|
||||
import { useLocale } from "@/i18n/useLocale.js";
|
||||
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "@/i18n/provider.js";
|
||||
import { scheduleWindowBounds } from "@/shared/dateWindow.js";
|
||||
import "./WeekTabs.scss";
|
||||
@@ -46,10 +45,6 @@ function startOfWeekMonday(d: Date): Date {
|
||||
return out;
|
||||
}
|
||||
|
||||
function fmt(date: Date, fmt: Intl.DateTimeFormat): string {
|
||||
return fmt.format(date).replace(/\.$/, "");
|
||||
}
|
||||
|
||||
function ymd(d: Date): string {
|
||||
const y = d.getFullYear();
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
@@ -58,14 +53,13 @@ function ymd(d: Date): string {
|
||||
}
|
||||
|
||||
export const WeekTabs: FC<WeekTabsProps> = ({ selectedMonday, onNavigate }) => {
|
||||
const { language } = useLocale();
|
||||
const { t } = useTranslation();
|
||||
// Angular shows month abbreviated ("13 апр - 19 апр"). Build once
|
||||
// per locale; the month part comes through in the locale's natural
|
||||
// short form.
|
||||
const dayMonthFmt = useMemo(
|
||||
() => new Intl.DateTimeFormat(language, { day: "numeric", month: "short" }),
|
||||
[language],
|
||||
// Short month abbreviations come from `MONTH-SHORT.{1..12}`, same
|
||||
// lookup table as Angular's `DatesTranslationService.getShortDateString`
|
||||
// ("27 апр." / "3 май." for ru; "Apr" / "May" for en).
|
||||
const shortDay = useCallback(
|
||||
(d: Date) => `${d.getDate()} ${t(`MONTH-SHORT.${d.getMonth() + 1}`)}`,
|
||||
[t],
|
||||
);
|
||||
|
||||
// Build the active weeks list anchored to the schedule window
|
||||
@@ -86,11 +80,11 @@ export const WeekTabs: FC<WeekTabsProps> = ({ selectedMonday, onNavigate }) => {
|
||||
monday,
|
||||
sunday,
|
||||
ymd: ymd(monday),
|
||||
label: `${fmt(monday, dayMonthFmt)} - ${fmt(sunday, dayMonthFmt)}`,
|
||||
label: `${shortDay(monday)} - ${shortDay(sunday)}`,
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}, [dayMonthFmt]);
|
||||
}, [shortDay]);
|
||||
|
||||
// Derive the page that contains selectedMonday. Re-derives whenever
|
||||
// selectedMonday or weeks change so navigation to a new week auto-scrolls
|
||||
|
||||
Reference in New Issue
Block a user