diff --git a/src/features/schedule/components/ScheduleFilter.tsx b/src/features/schedule/components/ScheduleFilter.tsx index 424a6931..3fc45e7b 100644 --- a/src/features/schedule/components/ScheduleFilter.tsx +++ b/src/features/schedule/components/ScheduleFilter.tsx @@ -54,6 +54,10 @@ export interface ScheduleFilterProps { initialDateTo?: string; initialTimeFrom?: string; initialTimeTo?: string; + initialReturnDateFrom?: string; + initialReturnDateTo?: string; + initialReturnTimeFrom?: string; + initialReturnTimeTo?: string; initialDirectOnly?: boolean; initialReturnFlights?: boolean; } @@ -90,6 +94,10 @@ export const ScheduleFilter: FC = ({ initialDateTo, initialTimeFrom, initialTimeTo, + initialReturnDateFrom, + initialReturnDateTo, + initialReturnTimeFrom, + initialReturnTimeTo, initialDirectOnly = false, initialReturnFlights = false, }) => { @@ -111,6 +119,15 @@ export const ScheduleFilter: FC = ({ ]); const [directOnly, setDirectOnly] = useState(initialDirectOnly); const [returnFlights, setReturnFlights] = useState(initialReturnFlights); + const initRetFrom = yyyymmddToDate(initialReturnDateFrom); + const initRetTo = yyyymmddToDate(initialReturnDateTo); + const [returnDateRange, setReturnDateRange] = useState<(Date | null)[]>( + initRetFrom && initRetTo ? [initRetFrom, initRetTo] : [null, null], + ); + const [returnTimeRange, setReturnTimeRange] = useState<[number, number]>([ + hhmmToMinutes(initialReturnTimeFrom, 0), + hhmmToMinutes(initialReturnTimeTo, 1440), + ]); // Mirrors Angular ScheduleFilterValidationService: a single inline // error shown below the arrival input when the user submits with // departure === arrival. Cleared whenever either city changes. @@ -166,11 +183,53 @@ export const ScheduleFilter: FC = ({ : {}), ...(directOnly ? { connections: 0 } : {}), }; - const params: ScheduleParams = { type: "route", outbound }; + + let params: ScheduleParams; + if (returnFlights) { + // Default return range to week-after-outbound if the user + // turned the checkbox on but hasn't picked dates. + const retFromDate = returnDateRange[0] ?? (() => { + const d = new Date(to); + d.setDate(d.getDate() + 1); + return d; + })(); + const retToDate = returnDateRange[1] ?? (() => { + const d = new Date(to); + d.setDate(d.getDate() + 7); + return d; + })(); + const inbound = { + departure: arr, + arrival: dep, + dateFrom: dateToYyyymmdd(retFromDate), + dateTo: dateToYyyymmdd(retToDate), + ...(returnTimeRange[0] !== 0 || returnTimeRange[1] !== 1440 + ? { + timeFrom: minutesToHhmm(returnTimeRange[0]), + timeTo: minutesToHhmm(returnTimeRange[1]), + } + : {}), + ...(directOnly ? { connections: 0 } : {}), + }; + params = { type: "roundtrip", outbound, inbound }; + } else { + params = { type: "route", outbound }; + } const url = buildScheduleUrl(params); void navigate(`/${locale}/${url}`); }, - [departure, arrival, dateRange, timeRange, directOnly, navigate, locale], + [ + departure, + arrival, + dateRange, + timeRange, + directOnly, + returnFlights, + returnDateRange, + returnTimeRange, + navigate, + locale, + ], ); return ( @@ -291,6 +350,57 @@ export const ScheduleFilter: FC = ({ /> {t("SHARED.RETURN_FLIGHT_VIEW")} + + {returnFlights && ( + <> +
+ + + setReturnDateRange( + (e.value as (Date | null)[]) ?? [null, null], + ) + } + selectionMode="range" + minDate={scheduleMinDate} + maxDate={scheduleMaxDate} + dateFormat="dd.mm.yy" + placeholder={`${t("SHARED.DATE_FORMAT")} - ${t("SHARED.DATE_FORMAT")}`} + showIcon + className="input--filter" + data-testid="schedule-return-date-input" + inputId="schedule-return-date-input" + readOnlyInput + /> +
+ +
+
+
+ {t("SHARED.RETURN_FLIGHT_TIME")} +
+
+ {minutesToTime(returnTimeRange[0])} — {minutesToTime(returnTimeRange[1])} +
+
+
+ + setReturnTimeRange(e.value as [number, number]) + } + range + min={0} + max={1440} + step={60} + /> +
+
+ + )}
diff --git a/src/features/schedule/components/ScheduleSearchPage.tsx b/src/features/schedule/components/ScheduleSearchPage.tsx index f3c468e4..ececbc61 100644 --- a/src/features/schedule/components/ScheduleSearchPage.tsx +++ b/src/features/schedule/components/ScheduleSearchPage.tsx @@ -287,6 +287,10 @@ export const ScheduleSearchPage: FC = ({ params }) => { initialDateTo={outbound.dateTo} {...(outbound.timeFrom ? { initialTimeFrom: outbound.timeFrom } : {})} {...(outbound.timeTo ? { initialTimeTo: outbound.timeTo } : {})} + {...(inbound?.dateFrom ? { initialReturnDateFrom: inbound.dateFrom } : {})} + {...(inbound?.dateTo ? { initialReturnDateTo: inbound.dateTo } : {})} + {...(inbound?.timeFrom ? { initialReturnTimeFrom: inbound.timeFrom } : {})} + {...(inbound?.timeTo ? { initialReturnTimeTo: inbound.timeTo } : {})} initialDirectOnly={outbound.connections === 0} initialReturnFlights={Boolean(inbound)} />