import { useEffect } from 'react'
import {
MemoryRouter,
Navigate,
Route,
Routes,
useNavigate,
useParams,
} from 'react-router-dom'
import type { FormSchema } from '@runilib/react-formbridge'
import { field, useFormBridgeWizard } from '@runilib/react-formbridge'
const steps = [
{
id: 'account',
label: 'Account',
schema: {
email: field.email('Email').required(),
password: field.password('Password').required(),
} satisfies FormSchema,
},
{
id: 'company',
label: 'Company',
schema: {
companyName: field.text('Company name').required(),
} satisfies FormSchema,
},
{ id: 'review', label: 'Review', schema: {} satisfies FormSchema },
]
export function SignupWizardRoute() {
const navigate = useNavigate()
const { stepId } = useParams()
const wizard = useFormBridgeWizard(steps, {
stepId,
initialStepId: 'account',
persist: { key: 'signup-wizard', storage: 'local' },
onStepChange: ({ step }) => navigate('/signup/' + step.id),
onSubmit: (allValues) => api.save(allValues),
})
useEffect(() => {
if (!wizard.isHydrating && wizard.currentStepId && stepId !== wizard.currentStepId) {
navigate('/signup/' + wizard.currentStepId, { replace: true })
}
}, [navigate, stepId, wizard.currentStepId, wizard.isHydrating])
if (wizard.isHydrating || !wizard.step) return null
const { Form, fields } = wizard.currentStep
return (
<Form onSubmit={async () => {
if (wizard.isLastStep) await wizard.submit()
else await wizard.next()
}}>
{'email' in fields && <fields.email />}
{'password' in fields && <fields.password />}
{'companyName' in fields && <fields.companyName />}
<Form.Submit>{wizard.isLastStep ? 'Finish' : 'Next'}</Form.Submit>
</Form>
)
}
export default function App() {
return (
<MemoryRouter initialEntries={['/signup/account']}>
<Routes>
<Route path="/" element={<Navigate replace to="/signup/account" />} />
<Route path="/signup/:stepId" element={<SignupWizardRoute />} />
</Routes>
</MemoryRouter>
)
}
const api = new Proxy({}, {
get: (_target, methodName) => async (values) => {
console.log('[doc-playground]', String(methodName), values)
return { methodName, values }
},
})