import React from 'react'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import PhoneIcon from '@mui/icons-material/Phone'; import type { SxProps, Theme } from '@mui/material/styles'; import { Link } from '../../atoms/Link'; import { Typography } from '../../atoms/Typography'; // ─── Types ─────────────────────────────────────────────────────────────────── /** Layout variant matching the wizard page templates */ export type WizardLayoutVariant = | 'centered-form' | 'wide-form' | 'list-map' | 'list-detail' | 'grid-sidebar' | 'detail-toggles'; /** Props for the WizardLayout template */ export interface WizardLayoutProps { /** Which layout variant to render */ variant: WizardLayoutVariant; /** Navigation bar — rendered at the top of the page */ navigation?: React.ReactNode; /** Optional progress stepper — shown below nav on grid-sidebar and detail-toggles variants */ progressStepper?: React.ReactNode; /** Optional running total widget — shown in a bar below nav (grid-sidebar, detail-toggles) */ runningTotal?: React.ReactNode; /** Show a back link above the content area */ showBackLink?: boolean; /** Label for the back link */ backLabel?: string; /** Click handler for the back link */ onBack?: () => void; /** Help bar phone number */ helpPhone?: string; /** Hide the sticky help bar */ hideHelpBar?: boolean; // ─── Slot content ─── /** Main content — for centered-form this is the form; for split layouts this is the primary (left) panel */ children: React.ReactNode; /** Secondary panel content — right panel for split layouts (map, detail, grid) */ secondaryPanel?: React.ReactNode; /** MUI sx prop for the root container */ sx?: SxProps; } // ─── Help bar ──────────────────────────────────────────────────────────────── const HelpBar: React.FC<{ phone: string }> = ({ phone }) => ( Need help? Call us on{' '} {phone} ); // ─── Back link ─────────────────────────────────────────────────────────────── const BackLink: React.FC<{ label: string; onClick?: () => void }> = ({ label, onClick }) => ( {label} ); // ─── Stepper + total bar ───────────────────────────────────────────────────── const StepperBar: React.FC<{ stepper?: React.ReactNode; total?: React.ReactNode; }> = ({ stepper, total }) => { if (!stepper && !total) return null; return ( {stepper} {total && {total}} ); }; // ─── Layout variants ───────────────────────────────────────────────────────── /** Centered Form: single column ~600px, heading + fields + CTA */ const CenteredFormLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => ( {children} ); /** Wide Form: single column maxWidth "lg", for card grids (coffins, etc.) */ const WideFormLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => ( {children} ); /** List + Map: 420px fixed scrollable list (left) / flex map (right) — D-B */ const ListMapLayout: React.FC<{ children: React.ReactNode; secondaryPanel?: React.ReactNode; backLink?: React.ReactNode; }> = ({ children, secondaryPanel, backLink }) => ( {/* Left panel — scrollable list with scrollbar visible on hover */} {/* Right panel — map or placeholder, fills available space */} {secondaryPanel} ); /** List + Detail: ~40% selection list (left) / ~60% detail panel (right) */ const ListDetailLayout: React.FC<{ children: React.ReactNode; secondaryPanel?: React.ReactNode; }> = ({ children, secondaryPanel }) => ( {children} {secondaryPanel} ); /** Grid + Sidebar: ~25% filter sidebar (left) / ~75% card grid (right). * Viewport-locked on desktop — both panels scroll independently. * On mobile, stacks vertically and scrolls as a single page. */ const GridSidebarLayout: React.FC<{ children: React.ReactNode; secondaryPanel?: React.ReactNode; }> = ({ children, secondaryPanel }) => ( {/* Left sidebar — scrollbar visible on hover */} {children} {/* Right panel — always scrollable */} {secondaryPanel} ); /** Detail + Toggles: scrollable left (image/desc) / sticky right (info/CTA) */ const DetailTogglesLayout: React.FC<{ children: React.ReactNode; secondaryPanel?: React.ReactNode; backLink?: React.ReactNode; }> = ({ children, secondaryPanel, backLink }) => ( {/* Left panel — scrollable content */} {backLink && {backLink}} {children} {/* Right panel — sticky info */} {secondaryPanel} ); // ─── Variant map ───────────────────────────────────────────────────────────── const LAYOUT_MAP: Record< WizardLayoutVariant, React.FC<{ children: React.ReactNode; secondaryPanel?: React.ReactNode; backLink?: React.ReactNode; }> > = { 'centered-form': CenteredFormLayout, 'wide-form': WideFormLayout, 'list-map': ListMapLayout, 'list-detail': ListDetailLayout, 'grid-sidebar': GridSidebarLayout, 'detail-toggles': DetailTogglesLayout, }; /* Stepper bar renders on any variant when progressStepper or runningTotal is provided */ // ─── Component ─────────────────────────────────────────────────────────────── /** * Page-level layout template for the FA arrangement wizard. * * Provides 5 layout variants matching the wizard page templates: * - **centered-form**: Single centered column for form steps (intro, auth, date/time, etc.) * - **list-map**: Split view with scrollable card list and map panel (providers) * - **list-detail**: Master-detail split for selection + detail (packages, preview) * - **grid-sidebar**: Filter sidebar + card grid (coffins) * - **detail-toggles**: Hero image + info column (venue, coffin details) * * All variants share: navigation slot, optional back link, sticky help bar, * and optional progress stepper + running total bar (shown when props provided). */ export const WizardLayout = React.forwardRef( ( { variant, navigation, progressStepper, runningTotal, showBackLink = false, backLabel = 'Back', onBack, helpPhone = '1800 987 888', hideHelpBar = false, children, secondaryPanel, sx, }, ref, ) => { const LayoutComponent = LAYOUT_MAP[variant]; return ( {/* Navigation */} {navigation} {/* Stepper + running total bar (grid-sidebar, detail-toggles only) */} {/* Back link — inside left panel for list-map/detail-toggles, above content for others */} {showBackLink && variant !== 'list-map' && variant !== 'detail-toggles' && ( )} {/* Main content area */} ) : undefined } > {children} {/* Sticky help bar */} {!hideHelpBar && } ); }, ); WizardLayout.displayName = 'WizardLayout'; export default WizardLayout;