Upgrade Schedule prefill codes to CitySuggestion objects once dictionaries load

ScheduleStartPage previously stored the raw IATA code from the prefill
in departureAirport / arrivalAirport state, so PrimeReact's AutoComplete
would render 'MOW' (or 'SVO' before the prior commit) literally in the
input. Now, once dictionaries resolve, the effect replaces each string
slot with a { code, name } object so the autocomplete shows 'Москва'.

Mirrors Angular CityAutocomplete.writeValue → getCityOrAirport, which
upgrades the bound string to a CityModel for display while keeping the
code as the outbound form value.
This commit is contained in:
2026-04-20 11:44:38 +03:00
parent af473f9877
commit 0c1701086d
@@ -7,7 +7,7 @@
* @module
*/
import { type FC, useState, useCallback, type FormEvent } from "react";
import { type FC, useState, useCallback, useEffect, type FormEvent } from "react";
import { useNavigate } from "@modern-js/runtime/router";
import { useLocale } from "@/i18n/useLocale.js";
import { Calendar } from "primereact/calendar";
@@ -92,6 +92,36 @@ export const ScheduleStartPage: FC = () => {
const [departureAirport, setDepartureAirport] = useState<CitySuggestion | string>(prefill.departure ?? "");
const [arrivalAirport, setArrivalAirport] = useState<CitySuggestion | string>(prefill.arrival ?? "");
// Prefill arrives as a bare IATA code ("MOW"). Once dictionaries are
// loaded, upgrade each state slot to a `{code, name}` CitySuggestion
// so the PrimeReact AutoComplete renders "Москва" rather than the raw
// code. Mirrors Angular's CityAutocomplete.writeValue + getCityOrAirport.
useEffect(() => {
if (!dictionaries) return;
const resolve = (code: string): CitySuggestion | null => {
const upper = code.toUpperCase();
const city = dictionaries.cityByCode.get(upper);
if (city) return { code: city.code, name: city.name };
const airport = dictionaries.airportByCode.get(upper);
if (airport) {
const parentCode = airport.city_code?.toUpperCase();
const parent = parentCode
? dictionaries.cityByCode.get(parentCode)
: null;
if (parent) return { code: parent.code, name: parent.name };
}
return null;
};
setDepartureAirport((current) => {
if (typeof current !== "string" || !current) return current;
return resolve(current) ?? current;
});
setArrivalAirport((current) => {
if (typeof current !== "string" || !current) return current;
return resolve(current) ?? current;
});
}, [dictionaries]);
// Start blank to match Angular's `ДД.ММ.ГГГГ - ДД.ММ.ГГГГ` placeholder
// (the "current week" pre-fill was a React-only convenience that
// pulled the date input out of parity). Submit handler defaults to