Add estimated-time note after leg route and accordion icons

- Move the '* Время прилета...' note from the footer to right after the
  LegRoute, matching Angular's position between the route strip and the
  Детали рейса accordion.
- Add inline SVG icons for each FlightDetailsAccordion row
  (Регистрация, Посадка, Высадка, Воздушное судно, Питание, Услуги) in
  blue to mirror Angular's sprite-based icons.
This commit is contained in:
2026-04-18 16:00:29 +03:00
parent ec67111d10
commit 54d1991a8f
4 changed files with 85 additions and 2 deletions
@@ -169,6 +169,13 @@
}
.flight-details {
&__estimated-note {
padding: 0 vars.$space-xl vars.$space-xl;
color: #8a8a8a;
font-size: 12px;
line-height: 1.5;
}
&--error,
&--not-found {
padding: vars.$space-xl;
@@ -264,6 +264,10 @@ function FlightLegs({
<LegRoute leg={leg} status={leg.status} />
<div className="flight-details__estimated-note">
* {t("BOARD.ESTIMATED-TIME-NOTE")}
</div>
{leg.equipment.name && (
<div className="flight-details__aircraft">
{t("SHARED.PLANE")}: {leg.equipment.name}
@@ -479,7 +483,6 @@ export const OnlineBoardDetailsPage: FC<OnlineBoardDetailsPageProps> = ({
<FlightSchedule flight={displayFlight} />
<div className="flight-details__footer-notes" data-testid="footer-notes">
<p>* {t("BOARD.ESTIMATED-TIME-NOTE")}</p>
<p>* {t("BOARD.LOCAL-TIME-NOTE")}</p>
</div>
</div>
@@ -20,6 +20,22 @@
&:hover {
background: #eef1f4;
}
&__title {
display: inline-flex;
align-items: center;
gap: 10px;
}
&__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
color: #2457ff;
flex-shrink: 0;
}
}
.p-accordion-content {
@@ -19,8 +19,52 @@ interface PanelDef {
id: string;
header: string;
content: JSX.Element;
/** Small inline SVG icon shown on the left of the header, Angular parity. */
icon?: JSX.Element;
}
// Inline SVG icons mirror Angular's sprite refs. Plain strokes + blue
// fill to match the details sidebar's visual language.
const ICON_REGISTRATION: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<circle cx="12" cy="7" r="3.2" />
<path d="M5.5 20v-1.5a4.5 4.5 0 0 1 4.5-4.5h4a4.5 4.5 0 0 1 4.5 4.5V20" />
</svg>
);
const ICON_BOARDING: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M4 20h16" />
<path d="M6 17l4-4h4l4-4" />
<circle cx="14" cy="7" r="1.5" />
</svg>
);
const ICON_DEBOARDING: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M4 20h16" />
<path d="M18 17l-4-4h-4l-4-4" />
<circle cx="10" cy="7" r="1.5" />
</svg>
);
const ICON_AIRCRAFT: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M21 16v-2l-8-5V3.5a1.5 1.5 0 1 0-3 0V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5L21 16z" />
</svg>
);
const ICON_MEAL: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M4 11c0-2 2-4 4-4s4 2 4 4" />
<path d="M14 7c2-2 5-1 5 2v8" />
<path d="M4 11v8" />
<path d="M4 19h20" />
</svg>
);
const ICON_SERVICES: JSX.Element = (
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<rect x="3" y="6" width="18" height="12" rx="2" />
<path d="M7 10v4M12 10v4M17 10v4" />
</svg>
);
export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, viewType }) => {
const { t } = useTranslation();
@@ -30,6 +74,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "registration",
header: t("DETAILS.REGISTRATION"),
icon: ICON_REGISTRATION,
content: <RegistrationPanel item={leg.transition!.registration!} />,
});
}
@@ -37,6 +82,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "boarding",
header: t("DETAILS.BOARDING"),
icon: ICON_BOARDING,
content: <BoardingPanel item={leg.transition!.boarding!} />,
});
}
@@ -44,6 +90,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "deboarding",
header: t("DETAILS.DEBOARDING"),
icon: ICON_DEBOARDING,
content: <DeboardingPanel item={leg.transition!.deboarding!} arrival={leg.arrival} />,
});
}
@@ -51,6 +98,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "aircraft",
header: t("DETAILS.AIRCRAFT"),
icon: ICON_AIRCRAFT,
content: <AircraftPanel equipment={leg.equipment} />,
});
}
@@ -58,6 +106,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "meal",
header: t("DETAILS.MEAL"),
icon: ICON_MEAL,
content: <MealPanel meals={leg.equipment.meal!} />,
});
}
@@ -65,6 +114,7 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
panels.push({
id: "services",
header: t("DETAILS.ON_BOARD_SERVICES"),
icon: ICON_SERVICES,
content: <ServicesPanel services={leg.equipment.aircraft!.actual!.onBoardServices!} />,
});
}
@@ -114,7 +164,14 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
}
}}
>
<span>{panel.header}</span>
<span className="p-accordion-header__title">
{panel.icon && (
<span className="p-accordion-header__icon" aria-hidden="true">
{panel.icon}
</span>
)}
<span>{panel.header}</span>
</span>
<span aria-hidden="true">{isOpen ? "\u25B2" : "\u25BC"}</span>
</div>
{isOpen && <div className="p-accordion-content">{panel.content}</div>}