import { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { AuthGateStep } from './AuthGateStep'; import type { AuthGateStepValues, AuthGateStepErrors } from './AuthGateStep'; 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: AuthGateStepValues = { subStep: 'email', email: '', firstName: '', lastName: '', phone: '', contactPreference: 'call_anytime', verificationCode: '', }; // ─── Meta ──────────────────────────────────────────────────────────────────── const meta: Meta = { title: 'Pages/AuthGateStep', component: AuthGateStep, tags: ['autodocs'], parameters: { layout: 'fullscreen', }, }; export default meta; type Story = StoryObj; // ─── Interactive (default) ────────────────────────────────────────────────── /** Fully interactive — walk through all three sub-steps */ export const Default: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues }); const [errors, setErrors] = useState({}); const handleContinue = () => { const newErrors: AuthGateStepErrors = {}; if (values.subStep === 'email') { if (!values.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) { newErrors.email = "That email address doesn't look quite right. Please check it and try again."; } if (Object.keys(newErrors).length === 0) { setValues((v) => ({ ...v, subStep: 'details' })); setErrors({}); return; } } if (values.subStep === 'details') { if (!values.firstName) newErrors.firstName = 'We need your first name to save the plan.'; if (!values.lastName) newErrors.lastName = 'We need your last name to save the plan.'; if (values.contactPreference !== 'email_only' && !values.phone) { newErrors.phone = 'Please enter a valid Australian phone number, like 0412 345 678.'; } if (Object.keys(newErrors).length === 0) { setValues((v) => ({ ...v, subStep: 'verify' })); setErrors({}); return; } } if (values.subStep === 'verify') { if (!values.verificationCode || values.verificationCode.length !== 6) { newErrors.verificationCode = "That code doesn't match. Please check the email we sent and try again."; } if (Object.keys(newErrors).length === 0) { alert(`Authenticated: ${values.firstName} ${values.lastName} (${values.email})`); return; } } setErrors(newErrors); }; return ( { setValues(v); setErrors({}); }} onContinue={handleContinue} onBack={() => alert('Back to preview')} onGoogleSSO={() => alert('Google SSO')} onMicrosoftSSO={() => alert('Microsoft SSO')} errors={errors} navigation={nav} /> ); }, }; // ─── Sub-step 2: Details ──────────────────────────────────────────────────── /** Details sub-step — email entered, name/phone fields revealed */ export const DetailsSubStep: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues, subStep: 'details', email: 'jane@example.com', }); return ( setValues((v) => ({ ...v, subStep: 'verify' }))} onBack={() => alert('Back')} navigation={nav} /> ); }, }; // ─── Sub-step 3: Verification ─────────────────────────────────────────────── /** Verification sub-step — code entry */ export const VerifySubStep: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues, subStep: 'verify', email: 'jane@example.com', firstName: 'Jane', lastName: 'Smith', phone: '0412 345 678', }); return ( alert('Verified!')} onBack={() => alert('Back')} navigation={nav} /> ); }, }; // ─── At-need variant ──────────────────────────────────────────────────────── /** At-need subheading copy variant */ export const AtNeed: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues }); return ( setValues((v) => ({ ...v, subStep: 'details' }))} onBack={() => alert('Back')} isAtNeed navigation={nav} /> ); }, }; // ─── Email-only preference ────────────────────────────────────────────────── /** Phone becomes optional when contact preference is email-only */ export const EmailOnlyPreference: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues, subStep: 'details', email: 'jane@example.com', contactPreference: 'email_only', }); return ( setValues((v) => ({ ...v, subStep: 'verify' }))} onBack={() => alert('Back')} navigation={nav} /> ); }, }; // ─── Validation errors ────────────────────────────────────────────────────── /** Details sub-step with all validation errors showing */ export const WithErrors: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues, subStep: 'details', email: 'jane@example.com', }); return ( {}} errors={{ firstName: 'We need your first name to save the plan.', lastName: 'We need your last name to save the plan.', phone: 'Please enter a valid Australian phone number, like 0412 345 678.', }} onBack={() => alert('Back')} navigation={nav} /> ); }, }; // ─── Loading state ────────────────────────────────────────────────────────── /** Continue button in loading state */ export const Loading: Story = { render: () => { const [values, setValues] = useState({ ...defaultValues, subStep: 'verify', email: 'jane@example.com', firstName: 'Jane', lastName: 'Smith', phone: '0412 345 678', verificationCode: '123456', }); return ( {}} loading navigation={nav} /> ); }, };