Add CemeteryStep page (wizard step 9)
- Progressive disclosure: "Have a plot?" → "Choose cemetery?" → card grid - Dependent field resets (changing parent answer clears child selections) - Cemetery card grid with radiogroup pattern + roving tabindex - Pre-planning variant: softer subheading about provider arranging later - "Provider can arrange this" shortcut skips grid entirely - Grief-sensitive copy: "we need to find one" not "I don't have a plot" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
243
src/components/pages/CemeteryStep/CemeteryStep.stories.tsx
Normal file
243
src/components/pages/CemeteryStep/CemeteryStep.stories.tsx
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { CemeteryStep } from './CemeteryStep';
|
||||||
|
import type { CemeteryStepValues, CemeteryStepErrors, Cemetery } from './CemeteryStep';
|
||||||
|
import { Navigation } from '../../organisms/Navigation';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
|
||||||
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const FALogo = () => (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Box
|
||||||
|
component="img"
|
||||||
|
src="/brandlogo/logo-full.svg"
|
||||||
|
alt="Funeral Arranger"
|
||||||
|
sx={{ height: 28, display: { xs: 'none', md: 'block' } }}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
component="img"
|
||||||
|
src="/brandlogo/logo-short.svg"
|
||||||
|
alt="Funeral Arranger"
|
||||||
|
sx={{ height: 28, display: { xs: 'block', md: 'none' } }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
const nav = (
|
||||||
|
<Navigation
|
||||||
|
logo={<FALogo />}
|
||||||
|
items={[
|
||||||
|
{ label: 'FAQ', href: '/faq' },
|
||||||
|
{ label: 'Contact Us', href: '/contact' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const sampleCemeteries: Cemetery[] = [
|
||||||
|
{
|
||||||
|
id: 'rookwood',
|
||||||
|
name: 'Rookwood Cemetery',
|
||||||
|
location: 'Lidcombe, NSW',
|
||||||
|
price: 4500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'northern-suburbs',
|
||||||
|
name: 'Northern Suburbs Memorial Gardens',
|
||||||
|
location: 'North Ryde, NSW',
|
||||||
|
price: 5200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'macquarie-park',
|
||||||
|
name: 'Macquarie Park Cemetery',
|
||||||
|
location: 'Macquarie Park, NSW',
|
||||||
|
price: 4800,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const defaultValues: CemeteryStepValues = {
|
||||||
|
burialOwn: null,
|
||||||
|
burialCustom: null,
|
||||||
|
selectedCemeteryId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Meta ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const meta: Meta<typeof CemeteryStep> = {
|
||||||
|
title: 'Pages/CemeteryStep',
|
||||||
|
component: CemeteryStep,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
parameters: {
|
||||||
|
layout: 'fullscreen',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof CemeteryStep>;
|
||||||
|
|
||||||
|
// ─── Interactive (default) ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** Fully interactive — progressive disclosure flow */
|
||||||
|
export const Default: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({ ...defaultValues });
|
||||||
|
const [errors, setErrors] = useState<CemeteryStepErrors>({});
|
||||||
|
|
||||||
|
const handleContinue = () => {
|
||||||
|
const newErrors: CemeteryStepErrors = {};
|
||||||
|
if (!values.burialOwn) newErrors.burialOwn = 'Please let us know about the burial plot.';
|
||||||
|
if (values.burialOwn === 'no' && !values.burialCustom)
|
||||||
|
newErrors.burialCustom = "Please let us know if you'd like to choose a specific cemetery.";
|
||||||
|
if (values.burialOwn === 'no' && values.burialCustom === 'yes' && !values.selectedCemeteryId)
|
||||||
|
newErrors.selectedCemeteryId = 'Please choose a cemetery.';
|
||||||
|
setErrors(newErrors);
|
||||||
|
if (Object.keys(newErrors).length === 0) alert('Continue');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={(v) => {
|
||||||
|
setValues(v);
|
||||||
|
setErrors({});
|
||||||
|
}}
|
||||||
|
onContinue={handleContinue}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
onSaveAndExit={() => alert('Save')}
|
||||||
|
errors={errors}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Has existing plot ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** User already owns a burial plot — short confirmation */
|
||||||
|
export const HasExistingPlot: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({
|
||||||
|
...defaultValues,
|
||||||
|
burialOwn: 'yes',
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => alert('Continue')}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Provider arranges ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** User wants provider to arrange — no cemetery grid */
|
||||||
|
export const ProviderArranges: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({
|
||||||
|
...defaultValues,
|
||||||
|
burialOwn: 'no',
|
||||||
|
burialCustom: 'no',
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => alert('Continue')}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Cemetery grid visible ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** User wants to choose — cemetery grid revealed */
|
||||||
|
export const CemeteryGridVisible: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({
|
||||||
|
...defaultValues,
|
||||||
|
burialOwn: 'no',
|
||||||
|
burialCustom: 'yes',
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => alert('Continue')}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Cemetery selected ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** Cemetery selected */
|
||||||
|
export const CemeterySelected: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({
|
||||||
|
burialOwn: 'no',
|
||||||
|
burialCustom: 'yes',
|
||||||
|
selectedCemeteryId: 'rookwood',
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => alert('Continue')}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Pre-planning ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** Pre-planning variant */
|
||||||
|
export const PrePlanning: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({ ...defaultValues });
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => alert('Continue')}
|
||||||
|
onBack={() => alert('Back')}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
isPrePlanning
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─── Validation errors ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** All errors showing */
|
||||||
|
export const WithErrors: Story = {
|
||||||
|
render: () => {
|
||||||
|
const [values, setValues] = useState<CemeteryStepValues>({ ...defaultValues });
|
||||||
|
return (
|
||||||
|
<CemeteryStep
|
||||||
|
values={values}
|
||||||
|
onChange={setValues}
|
||||||
|
onContinue={() => {}}
|
||||||
|
errors={{ burialOwn: 'Please let us know about the burial plot.' }}
|
||||||
|
cemeteries={sampleCemeteries}
|
||||||
|
navigation={nav}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
296
src/components/pages/CemeteryStep/CemeteryStep.tsx
Normal file
296
src/components/pages/CemeteryStep/CemeteryStep.tsx
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import FormControl from '@mui/material/FormControl';
|
||||||
|
import FormLabel from '@mui/material/FormLabel';
|
||||||
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import RadioGroup from '@mui/material/RadioGroup';
|
||||||
|
import Radio from '@mui/material/Radio';
|
||||||
|
import type { SxProps, Theme } from '@mui/material/styles';
|
||||||
|
import { WizardLayout } from '../../templates/WizardLayout';
|
||||||
|
import { Card } from '../../atoms/Card';
|
||||||
|
import { Collapse } from '../../atoms/Collapse';
|
||||||
|
import { Typography } from '../../atoms/Typography';
|
||||||
|
import { Button } from '../../atoms/Button';
|
||||||
|
import { Divider } from '../../atoms/Divider';
|
||||||
|
|
||||||
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** A cemetery available for selection */
|
||||||
|
export interface Cemetery {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
location: string;
|
||||||
|
price?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Form values for the cemetery step */
|
||||||
|
export interface CemeteryStepValues {
|
||||||
|
/** Does the family already own a burial plot? */
|
||||||
|
burialOwn: 'yes' | 'no' | null;
|
||||||
|
/** Would they like to choose a specific cemetery? (when burialOwn=no) */
|
||||||
|
burialCustom: 'yes' | 'no' | null;
|
||||||
|
/** Selected cemetery ID */
|
||||||
|
selectedCemeteryId: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Field-level error messages */
|
||||||
|
export interface CemeteryStepErrors {
|
||||||
|
burialOwn?: string;
|
||||||
|
burialCustom?: string;
|
||||||
|
selectedCemeteryId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Props for the CemeteryStep page component */
|
||||||
|
export interface CemeteryStepProps {
|
||||||
|
/** Current form values */
|
||||||
|
values: CemeteryStepValues;
|
||||||
|
/** Callback when any field value changes */
|
||||||
|
onChange: (values: CemeteryStepValues) => void;
|
||||||
|
/** Callback when the Continue button is clicked */
|
||||||
|
onContinue: () => void;
|
||||||
|
/** Callback for back navigation */
|
||||||
|
onBack?: () => void;
|
||||||
|
/** Callback for save-and-exit */
|
||||||
|
onSaveAndExit?: () => void;
|
||||||
|
/** Field-level validation errors */
|
||||||
|
errors?: CemeteryStepErrors;
|
||||||
|
/** Whether the Continue button is in a loading state */
|
||||||
|
loading?: boolean;
|
||||||
|
/** Available cemeteries */
|
||||||
|
cemeteries: Cemetery[];
|
||||||
|
/** Whether this is a pre-planning flow */
|
||||||
|
isPrePlanning?: boolean;
|
||||||
|
/** Navigation bar */
|
||||||
|
navigation?: React.ReactNode;
|
||||||
|
/** Progress stepper */
|
||||||
|
progressStepper?: React.ReactNode;
|
||||||
|
/** Running total */
|
||||||
|
runningTotal?: React.ReactNode;
|
||||||
|
/** Hide the help bar */
|
||||||
|
hideHelpBar?: boolean;
|
||||||
|
/** MUI sx prop */
|
||||||
|
sx?: SxProps<Theme>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Component ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 9 — Cemetery for the FA arrangement wizard.
|
||||||
|
*
|
||||||
|
* Cemetery selection and burial plot preferences. Only shown for
|
||||||
|
* burial-type funerals (Service & Burial, Graveside, Burial Only).
|
||||||
|
*
|
||||||
|
* Progressive disclosure flow:
|
||||||
|
* 1. "Do you have a burial plot?" → Yes/No
|
||||||
|
* 2. If No: "Would you like to choose a specific cemetery?" → Yes/No
|
||||||
|
* 3. If Yes to #2: Cemetery card grid
|
||||||
|
*
|
||||||
|
* If the user already owns a plot, the cemetery grid can be shown
|
||||||
|
* for confirmation (passed via showGridForExistingPlot).
|
||||||
|
*
|
||||||
|
* Pure presentation component — props in, callbacks out.
|
||||||
|
*
|
||||||
|
* Spec: documentation/steps/steps/09_cemetery.yaml
|
||||||
|
*/
|
||||||
|
export const CemeteryStep: React.FC<CemeteryStepProps> = ({
|
||||||
|
values,
|
||||||
|
onChange,
|
||||||
|
onContinue,
|
||||||
|
onBack,
|
||||||
|
onSaveAndExit,
|
||||||
|
errors,
|
||||||
|
loading = false,
|
||||||
|
cemeteries,
|
||||||
|
isPrePlanning = false,
|
||||||
|
navigation,
|
||||||
|
progressStepper,
|
||||||
|
runningTotal,
|
||||||
|
hideHelpBar,
|
||||||
|
sx,
|
||||||
|
}) => {
|
||||||
|
const showCustomQuestion = values.burialOwn === 'no';
|
||||||
|
const showCemeteryGrid = values.burialOwn === 'no' && values.burialCustom === 'yes';
|
||||||
|
|
||||||
|
const handleBurialOwnChange = (value: string) => {
|
||||||
|
onChange({
|
||||||
|
...values,
|
||||||
|
burialOwn: value as CemeteryStepValues['burialOwn'],
|
||||||
|
// Reset dependent fields when parent changes
|
||||||
|
burialCustom: null,
|
||||||
|
selectedCemeteryId: null,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBurialCustomChange = (value: string) => {
|
||||||
|
onChange({
|
||||||
|
...values,
|
||||||
|
burialCustom: value as CemeteryStepValues['burialCustom'],
|
||||||
|
selectedCemeteryId: null,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCemeterySelect = (id: string) => {
|
||||||
|
onChange({ ...values, selectedCemeteryId: id });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WizardLayout
|
||||||
|
variant="centered-form"
|
||||||
|
navigation={navigation}
|
||||||
|
progressStepper={progressStepper}
|
||||||
|
runningTotal={runningTotal}
|
||||||
|
showBackLink={!!onBack}
|
||||||
|
backLabel="Back"
|
||||||
|
onBack={onBack}
|
||||||
|
hideHelpBar={hideHelpBar}
|
||||||
|
sx={sx}
|
||||||
|
>
|
||||||
|
{/* Page heading */}
|
||||||
|
<Typography variant="display3" component="h1" sx={{ mb: 1 }} tabIndex={-1}>
|
||||||
|
Cemetery
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
|
||||||
|
{isPrePlanning
|
||||||
|
? "If you haven't decided on a cemetery yet, the funeral provider can help with this later."
|
||||||
|
: 'Choose where the burial will take place.'}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
component="form"
|
||||||
|
noValidate
|
||||||
|
onSubmit={(e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
onContinue();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* ─── Burial plot question ─── */}
|
||||||
|
<FormControl component="fieldset" sx={{ mb: 3, display: 'block' }}>
|
||||||
|
<FormLabel component="legend" sx={{ mb: 1 }}>
|
||||||
|
Do you already have a burial plot?
|
||||||
|
</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
value={values.burialOwn ?? ''}
|
||||||
|
onChange={(e) => handleBurialOwnChange(e.target.value)}
|
||||||
|
>
|
||||||
|
<FormControlLabel value="yes" control={<Radio />} label="Yes, we have a plot" />
|
||||||
|
<FormControlLabel value="no" control={<Radio />} label="No, we need to find one" />
|
||||||
|
</RadioGroup>
|
||||||
|
{errors?.burialOwn && (
|
||||||
|
<Typography variant="body2" color="error" sx={{ mt: 0.5 }} role="alert">
|
||||||
|
{errors.burialOwn}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* ─── Custom cemetery question (progressive disclosure) ─── */}
|
||||||
|
<Collapse in={showCustomQuestion}>
|
||||||
|
<FormControl component="fieldset" sx={{ mb: 3, display: 'block' }}>
|
||||||
|
<FormLabel component="legend" sx={{ mb: 1 }}>
|
||||||
|
Would you like to choose a specific cemetery?
|
||||||
|
</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
value={values.burialCustom ?? ''}
|
||||||
|
onChange={(e) => handleBurialCustomChange(e.target.value)}
|
||||||
|
>
|
||||||
|
<FormControlLabel value="yes" control={<Radio />} label="Yes, I'd like to choose" />
|
||||||
|
<FormControlLabel
|
||||||
|
value="no"
|
||||||
|
control={<Radio />}
|
||||||
|
label="No, the funeral provider can arrange this"
|
||||||
|
/>
|
||||||
|
</RadioGroup>
|
||||||
|
{errors?.burialCustom && (
|
||||||
|
<Typography variant="body2" color="error" sx={{ mt: 0.5 }} role="alert">
|
||||||
|
{errors.burialCustom}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
{/* ─── Cemetery card grid (progressive disclosure) ─── */}
|
||||||
|
<Collapse in={showCemeteryGrid}>
|
||||||
|
<Box sx={{ mb: 3 }}>
|
||||||
|
<Typography variant="h5" sx={{ mb: 2 }}>
|
||||||
|
Available cemeteries
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
role="radiogroup"
|
||||||
|
aria-label="Available cemeteries"
|
||||||
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)' },
|
||||||
|
gap: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{cemeteries.map((cemetery, index) => (
|
||||||
|
<Card
|
||||||
|
key={cemetery.id}
|
||||||
|
interactive
|
||||||
|
selected={cemetery.id === values.selectedCemeteryId}
|
||||||
|
onClick={() => handleCemeterySelect(cemetery.id)}
|
||||||
|
role="radio"
|
||||||
|
aria-checked={cemetery.id === values.selectedCemeteryId}
|
||||||
|
tabIndex={
|
||||||
|
values.selectedCemeteryId === null
|
||||||
|
? index === 0
|
||||||
|
? 0
|
||||||
|
: -1
|
||||||
|
: cemetery.id === values.selectedCemeteryId
|
||||||
|
? 0
|
||||||
|
: -1
|
||||||
|
}
|
||||||
|
sx={{ p: 3 }}
|
||||||
|
>
|
||||||
|
<Typography variant="h5">{cemetery.name}</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{cemetery.location}
|
||||||
|
</Typography>
|
||||||
|
{cemetery.price != null && (
|
||||||
|
<Typography variant="h6" color="primary" sx={{ mt: 1 }}>
|
||||||
|
${cemetery.price.toLocaleString('en-AU')}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{errors?.selectedCemeteryId && (
|
||||||
|
<Typography variant="body2" color="error" sx={{ mt: 1 }} role="alert">
|
||||||
|
{errors.selectedCemeteryId}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
{/* CTAs */}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexDirection: { xs: 'column-reverse', sm: 'row' },
|
||||||
|
gap: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{onSaveAndExit ? (
|
||||||
|
<Button variant="text" color="secondary" onClick={onSaveAndExit} type="button">
|
||||||
|
Save and continue later
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Box />
|
||||||
|
)}
|
||||||
|
<Button type="submit" variant="contained" size="large" loading={loading}>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</WizardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
CemeteryStep.displayName = 'CemeteryStep';
|
||||||
|
export default CemeteryStep;
|
||||||
7
src/components/pages/CemeteryStep/index.ts
Normal file
7
src/components/pages/CemeteryStep/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export { CemeteryStep, default } from './CemeteryStep';
|
||||||
|
export type {
|
||||||
|
CemeteryStepProps,
|
||||||
|
CemeteryStepValues,
|
||||||
|
CemeteryStepErrors,
|
||||||
|
Cemetery,
|
||||||
|
} from './CemeteryStep';
|
||||||
Reference in New Issue
Block a user