Files
flights_web/src/ui/layout/PageLayout.tsx
T
gnezim a982d9a669 Fix lint: route sessionStorage through shared storage module, drop dead imports
- storage.ts: add sessionStore wrapper (getRaw/setRaw/delete/clear) so
  transientPrefill + ScheduleStartPage tests don't trip the
  no-restricted-globals rule.
- transientPrefill.ts + ScheduleStartPage.test.tsx: use sessionStore.
- closestFlight.ts: hoist bracket-index key so no newline-before-[ ASI.
- Test files: hoist typeof import(...) into named type alias with
  type-only namespace import.
- Drop unused imports: FlightCard (Link, languageToLocale),
  OnlineBoardDetailsPage (operatingCarrier),
  ScheduleSearchPage (FlightList, inline import() types),
  PageLayout (FeedbackButton).
- Drop react-hooks/exhaustive-deps disable comments for a rule not
  registered in eslint.config.js.
2026-04-20 08:15:21 +03:00

77 lines
2.7 KiB
TypeScript

/**
* Shared page layout wrapper matching the Angular `page-layout` component.
*
* Produces the same DOM structure and CSS class names so global SCSS
* styles apply identically. Includes breadcrumbs, feedback button,
* and scroll-up button from the Angular app.
*/
import type { ReactNode, FC } from "react";
import { Breadcrumbs, type BreadcrumbItem } from "./Breadcrumbs.js";
import { ScrollUpButton } from "./ScrollUpButton.js";
import "./PageLayout.scss";
export interface PageLayoutProps {
/** Content rendered in the header left column (e.g. page tabs). */
headerLeft?: ReactNode;
/** Page title rendered in the header right column. */
title?: ReactNode;
/** Content in the left column of the main content area (e.g. filter). */
contentLeft?: ReactNode;
/** Sticky content in the right column above main children. */
stickyContent?: ReactNode;
/** Main content rendered in the right column. */
children?: ReactNode;
/** Breadcrumb trail items (beyond the default "Главная" root). */
breadcrumbs?: BreadcrumbItem[];
}
export const PageLayout: FC<PageLayoutProps> = ({
headerLeft,
title,
contentLeft,
stickyContent,
children,
breadcrumbs,
}) => {
return (
<div className="page-layout">
{stickyContent && <div className="page-layout__scroll-overlay" aria-hidden="true" />}
<div className="page-layout__row page-layout__header">
<aside className="page-layout__column-left page-layout__header-left">
{headerLeft}
</aside>
<div className="page-layout__column-right page-layout__header-right">
{/*
Angular stacks the breadcrumb trail and the <h1> inside a
single `__title` wrapper, then uses `__header-right`'s
`justify-content: space-between` to push the optional
feedback button to the far right. Mirror that structure so
the breadcrumb sits directly above the title rather than
drifting to the row start.
*/}
<div className="page-layout__title">
{breadcrumbs && <Breadcrumbs items={breadcrumbs} />}
{title}
</div>
{/* FeedbackButton hidden: Angular has it behind FEEDBACK_BUTTON_AVAILABLE feature flag (off by default) */}
</div>
</div>
<div className="page-layout__row page-layout__content">
<aside className="page-layout__column-left">
{contentLeft}
</aside>
<main className="page-layout__column-right">
{stickyContent && (
<div className="page-layout__sticky-content">
{stickyContent}
</div>
)}
{children}
</main>
</div>
<ScrollUpButton />
</div>
);
};