Corrected Form Layout

This commit is contained in:
Ebube
2024-03-21 10:05:44 +01:00
parent 21b4bf5e8f
commit 266627d941
13 changed files with 474 additions and 224 deletions
+70 -190
View File
@@ -1,219 +1,99 @@
import React, { useRef, useState } from "react";
import InputCompOne from "../shared/InputCompOne";
import InputSection from "./InputSection";
import OTPSection from "./OtpSection";
import SpouseDetails from "./SpouseDetails";
import { Button } from "..";
interface Option {
value: string;
label: string;
}
const BasicInfo: React.FC = () => {
interface BasicInfoProps {
inputValues: {
title: string;
marital: string;
agentId: string;
bvn: string;
firstName: string;
phone: string;
email: string;
surname: string;
dob: string;
secondName: string;
spouseBVN: string;
};
setInputValues: React.Dispatch<React.SetStateAction<any>>;
handleNextStep: React.MouseEventHandler<HTMLButtonElement>;
}
const BasicInfo: React.FC<BasicInfoProps> = ({
inputValues,
setInputValues,
handleNextStep,
}) => {
const [hideOTPComponent, setHideOTPComponent] = useState<boolean>(true);
const [inputValues, setInputValues] = useState({
title: "",
marital: "",
agentId: "",
bvn: "",
firstName: "",
phone: "",
email: "",
surname: "",
dob: "",
secondName: "",
});
const inputRef = useRef<HTMLInputElement>(null);
// Array for marital status options
const maritalStatusOptions: Option[] = [
{ value: "", label: "Select" },
{ value: "single", label: "Single" },
{ value: "married", label: "Married" },
{ value: "divorced", label: "Divorced" },
{ value: "widowed", label: "Widowed" },
];
// Array for title options
const titleOptions: Option[] = [
{ value: "", label: "Select" },
{ value: "ms", label: "Ms" },
{ value: "mr", label: "Mr" },
{ value: "miss", label: "Miss" },
{ value: "mrs", label: "Mrs" },
];
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setInputValues((prev) => ({ ...prev, [name]: value }));
};
const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
if (name === "bvn") {
const regex = /^[0-9]+$/;
const isNumeric = /^[0-9]+$/.test(value);
if (regex.test(value)) {
if (value?.length === 10) {
if (isNumeric) {
if (value.length === 10) {
setHideOTPComponent(false);
// secondInputRef.current?.focus();
} else setHideOTPComponent(true);
} else {
setHideOTPComponent(true);
}
} else {
console.log("object not found");
console.log("Invalid BVN");
}
}
};
return (
<>
<div className="mt-8 max-w-[31.5rem]">
<div className="flex flex-col gap-3">
<InputCompOne
label="Title"
name="title"
parentInputClass="max-w-[224px] w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
select
selectClass="w-full h-[36px] rounded-[6px]"
selectOptions={titleOptions}
value={inputValues.title}
onChange={handleChange}
ref={inputRef}
/>
<InputCompOne
label="Marital Status"
name="marital"
parentInputClass="max-w-[224px] w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
select
selectClass="w-full h-[36px] rounded-[6px]"
selectOptions={maritalStatusOptions}
value={inputValues.marital}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="Direct Sales Agent ID"
name="agentId"
parentInputClass="max-w-[224px] w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
select
selectClass="w-full h-[36px] rounded-[6px]"
selectOptions={[{ value: "", label: "Select" }]}
value={inputValues.agentId}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="BVN"
name="bvn"
parentInputClass=" w-full"
labelSpan="( To get your BVN, dial *565*0# )"
labelSpanClass="text-[11px] text-[#7a7373]"
placeholder="Enter your BVN"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px] gap-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
value={inputValues.bvn}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
maxLength={10}
/>
</div>
</div>
{!hideOTPComponent ? (
<div className="flex flex-col gap-5">
<div className="flex justify-between items-center g4">
<div className="mt-8 max-w-[31.5rem] w-full">
<div className="flex flex-col gap-3">
<InputCompOne
label="First Name"
name="firstName"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
value={inputValues.firstName}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="Phone Number"
name="phone"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
value={inputValues.phone}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="Email Address"
name="email"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
value={inputValues.email}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
</div>
</div>
<div className="mt-8 max-w-[31.5rem] w-full">
<div className="flex flex-col gap-3">
<InputCompOne
label="Surname"
name="surname"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px] px-3"
value={inputValues.surname}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="Date of Birth"
name="dob"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px] px-3"
value={inputValues.dob}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
label="Second Name"
name="secondName"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px] px-3"
value={inputValues.secondName}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
</div>
</div>
</div>
<div className="w-full flex justify-end">
<button className="w-full max-w-[15.25rem] h-[36px] rounded bg-[#FBB700] rounded-2 px-4 text-[18px] text-[#282828] font-semibold disabled:text-[#282828] disabled:text-opacity-50">
Enter
</button>
</div>
</div>
) : null}
{/* Header */}
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
Lets Get You Started
</h1>
<form>
<InputSection
inputValues={inputValues}
handleChange={handleChange}
handleInput={handleInput}
inputRef={inputRef}
/>
{!hideOTPComponent && (
<>
<OTPSection
inputValues={inputValues}
handleChange={handleChange}
handleInput={handleInput}
inputRef={inputRef}
/>
<SpouseDetails
inputValues={inputValues}
handleChange={handleChange}
handleInput={handleInput}
inputRef={inputRef}
/>
<Button
className="mt-8 btn-R"
text="Enter"
type="button"
onClick={handleNextStep}
/>
</>
)}
</form>
</>
);
};
+33 -10
View File
@@ -1,21 +1,44 @@
import React from "react";
import BasicInfo from "./BasicInfo";
const GetStarted = () => {
const [step, setStep] = React.useState(1);
const handleNextStep = () => {
setStep(step + 1);
};
const handlePreviousStep = () => {
setStep(step - 1);
};
const [inputValues, setInputValues] = React.useState({
title: "",
marital: "",
agentId: "",
bvn: "",
firstName: "",
phone: "",
email: "",
surname: "",
dob: "",
secondName: "",
spouseBVN: "",
});
return (
<div className="w-full flex items-center justify-center">
<div className="containerMode">
{/* Header */}
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
Lets Get You Started
</h1>
{/* Main */}
<main>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
BASIC INFORMATION
</p>
</div>
<BasicInfo />
{step === 1 && (
<BasicInfo
inputValues={inputValues}
setInputValues={setInputValues}
handleNextStep={handleNextStep}
/>
)}
{step === 2 && "lol"}
</main>
</div>
</div>
+133
View File
@@ -0,0 +1,133 @@
import React from "react";
import InputCompOne from "../shared/InputCompOne";
interface Option {
value: string;
label: string;
}
interface InputSectionProps {
inputValues: {
title: string;
marital: string;
agentId: string;
bvn: string;
};
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleInput: (e: React.FormEvent<HTMLInputElement>) => void;
inputRef: React.RefObject<HTMLInputElement>;
}
const InputSection: React.FC<InputSectionProps> = ({
inputValues,
handleChange,
handleInput,
inputRef,
}) => {
const basicInfoInputFields = [
{
label: "Title",
name: "title",
parentInputClass: "max-w-[224px] w-full",
labelClass:
"font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]",
select: true,
selectClass: "w-full h-[36px] rounded-[6px]",
selectOptions: titleOptions,
value: inputValues.title,
},
{
label: "Marital Status",
name: "marital",
parentInputClass: "max-w-[224px] w-full",
labelClass:
"font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]",
select: true,
selectClass: "w-full h-[36px] rounded-[6px]",
selectOptions: maritalStatusOptions,
value: inputValues.marital,
onInput: handleInput,
},
{
label: "Direct Sales Agent ID",
name: "agentId",
parentInputClass: "max-w-[224px] w-full",
labelClass:
"font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]",
select: true,
selectClass: "w-full h-[36px] rounded-[6px]",
selectOptions: [{ value: "", label: "Select" }],
value: inputValues.agentId,
onInput: handleInput,
},
{
label: "BVN",
name: "bvn",
parentInputClass: " w-full",
labelSpan: "( To get your BVN, dial *565*0# )",
labelSpanClass: "text-[11px] text-[#7a7373]",
placeholder: "Enter your BVN",
labelClass:
"font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px] gap-[2px]",
input: true,
inputClass: "w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]",
value: inputValues.bvn,
onInput: handleInput,
maxLength: 10,
},
];
return (
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
BASIC INFORMATION
</p>
</div>
<div className="mt-8 grid grid-cols-2">
<div className="flex flex-col gap-4 max-w-[15.6875rem]">
{basicInfoInputFields.map((field, index) => (
<InputCompOne
key={index}
label={field.label}
name={field.name}
parentInputClass={field.parentInputClass}
labelClass={field.labelClass}
select={field.select}
selectClass={field.selectClass}
selectOptions={field.selectOptions}
value={field.value}
onChange={handleChange}
onInput={field.onInput}
placeholder={field.placeholder}
labelSpan={field.labelSpan}
labelSpanClass={field.labelSpanClass}
input={field.input}
inputClass={field.inputClass}
maxLength={field.maxLength}
ref={inputRef}
/>
))}
</div>
</div>
</>
);
};
export default InputSection;
const maritalStatusOptions: Option[] = [
{ value: "", label: "Select" },
{ value: "single", label: "Single" },
{ value: "married", label: "Married" },
{ value: "divorced", label: "Divorced" },
{ value: "widowed", label: "Widowed" },
];
const titleOptions: Option[] = [
{ value: "", label: "Select" },
{ value: "ms", label: "Ms" },
{ value: "mr", label: "Mr" },
{ value: "miss", label: "Miss" },
{ value: "mrs", label: "Mrs" },
];
+111
View File
@@ -0,0 +1,111 @@
import React from "react";
import InputCompOne from "../shared/InputCompOne";
interface OTPSectionProps {
inputValues: {
firstName: string;
phone: string;
email: string;
surname: string;
dob: string;
secondName: string;
};
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleInput: (e: React.FormEvent<HTMLInputElement>) => void;
inputRef: React.RefObject<HTMLInputElement>;
}
const OTPSection: React.FC<OTPSectionProps> = ({
inputValues,
handleChange,
handleInput,
inputRef,
}) => {
return (
<div className="mt-5">
<div className="grid grid-cols-2 gap-4">
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="First Name"
name="firstName"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem]"
value={inputValues.firstName}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Phone Number"
name="phone"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem]"
value={inputValues.phone}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Email Address"
name="email"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem]"
value={inputValues.email}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Surname"
name="surname"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem] px-3"
value={inputValues.surname}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Date of Birth"
name="dob"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem] px-3"
value={inputValues.dob}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Second Name"
name="secondName"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem] px-3"
value={inputValues.secondName}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
</div>
</div>
);
};
export default OTPSection;
@@ -0,0 +1,49 @@
import React from "react";
import { InputCompOne } from "..";
interface SpouseDetailsProps {
inputValues: {
spouseBVN: string;
};
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleInput: (e: React.FormEvent<HTMLInputElement>) => void;
inputRef: React.RefObject<HTMLInputElement>;
}
const SpouseDetails: React.FC<SpouseDetailsProps> = ({
inputValues,
handleChange,
handleInput,
inputRef,
}) => {
return (
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5 mt-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
SPOUSE DETAILS ( If not applicable, please move to the next stage )
</p>
</div>
<div className="mt-8 grid grid-cols-2">
<div className="flex flex-col gap-4 max-w-[15.6875rem]">
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="BVN"
name="firstName"
parentInputClass="w-full"
labelSpan="( To get your BVN, dial *565*0# )"
labelSpanClass="text-[11px] text-[#7a7373]"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] px-[.125rem] rounded-[.375rem]"
value={inputValues.firstName}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
</div>
</div>
</>
);
};
export default SpouseDetails;