mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-25 01:12:42 -04:00
Add basic multi-step form
This commit is contained in:
23
app/register_test/page.tsx
Normal file
23
app/register_test/page.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import {Suspense} from "react";
|
||||
import MultiStepForm from "@/components/MultiStepForm";
|
||||
|
||||
|
||||
export default function RegisterPage() {
|
||||
return (
|
||||
<Suspense fallback={<div></div>}>
|
||||
<RegisterComponent/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
function RegisterComponent() {
|
||||
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<MultiStepForm/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
97
components/MultiStepForm.tsx
Normal file
97
components/MultiStepForm.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import React, {useState} from "react";
|
||||
import {useForm, SubmitHandler} from "react-hook-form";
|
||||
|
||||
type Question = {
|
||||
name: string;
|
||||
label: string;
|
||||
type?: string;
|
||||
options?: string[];
|
||||
};
|
||||
|
||||
const questions: Question[] = [
|
||||
{
|
||||
name: "firstName",
|
||||
label: "First Name"
|
||||
},
|
||||
{
|
||||
name: "lastName",
|
||||
label: "Last Name"
|
||||
},
|
||||
{
|
||||
name: "age",
|
||||
label: "Age",
|
||||
type: "number"
|
||||
},
|
||||
{
|
||||
name: "gender",
|
||||
label: "Gender",
|
||||
type: "select",
|
||||
options: ["Male", "Female", "Other"],
|
||||
},
|
||||
];
|
||||
|
||||
type FormValues = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
const MultiStepForm: React.FC = () => {
|
||||
const [step, setStep] = useState(0);
|
||||
const {register, handleSubmit, getValues, formState: {errors}} = useForm<FormValues>();
|
||||
const isLastStep = step === questions.length - 1;
|
||||
|
||||
const onSubmit: SubmitHandler<FormValues> = (data) => {
|
||||
// handle final form submission
|
||||
alert(JSON.stringify(data, null, 2));
|
||||
};
|
||||
|
||||
const nextStep = () => setStep((s) => Math.min(s + 1, questions.length - 1));
|
||||
const prevStep = () => setStep((s) => Math.max(s - 1, 0));
|
||||
|
||||
const currentQuestion = questions[step];
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-8 space-y-6">
|
||||
<div>
|
||||
<label className="px-4">{currentQuestion.label}</label>
|
||||
{currentQuestion.type === "select" ? (
|
||||
<select {...register(currentQuestion.name, {required: true})} className="px-4">
|
||||
<option value="">Select...</option>
|
||||
{currentQuestion.options?.map((opt) => (
|
||||
<option key={opt} value={opt}>{opt}</option>
|
||||
))}
|
||||
</select>
|
||||
) : (
|
||||
<input
|
||||
type={currentQuestion.type || "text"}
|
||||
{...register(currentQuestion.name, {required: true})}
|
||||
defaultValue={getValues(currentQuestion.name) || ""}
|
||||
/>
|
||||
)}
|
||||
{errors[currentQuestion.name] && <span>This field is required</span>}
|
||||
</div>
|
||||
<div style={{margin: 16,}}>
|
||||
{step > 0 && (
|
||||
<button type="button" onClick={prevStep} style={{margin: 16,}}>
|
||||
Back
|
||||
</button>
|
||||
)}
|
||||
{!isLastStep ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
// Validate current step before proceeding
|
||||
handleSubmit(() => nextStep())();
|
||||
}}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
) : (
|
||||
<button type="submit">Submit</button>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultiStepForm;
|
||||
|
||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -40,6 +40,7 @@
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"resend": "^4.7.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
@@ -13538,6 +13539,21 @@
|
||||
"react": "^19.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-hook-form": {
|
||||
"version": "7.62.0",
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
|
||||
"integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/react-hook-form"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-hook-form": "^7.62.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"resend": "^4.7.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
|
||||
Reference in New Issue
Block a user