Compare commits

..

19 Commits

Author SHA1 Message Date
victorAnumudu 2cb5c471f6 form validation with formik 2024-04-24 11:42:04 +01:00
ameye 4b008f6785 Merge branch 'input-validation' of DigiFi/digifi-www into master 2024-04-23 18:50:24 +00:00
ameye f632099128 Merge branch 'docker-compose-props' of DigiFi/digifi-www into master 2024-04-23 18:50:20 +00:00
ameye 122eb31732 Merge branch 'header-z-index' of DigiFi/digifi-www into master 2024-04-23 18:50:17 +00:00
victorAnumudu 0207bf631a started input validation on forms 2024-04-23 19:25:50 +01:00
victorAnumudu 378ff4a625 added props to docker compose file 2024-04-23 15:41:54 +01:00
victorAnumudu f88b6df24c increase z-index level for the header component 2024-04-23 11:36:18 +01:00
ameye fe759c6d0a Merge branch 'select-input' of DigiFi/digifi-www into master 2024-04-23 10:26:53 +00:00
victorAnumudu 104295bdb2 select input added where necessary 2024-04-22 22:38:35 +01:00
ameye 44933d4362 Merge branch 'loan-application-process' of DigiFi/digifi-www into master 2024-04-22 17:08:37 +00:00
victorAnumudu 9ce7110a5d added steps to loan application 2024-04-22 15:42:40 +01:00
ameye 085b2d4aaa Merge branch 'get-started-page' of DigiFi/digifi-www into master 2024-04-22 11:39:10 +00:00
victorAnumudu 747c945659 get started first step added 2024-04-22 09:36:48 +01:00
ameye 94f9803ec5 Merge branch 'otp-input' of DigiFi/digifi-www into master 2024-04-17 18:49:10 +00:00
victorAnumudu 3998596fba validation bug fix 2024-04-16 20:56:34 +01:00
victorAnumudu 886fd64347 validated otp input to be numbers 2024-04-16 20:17:57 +01:00
tokslaw f95fd66c57 Merge branch 'layout-update' of DigiFi/digifi-www into master 2024-04-04 09:35:17 +00:00
tokslaw 98b5d4bc4f Merge branch 'Corporate' of DigiFi/digifi-www into master 2024-04-04 09:33:45 +00:00
Pascallina Ocheme 537d609117 Modified pathlink 2024-03-26 12:17:15 +01:00
28 changed files with 2231 additions and 993 deletions
+2
View File
@@ -14,5 +14,7 @@ services:
- "5173"
environment:
- PORT=${DIGIFI_PORT}
tty: true
stdin_open: true
volumes:
src:
+1
View File
@@ -15,6 +15,7 @@
"formik": "2.4.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.0.1",
"react-redux": "^8.0.5",
"react-router-dom": "6.3.0",
"react-select": "^5.8.0",
+107 -40
View File
@@ -1,51 +1,118 @@
import { Button, InputCompOne, Stepper } from "..";
import { useNavigate } from "react-router-dom";
import { RouteHandler } from "../../router/routes";
import {Formik, Form} from 'formik'
import * as Yup from "yup";
export default function DashboardFormInit() {
let navigate = useNavigate();
type Props = {
handleNextStep:()=>any
}
const initialValues = {
amount: "",
duration: "",
id: "",
};
// To get the validation schema
const validationSchema = Yup.object().shape({
duration: Yup.string()
.required("Required"),
amount: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
id: Yup.string()
.required("Required")
});
export default function DashboardFormInit({handleNextStep}:Props) {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
const navigateToProfile = () => navigate(RouteHandler.dashboardProfile);
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={0} />
</div>
<div className="mt-[3.25rem] flex flex-col gap-9">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="How Much Do You Want To Apply For?"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="350,000"
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="For How Many Months?"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="12 Months"
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Direct sales agent ID ( Optional )"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Agent ID"
/>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="button"
onClick={navigateToProfile}
/>
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="mt-[3.25rem] flex flex-col gap-9">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="amount"
label="How Much Do You Want To Apply For?"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem] text-right"
placeholder="350,000"
value={props.values.amount}
onChange={props.handleChange}
error={(props.errors.amount && props.touched.amount) ? props.errors.amount : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="duration"
label="For How Many Months?"
labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={duration}
selectValue={props.values.duration}
onChange={props.handleChange}
error={(props.errors.duration && props.touched.duration) ? props.errors.duration : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="id"
label="Direct sales agent ID ( Optional )"
labelClass="font-bold text-[1.125rem]"
floatLabel='Enter agent ID'
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Agent ID"
value={props.values.id}
onChange={props.handleChange}
error={(props.errors.id && props.touched.id) ? props.errors.id : ''}
/>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</div>
);
}
interface SelectOption {
loading: boolean;
data: {value: string;
label: string}[]
}
const duration: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "6", label: "6 Months" },
{ value: "12", label: "12 Months" },
{ value: "18", label: "18 Months" },
{ value: "24", label: "24 Months" },
]
}
+12 -3
View File
@@ -1,6 +1,10 @@
import React, { FC } from "react";
import DashboardHomeIntro from "./DashboardHomeIntro";
import DashboardFormInit from "./DashboardFormInit";
import DashboardHomeDetail from "./home/DashboardHomeDetail";
import DashboardHomeEmploymentInfo from "./home/DashboardHomeEmploymentInfo";
import DashboardHomeRefereeInfo from "./home/DashboardHomeRefereeInfo";
import DashboardHomeAttestation from "./home/DashboardHomeAttestation";
interface DashboardHomeProps {}
@@ -8,15 +12,20 @@ const DashboardHome: FC<DashboardHomeProps> = () => {
const [step, setStep] = React.useState(1);
const handleNextStep = () => {
if (step < 2) {
if (step < 7) {
setStep(step + 1);
}
};
return (
<div className="w-full">
{step === 1 && <DashboardHomeIntro handleNextStep={handleNextStep} />}
{step === 2 && <DashboardFormInit />}
{step === 1 && <DashboardHomeIntro step={step} handleNextStep={handleNextStep} />}
{step === 2 && <DashboardFormInit handleNextStep={handleNextStep} />}
{step === 3 && <DashboardHomeDetail handleNextStep={handleNextStep} />}
{step === 4 && <DashboardHomeEmploymentInfo handleNextStep={handleNextStep} />}
{step === 5 && <DashboardHomeRefereeInfo handleNextStep={handleNextStep} />}
{step === 6 && <DashboardHomeAttestation handleNextStep={handleNextStep} />}
{step === 7 && <DashboardHomeIntro step={step} handleNextStep={handleNextStep} />}
</div>
);
};
+39 -16
View File
@@ -69,26 +69,49 @@ export const DashBoardCard: React.FC<DashBoardCardProps> = ({
interface DashboardHomeIntroProps {
handleNextStep: any;
step?:number|string
}
const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep }) => {
const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep, step }) => {
return (
<>
<h1 className="font-bold my-5 text-2xl">Hello, Olanrewaju</h1>
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
<DashBoardCard
cardClass="bg-[#5C2684] relative"
desc="Begin your application and get up to "
descSpan="5 million naira loan."
descClass="leading-[1.5625rem] text-lg text-white"
descSpanClass="font-bold"
btnTitle="Apply here"
btnTextClass="w-[11.125rem] h-[2.8125rem] flex justify-center item-center btn-W text-[#FBB700]"
image={NairaBag}
imgClass="translate-y-4 -rotate-6"
onClick={handleNextStep}
/>
</div>
{step == 1 ?
<>
<h1 className="font-bold my-5 text-2xl">Hello, Olanrewaju</h1>
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
<DashBoardCard
cardClass="bg-[#5C2684] relative"
desc="Begin your application and get up to "
descSpan="5 million naira loan."
descClass="leading-[1.5625rem] text-lg text-white"
descSpanClass="font-bold"
btnTitle="Apply here"
btnTextClass="w-[11.125rem] h-[2.8125rem] flex justify-center item-center btn-W text-[#FBB700]"
image={NairaBag}
imgClass="translate-y-4 -rotate-6"
onClick={handleNextStep}
/>
</div>
</>
:
<>
<h1 className="font-bold my-5 text-2xl">Welcome Back, Olanrewaju</h1>
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
<DashBoardCard
cardClass="bg-[#5C2684] relative"
desc="Your loan application has been reviewed and accepted, please confirm for disbursement."
// descSpan="5 million naira loan."
descClass="leading-[1.5625rem] text-lg text-white"
// descSpanClass="font-bold"
btnTitle="View and accept"
btnTextClass="w-[11.125rem] h-[2.8125rem] flex justify-center item-center btn-W text-[#FBB700]"
image={NairaBag}
imgClass="translate-y-4 -rotate-6"
// onClick={handleNextStep}
/>
</div>
</>
}
</>
);
};
+38 -34
View File
@@ -1,21 +1,34 @@
import { Button, InputCompOne, Stepper } from "..";
import { InputCompOne } from "..";
import { useNavigate } from "react-router-dom";
import { RouteHandler } from "../../router/routes";
export default function DashboardProfile() {
let navigate = useNavigate();
const navigateToProfile = () => navigate(RouteHandler.dashboardHome);
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={1} />
<div className='my-[2rem] flex items-center'>
<button onClick={navigateToProfile} className='w-6 h-6 text-lg flex justify-center items-center rounded-full bg-gray-500'>&lt;</button>
</div>
<div className="mt-[3.25rem] flex flex-col gap-9">
<div className="flex items-center gap-[4.125rem]">
<div className="max-w-[25.875rem] w-full p-4 rounded-xl flex flex-col gap-1 bg-[#FBB700]/30">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Select your gender"
label="Full name"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Male"
placeholder="John James"
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Phone number"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="07000000000"
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
@@ -26,17 +39,6 @@ export default function DashboardProfile() {
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Somewhere in lagos"
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Marital status"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Single"
/>{" "}
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
@@ -46,22 +48,24 @@ export default function DashboardProfile() {
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Lagos"
/>
</div>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Email address"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="johndoe@gmail.com"
/>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="button"
// onClick={navigateToProfile}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Email address"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="johndoe@gmail.com"
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="applyIshInput"
label="Date of birth"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="12/10/1994"
/>
</div>
</div>
);
@@ -0,0 +1,89 @@
import { Button, InputCompOne, Stepper } from '../../shared/index';
import {Formik, Form} from 'formik'
import * as Yup from "yup";
// import { useNavigate } from "react-router-dom";
// import { RouteHandler } from '../../../router/routes';
type Props = {
handleNextStep:()=>any
}
const initialValues = {
account_number: "",
checked: false
};
// To get the validation schema
const validationSchema = Yup.object().shape({
account_number: Yup.string()
.required("Required"),
checked: Yup.bool() // use bool instead of boolean
.oneOf([true], "You must accept the terms and conditions")
});
export default function DashboardHomeAttestation({handleNextStep}:Props) {
// let navigate = useNavigate();
// const navigateToProfile = () => navigate(RouteHandler.dashboardProfile);
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={4} />
</div>
<p className='my-10 text-red-500 text-lg md:text-2xl'>Applicant's Attestation and Debit Instruction</p>
<p className='text-red-500 text-base'>NB: Must be your FCMB account number</p>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="flex flex-col gap-9">
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="account_number"
floatLabel="Disbursement account number"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="0102547896"
value={props.values.account_number}
onChange={props.handleChange}
error={(props.errors.account_number && props.touched.account_number) ? props.errors.account_number : ''}
/>
</div>
<div className='max-w-[25.875rem]'>
<div className='flex gap-4 items-start'>
<input
type='checkbox'
name="checked"
className='w-4 h-4 p-2 accent-purple-600 text-purple-600 bg-gray-100 border-gray-300 rounded focus:ring-purple-500'
onChange={props.handleChange}
/>
<p className='text-[12px] text-justify'>By pressing, you agree that you have read, understood and accept the <span className='text-blue-600'>applicatant's attestation</span> and <span className='text-blue-600'>terms and conditions</span> for FCMB
premium salary loan. You also give us permission to collect financial information and run credit checks on the account provided through our partners
</p>
</div>
{props.errors.checked && props.touched.checked && <span className='text-[10px] text-red-500'>{props.errors.checked}</span>}
</div>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Apply"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</div>
);
}
@@ -0,0 +1,166 @@
import { Button, InputCompOne, Stepper } from '../../shared/index';
import {Formik, Form} from 'formik'
import * as Yup from "yup";
type Props = {
handleNextStep:()=>any
}
const initialValues = {
gender: "",
address: "",
marital_status: "",
state: "",
email:""
};
// To get the validation schema
const validationSchema = Yup.object().shape({
gender: Yup.string()
.required("Required"),
address: Yup.string()
.required("Required"),
marital_status: Yup.string()
.required("Required"),
state: Yup.string()
.required("Required"),
email: Yup.string()
.email("Invalid")
.required("Required"),
});
export default function DashboardHomeDetail({handleNextStep}:Props) {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={1} />
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="mt-[3.25rem] flex flex-col gap-9">
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="gender"
label="Select your gender"
labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={gender}
selectValue={props.values.gender}
onChange={props.handleChange}
error={(props.errors.gender && props.touched.gender) ? props.errors.gender : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="address"
label="Residential address"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Somewhere in lagos"
value={props.values.address}
onChange={props.handleChange}
error={(props.errors.address && props.touched.address) ? props.errors.address : ''}
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="marital_status"
label="Marital status"
labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={maritalStatus}
selectValue={props.values.marital_status}
onChange={props.handleChange}
error={(props.errors.marital_status && props.touched.marital_status) ? props.errors.marital_status : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="state"
label="Select your state"
labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={state}
selectValue={props.values.state}
onChange={props.handleChange}
error={(props.errors.state && props.touched.state) ? props.errors.state : ''}
/>
</div>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="email"
label="Email address"
labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="johndoe@gmail.com"
value={props.values.email}
onChange={props.handleChange}
error={(props.errors.email && props.touched.email) ? props.errors.email : ''}
/>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</div>
);
}
interface SelectOption {
loading: boolean;
data: {value: string;
label: string}[]
}
const gender: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "male", label: "Male" },
{ value: "female", label: "Female" },
{ value: "others", label: "Prefer not to say" },
]
}
const maritalStatus: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "single", label: "Single" },
{ value: "married", label: "Married" },
{ value: "divorced", label: "Divorced" },
]
}
const state: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "abia", label: "Abia" },
{ value: "imo", label: "Imo" },
{ value: "lagos", label: "Lagos" },
]
}
@@ -0,0 +1,275 @@
import { Button, InputCompOne, Stepper } from '../../shared/index';
import {Formik, Form} from 'formik'
import * as Yup from "yup";
type Props = {
handleNextStep:()=>any
}
const initialValues = {
job_title: "",
employer_name: "",
job_sector: "",
industry: "",
date_of_resumption: "",
employer_email:"",
annual_income: "",
monthly_salary: "",
salary_payment_date: "",
employee_id: "",
qualification: ""
};
// To get the validation schema
const validationSchema = Yup.object().shape({
job_title: Yup.string()
.required("Required"),
employer_name: Yup.string()
.required("Required"),
job_sector: Yup.string()
.required("Required"),
industry: Yup.string()
.required("Required"),
date_of_resumption: Yup.string()
.required("Required"),
employer_email: Yup.string()
.email("Invalid")
.required("Required"),
annual_income: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
monthly_salary: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
salary_payment_date: Yup.string()
.required("Required"),
employee_id: Yup.string()
.required("Required"),
qualification: Yup.string()
.required("Required"),
});
export default function DashboardHomeEmploymentInfo({handleNextStep}:Props) {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={2} />
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="mt-[3.25rem] flex flex-col gap-9">
<p className='text-red-500 text-lg md:text-2xl'>Employment Informaton</p>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="job_title"
floatLabel="Job Title"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Software Engineer"
value={props.values.job_title}
onChange={props.handleChange}
error={(props.errors.job_title && props.touched.job_title) ? props.errors.job_title : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="employer_name"
floatLabel="Employer name"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Mr. Mark John"
value={props.values.employer_name}
onChange={props.handleChange}
error={(props.errors.employer_name && props.touched.employer_name) ? props.errors.employer_name : ''}
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="job_sector"
floatLabel="Job Sector"
// labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={jobSector}
selectValue={props.values.job_sector}
onChange={props.handleChange}
error={(props.errors.job_sector && props.touched.job_sector) ? props.errors.job_sector : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="industry"
floatLabel="Select your industry"
// labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={industry}
selectValue={props.values.industry}
onChange={props.handleChange}
error={(props.errors.industry && props.touched.industry) ? props.errors.industry : ''}
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="date_of_resumption"
floatLabel="Date of resumption"
// labelClass="font-bold text-[1.125rem]"
input
inputType='date'
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="12/12/2015"
value={props.values.date_of_resumption}
onChange={props.handleChange}
error={(props.errors.date_of_resumption && props.touched.date_of_resumption) ? props.errors.date_of_resumption : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="employer_email"
floatLabel="Employers official email"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="example@gmail.com"
value={props.values.employer_email}
onChange={props.handleChange}
error={(props.errors.employer_email && props.touched.employer_email) ? props.errors.employer_email : ''}
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="annual_income"
floatLabel="Annual Income"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem] text-right"
placeholder="1,200,000"
value={props.values.annual_income}
onChange={props.handleChange}
error={(props.errors.annual_income && props.touched.annual_income) ? props.errors.annual_income : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="monthly_salary"
floatLabel="Net monthly salary"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem] text-right"
placeholder="100,000"
value={props.values.monthly_salary}
onChange={props.handleChange}
error={(props.errors.monthly_salary && props.touched.monthly_salary) ? props.errors.monthly_salary : ''}
/>
</div>
<div className="flex items-center gap-[4.125rem]">
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="salary_payment_date"
floatLabel="Salary payment date"
// labelClass="font-bold text-[1.125rem]"
input
inputType='date'
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="30th of every month"
value={props.values.salary_payment_date}
onChange={props.handleChange}
error={(props.errors.salary_payment_date && props.touched.salary_payment_date) ? props.errors.salary_payment_date : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="employee_id"
floatLabel="Employee ID"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="LS/001/005"
value={props.values.employee_id}
onChange={props.handleChange}
error={(props.errors.employee_id && props.touched.employee_id) ? props.errors.employee_id : ''}
/>
</div>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="qualification"
floatLabel="Highest level of education"
// labelClass="font-bold text-[1.125rem]"
select={true}
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
selectOptions={qualification}
selectValue={props.values.qualification}
onChange={props.handleChange}
error={(props.errors.qualification && props.touched.qualification) ? props.errors.qualification : ''}
/>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</div>
);
}
interface SelectOption {
loading: boolean;
data: {value: string;
label: string}[]
}
const jobSector: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "private (non academic)", label: "Private (non academic)" },
]
}
const industry: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "engineering", label: "Engineering" },
]
}
const qualification: SelectOption = {
loading: false,
data: [
{ value: "", label: "Please Select" },
{ value: "b.sc + professional qualification", label: "B.Sc + Professional Qualification" },
]
}
@@ -0,0 +1,231 @@
import { Button, InputCompOne, Stepper } from '../../shared/index';
import {Formik, Form} from 'formik'
import * as Yup from "yup";
type Props = {
handleNextStep:()=>any
}
const initialValues = {
ref_name: "",
ref_email: "",
ref_number: "",
ref_relationship: "",
ref_bvn: "",
ref_two_name: "",
ref_two_email: "",
ref_two_number: "",
ref_two_relationship: "",
ref_two_bvn: "",
};
// To get the validation schema
const validationSchema = Yup.object().shape({
ref_name: Yup.string()
.required("Required"),
ref_email: Yup.string()
.email("Invalid")
.required("Required"),
ref_number: Yup.string()
.required("Required"),
ref_relationship: Yup.string()
.required("Required"),
ref_bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
ref_two_name: Yup.string()
.required("Required"),
ref_two_email: Yup.string()
.email("Invalid")
.required("Required"),
ref_two_number: Yup.string()
.required("Required"),
ref_two_relationship: Yup.string()
.required("Required"),
ref_two_bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
});
export default function DashboardHomeRefereeInfo({handleNextStep}:Props) {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
<div className="w-full">
<div className="w-full flex justify-center">
<Stepper step={3} />
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="mt-[3.25rem] flex flex-col gap-9">
<p className='text-red-500 text-lg md:text-2xl'>Reference Details <span className='text-base'>(Must be 18 years and above)</span></p>
<div className="flex items-center gap-[4.125rem]">
<div className='w-full max-w-[25.875rem]'>
<p className='text-red-500 text-base'>Reference one</p>
<div className='w-full flex flex-col gap-9'>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_name"
floatLabel="Full name"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="John James"
value={props.values.ref_name}
onChange={props.handleChange}
error={(props.errors.ref_name && props.touched.ref_name) ? props.errors.ref_name : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_relationship"
floatLabel="Relationship"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Sister"
value={props.values.ref_relationship}
onChange={props.handleChange}
error={(props.errors.ref_relationship && props.touched.ref_relationship) ? props.errors.ref_relationship : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_number"
floatLabel="Phone number"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="07000000000"
value={props.values.ref_number}
onChange={props.handleChange}
error={(props.errors.ref_number && props.touched.ref_number) ? props.errors.ref_number : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_email"
floatLabel="Email address"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="demo@gamil.com"
value={props.values.ref_email}
onChange={props.handleChange}
error={(props.errors.ref_email && props.touched.ref_email) ? props.errors.ref_email : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_bvn"
floatLabel="BVN"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="2228457896"
value={props.values.ref_bvn}
onChange={props.handleChange}
error={(props.errors.ref_bvn && props.touched.ref_bvn) ? props.errors.ref_bvn : ''}
/>
</div>
</div>
<div className='w-full max-w-[25.875rem]'>
<p className='text-red-500 text-base'>Reference two</p>
<div className='w-full flex flex-col gap-9'>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_two_name"
floatLabel="Full name"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="John James"
value={props.values.ref_two_name}
onChange={props.handleChange}
error={(props.errors.ref_two_name && props.touched.ref_two_name) ? props.errors.ref_two_name : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_two_relationship"
floatLabel="Relationship"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="Sister"
value={props.values.ref_two_relationship}
onChange={props.handleChange}
error={(props.errors.ref_two_relationship && props.touched.ref_two_relationship) ? props.errors.ref_two_relationship : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_two_number"
floatLabel="Phone number"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="07000000000"
value={props.values.ref_two_number}
onChange={props.handleChange}
error={(props.errors.ref_two_number && props.touched.ref_two_number) ? props.errors.ref_two_number : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_two_email"
floatLabel="Email address"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="demo@gamil.com"
value={props.values.ref_two_email}
onChange={props.handleChange}
error={(props.errors.ref_two_email && props.touched.ref_two_email) ? props.errors.ref_two_email : ''}
/>
<InputCompOne
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="ref_two_bvn"
floatLabel="BVN"
// labelClass="font-bold text-[1.125rem]"
input
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
placeholder="2228457896"
value={props.values.ref_two_bvn}
onChange={props.handleChange}
error={(props.errors.ref_two_bvn && props.touched.ref_two_bvn) ? props.errors.ref_two_bvn : ''}
/>
</div>
</div>
</div>
<Button
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
text="Next"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</div>
);
}
@@ -1,6 +1,7 @@
import React from "react";
import DebitAccount from "./DebitAccount";
const ApplicantsAttestation: React.FC = () => {
return (
<>
+89
View File
@@ -0,0 +1,89 @@
import React from "react";
import * as Yup from "yup";
import { Form, Formik } from "formik";
import { InputCompOne } from "../shared";
// To get the validation schema
const validationSchema = Yup.object().shape({
bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits")
});
// initial values for formik
let initialValues = {
bvn: ''
};
type Props = {
handleNextStep:()=>any
}
const BVN = ({handleNextStep}:Props) => {
const firstInputRef = React.useRef<HTMLInputElement>(null);
const handleSubmit = (values:any) => {
console.log('values', values)
handleNextStep()
};
return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props:any) => (
<Form className="">
<div className="w-full">
<div className="containerMode flex justify-between gap-1 xl:gap-8 flex-col">
<div className="my-[4rem] flex items-center justify-center w-full">
<h1 className="font-bold text-[2.375rem] text-[#5C2684] my-[.5rem] text-center">
Lets Get You Started
</h1>
</div>
<div className="mx-auto flex flex-col gap-8 max-w-[31.625rem]">
<InputCompOne
parentClass="flex flex-col gap-2"
label="Enter Your BVN "
name="bvn"
parentInputClass="w-full"
labelSpan="( To get your BVN, dial *565*0# )"
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
placeholder="Enter your BVN"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
input
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
value={props.values.bvn}
onChange={props.handleChange}
ref={firstInputRef}
maxLength={11}
error={(props.errors.bvn && props.touched.bvn) && props.errors.bvn}
/>
<button
type='submit'
className="w-full h-[3.625rem] rounded bg-[#FBB700] rounded-2 px-4 text-[18px] text-[#282828] font-semibold disabled:text-[#282828] disabled:text-opacity-50"
>
Enter
</button>
<p className="text-[#5C2684] mt-[1.5625rem] max-w-[31.625rem]">
***Every personal information attached to your BVN is safe and secured. It is only inportant for us to verify your information and also give you access to your application profile/account
</p>
</div>
</div>
</div>
</Form>
)}
</Formik>
);
};
export default BVN;
+285 -75
View File
@@ -1,61 +1,87 @@
import React, { useRef, useState } from "react";
import InputDetails from "./IntroDetails";
import OTPSection from "./OtpSection";
import SpouseDetails from "./SpouseDetails";
import { Button } from "..";
import React from "react";
// interface Option {
// value: string;
// label: string;
// }
import { Button, InputCompOne } from "..";
import {Formik, Form} from 'formik'
import * as Yup from "yup";
const initialValues = {
title: "",
marital_status: "",
agent_id: "",
bvn: "",
first_name: "",
phone: "",
email: "",
surname: "",
dob: "",
second_name: "",
spouse_bvn: "",
};
// To get the validation schema
const validationSchema = Yup.object().shape({
title: Yup.string()
.required("Required"),
marital_status: Yup.string()
.required("Required"),
agent_id: Yup.string()
.required("Required"),
bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
first_name: Yup.string()
.required("Required"),
phone: Yup.string()
.required("Required"),
email: Yup.string()
.required("Required")
.email("Wrong email format"),
surname: Yup.string()
.required("Required"),
dob: Yup.string()
.required("Required"),
});
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: any;
}
const BasicInfo: React.FC<BasicInfoProps> = ({
inputValues,
setInputValues,
handleNextStep,
}) => {
const [hideOTPComponent, setHideOTPComponent] = useState<boolean>(false);
const inputRef = useRef<HTMLInputElement>(null);
// const inputRef = useRef<HTMLInputElement>(null);
const handleChange = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.target as HTMLInputElement;
setInputValues((prev: typeof inputValues) => ({ ...prev, [name]: value }));
};
// const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
// const { name, value } = e.target as HTMLInputElement;
const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.target as HTMLInputElement;
// if (name === "bvn") {
// const isNumeric = /^[0-9]+$/.test(value);
if (name === "bvn") {
const isNumeric = /^[0-9]+$/.test(value);
// if (isNumeric) {
// if (value.length === 10) {
// setHideOTPComponent(false);
// } else {
// setHideOTPComponent(true);
// }
// } else {
// console.log("Invalid BVN");
// }
// }
// };
if (isNumeric) {
if (value.length === 10) {
setHideOTPComponent(false);
} else {
setHideOTPComponent(true);
}
} else {
console.log("Invalid BVN");
}
}
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
@@ -64,38 +90,222 @@ const BasicInfo: React.FC<BasicInfoProps> = ({
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
Lets Get You Started
</h1>
<form>
<InputDetails
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 bg-[#5A2C82]"
text="Enter"
type="button"
onClick={handleNextStep}
/>
</>
)}
</form>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<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]">
<InputCompOne
parentInputClass="max-w-[224px] w-full"
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="title"
label="Title"
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}
selectValue={props.values.title}
onChange={props.handleChange}
error={(props.errors.title && props.touched.title) ? props.errors.title : ''}
/>
<InputCompOne
parentInputClass="max-w-[224px] w-full"
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="marital_status"
label="Marital Status"
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}
selectValue={props.values.marital_status}
onChange={props.handleChange}
error={(props.errors.marital_status && props.touched.marital_status) ? props.errors.marital_status : ''}
/>
<InputCompOne
parentInputClass="max-w-[224px] w-full"
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
name="agent_id"
label="Direct Sales Agent ID"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
select={true}
selectClass="w-full h-[36px] rounded-[6px]"
selectOptions={{loading: false, data:[{ value: "", label: "Select" }, { value: "dd", label: "AB001" }]}}
selectValue={props.values.agent_id}
onChange={props.handleChange}
error={(props.errors.agent_id && props.touched.agent_id) ? props.errors.agent_id : ''}
/>
<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={true}
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
value={props.values.bvn}
onChange={props.handleChange}
error={(props.errors.bvn && props.touched.bvn) ? props.errors.bvn : ''}
/>
</div>
</div>
<div className="mt-5">
<div className="grid grid-cols-2 gap-4">
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="First Name"
name="first_name"
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] rounded-[.375rem]"
value={props.values.first_name}
onChange={props.handleChange}
error={(props.errors.first_name && props.touched.first_name) ? props.errors.first_name : ''}
/>
<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] rounded-[.375rem]"
value={props.values.phone}
onChange={props.handleChange}
error={(props.errors.phone && props.touched.phone) ? props.errors.phone : ''}
/>
<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] rounded-[.375rem]"
value={props.values.email}
onChange={props.handleChange}
error={(props.errors.email && props.touched.email) ? props.errors.email : ''}
/>
<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] rounded-[.375rem] px-3"
value={props.values.surname}
onChange={props.handleChange}
error={(props.errors.surname && props.touched.surname) ? props.errors.surname : ''}
/>
<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
inputType='date'
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem] px-3"
value={props.values.dob}
onChange={props.handleChange}
error={(props.errors.dob && props.touched.dob) ? props.errors.dob : ''}
/>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Second Name"
name="second_name"
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] rounded-[.375rem] px-3"
value={props.values.second_name}
onChange={props.handleChange}
error={(props.errors.second_name && props.touched.second_name) ? props.errors.second_name : ''}
/>
</div>
</div>
<div className='w-full'>
<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="spouse_bvn"
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] rounded-[.375rem]"
value={props.values.spouse_bvn}
onChange={props.handleChange}
error={(props.errors.spouse_bvn && props.touched.spouse_bvn) ? props.errors.spouse_bvn : ''}
/>
</div>
</div>
</div>
<>
<Button
className="mt-8 btn-R bg-[#5A2C82]"
text="Enter"
type="submit"
/>
</>
</Form>
)}
</Formik>
</>
);
};
export default BasicInfo;
interface SelectOption {
loading: boolean;
data: {value: string;
label: string}[]
}
const maritalStatusOptions: SelectOption = {
loading: false,
data: [
{ value: "", label: "Select" },
{ value: "single", label: "Single" },
{ value: "married", label: "Married" },
{ value: "divorced", label: "Divorced" },
{ value: "widowed", label: "Widowed" },
]
}
const titleOptions: SelectOption = {
loading: false,
data: [
{ value: "", label: "Select" },
{ value: "ms", label: "Ms" },
{ value: "mr", label: "Mr" },
{ value: "miss", label: "Miss" },
{ value: "mrs", label: "Mrs" },
]
}
+124 -69
View File
@@ -3,8 +3,40 @@ import {useNavigate} from 'react-router-dom'
import { Button, InputCompOne } from "..";
import { RouteHandler } from "../../router/routes";
import {Formik, Form} from 'formik'
import * as Yup from "yup";
const initialValues = {
disburse_account: "",
bank_name: "",
account_name: "",
account_number: "",
checked: false
};
// To get the validation schema
const validationSchema = Yup.object().shape({
disburse_account: Yup.string()
.required("Required"),
bank_name: Yup.string()
.required("Required"),
account_name: Yup.string()
.required("Required"),
account_number: Yup.string()
.required("Required"),
checked: Yup.bool() // use bool instead of boolean
.oneOf([true], "You must accept the terms and conditions")
});
const DebitAccount: React.FC = () => {
const navigate = useNavigate()
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
navigate(RouteHandler.letsGetStarted, {replace:true})
};
return (
<>
<div className="w-full rounded py-3 mb-9 bg-[#5C2684] px-5">
@@ -12,78 +44,101 @@ const DebitAccount: React.FC = () => {
CREDIT ACCOUNT ( Your account to receive your loan )
</p>
</div>
<InputCompOne
parentClass="max-w-[29.4375rem] w-full my-5 ml-5"
label="Disbursement Account Number "
name="disbursementAccountNumber"
labelSpan="( Your FCMB Account )"
labelSpanClass="text-[12px] text-[#5C2684] ml-1"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
/>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<InputCompOne
parentClass="max-w-[29.4375rem] w-full my-5 ml-5"
label="Disbursement Account Number "
name="disburse_account"
labelSpan="( Your FCMB Account )"
labelSpanClass="text-[12px] text-[#5C2684] ml-1"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
value={props.values.disburse_account}
onChange={props.handleChange}
error={(props.errors.disburse_account && props.touched.disburse_account) ? props.errors.disburse_account : ''}
/>
<div className="mt-9 flex flex-col gap-9">
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
DEBIT ACCOUNT ( Your salary account for monthly repayment )
</p>
</div>
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Bank Name"
name="bankName"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
/>
<div className="mt-9 flex flex-col gap-9">
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
DEBIT ACCOUNT ( Your salary account for monthly repayment )
</p>
</div>
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Bank Name"
name="bank_name"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
value={props.values.bank_name}
onChange={props.handleChange}
error={(props.errors.bank_name && props.touched.bank_name) ? props.errors.bank_name : ''}
/>
<div className="flex items-center gap-[59px]">
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Account Number"
name="accountNumber"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
/>
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Account Name"
name="accountName"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
/>
</div>
<div className="flex items-center gap-[59px]">
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Account Number"
name="account_number"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
value={props.values.account_number}
onChange={props.handleChange}
error={(props.errors.account_number && props.touched.account_number) ? props.errors.account_number : ''}
/>
<InputCompOne
parentClass="max-w-[471px] w-full ml-5"
label="Account Name"
name="account_name"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
value={props.values.account_name}
onChange={props.handleChange}
error={(props.errors.account_name && props.touched.account_name) ? props.errors.account_name : ''}
/>
</div>
<div className="max-w-[578px] flex items-center">
<input
type="checkbox"
// checked={true}
defaultChecked
// onChange={onChange}
className="form-checkbox h-[25px] w-[25px] rounded-sm text-[#5c2684] "
style={{ backgroundColor: "#5C2684" }}
/>
<label className="ml-2 text-gray-700">
I have read, understood and accept the{" "}
<span className="text-[#4545CB]">applicant's attestation</span> and
all the <span className="text-[#4545CB]">terms and conditions</span>{" "}
for FCMB premium salary loan.
</label>
</div>
<Button
className="my-8 max-w-[33.875rem] btn-R bg-[#5A2C82] w-full h-11"
text="Apply"
type="button"
onClick={()=>navigate(RouteHandler.dashboardHome, {replace:true})}
/>
</div>
<div className="max-w-[578px] flex items-center">
<input
type="checkbox"
// checked={true}
name='checked'
onChange={props.handleChange}
className="form-checkbox h-[25px] w-[25px] rounded-sm text-[#5c2684] "
style={{ backgroundColor: "#5C2684" }}
/>
<label className="ml-2 text-gray-700">
I have read, understood and accept the{" "}
<span className="text-[#4545CB]">applicant's attestation</span> and
all the <span className="text-[#4545CB]">terms and conditions</span>{" "}
for FCMB premium salary loan.
</label>
{props.errors.checked && props.touched.checked && <span className='text-[10px] text-red-500'>{props.errors.checked}</span>}
</div>
<Button
className="my-8 max-w-[33.875rem] btn-R bg-[#5A2C82] w-full h-11"
text="Apply"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</>
);
};
@@ -1,99 +0,0 @@
import React from "react";
import { InputCompOne } from "..";
const EmploymentDetails: React.FC = () => {
return (
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
EMPLOYMENT DETAILS
</p>
</div>
<div className="flex flex-col gap-4">
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Job Title"
name="jobTitle"
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]"
/>
<div className="flex items-center gap-[3.6875rem]">
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Employers Name"
name="employerName"
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]"
/>
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Employers Official Email"
name="employerOfficialEmail"
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]"
/>
</div>
<div className="flex items-center gap-[9rem]">
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Resumption Date"
name="resumptionDate"
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]"
/>
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Employee ID."
name="employeeID"
labelSpan="Upload your work ID"
labelSpanClass="text-[11px] text-[#7a7373]"
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]"
/>
</div>
<div className="flex items-center gap-[3.6875rem]">
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Salary ( Gross annual income )"
name="salaryGross"
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]"
/>
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Salary ( Net monthly Income )"
name="salaryNet"
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]"
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Salary Payment Date"
name="salary-payment-date"
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]"
/>
</div>
</>
);
};
export default EmploymentDetails;
+5 -33
View File
@@ -1,51 +1,23 @@
import React from "react";
import BasicInfo from "./BasicInfo";
import YourAreAlmostThere from "./YourAreAlmostThere";
import LoanAmountComp from "./LoanAmountComp";
import ApplicantsAttestation from "./ApplicantsAttestation";
const GetStarted = () => {
const [step, setStep] = React.useState(1);
const handleNextStep = () => {
if (step < 4) {
setStep(step + 1);
}
};
// const handlePreviousStep: React.MouseEvent<HTMLButtonElement> = () => {
// setStep(step - 1);
// };
const [inputValues, setInputValues] = React.useState({
title: "",
marital: "",
agentId: "",
bvn: "",
firstName: "",
phone: "",
email: "",
surname: "",
dob: "",
secondName: "",
spouseBVN: "",
});
const GetStarted = ({handleNextStep, step}:{handleNextStep:any, step:string|number|any}) => {
return (
<div className="w-full flex items-center justify-center">
<div className="containerMode">
{/* Main */}
<main>
{step === 1 && (
{step === 2 && (
<BasicInfo
inputValues={inputValues}
setInputValues={setInputValues}
handleNextStep={handleNextStep}
/>
)}
{step === 2 && <YourAreAlmostThere handleNextStep={handleNextStep} />}
{step === 3 && <LoanAmountComp handleNextStep={handleNextStep} />}
{step === 4 && <ApplicantsAttestation />}
{step === 3 && <YourAreAlmostThere handleNextStep={handleNextStep} />}
{step === 4 && <LoanAmountComp handleNextStep={handleNextStep} />}
{step === 5 && <ApplicantsAttestation />}
</main>
</div>
</div>
-133
View File
@@ -1,133 +0,0 @@
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.FormEvent<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" },
];
+163 -90
View File
@@ -1,20 +1,56 @@
import React from "react";
import { Button, InputCompOne } from "..";
interface SliderProps {
handleSliderChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
value: number;
}
import {Formik, Form} from 'formik'
import * as Yup from "yup";
const initialValues = {
monthly_salary: "",
loan_amount: "",
duration: 6
};
// To get the validation schema
const validationSchema = Yup.object().shape({
duration: Yup.number()
.required("Required"),
monthly_salary: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
loan_amount: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
});
// interface SliderProps {
// handleSliderChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
// value: number;
// }
interface LoanAmountProps {
handleNextStep: any;
}
const LoanAmountComp: React.FC<LoanAmountProps> = ({ handleNextStep }) => {
const [value, setValue] = React.useState(6);
// const [value, setValue] = React.useState(6);
const handleSliderChange = (e: any) => {
setValue(e.target.value);
// const handleSliderChange = (e: any) => {
// setValue(e.target.value);
// };
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
@@ -35,95 +71,132 @@ const LoanAmountComp: React.FC<LoanAmountProps> = ({ handleNextStep }) => {
</p>
</div>
</div>
<div className="flex flex-col gap-[45px] justify-center ml-[40px] mb-[40px]">
<InputCompOne
parentClass="max-w-[29.4375rem] w-full"
label="Your Monthly Salary*"
name="salary"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-4"
placeholder="150,000"
/>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="flex flex-col gap-[45px] justify-center ml-[40px] mb-[40px]">
<InputCompOne
parentClass="max-w-[29.4375rem] w-full"
label="Your Monthly Salary*"
name="monthly_salary"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-4"
placeholder="150,000"
value={props.values.monthly_salary}
onChange={props.handleChange}
error={(props.errors.monthly_salary && props.touched.monthly_salary) ? props.errors.monthly_salary : ''}
/>
<div className="w-full border-[.1875rem] rounded-xl border-black min-h-[884px] py-4 px-8 max-w-[784px]">
<p className="leading-[22px] tracking-[3%] text-[#5C2684] w-[729px] mb-[2.625rem]">
The maximum amount you can apply for on this offer is based on the
information you shared with us in your loan application. We have
made this offer to suit your monthly remuneration and to enable you
pay your loan on-time
</p>
<InputCompOne
parentClass="max-w-[45.8125rem] w-full mb-3"
label="How much do you want to apply for?"
name="loan"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-9"
placeholder="350,000"
/>
<div className="flex items-center justify-between w-full">
<div className=" h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
<span>Minimum Offer:</span>
<p>
<b>N</b>100,000
</p>
</div>
<div className="w-full border-[.1875rem] rounded-xl border-black min-h-[884px] py-4 px-8 max-w-[784px]">
<p className="leading-[22px] tracking-[3%] text-[#5C2684] w-[729px] mb-[2.625rem]">
The maximum amount you can apply for on this offer is based on the
information you shared with us in your loan application. We have
made this offer to suit your monthly remuneration and to enable you
pay your loan on-time
</p>
<InputCompOne
parentClass="max-w-[45.8125rem] w-full mb-3"
label="How much do you want to apply for?"
name="loan_amount"
parentInputClass="w-full"
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
input
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-9"
placeholder="350,000"
value={props.values.loan_amount}
onChange={props.handleChange}
error={(props.errors.loan_amount && props.touched.loan_amount) ? props.errors.loan_amount : ''}
/>
<div className="flex items-center justify-between w-full">
<div className=" h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
<span>Minimum Offer:</span>
<p>
<b>N</b>100,000
</p>
</div>
<div className="h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
<span>Maximum Offer:</span>
<p>
<b>N</b>500,000
</p>
</div>
</div>
<div className="h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
<span>Maximum Offer:</span>
<p>
<b>N</b>500,000
</p>
</div>
</div>
<Slider handleSliderChange={handleSliderChange} value={value} />
<>
<div className="flex flex-col items-start mt-11 mb-16">
<p className="text-lg font-semibold">For how many months? <span className='text-[10px] text-red-500'>{(props.errors.duration && props.touched.duration) ? props.errors.duration : ''}</span></p>
<div className="w-full">
<input
type="range"
min="6"
max="24"
value={props.values.duration}
onChange={props.handleChange}
className="slider w-full h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer"
style={{
background: `linear-gradient(90deg, #6B21A8 ${
((props.values.duration - 6) / 18) * 100
}%, #D1D5DB ${((props.values.duration - 6) / 18) * 100}%)`,
}}
/>
</div>
<div className="mt-4 text-lg font-semibold text-gray-700 w-full flex items-center text-center justify-center">
{props.values.duration} months
</div>
</div>
</>
<div className="w-full flex items-center justify-center flex-col">
<div className="w-[279px] h-[130px] mb-[76px] flex items-center justify-center flex-col">
<p className="text-[#FBB700]">Your Monthly Repayment</p>
<p>N</p>
</div>
<Button
className="max-w-[462px] w-full bg-[#5C2684] rounded h-[2.75rem]"
text="Submit"
type="button"
onClick={handleNextStep}
/>
</div>
</div>
</div>
<div className="w-full flex items-center justify-center flex-col">
<div className="w-[279px] h-[130px] mb-[76px] flex items-center justify-center flex-col">
<p className="text-[#FBB700]">Your Monthly Repayment</p>
<p>N</p>
</div>
<Button
className="max-w-[462px] w-full bg-[#5C2684] rounded h-[2.75rem]"
text="Submit"
type='submit'
/>
</div>
</div>
</div>
</Form>
)}
</Formik>
</>
);
};
export default LoanAmountComp;
const Slider: React.FC<SliderProps> = ({ handleSliderChange, value }) => {
return (
<div className="flex flex-col items-start mt-11 mb-16">
<p className="text-lg font-semibold">For how many months?</p>
<div className="w-full">
<input
type="range"
min="6"
max="24"
value={value}
onChange={handleSliderChange}
className="slider w-full h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer"
style={{
background: `linear-gradient(90deg, #6B21A8 ${
((value - 6) / 18) * 100
}%, #D1D5DB ${((value - 6) / 18) * 100}%)`,
}}
/>
</div>
<div className="mt-4 text-lg font-semibold text-gray-700 w-full flex items-center text-center justify-center">
{value} months
</div>
</div>
);
};
// const Slider: React.FC<SliderProps> = ({ handleSliderChange, value }) => {
// return (
// <div className="flex flex-col items-start mt-11 mb-16">
// <p className="text-lg font-semibold">For how many months?</p>
// <div className="w-full">
// <input
// type="range"
// min="6"
// max="24"
// value={value}
// onChange={handleSliderChange}
// className="slider w-full h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer"
// style={{
// background: `linear-gradient(90deg, #6B21A8 ${
// ((value - 6) / 18) * 100
// }%, #D1D5DB ${((value - 6) / 18) * 100}%)`,
// }}
// />
// </div>
// <div className="mt-4 text-lg font-semibold text-gray-700 w-full flex items-center text-center justify-center">
// {value} months
// </div>
// </div>
// );
// };
-111
View File
@@ -1,111 +0,0 @@
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.FormEvent<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;
@@ -1,126 +0,0 @@
import React from "react";
import { InputCompOne } from "..";
const ReferenceDetails: React.FC = () => {
return (
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
REFERENCE DETAILS ( Must be 18 years and above )
</p>
</div>
<div className="">
<div className="flex flex-col gap-[3.4375rem]">
<div className="flex flex-col gap-4">
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Name"
name="referenceName"
labelSpan="1st reference"
labelSpanClass="text-[12px] text-[#5C2684] ml-1"
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]"
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Relationship with He/She"
name="referenceRelationship"
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]"
/>
</div>
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Phone Number"
name="referencePhoneNumber"
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]"
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Email Address"
name="referenceEmail"
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]"
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="BVN"
name="ReferenceBvn"
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]"
/>
</div>
<div className="flex flex-col gap-4">
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Name"
name="referenceName2"
labelSpan="2nd reference"
labelSpanClass="text-[12px] text-[#5C2684] ml-[4px]"
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]"
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Relationship with He/She"
name="referenceRelationship2"
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]"
/>
</div>
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Phone Number"
name="referencePhoneNumber2"
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]"
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Email Address"
name="referenceEmail2"
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]"
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="BVN"
name="ReferenceBvn2"
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]"
/>
</div>
</div>
</div>
</>
);
};
export default ReferenceDetails;
@@ -1,49 +0,0 @@
import React from "react";
import { InputCompOne } from "..";
interface SpouseDetailsProps {
inputValues: {
spouseBVN: string;
};
handleChange: (e: React.FormEvent<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="spouseBVN"
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.spouseBVN}
onChange={handleChange}
onInput={handleInput}
ref={inputRef}
/>
</div>
</div>
</>
);
};
export default SpouseDetails;
+385 -14
View File
@@ -1,29 +1,400 @@
import React from "react";
// import { useNavigate } from "react-router-dom";
import EmploymentDetails from "./EmploymentDetails";
import ReferenceDetails from "./ReferenceDetails";
import { Button } from "..";
import { Button, InputCompOne } from "..";
import {Formik, Form} from 'formik'
import * as Yup from "yup";
const initialValues = {
job_title: "",
employer_name: "",
employer_email:"",
date_of_resumption: "",
employee_id: "",
annual_income: "",
monthly_salary: "",
salary_payment_date: "",
ref_name: "",
ref_email: "",
ref_number: "",
ref_relationship: "",
ref_bvn: "",
ref_two_name: "",
ref_two_email: "",
ref_two_number: "",
ref_two_relationship: "",
ref_two_bvn: "",
};
// To get the validation schema
const validationSchema = Yup.object().shape({
job_title: Yup.string()
.required("Required"),
employer_name: Yup.string()
.required("Required"),
date_of_resumption: Yup.string()
.required("Required"),
employer_email: Yup.string()
.email("Invalid")
.required("Required"),
annual_income: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
monthly_salary: Yup.string()
.required("Required")
.test("no-e", "Invalid", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
}),
salary_payment_date: Yup.string()
.required("Required"),
employee_id: Yup.string()
.required("Required"),
ref_name: Yup.string()
.required("Required"),
ref_email: Yup.string()
.email("Invalid")
.required("Required"),
ref_number: Yup.string()
.required("Required"),
ref_relationship: Yup.string()
.required("Required"),
ref_bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
ref_two_name: Yup.string()
.required("Required"),
ref_two_email: Yup.string()
.email("Invalid")
.required("Required"),
ref_two_number: Yup.string()
.required("Required"),
ref_two_relationship: Yup.string()
.required("Required"),
ref_two_bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
});
interface YourAreAlmostThereProps {
handleNextStep: any;
}
const YourAreAlmostThere: React.FC<YourAreAlmostThereProps> = ({ handleNextStep }) => {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values:any) => {
console.log(values)
handleNextStep()
};
return (
<>
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
Youre almost there
</h1>
<form action="" className="flex flex-col gap-6">
<EmploymentDetails />
<ReferenceDetails />
<Button
className="my-8 max-w-[20.3125rem] btn-R bg-[#5A2C82]"
text="Continue"
type="button"
onClick={handleNextStep}
/>
</form>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props)=>(
<Form>
<div className="flex flex-col gap-6">
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
EMPLOYMENT DETAILS
</p>
</div>
<div className="flex flex-col gap-4">
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Job Title"
name="job_title"
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] rounded-[.375rem]"
value={props.values.job_title}
onChange={props.handleChange}
error={(props.errors.job_title && props.touched.job_title) ? props.errors.job_title : ''}
/>
<div className="flex items-center gap-[3.6875rem]">
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Employers Name"
name="employer_name"
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] rounded-[.375rem]"
value={props.values.employer_name}
onChange={props.handleChange}
error={(props.errors.employer_name && props.touched.employer_name) ? props.errors.employer_name : ''}
/>
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Employers Official Email"
name="employer_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] rounded-[.375rem]"
value={props.values.employer_email}
onChange={props.handleChange}
error={(props.errors.employer_email && props.touched.employer_email) ? props.errors.employer_email : ''}
/>
</div>
<div className="flex items-center gap-[9rem]">
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Resumption Date"
name="date_of_resumption"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputType='date'
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
value={props.values.date_of_resumption}
onChange={props.handleChange}
error={(props.errors.date_of_resumption && props.touched.date_of_resumption) ? props.errors.date_of_resumption : ''}
/>
<InputCompOne
parentClass="max-w-[17.9375rem] w-full"
label="Employee ID."
name="employee_id"
labelSpan="Upload your work ID"
labelSpanClass="text-[11px] text-[#7a7373]"
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] rounded-[.375rem]"
value={props.values.employee_id}
onChange={props.handleChange}
error={(props.errors.employee_id && props.touched.employee_id) ? props.errors.employee_id : ''}
/>
</div>
<div className="flex items-center gap-[3.6875rem]">
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Salary ( Gross annual income )"
name="annual_income"
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] rounded-[.375rem]"
value={props.values.annual_income}
onChange={props.handleChange}
error={(props.errors.annual_income && props.touched.annual_income) ? props.errors.annual_income : ''}
/>
<InputCompOne
parentClass="max-w-[23.1875rem] w-full"
label="Salary ( Net monthly Income )"
name="monthly_salary"
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] rounded-[.375rem]"
value={props.values.monthly_salary}
onChange={props.handleChange}
error={(props.errors.monthly_salary && props.touched.monthly_salary) ? props.errors.monthly_salary : ''}
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem]"
label="Salary Payment Date"
name="salary_payment_date"
parentInputClass="w-full"
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
input
inputType='date'
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
value={props.values.salary_payment_date}
onChange={props.handleChange}
error={(props.errors.salary_payment_date && props.touched.salary_payment_date) ? props.errors.salary_payment_date : ''}
/>
</div>
</>
<>
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
REFERENCE DETAILS ( Must be 18 years and above )
</p>
</div>
<div className="">
<div className="flex flex-col gap-[3.4375rem]">
<div className="flex flex-col gap-4">
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Name"
name="ref_name"
labelSpan="1st reference"
labelSpanClass="text-[12px] text-[#5C2684] ml-1"
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={props.values.ref_name}
onChange={props.handleChange}
error={(props.errors.ref_name && props.touched.ref_name) ? props.errors.ref_name : ''}
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Relationship with He/She"
name="ref_relationship"
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={props.values.ref_relationship}
onChange={props.handleChange}
error={(props.errors.ref_relationship && props.touched.ref_relationship) ? props.errors.ref_relationship : ''}
/>
</div>
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Phone Number"
name="ref_number"
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] rounded-[.375rem]"
value={props.values.ref_number}
onChange={props.handleChange}
error={(props.errors.ref_number && props.touched.ref_number) ? props.errors.ref_number : ''}
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Email Address"
name="ref_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] rounded-[.375rem]"
value={props.values.ref_email}
onChange={props.handleChange}
error={(props.errors.ref_email && props.touched.ref_email) ? props.errors.ref_email : ''}
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="BVN"
name="ref_bvn"
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] rounded-[.375rem]"
value={props.values.ref_bvn}
onChange={props.handleChange}
error={(props.errors.ref_bvn && props.touched.ref_bvn) ? props.errors.ref_bvn : ''}
/>
</div>
<div className="flex flex-col gap-4">
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Name"
name="ref_two_name"
labelSpan="2nd reference"
labelSpanClass="text-[12px] text-[#5C2684] ml-[4px]"
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] rounded-[.375rem]"
value={props.values.ref_two_name}
onChange={props.handleChange}
error={(props.errors.ref_two_name && props.touched.ref_two_name) ? props.errors.ref_two_name : ''}
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Relationship with He/She"
name="ref_two_relationship"
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] rounded-[.375rem]"
value={props.values.ref_two_relationship}
onChange={props.handleChange}
error={(props.errors.ref_two_relationship && props.touched.ref_two_relationship) ? props.errors.ref_two_relationship : ''}
/>
</div>
<div className="flex items-center gap-[6.5625rem]">
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Phone Number"
name="ref_two_number"
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] rounded-[.375rem]"
value={props.values.ref_two_number}
onChange={props.handleChange}
error={(props.errors.ref_two_number && props.touched.ref_two_number) ? props.errors.ref_two_number : ''}
/>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="Email Address"
name="ref_two_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] rounded-[.375rem]"
value={props.values.ref_two_email}
onChange={props.handleChange}
error={(props.errors.ref_two_email && props.touched.ref_two_email) ? props.errors.ref_two_email : ''}
/>
</div>
<InputCompOne
parentClass="max-w-[20.3125rem] w-full"
label="BVN"
name="ref_two_bvn"
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] rounded-[.375rem]"
value={props.values.ref_two_bvn}
onChange={props.handleChange}
error={(props.errors.ref_two_bvn && props.touched.ref_two_bvn) ? props.errors.ref_two_bvn : ''}
/>
</div>
</div>
</div>
</>
<Button
className="my-8 max-w-[20.3125rem] btn-R bg-[#5A2C82]"
text="Continue"
type="submit"
/>
</div>
</Form>
)}
</Formik>
</>
);
};
+7 -2
View File
@@ -1,10 +1,13 @@
import { FaCaretDown } from "react-icons/fa";
import dashIcon from "../../assets/images/dashboard/dashDefault.svg";
type Props = {
name: string;
fillColor?: string;
className?:string;
};
export default function Icons({ name, fillColor }: Props) {
export default function Icons({ name, fillColor, className }: Props) {
return (
<>
{name == "home" ? (
@@ -106,7 +109,9 @@ export default function Icons({ name, fillColor }: Props) {
fill={fillColor ? fillColor : "#FFF"}
/>
</svg>
) : name == "dash-icon" ? (
) :name == 'arrow-down'?
<FaCaretDown className={`text-xl ${className && className}`} />
:name == "dash-icon" ? (
<img src={dashIcon} alt="dash-icon" />
) : null}
</>
+131 -73
View File
@@ -1,21 +1,62 @@
import React from "react";
import * as Yup from "yup";
import { Form, Formik } from "formik";
import { InputCompOne } from "..";
import {useNavigate} from 'react-router-dom'
import { RouteHandler } from "../../router/routes";
// To get the validation schema
const validationSchema = Yup.object().shape({
bvn: Yup.string()
.required("BVN is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(11, "must be 11 digits")
.max(11, "must be 11 digits"),
otp: Yup.string()
.required("OTP is required")
.test("no-e", "Invalid number", (value:any) => {
if (value && /^[0-9]*$/.test(value) == false) {
return false;
}
return true;
})
.min(5, "must be 5 digits")
.max(5, "must be 5 digits"),
// .test("no-e", "must be 11 characters", (value:any) => {
// if (value.length < 11) {
// return false;
// }
// return true;
// })
});
// initial values for formik
let initialValues = {
bvn: '',
otp: '',
};
const LetsGetStarted: React.FC = () => {
const [pinValues, setPinValues] = React.useState({
bvn: "",
otp: "",
});
const navigate = useNavigate()
// const [pinValues, setPinValues] = React.useState({
// bvn: "",
// otp: "",
// });
const [hideOTPComponent, setHideOTPComponent] = React.useState<boolean>(true);
const firstInputRef = React.useRef<HTMLInputElement>(null);
const secondInputRef = React.useRef<HTMLInputElement>(null);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let { name, value } = e.target as HTMLInputElement;
// const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// let { name, value } = e.target as HTMLInputElement;
setPinValues((prev) => ({ ...prev, [name]: value }));
};
// setPinValues((prev) => ({ ...prev, [name]: value }));
// };
const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
let { name, value } = e.target as HTMLInputElement;
@@ -24,7 +65,7 @@ const LetsGetStarted: React.FC = () => {
const regex = /^[0-9]+$/;
if (regex.test(value)) {
if (value?.length == 10) {
if (value?.length == 11) {
setHideOTPComponent(false);
// secondInputRef.current?.focus();
} else setHideOTPComponent(true);
@@ -34,73 +75,90 @@ const LetsGetStarted: React.FC = () => {
}
};
console.log(secondInputRef)
const handleSubmit = (values:any) => {
console.log('values', values)
navigate(RouteHandler.dashboardHome, {replace:true})
};
return (
<div className="w-full">
<div className="containerMode flex justify-between gap-1 xl:gap-8 flex-col">
<div className="my-[4rem] flex items-center justify-center w-full">
<h1 className="font-bold text-[2.375rem] text-[#5C2684] my-[.5rem] text-center">
Lets Get You Started
</h1>
</div>
<form className="mx-auto flex flex-col gap-8 max-w-[31.625rem] ">
<InputCompOne
parentClass="flex flex-col gap-2"
label="Enter Your BVN "
name="bvn"
parentInputClass="w-full"
labelSpan="( To get your BVN, dial *565*0# )"
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
placeholder="Enter your BVN"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
input
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
value={pinValues.bvn}
onChange={handleChange}
onInput={handleInput}
ref={firstInputRef}
maxLength={10}
/>
{!hideOTPComponent ? (
<InputCompOne
parentClass="flex flex-col gap-2"
label="Enter OTP "
name="otp"
parentInputClass="w-full"
labelSpan="( Please check your BVN phone number for verification pin )"
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
placeholder="Enter your OTP"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
input
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
value={pinValues.otp}
onChange={handleChange}
onInput={handleInput}
ref={secondInputRef}
/>
) : null}
<button
className="w-full h-[3.625rem] rounded bg-[#FBB700] rounded-2 px-4 text-[18px] text-[#282828] font-semibold disabled:text-[#282828] disabled:text-opacity-50"
disabled={!pinValues.otp}
>
Enter
</button>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props:any) => (
<Form className="">
<div className="w-full">
<div className="containerMode flex justify-between gap-1 xl:gap-8 flex-col">
<div className="my-[4rem] flex items-center justify-center w-full">
<h1 className="font-bold text-[2.375rem] text-[#5C2684] my-[.5rem] text-center">
Lets Get You Started
</h1>
</div>
<div className="mx-auto flex flex-col gap-8 max-w-[31.625rem] ">
<InputCompOne
parentClass="flex flex-col gap-2"
label="Enter Your BVN "
name="bvn"
parentInputClass="w-full"
labelSpan="( To get your BVN, dial *565*0# )"
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
placeholder="Enter your BVN"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
input
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
value={props.values.bvn}
onChange={props.handleChange}
onInput={handleInput}
ref={firstInputRef}
maxLength={11}
error={(props.errors.bvn && props.touched.bvn) && props.errors.bvn}
/>
{!hideOTPComponent && (
<InputCompOne
parentClass="flex flex-col gap-2"
label="Enter OTP "
name="otp"
parentInputClass="w-full"
labelSpan="( Please check your BVN phone number for verification pin )"
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
placeholder="Enter your OTP"
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
input
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
value={props.values.otp}
onChange={props.handleChange}
onInput={handleInput}
ref={secondInputRef}
maxLength={11}
error={(props.errors.otp && props.touched.otp) && props.errors.otp}
/>
)}
<button
type='submit'
className="w-full h-[3.625rem] rounded bg-[#FBB700] rounded-2 px-4 text-[18px] text-[#282828] font-semibold disabled:text-[#282828] disabled:text-opacity-50"
disabled={!props.values.otp}
>
Enter
</button>
{hideOTPComponent ? (
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
***Every personal information attached to your BVN is safe and
secure. It is only important for us to verify your information and
also give you access to your application profile/account.
</p>
) : (
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
***Did not receive OTP? Click to resend
</p>
)}
</form>
</div>
</div>
{hideOTPComponent ? (
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
***Every personal information attached to your BVN is safe and
secure. It is only important for us to verify your information and
also give you access to your application profile/account.
</p>
) : (
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
***Did not receive OTP? Click to resend
</p>
)}
</div>
</div>
</div>
</Form>
)}
</Formik>
);
};
+56 -17
View File
@@ -1,28 +1,30 @@
import React, { forwardRef } from "react";
import { Icons } from "../Icons";
export interface InputCompOneProps {
label: string;
labelClass: string;
label?: string;
labelClass?: string;
labelSpan?: string;
labelSpanClass?: string;
floatLabel?: string;
placeholder?: string;
value?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
onInput?: (e: React.FormEvent<HTMLInputElement>) => void;
value?: string | any;
onChange?: (e:any) => any;
onInput?: (e:any) => any;
name: string;
tabIndex?: number;
ref?: React.RefObject<HTMLInputElement>;
selectValue?: string;
input?: boolean;
select?: boolean;
selectOptions?: { value: string; label: string }[];
selectOptions?: {loading:boolean, data:{ value: string; label: string }[]};
inputType?: string;
inputClass?: string;
parentInputClass?: string;
selectClass?: string;
parentSelectClass?: string;
parentClass?: string;
maxLength?: number;
error?: string;
}
const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
@@ -32,6 +34,7 @@ const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
labelClass,
labelSpan,
labelSpanClass,
floatLabel,
placeholder,
value,
onChange,
@@ -41,27 +44,28 @@ const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
selectValue,
input = false,
select = false,
selectOptions = [],
selectOptions = {loading:false, data:[]},
inputType = "text",
inputClass,
parentInputClass,
selectClass,
parentSelectClass,
parentClass,
maxLength,
error,
},
forwardedRef
) => {
return (
<div className={parentClass}>
{label && (
<label htmlFor="" className={labelClass}>
<label htmlFor={label ? label : floatLabel} className={`flex gap-2 items-center flex-wrap ${labelClass}`}>
{label}
{labelSpan && <span className={labelSpanClass}>{labelSpan}</span>}
{error && label && <span className='text-[10px] text-red-500'>{error}</span>}
</label>
)}
{input && (
<div className={parentInputClass}>
<div className={`relative ${parentInputClass}`}>
<input
type={inputType}
placeholder={placeholder}
@@ -71,25 +75,60 @@ const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
name={name}
tabIndex={tabIndex}
ref={forwardedRef}
className={inputClass}
className={`px-4 ${floatLabel && 'peer pt-4 placeholder:text-transparent'} ${inputClass}`}
maxLength={maxLength}
id={label ? label : floatLabel}
/>
{floatLabel &&
<label
htmlFor={label ? label : floatLabel}
className={`flex items-center gap-2 cursor-pointer text-sm text-black/70 dark:text-white absolute left-4 top-0 translate-y-0 peer-focus:top-0 peer-focus:translate-y-0 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 transition-all duration-500`}
>
{floatLabel}
{error && floatLabel && !label && <span className='text-[10px] text-red-500'>{error}</span>}
</label>
}
</div>
)}
{select && (
<div className={parentSelectClass}>
<div className={`relative ${parentInputClass}`}>
<select
name={name}
id=""
id={label ? label : floatLabel}
value={selectValue}
className={selectClass}
className={`px-4 appearance-none ${floatLabel && 'peer pt-4'} ${selectClass}`}
onChange={onChange}
>
{selectOptions.map(({ value, label }) => (
{selectOptions.loading ?
<option value=''>Loading</option>
: selectOptions.data.length ?
selectOptions.data.map(({ value, label }) => (
<option key={value} value={value}>
{label}
</option>
))
:
<option value=''>Not Found</option>
}
{/* {selectOptions.map(({ value, label }) => (
<option key={value} value={value}>
{label}
</option>
))}
))} */}
</select>
{floatLabel &&
<label
htmlFor={label ? label : floatLabel}
className={`flex items-center gap-2 cursor-pointer text-sm text-black/70 dark:text-white absolute left-4 top-0 translate-y-0 peer-focus:top-0 peer-focus:translate-y-0 transition-all duration-500`}
>
{floatLabel}
{error && floatLabel && !label && <span className='text-[10px] text-red-500'>{error}</span>}
</label>
}
{/* select custon arrow */}
<div className='absolute right-4 top-1/2 -translate-y-1/2'>
<Icons name='arrow-down' />
</div>
</div>
)}
</div>
+1 -1
View File
@@ -8,7 +8,7 @@ interface GetStartedLayoutProps {
const GetStartedLayout: React.FC<GetStartedLayoutProps> = ({ children }) => {
return (
<div className="containerMode mb-[5.4375rem]">
<div className='sticky top-0 bg-white'>
<div className='sticky z-50 top-0 bg-white'>
<Header hideSidebar={true} hideMenu={true} />
</div>
<div className="flex flex-col min-h-[70vh] justify-between">
+20 -4
View File
@@ -1,12 +1,28 @@
import React from "react";
import { GetStarted as Main } from "../components";
import { GetStartedLayout } from "../layouts";
import { GetStartedLayout, LetsGetStartedLayout } from "../layouts";
import BVN from "../components/GetStarted/BVN";
const GetStartedPage: React.FC = () => {
const [step, setStep] = React.useState(1);
const handleNextStep = () => {
if (step < 5) {
setStep(step + 1);
}
};
return (
<GetStartedLayout>
<Main />
</GetStartedLayout>
<>
{step == 1 ?
<LetsGetStartedLayout>
<BVN handleNextStep={handleNextStep} />
</LetsGetStartedLayout>
:
<GetStartedLayout>
<Main step={step} handleNextStep={handleNextStep} />
</GetStartedLayout>
}
</>
);
};
+4 -4
View File
@@ -32,7 +32,7 @@ export const lowerMenuItems = [
{
id: 3,
name: "CORPORATE BANKING",
linkPath: "/corporate-banking",
linkPath: "/cooperate-banking",
},
{
id: 4,
@@ -277,7 +277,7 @@ export const _lowerMenuItems = [
},
{
name: "CORPORATE BANKING",
linkPath: "/corporate-banking",
linkPath: "/cooperate-banking",
subItems: [
{
name: "FOREIGN EXCHANGE SERVICES",
@@ -436,12 +436,12 @@ export const footerItems = [
],
},
{
category: "CORPORATE BANKING",
category: "COOPORATE BANKING",
subItems: [
{ text: "FOREIGN EXCHANGE SERVICES", href: "/foreign-exchange-services" },
{ text: "TRADE SERVICES", href: "/node/166" },
{ text: "CASH MANAGEMENT SOLUTIONS", href: "/cash-management" },
{ text: "CORPORATE FINANCE", href: "/corporate-finance" },
{ text: "COOPORATE FINANCE", href: "/corporate-finance" },
],
},
{