diff --git a/src/components/pages/ConfirmationStep/ConfirmationStep.stories.tsx b/src/components/pages/ConfirmationStep/ConfirmationStep.stories.tsx
new file mode 100644
index 0000000..cbe4834
--- /dev/null
+++ b/src/components/pages/ConfirmationStep/ConfirmationStep.stories.tsx
@@ -0,0 +1,88 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { ConfirmationStep } from './ConfirmationStep';
+import { Navigation } from '../../organisms/Navigation';
+import Box from '@mui/material/Box';
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+const FALogo = () => (
+
+
+
+
+);
+
+const nav = (
+ }
+ items={[
+ { label: 'FAQ', href: '/faq' },
+ { label: 'Contact Us', href: '/contact' },
+ ]}
+ />
+);
+
+// ─── Meta ────────────────────────────────────────────────────────────────────
+
+const meta: Meta = {
+ title: 'Pages/ConfirmationStep',
+ component: ConfirmationStep,
+ tags: ['autodocs'],
+ parameters: {
+ layout: 'fullscreen',
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+// ─── At-need (default) ──────────────────────────────────────────────────────
+
+/** At-need confirmation — arranger will call */
+export const Default: Story = {
+ render: () => (
+ alert('View plan')}
+ nextSteps={[
+ { label: 'Start detailed arrangement', onClick: () => alert('Arrangement') },
+ { label: 'Go to dashboard', onClick: () => alert('Dashboard') },
+ ]}
+ navigation={nav}
+ />
+ ),
+};
+
+// ─── Pre-planning ───────────────────────────────────────────────────────────
+
+/** Pre-planning confirmation — plan saved, return anytime */
+export const PrePlanning: Story = {
+ render: () => (
+ alert('View plan')}
+ nextSteps={[{ label: 'Go to dashboard', onClick: () => alert('Dashboard') }]}
+ navigation={nav}
+ />
+ ),
+};
+
+// ─── Minimal ────────────────────────────────────────────────────────────────
+
+/** Minimal — no next steps, no view plan */
+export const Minimal: Story = {
+ render: () => ,
+};
diff --git a/src/components/pages/ConfirmationStep/ConfirmationStep.tsx b/src/components/pages/ConfirmationStep/ConfirmationStep.tsx
new file mode 100644
index 0000000..58f218e
--- /dev/null
+++ b/src/components/pages/ConfirmationStep/ConfirmationStep.tsx
@@ -0,0 +1,152 @@
+import React from 'react';
+import Box from '@mui/material/Box';
+import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
+import type { SxProps, Theme } from '@mui/material/styles';
+import { WizardLayout } from '../../templates/WizardLayout';
+import { Typography } from '../../atoms/Typography';
+import { Button } from '../../atoms/Button';
+
+// ─── Types ───────────────────────────────────────────────────────────────────
+
+/** Next step link shown on the confirmation page */
+export interface ConfirmationLink {
+ label: string;
+ href?: string;
+ onClick?: () => void;
+}
+
+/** Props for the ConfirmationStep page component */
+export interface ConfirmationStepProps {
+ /** Whether this is a pre-planning flow (different copy) */
+ isPrePlanning?: boolean;
+ /** User's email address (shown in confirmation text) */
+ email?: string;
+ /** User's phone number (shown in at-need confirmation) */
+ phone?: string;
+ /** Expected callback timeframe (at-need) */
+ callbackTimeframe?: string;
+ /** Navigation links to next steps */
+ nextSteps?: ConfirmationLink[];
+ /** Callback for "View your plan" */
+ onViewPlan?: () => void;
+ /** Navigation bar */
+ navigation?: React.ReactNode;
+ /** Hide the help bar */
+ hideHelpBar?: boolean;
+ /** MUI sx prop */
+ sx?: SxProps;
+}
+
+// ─── Component ───────────────────────────────────────────────────────────────
+
+/**
+ * Step 15 — Confirmation / Plan View for the FA arrangement wizard.
+ *
+ * Terminal confirmation page. Different copy for at-need vs pre-planning.
+ * Confirming and orienting — not celebratory.
+ *
+ * At-need: "Your arrangement has been submitted" + callback info
+ * Pre-planning: "Your plan has been saved" + return-anytime info
+ *
+ * No progress indicator. No back button. Links to post-plan flows.
+ *
+ * Pure presentation component — props in, callbacks out.
+ *
+ * Spec: documentation/steps/steps/15_view.yaml
+ */
+export const ConfirmationStep: React.FC = ({
+ isPrePlanning = false,
+ email,
+ phone,
+ callbackTimeframe = 'within 2 hours',
+ nextSteps = [],
+ onViewPlan,
+ navigation,
+ hideHelpBar,
+ sx,
+}) => {
+ return (
+
+
+ {/* Success icon — muted, not celebratory */}
+
+
+ {/* Heading */}
+
+ {isPrePlanning ? 'Your plan has been saved' : 'Your arrangement has been submitted'}
+
+
+ {/* Body text */}
+ {isPrePlanning ? (
+
+
+ You can return and update it anytime.
+ {email && ` We've sent a copy to ${email}.`}
+
+
+ When the time comes, your family can contact us and we'll have everything ready.
+
+
+ ) : (
+
+
+ A funeral arranger will call you
+ {phone && ` on ${phone}`} {callbackTimeframe} to confirm the details.
+ {email && ` A confirmation has been sent to ${email}.`}
+
+
+ If you need to make changes before then, call us on{' '}
+
+ 1300 000 000
+
+ .
+
+
+ )}
+
+ {/* View plan CTA */}
+ {onViewPlan && (
+
+ )}
+
+ {/* Next steps */}
+ {nextSteps.length > 0 && (
+
+ {nextSteps.map((link) => (
+
+ ))}
+
+ )}
+
+
+ );
+};
+
+ConfirmationStep.displayName = 'ConfirmationStep';
+export default ConfirmationStep;
diff --git a/src/components/pages/ConfirmationStep/index.ts b/src/components/pages/ConfirmationStep/index.ts
new file mode 100644
index 0000000..9214a89
--- /dev/null
+++ b/src/components/pages/ConfirmationStep/index.ts
@@ -0,0 +1,2 @@
+export { ConfirmationStep, default } from './ConfirmationStep';
+export type { ConfirmationStepProps, ConfirmationLink } from './ConfirmationStep';
diff --git a/src/components/pages/PaymentStep/PaymentStep.stories.tsx b/src/components/pages/PaymentStep/PaymentStep.stories.tsx
new file mode 100644
index 0000000..7cafe73
--- /dev/null
+++ b/src/components/pages/PaymentStep/PaymentStep.stories.tsx
@@ -0,0 +1,184 @@
+import { useState } from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { PaymentStep } from './PaymentStep';
+import type { PaymentStepValues, PaymentStepErrors } from './PaymentStep';
+import { Navigation } from '../../organisms/Navigation';
+import Box from '@mui/material/Box';
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+const FALogo = () => (
+
+
+
+
+);
+
+const nav = (
+ }
+ items={[
+ { label: 'FAQ', href: '/faq' },
+ { label: 'Contact Us', href: '/contact' },
+ ]}
+ />
+);
+
+const defaultValues: PaymentStepValues = {
+ paymentPlan: null,
+ paymentMethod: null,
+ termsAccepted: false,
+};
+
+// ─── Meta ────────────────────────────────────────────────────────────────────
+
+const meta: Meta = {
+ title: 'Pages/PaymentStep',
+ component: PaymentStep,
+ tags: ['autodocs'],
+ parameters: {
+ layout: 'fullscreen',
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+// ─── Interactive (default) ──────────────────────────────────────────────────
+
+/** Full interactive payment flow */
+export const Default: Story = {
+ render: () => {
+ const [values, setValues] = useState({ ...defaultValues });
+ const [errors, setErrors] = useState({});
+
+ const handleConfirm = () => {
+ const newErrors: PaymentStepErrors = {};
+ if (!values.paymentPlan) newErrors.paymentPlan = 'Please choose a payment option.';
+ if (!values.paymentMethod) newErrors.paymentMethod = 'Please choose a payment method.';
+ if (!values.termsAccepted)
+ newErrors.termsAccepted = 'Please review and accept the service agreement to continue.';
+ setErrors(newErrors);
+ if (Object.keys(newErrors).length === 0) alert('Payment confirmed!');
+ };
+
+ return (
+ {
+ setValues(v);
+ setErrors({});
+ }}
+ onConfirmPayment={handleConfirm}
+ onBack={() => alert('Back to summary')}
+ errors={errors}
+ totalPrice={9850}
+ depositAmount={2000}
+ navigation={nav}
+ />
+ );
+ },
+};
+
+// ─── Card selected ──────────────────────────────────────────────────────────
+
+/** Card payment selected — shows payment form placeholder */
+export const CardPayment: Story = {
+ render: () => {
+ const [values, setValues] = useState({
+ paymentPlan: 'full',
+ paymentMethod: 'Card',
+ termsAccepted: false,
+ });
+ return (
+ alert('Confirm')}
+ onBack={() => alert('Back')}
+ totalPrice={9850}
+ navigation={nav}
+ />
+ );
+ },
+};
+
+// ─── Bank transfer selected ─────────────────────────────────────────────────
+
+/** Bank transfer selected — shows account details */
+export const BankTransfer: Story = {
+ render: () => {
+ const [values, setValues] = useState({
+ paymentPlan: 'deposit',
+ paymentMethod: 'Bank',
+ termsAccepted: true,
+ });
+ return (
+ alert('Confirm')}
+ onBack={() => alert('Back')}
+ totalPrice={9850}
+ depositAmount={2000}
+ navigation={nav}
+ />
+ );
+ },
+};
+
+// ─── Validation errors ──────────────────────────────────────────────────────
+
+/** All errors showing */
+export const WithErrors: Story = {
+ render: () => {
+ const [values, setValues] = useState({ ...defaultValues });
+ return (
+ {}}
+ errors={{
+ paymentPlan: 'Please choose a payment option.',
+ paymentMethod: 'Please choose a payment method.',
+ termsAccepted: 'Please review and accept the service agreement to continue.',
+ }}
+ totalPrice={9850}
+ navigation={nav}
+ />
+ );
+ },
+};
+
+// ─── Processing ─────────────────────────────────────────────────────────────
+
+/** Payment processing */
+export const Processing: Story = {
+ render: () => {
+ const [values, setValues] = useState({
+ paymentPlan: 'full',
+ paymentMethod: 'Card',
+ termsAccepted: true,
+ });
+ return (
+ {}}
+ loading
+ totalPrice={9850}
+ navigation={nav}
+ />
+ );
+ },
+};
diff --git a/src/components/pages/PaymentStep/PaymentStep.tsx b/src/components/pages/PaymentStep/PaymentStep.tsx
new file mode 100644
index 0000000..95ad5c6
--- /dev/null
+++ b/src/components/pages/PaymentStep/PaymentStep.tsx
@@ -0,0 +1,332 @@
+import React from 'react';
+import Box from '@mui/material/Box';
+import Paper from '@mui/material/Paper';
+import Checkbox from '@mui/material/Checkbox';
+import FormControlLabel from '@mui/material/FormControlLabel';
+import type { SxProps, Theme } from '@mui/material/styles';
+import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
+import { WizardLayout } from '../../templates/WizardLayout';
+import { ToggleButtonGroup } from '../../atoms/ToggleButtonGroup';
+import { Collapse } from '../../atoms/Collapse';
+import { Typography } from '../../atoms/Typography';
+import { Button } from '../../atoms/Button';
+import { Divider } from '../../atoms/Divider';
+
+// ─── Types ───────────────────────────────────────────────────────────────────
+
+/** Payment plan choice */
+export type PaymentPlan = 'full' | 'deposit' | null;
+
+/** Payment method choice */
+export type PaymentMethod = 'Card' | 'Bank' | null;
+
+/** Form values for the payment step */
+export interface PaymentStepValues {
+ /** Full payment or deposit */
+ paymentPlan: PaymentPlan;
+ /** Card or bank transfer */
+ paymentMethod: PaymentMethod;
+ /** Terms accepted */
+ termsAccepted: boolean;
+}
+
+/** Field-level error messages */
+export interface PaymentStepErrors {
+ paymentPlan?: string;
+ paymentMethod?: string;
+ termsAccepted?: string;
+ card?: string;
+}
+
+/** Props for the PaymentStep page component */
+export interface PaymentStepProps {
+ /** Current form values */
+ values: PaymentStepValues;
+ /** Callback when any field value changes */
+ onChange: (values: PaymentStepValues) => void;
+ /** Callback when Confirm Payment is clicked */
+ onConfirmPayment: () => void;
+ /** Callback for back navigation */
+ onBack?: () => void;
+ /** Field-level validation errors */
+ errors?: PaymentStepErrors;
+ /** Whether the button is in a loading/processing state */
+ loading?: boolean;
+ /** Total amount */
+ totalPrice: number;
+ /** Deposit amount */
+ depositAmount?: number;
+ /** Bank account details for transfer */
+ bankDetails?: {
+ accountName: string;
+ bsb: string;
+ accountNumber: string;
+ reference?: string;
+ };
+ /** Card payment iframe slot (PayWay integration) */
+ cardFormSlot?: React.ReactNode;
+ /** Navigation bar */
+ navigation?: React.ReactNode;
+ /** Progress stepper */
+ progressStepper?: React.ReactNode;
+ /** Hide the help bar */
+ hideHelpBar?: boolean;
+ /** MUI sx prop */
+ sx?: SxProps;
+}
+
+// ─── Component ───────────────────────────────────────────────────────────────
+
+/**
+ * Step 14 — Payment for the FA arrangement wizard.
+ *
+ * Collect payment via credit card or bank transfer. Supports full
+ * payment or deposit. Hidden for pre-planning users.
+ *
+ * Payment plan shown before method so users know the amount first.
+ * Card details via PayWay iframe (slot). Bank transfer shows account info.
+ *
+ * Pure presentation component — props in, callbacks out.
+ *
+ * Spec: documentation/steps/steps/14_payment.yaml
+ */
+export const PaymentStep: React.FC = ({
+ values,
+ onChange,
+ onConfirmPayment,
+ onBack,
+ errors,
+ loading = false,
+ totalPrice,
+ depositAmount = 2000,
+ bankDetails = {
+ accountName: 'Funeral Arranger Services Pty Ltd',
+ bsb: '112-879',
+ accountNumber: '481 449 385',
+ },
+ cardFormSlot,
+ navigation,
+ progressStepper,
+ hideHelpBar,
+ sx,
+}) => {
+ const payingAmount = values.paymentPlan === 'deposit' ? depositAmount : totalPrice;
+
+ return (
+
+ {/* Page heading */}
+
+ Payment
+
+
+
+
+
+ Your payment is processed securely. You won't be charged more than the total shown.
+
+
+
+ {/* ─── Amount display ─── */}
+
+
+ {values.paymentPlan === 'deposit' ? 'Deposit amount' : 'Total due'}
+
+
+ ${payingAmount.toLocaleString('en-AU')}
+
+ {values.paymentPlan === 'deposit' && (
+
+ Remaining balance: ${(totalPrice - depositAmount).toLocaleString('en-AU')}
+
+ )}
+
+
+ {
+ e.preventDefault();
+ onConfirmPayment();
+ }}
+ >
+ {/* ─── Payment plan ─── */}
+
+ onChange({ ...values, paymentPlan: v as PaymentPlan })}
+ error={!!errors?.paymentPlan}
+ helperText={errors?.paymentPlan}
+ required
+ fullWidth
+ />
+
+
+ {/* ─── Payment method ─── */}
+
+ onChange({ ...values, paymentMethod: v as PaymentMethod })}
+ error={!!errors?.paymentMethod}
+ helperText={errors?.paymentMethod}
+ required
+ fullWidth
+ />
+
+
+ {/* ─── Card form (PayWay iframe slot) ─── */}
+
+
+ {cardFormSlot || (
+
+
+ Secure card payment form will appear here
+
+
+ )}
+ {errors?.card && (
+
+ {errors.card}
+
+ )}
+
+
+
+ {/* ─── Bank transfer details ─── */}
+
+
+
+ Bank transfer details
+
+
+ {[
+ { label: 'Account name', value: bankDetails.accountName },
+ { label: 'BSB', value: bankDetails.bsb },
+ { label: 'Account number', value: bankDetails.accountNumber },
+ ].map(({ label, value }) => (
+
+
+ {label}
+
+
+ {value}
+
+
+ ))}
+
+ {bankDetails.reference && (
+
+ Reference: {bankDetails.reference}
+
+ )}
+
+
+
+ {/* ─── Terms checkbox ─── */}
+ onChange({ ...values, termsAccepted: e.target.checked })}
+ />
+ }
+ label={
+
+ I agree to the{' '}
+
+ service agreement
+ {' '}
+ and{' '}
+
+ privacy policy
+
+
+ }
+ sx={{ mb: 1, alignItems: 'flex-start', '& .MuiCheckbox-root': { pt: 0.5 } }}
+ />
+ {errors?.termsAccepted && (
+
+ {errors.termsAccepted}
+
+ )}
+
+
+
+ {/* CTA */}
+
+
+
+
+
+ );
+};
+
+PaymentStep.displayName = 'PaymentStep';
+export default PaymentStep;
diff --git a/src/components/pages/PaymentStep/index.ts b/src/components/pages/PaymentStep/index.ts
new file mode 100644
index 0000000..0709757
--- /dev/null
+++ b/src/components/pages/PaymentStep/index.ts
@@ -0,0 +1,8 @@
+export { PaymentStep, default } from './PaymentStep';
+export type {
+ PaymentStepProps,
+ PaymentStepValues,
+ PaymentStepErrors,
+ PaymentPlan,
+ PaymentMethod,
+} from './PaymentStep';
diff --git a/src/components/pages/SummaryStep/SummaryStep.stories.tsx b/src/components/pages/SummaryStep/SummaryStep.stories.tsx
new file mode 100644
index 0000000..c4b2fb1
--- /dev/null
+++ b/src/components/pages/SummaryStep/SummaryStep.stories.tsx
@@ -0,0 +1,150 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { SummaryStep } from './SummaryStep';
+import type { SummarySection } from './SummaryStep';
+import { Navigation } from '../../organisms/Navigation';
+import Box from '@mui/material/Box';
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+const FALogo = () => (
+
+
+
+
+);
+
+const nav = (
+ }
+ items={[
+ { label: 'FAQ', href: '/faq' },
+ { label: 'Contact Us', href: '/contact' },
+ ]}
+ />
+);
+
+const sampleSections: SummarySection[] = [
+ {
+ id: 'provider',
+ title: 'Funeral Provider',
+ editStepId: 'providers',
+ items: [
+ { label: 'Provider', value: 'H. Parsons Funeral Directors' },
+ { label: 'Package', value: 'Essential Service Package', price: 4950 },
+ ],
+ },
+ {
+ id: 'venue',
+ title: 'Service Venue',
+ editStepId: 'venue',
+ items: [
+ { label: 'Venue', value: 'West Chapel, Strathfield', price: 900 },
+ { label: 'Photo presentation', value: 'Included', price: 150 },
+ { label: 'Livestream', value: 'Included', price: 200 },
+ ],
+ },
+ {
+ id: 'crematorium',
+ title: 'Crematorium',
+ editStepId: 'crematorium',
+ items: [
+ { label: 'Crematorium', value: 'Warrill Park Crematorium', price: 850 },
+ { label: 'Following hearse', value: 'Yes' },
+ ],
+ },
+ {
+ id: 'coffin',
+ title: 'Coffin',
+ editStepId: 'coffins',
+ items: [
+ { label: 'Coffin', value: 'Cedar Classic', price: 2800 },
+ { label: 'Handles', value: 'Brass Bar Handle', price: 0 },
+ { label: 'Lining', value: 'White Satin', price: 0 },
+ ],
+ },
+ {
+ id: 'services',
+ title: 'Additional Services',
+ editStepId: 'additional_services',
+ items: [
+ { label: 'Funeral announcement', value: 'Included' },
+ { label: 'Bearing', value: 'Family and friends' },
+ ],
+ },
+];
+
+// ─── Meta ────────────────────────────────────────────────────────────────────
+
+const meta: Meta = {
+ title: 'Pages/SummaryStep',
+ component: SummaryStep,
+ tags: ['autodocs'],
+ parameters: {
+ layout: 'fullscreen',
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+// ─── At-need (default) ──────────────────────────────────────────────────────
+
+/** Full summary for at-need flow */
+export const Default: Story = {
+ render: () => (
+ alert('Confirmed — proceed to payment')}
+ onBack={() => alert('Back')}
+ onSaveAndExit={() => alert('Save')}
+ onEdit={(stepId) => alert(`Edit: ${stepId}`)}
+ onShare={() => alert('Share plan')}
+ navigation={nav}
+ />
+ ),
+};
+
+// ─── Pre-planning ───────────────────────────────────────────────────────────
+
+/** Pre-planning variant — "Save your plan" CTA, no payment */
+export const PrePlanning: Story = {
+ render: () => (
+ alert('Plan saved')}
+ onBack={() => alert('Back')}
+ onEdit={(stepId) => alert(`Edit: ${stepId}`)}
+ onShare={() => alert('Share plan')}
+ isPrePlanning
+ navigation={nav}
+ />
+ ),
+};
+
+// ─── Loading ────────────────────────────────────────────────────────────────
+
+/** Confirm button loading */
+export const Loading: Story = {
+ render: () => (
+ {}}
+ loading
+ navigation={nav}
+ />
+ ),
+};
diff --git a/src/components/pages/SummaryStep/SummaryStep.tsx b/src/components/pages/SummaryStep/SummaryStep.tsx
new file mode 100644
index 0000000..088e4df
--- /dev/null
+++ b/src/components/pages/SummaryStep/SummaryStep.tsx
@@ -0,0 +1,264 @@
+import React from 'react';
+import Box from '@mui/material/Box';
+import Paper from '@mui/material/Paper';
+import Accordion from '@mui/material/Accordion';
+import AccordionSummary from '@mui/material/AccordionSummary';
+import AccordionDetails from '@mui/material/AccordionDetails';
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
+import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined';
+import type { SxProps, Theme } from '@mui/material/styles';
+import { WizardLayout } from '../../templates/WizardLayout';
+import { Typography } from '../../atoms/Typography';
+import { Button } from '../../atoms/Button';
+import { IconButton } from '../../atoms/IconButton';
+import { Divider } from '../../atoms/Divider';
+
+// ─── Types ───────────────────────────────────────────────────────────────────
+
+/** A single line item in the summary */
+export interface SummaryLineItem {
+ label: string;
+ value: string;
+ price?: number;
+}
+
+/** A section in the summary (e.g. Provider, Venue, Coffin) */
+export interface SummarySection {
+ id: string;
+ title: string;
+ items: SummaryLineItem[];
+ /** Step ID to navigate back to for editing */
+ editStepId?: string;
+}
+
+/** Props for the SummaryStep page component */
+export interface SummaryStepProps {
+ /** Summary sections */
+ sections: SummarySection[];
+ /** Total cost */
+ totalPrice: number;
+ /** Deposit amount (if applicable) */
+ depositAmount?: number;
+ /** Callback when Confirm is clicked */
+ onConfirm: () => void;
+ /** Callback for back navigation */
+ onBack?: () => void;
+ /** Callback for save-and-exit */
+ onSaveAndExit?: () => void;
+ /** Callback when edit is clicked on a section */
+ onEdit?: (stepId: string) => void;
+ /** Callback for sharing the plan */
+ onShare?: () => void;
+ /** Whether the Confirm button is in a loading state */
+ loading?: boolean;
+ /** Whether this is a pre-planning flow */
+ isPrePlanning?: boolean;
+ /** Navigation bar */
+ navigation?: React.ReactNode;
+ /** Progress stepper */
+ progressStepper?: React.ReactNode;
+ /** Hide the help bar */
+ hideHelpBar?: boolean;
+ /** MUI sx prop */
+ sx?: SxProps;
+}
+
+// ─── Component ───────────────────────────────────────────────────────────────
+
+/**
+ * Step 13 — Summary / Review for the FA arrangement wizard.
+ *
+ * Complete summary of the funeral plan with all selections and pricing.
+ * Accordion sections with edit links back to each step. Total bar at bottom.
+ *
+ * For pre-planning: CTA is "Save your plan" instead of "Confirm".
+ * For at-need: CTA is "Confirm and continue to payment".
+ *
+ * Pure presentation component — props in, callbacks out.
+ *
+ * Spec: documentation/steps/steps/13_summary.yaml
+ */
+export const SummaryStep: React.FC = ({
+ sections,
+ totalPrice,
+ depositAmount,
+ onConfirm,
+ onBack,
+ onSaveAndExit,
+ onEdit,
+ onShare,
+ loading = false,
+ isPrePlanning = false,
+ navigation,
+ progressStepper,
+ hideHelpBar,
+ sx,
+}) => {
+ return (
+
+ {/* Header with share */}
+
+
+ Review your plan
+
+ {onShare && (
+
+
+
+ )}
+
+
+
+ Check everything looks right before confirming.
+
+
+
+ You can edit any section by tapping the edit icon.
+
+
+ {/* ─── Summary sections ─── */}
+ {sections.map((section) => (
+
+ } sx={{ px: 3, py: 1 }}>
+
+
+ {section.title}
+
+ {section.editStepId && onEdit && (
+ {
+ e.stopPropagation();
+ onEdit(section.editStepId!);
+ }}
+ >
+
+
+ )}
+
+
+
+
+ {section.items.map((item, i) => (
+
+
+
+ {item.label}
+
+
+ {item.value}
+
+
+ {item.price != null && (
+
+ ${item.price.toLocaleString('en-AU')}
+
+ )}
+
+ ))}
+
+
+
+ ))}
+
+ {/* ─── Total bar ─── */}
+
+
+ Total cost
+ {depositAmount != null && !isPrePlanning && (
+
+ Deposit: ${depositAmount.toLocaleString('en-AU')}
+
+ )}
+
+
+ ${totalPrice.toLocaleString('en-AU')}
+
+
+
+ {/* Payment reassurance */}
+ {!isPrePlanning && (
+
+ You won't be charged until you complete the next step.
+
+ )}
+
+
+
+ {/* CTAs */}
+
+ {onSaveAndExit ? (
+
+ ) : (
+
+ )}
+
+
+
+ );
+};
+
+SummaryStep.displayName = 'SummaryStep';
+export default SummaryStep;
diff --git a/src/components/pages/SummaryStep/index.ts b/src/components/pages/SummaryStep/index.ts
new file mode 100644
index 0000000..020b817
--- /dev/null
+++ b/src/components/pages/SummaryStep/index.ts
@@ -0,0 +1,2 @@
+export { SummaryStep, default } from './SummaryStep';
+export type { SummaryStepProps, SummarySection, SummaryLineItem } from './SummaryStep';