import React from 'react'; import Box from '@mui/material/Box'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import type { SxProps, Theme } from '@mui/material/styles'; import { Typography } from '../../atoms/Typography'; import { Button } from '../../atoms/Button'; import { Divider } from '../../atoms/Divider'; import { LineItem } from '../../molecules/LineItem'; // ─── Types ─────────────────────────────────────────────────────────────────── /** A single item within a package section */ export interface PackageLineItem { /** Item name */ name: string; /** Tooltip description — clients have laboured over these, display them all */ info?: string; /** Price in dollars — omit for complimentary items */ price?: number; /** Whether this is an allowance (shows asterisk) */ isAllowance?: boolean; /** Custom price display — overrides formatted price (e.g. "Complimentary", "Price On Application") */ priceLabel?: string; } /** A section of items within a package (e.g. "Essentials", "Complimentary Items") */ export interface PackageSection { /** Section heading */ heading: string; /** Items in this section */ items: PackageLineItem[]; } /** Props for the FA PackageDetail organism */ export interface PackageDetailProps { /** Package name */ name: string; /** Package price in dollars */ price: number; /** Main package sections shown BEFORE the total (Essentials, Complimentary Items) */ sections: PackageSection[]; /** Package total — shown between main sections and extras */ total?: number; /** Additional-cost extras shown AFTER the total — these can be added at extra cost */ extras?: PackageSection; /** Terms and conditions text — required by providers */ terms?: string; /** Called when user clicks "Make Arrangement" */ onArrange?: () => void; /** Called when user clicks "Compare" */ onCompare?: () => void; /** Whether the arrange button is disabled */ arrangeDisabled?: boolean; /** Whether the compare button is in loading state */ compareLoading?: boolean; /** Custom label for the arrange CTA button (default: "Make Arrangement") */ arrangeLabel?: string; /** Disclaimer shown below the price (e.g. for unverified/estimated pricing) */ priceDisclaimer?: string; /** When true, replaces the itemised breakdown with an "Itemised Pricing Unavailable" notice */ itemizedUnavailable?: boolean; /** MUI sx prop for the root element */ sx?: SxProps; } // ─── Helpers ───────────────────────────────────────────────────────────────── /** Renders a section heading + list of LineItems */ function SectionBlock({ section, subtext }: { section: PackageSection; subtext?: string }) { return ( {section.heading} {subtext && ( {subtext} )} {section.items.map((item) => ( ))} ); } // ─── Component ─────────────────────────────────────────────────────────────── /** * Package detail panel for the FA design system. * * Displays the full contents of a funeral package — name, price, CTA buttons, * grouped line items, total, optional extras, and T&Cs. * * Structure: * - **Header** (warm bg): Package name, price, and CTA buttons * - **sections** (before total): What's included in the package price * (Essentials, Complimentary Items) * - **total**: The package price * - **extras** (after total): Additional items that can be added at extra cost * - **terms**: Provider T&Cs (grey footer) * * "Make Arrangement" is the FA term for selecting/committing to a package. * * Composes Typography + Button + Divider + LineItem. */ export const PackageDetail = React.forwardRef( ( { name, price, sections, total, extras, terms, onArrange, onCompare, arrangeDisabled = false, compareLoading = false, arrangeLabel = 'Make Arrangement', priceDisclaimer, itemizedUnavailable = false, sx, }, ref, ) => { return ( {/* Header band — warm bg to separate from content */} Package {name} ${price.toLocaleString('en-AU')} {/* Price disclaimer */} {priceDisclaimer && ( {priceDisclaimer} )} {/* CTA buttons */} {onCompare && ( )} {/* Package contents */} {itemizedUnavailable ? ( Itemised Pricing Unavailable This provider has shared their overall package price, but has not provided a detailed breakdown of what is included. ) : ( <> {/* Main sections — included in the package price */} {sections.map((section, idx) => ( ))} {/* Total — separates included content from extras */} {total != null && } {/* Extras — additional cost items after the total */} {extras && extras.items.length > 0 && ( <> )} )} {/* Terms & Conditions footer */} {terms && ( {terms} )} ); }, ); PackageDetail.displayName = 'PackageDetail'; export default PackageDetail;