diff --git a/src/features/online-board/components/details-panels/AircraftPanel.test.tsx b/src/features/online-board/components/details-panels/AircraftPanel.test.tsx new file mode 100644 index 00000000..a30e5a4a --- /dev/null +++ b/src/features/online-board/components/details-panels/AircraftPanel.test.tsx @@ -0,0 +1,51 @@ +// @vitest-environment jsdom +import { describe, it, expect, vi } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { AircraftPanel } from "./AircraftPanel.js"; +import type { IEquipmentFull } from "../../types.js"; + +vi.mock("@/i18n/provider.js", () => ({ + useTranslation: () => ({ t: (k: string) => k }), +})); + +describe("AircraftPanel", () => { + it("renders actual title when present", () => { + const eq: IEquipmentFull = { aircraft: { actual: { title: "Airbus A321" } } }; + render(); + expect(screen.getByText("Airbus A321")).toBeTruthy(); + }); + + it("falls back to scheduled when actual.title is empty", () => { + const eq: IEquipmentFull = { + aircraft: { actual: { title: "" }, scheduled: { title: "Boeing 737" } }, + }; + render(); + expect(screen.getByText("Boeing 737")).toBeTruthy(); + }); + + it("renders both actual and scheduled when they differ", () => { + const eq: IEquipmentFull = { + aircraft: { + actual: { title: "Airbus A321" }, + scheduled: { title: "Airbus A320" }, + }, + }; + render(); + expect(screen.getByText("Airbus A321")).toBeTruthy(); + expect(screen.getByText("Airbus A320")).toBeTruthy(); + }); + + it("renders configuration when present", () => { + const eq: IEquipmentFull = { + aircraft: { actual: { title: "A320" }, configuration: "C12Y138" }, + }; + render(); + expect(screen.getByText("C12Y138")).toBeTruthy(); + }); + + it("has data-testid", () => { + const eq: IEquipmentFull = { aircraft: { actual: { title: "A320" } } }; + render(); + expect(screen.getByTestId("aircraft-panel")).toBeTruthy(); + }); +}); diff --git a/src/features/online-board/components/details-panels/AircraftPanel.tsx b/src/features/online-board/components/details-panels/AircraftPanel.tsx new file mode 100644 index 00000000..01c22e0b --- /dev/null +++ b/src/features/online-board/components/details-panels/AircraftPanel.tsx @@ -0,0 +1,51 @@ +import type { FC } from "react"; +import { useTranslation } from "@/i18n/provider.js"; +import type { IEquipmentFull } from "../../types.js"; +import "./panels.scss"; + +export interface AircraftPanelProps { + equipment: IEquipmentFull; +} + +export const AircraftPanel: FC = ({ equipment }) => { + const { t } = useTranslation(); + const aircraft = equipment.aircraft; + const actualTitle = aircraft?.actual?.title; + const scheduledTitle = aircraft?.scheduled?.title; + const configuration = aircraft?.configuration; + + // If actual has content and differs from scheduled, show both; otherwise + // fall back to whichever is present. + const showBoth = Boolean(actualTitle && scheduledTitle && actualTitle !== scheduledTitle); + const primaryTitle = actualTitle || scheduledTitle; + + return ( +
+ {showBoth ? ( + <> +
+ {t("DETAILS.ACTUAL")} + {actualTitle} +
+
+ {t("DETAILS.SCHEDULED")} + {scheduledTitle} +
+ + ) : ( + primaryTitle && ( +
+ {t("DETAILS.AIRCRAFT")} + {primaryTitle} +
+ ) + )} + {configuration && ( +
+ {t("DETAILS.CONFIGURATION")} + {configuration} +
+ )} +
+ ); +};