From fbd819c7077d35b5c7d6e728c4e1c26f6000efc7 Mon Sep 17 00:00:00 2001 From: gnezim Date: Thu, 23 Apr 2026 17:19:32 +0300 Subject: [PATCH] Transfer gaps 40px + always-visible Buy pill in schedule summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Пересадка wrapper bumps to $space-xxl (40px) margin: at 15px the strip blended with the regular between-card gap from `.schedule-details { gap: $space-l }` and read as a sibling card rather than a separator. 40/40 mirrors Angular's breathing room. FlightActions gains a `forceBuy` prop that bypasses the canBuyTicket() status/window gate. The schedule summary passes it because the Buy pill there is a generic 'open the Aeroflot booking tool for this route' affordance — the user picks any date in the booking flow, so hiding the button on a specific day's 'Cancelled' status (as the Onlineboard detail page does) loses a useful entry point. Board detail pages still pass the default (status-gated). --- .../components/BoardDetailsHeader/FlightActions.tsx | 12 +++++++++++- .../schedule/components/ScheduleDetailsPage.scss | 7 ++++++- .../schedule/components/ScheduleDetailsPage.tsx | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/features/online-board/components/BoardDetailsHeader/FlightActions.tsx b/src/features/online-board/components/BoardDetailsHeader/FlightActions.tsx index 08cb7c63..f5202599 100644 --- a/src/features/online-board/components/BoardDetailsHeader/FlightActions.tsx +++ b/src/features/online-board/components/BoardDetailsHeader/FlightActions.tsx @@ -19,6 +19,14 @@ export interface FlightActionsProps { showShare?: boolean; showRegister?: boolean; showBuy?: boolean; + /** + * Skip the `canBuyTicket` status/window gate and always render the + * Buy pill. Used by the Schedule summary header where the Buy link + * is a generic "open the Aeroflot booking tool for this route" + * affordance — the user can then pick any date, so gating on a + * particular day's "Cancelled" status would hide a useful action. + */ + forceBuy?: boolean; } export const FlightActions: FC = ({ @@ -29,11 +37,13 @@ export const FlightActions: FC = ({ showShare = true, showRegister = true, showBuy = true, + forceBuy = false, }) => { const { flightStatusAvailableFromHours, buyTicketMinHours, buyTicketMaxHours } = useAppSettings(); const now = new Date(); - const canBuy = showBuy && canBuyTicket(flight, now, buyTicketMinHours, buyTicketMaxHours); + const canBuy = + showBuy && (forceBuy || canBuyTicket(flight, now, buyTicketMinHours, buyTicketMaxHours)); const canReg = showRegister && canRegister(flight, AIRLINES); const canStatus = showStatus && diff --git a/src/features/schedule/components/ScheduleDetailsPage.scss b/src/features/schedule/components/ScheduleDetailsPage.scss index 1a110159..1d662c33 100644 --- a/src/features/schedule/components/ScheduleDetailsPage.scss +++ b/src/features/schedule/components/ScheduleDetailsPage.scss @@ -49,7 +49,12 @@ // and the next flight's header, reading as a shared edge rather than // a separator. .schedule-details__transfer { - margin: vars.$space-l 0; + // $space-xxl (40px) so the strip reads unmistakably as a SEPARATOR. + // $space-l (15px) was physically present but visually indistinguishable + // from the regular between-card gap set by `.schedule-details { gap }`, + // so the Пересадка looked glued to its neighbours. 40/40 mirrors + // Angular's breathing room between `.multi-flight--details` blocks. + margin: vars.$space-xxl 0; > .transfer-bar { border-radius: vars.$border-radius; diff --git a/src/features/schedule/components/ScheduleDetailsPage.tsx b/src/features/schedule/components/ScheduleDetailsPage.tsx index 6c547a79..98bb2175 100644 --- a/src/features/schedule/components/ScheduleDetailsPage.tsx +++ b/src/features/schedule/components/ScheduleDetailsPage.tsx @@ -512,6 +512,7 @@ export const ScheduleDetailsPage: FC = ({ locale={locale} showStatus={miniListCurrentFlight.routeType === "Direct"} showRegister={false} + forceBuy />