Split AdditionalServicesStep into IncludedServicesStep + ExtrasStep
- IncludedServicesStep: package inclusions at no cost (dressing, viewing,
prayers, funeral announcement). Sub-options render inside parent card.
- ExtrasStep: optional paid extras for lead generation (catering, music,
coffin bearing, newspaper notice). POA support, tally of priced items.
- AddOnOption: children prop (sub-options inside card), priceLabel prop
(custom text like "Price on application" in brand copper italic)
- Flattened sub-option pattern: inline toggle rows inside parent card
instead of nested card-in-card ("Russian doll") pattern
- Coffin bearing now uses toggle + bearer type radio (consistent UX)
- Removed old AdditionalServicesStep (replaced by two new pages)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,8 @@ import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import type { SxProps, Theme } from '@mui/material/styles';
|
||||
import { Card } from '../../atoms/Card';
|
||||
import { Collapse } from '../../atoms/Collapse';
|
||||
import { Divider } from '../../atoms/Divider';
|
||||
import { Typography } from '../../atoms/Typography';
|
||||
import { Switch } from '../../atoms/Switch';
|
||||
import { Link } from '../../atoms/Link';
|
||||
@@ -16,6 +18,8 @@ export interface AddOnOptionProps {
|
||||
description?: string;
|
||||
/** Price in dollars — shown below the heading */
|
||||
price?: number;
|
||||
/** Custom price label (e.g. "Price on application") — overrides formatted price */
|
||||
priceLabel?: string;
|
||||
/** Whether this add-on is currently enabled */
|
||||
checked?: boolean;
|
||||
/** Called when the toggle changes */
|
||||
@@ -24,6 +28,8 @@ export interface AddOnOptionProps {
|
||||
disabled?: boolean;
|
||||
/** Max visible lines for description before "View more" toggle. Omit for no limit. */
|
||||
maxDescriptionLines?: number;
|
||||
/** Sub-options rendered inside the card when checked. Appears below a divider. */
|
||||
children?: React.ReactNode;
|
||||
/** MUI sx prop for style overrides */
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
@@ -59,10 +65,12 @@ export const AddOnOption = React.forwardRef<HTMLDivElement, AddOnOptionProps>(
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
priceLabel,
|
||||
checked = false,
|
||||
onChange,
|
||||
disabled = false,
|
||||
maxDescriptionLines,
|
||||
children,
|
||||
sx,
|
||||
},
|
||||
ref,
|
||||
@@ -141,10 +149,16 @@ export const AddOnOption = React.forwardRef<HTMLDivElement, AddOnOptionProps>(
|
||||
</Box>
|
||||
|
||||
{/* Price — tucks directly under heading */}
|
||||
{price != null && (
|
||||
<Typography variant="body2" color="primary">
|
||||
${price.toLocaleString('en-AU')}
|
||||
{priceLabel ? (
|
||||
<Typography variant="body2" color="primary" sx={{ fontStyle: 'italic' }}>
|
||||
{priceLabel}
|
||||
</Typography>
|
||||
) : (
|
||||
price != null && (
|
||||
<Typography variant="body2" color="primary">
|
||||
${price.toLocaleString('en-AU')}
|
||||
</Typography>
|
||||
)
|
||||
)}
|
||||
|
||||
{/* Description with optional line clamping */}
|
||||
@@ -182,6 +196,14 @@ export const AddOnOption = React.forwardRef<HTMLDivElement, AddOnOptionProps>(
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Sub-options — rendered inside the card when checked */}
|
||||
{children && (
|
||||
<Collapse in={checked}>
|
||||
<Divider sx={{ my: 1.5 }} />
|
||||
<Box onClick={(e) => e.stopPropagation()}>{children}</Box>
|
||||
</Collapse>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user