Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f63171273e | |||
| 6bd533c7ca | |||
| 408777353d | |||
| a2e039eab4 | |||
| 8d6cc5861e | |||
| 18967d720c | |||
| 044b2ef917 | |||
| 4f7fdfb2ba | |||
| ab389d6632 | |||
| 29538e3b6e | |||
| dd2df0d695 | |||
| a97db9a661 | |||
| 135cbce348 | |||
| 814bfe041a | |||
| d90d515f60 | |||
| e93a3dea68 | |||
| a50d5ec82d | |||
| 333ada0a1c | |||
| bb718953ad | |||
| a31b36686d | |||
| 00f4e1b565 | |||
| 6d302def04 | |||
| 82dd11a772 | |||
| 7e9c395f4a | |||
| 2cb5c471f6 | |||
| 4b008f6785 | |||
| f632099128 | |||
| 122eb31732 | |||
| 378ff4a625 | |||
| f88b6df24c |
@@ -3,4 +3,7 @@ DIGIFI_PORT=5173
|
|||||||
# Social Links
|
# Social Links
|
||||||
FACEBOOK_URL=https://www.facebook.com
|
FACEBOOK_URL=https://www.facebook.com
|
||||||
TWITTER_URL=https://twitter.com
|
TWITTER_URL=https://twitter.com
|
||||||
INSTAGRAM_URL=https://www.instagram.com
|
INSTAGRAM_URL=https://www.instagram.com
|
||||||
|
|
||||||
|
# BACKEND END POINTS
|
||||||
|
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
|
||||||
+4
-1
@@ -3,4 +3,7 @@ DIGIFI_PORT=5173
|
|||||||
# Social Links
|
# Social Links
|
||||||
VITE_FACEBOOK_URL=https://www.facebook.com
|
VITE_FACEBOOK_URL=https://www.facebook.com
|
||||||
VITE_TWITTER_URL=https://twitter.com
|
VITE_TWITTER_URL=https://twitter.com
|
||||||
VITE_INSTAGRAM_URL=https://www.instagram.com
|
VITE_INSTAGRAM_URL=https://www.instagram.com
|
||||||
|
|
||||||
|
# BACKEND END POINTS
|
||||||
|
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
|
||||||
+4
-1
@@ -3,4 +3,7 @@ DIGIFI_PORT=5173
|
|||||||
# Social Links
|
# Social Links
|
||||||
FACEBOOK_URL=https://www.facebook.com
|
FACEBOOK_URL=https://www.facebook.com
|
||||||
TWITTER_URL=https://twitter.com
|
TWITTER_URL=https://twitter.com
|
||||||
INSTAGRAM_URL=https://www.instagram.com
|
INSTAGRAM_URL=https://www.instagram.com
|
||||||
|
|
||||||
|
# BACKEND END POINTS
|
||||||
|
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
|
||||||
+7
-2
@@ -11,8 +11,13 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 6030:5173
|
- 6030:5173
|
||||||
expose:
|
expose:
|
||||||
- "5173"
|
- "5173"
|
||||||
|
extra_hosts:
|
||||||
|
- digifi-apidev.chiefsoft.net:10.10.33.15
|
||||||
|
- backend.wrenchboard.api.test:10.10.33.15
|
||||||
environment:
|
environment:
|
||||||
- PORT=${DIGIFI_PORT}
|
- PORT=${DIGIFI_PORT}
|
||||||
|
tty: true
|
||||||
|
stdin_open: true
|
||||||
volumes:
|
volumes:
|
||||||
src:
|
src:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reduxjs/toolkit": "^2.2.1",
|
"@reduxjs/toolkit": "^2.2.1",
|
||||||
|
"axios": "^1.6.8",
|
||||||
"clsx": "2.1.0",
|
"clsx": "2.1.0",
|
||||||
"formik": "2.4.5",
|
"formik": "2.4.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
@@ -3,20 +3,20 @@ import {Formik, Form} from 'formik'
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleNextStep:()=>any
|
handleNextStep:(value:{})=>any
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
amount: "",
|
loan_amount: "",
|
||||||
duration: "",
|
payment_month: "",
|
||||||
id: "",
|
sales_agent: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
duration: Yup.string()
|
payment_month: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
amount: Yup.string()
|
loan_amount: Yup.string()
|
||||||
.required("Required")
|
.required("Required")
|
||||||
.test("no-e", "Invalid", (value:any) => {
|
.test("no-e", "Invalid", (value:any) => {
|
||||||
if (value && /^[0-9]*$/.test(value) == false) {
|
if (value && /^[0-9]*$/.test(value) == false) {
|
||||||
@@ -24,16 +24,14 @@ const validationSchema = Yup.object().shape({
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
id: Yup.string()
|
sales_agent: Yup.string()
|
||||||
.required("Required")
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function DashboardFormInit({handleNextStep}:Props) {
|
export default function DashboardFormInit({handleNextStep}:Props) {
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values:{}) => {
|
||||||
console.log(values)
|
handleNextStep(values)
|
||||||
handleNextStep()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -51,40 +49,40 @@ export default function DashboardFormInit({handleNextStep}:Props) {
|
|||||||
<div className="mt-[3.25rem] flex flex-col gap-9">
|
<div className="mt-[3.25rem] flex flex-col gap-9">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="amount"
|
name="loan_amount"
|
||||||
label="How Much Do You Want To Apply For?"
|
label="How Much Do You Want To Apply For?"
|
||||||
labelClass="font-bold text-[1.125rem]"
|
labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem] text-right"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem] text-right"
|
||||||
placeholder="350,000"
|
placeholder="350,000"
|
||||||
value={props.values.amount}
|
value={props.values.loan_amount}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.amount && props.touched.amount) ? props.errors.amount : ''}
|
error={(props.errors.loan_amount && props.touched.loan_amount) ? props.errors.loan_amount : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="duration"
|
name="payment_month"
|
||||||
label="For How Many Months?"
|
label="For How Many Months?"
|
||||||
labelClass="font-bold text-[1.125rem]"
|
labelClass="font-bold text-[1.125rem]"
|
||||||
select={true}
|
select={true}
|
||||||
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
selectOptions={duration}
|
selectOptions={paymentMonth}
|
||||||
selectValue={props.values.duration}
|
selectValue={props.values.payment_month}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.duration && props.touched.duration) ? props.errors.duration : ''}
|
error={(props.errors.payment_month && props.touched.payment_month) ? props.errors.payment_month : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="id"
|
name="sales_agent"
|
||||||
label="Direct sales agent ID ( Optional )"
|
label="Direct sales agent ID ( Optional )"
|
||||||
labelClass="font-bold text-[1.125rem]"
|
labelClass="font-bold text-[1.125rem]"
|
||||||
floatLabel='Enter agent ID'
|
floatLabel='Enter agent ID'
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="Agent ID"
|
placeholder="Agent ID"
|
||||||
value={props.values.id}
|
value={props.values.sales_agent}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.id && props.touched.id) ? props.errors.id : ''}
|
error={(props.errors.sales_agent && props.touched.sales_agent) ? props.errors.sales_agent : ''}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
||||||
@@ -106,7 +104,7 @@ interface SelectOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const duration: SelectOption = {
|
const paymentMonth: SelectOption = {
|
||||||
loading: false,
|
loading: false,
|
||||||
data: [
|
data: [
|
||||||
{ value: "", label: "Please Select" },
|
{ value: "", label: "Please Select" },
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ interface DashboardHomeProps {}
|
|||||||
|
|
||||||
const DashboardHome: FC<DashboardHomeProps> = () => {
|
const DashboardHome: FC<DashboardHomeProps> = () => {
|
||||||
const [step, setStep] = React.useState(1);
|
const [step, setStep] = React.useState(1);
|
||||||
|
const [applicationDetails, setApplicationDetails] = React.useState({});
|
||||||
|
|
||||||
const handleNextStep = () => {
|
const handleNextStep = (values:{}={}) => {
|
||||||
if (step < 7) {
|
if (step < 7) {
|
||||||
setStep(step + 1);
|
setStep(step + 1);
|
||||||
}
|
}
|
||||||
};
|
setApplicationDetails((prev:{}) => ({...prev, ...values}))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
@@ -24,8 +26,9 @@ const DashboardHome: FC<DashboardHomeProps> = () => {
|
|||||||
{step === 3 && <DashboardHomeDetail handleNextStep={handleNextStep} />}
|
{step === 3 && <DashboardHomeDetail handleNextStep={handleNextStep} />}
|
||||||
{step === 4 && <DashboardHomeEmploymentInfo handleNextStep={handleNextStep} />}
|
{step === 4 && <DashboardHomeEmploymentInfo handleNextStep={handleNextStep} />}
|
||||||
{step === 5 && <DashboardHomeRefereeInfo handleNextStep={handleNextStep} />}
|
{step === 5 && <DashboardHomeRefereeInfo handleNextStep={handleNextStep} />}
|
||||||
{step === 6 && <DashboardHomeAttestation handleNextStep={handleNextStep} />}
|
{step === 6 && <DashboardHomeAttestation handleNextStep={handleNextStep} applicationDetails={applicationDetails} />}
|
||||||
{step === 7 && <DashboardHomeIntro step={step} handleNextStep={handleNextStep} />}
|
{step === 7 && <DashboardHomeIntro step={step} handleNextStep={handleNextStep} />}
|
||||||
|
{/* <DashboardHomeAttestation handleNextStep={handleNextStep} applicationDetails={applicationDetails} /> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import React, { FC } from "react";
|
import React, { FC, useState, useEffect } from "react";
|
||||||
import NairaBag from "../../assets/images/dashboard/naira-bag.png";
|
import NairaBag from "../../assets/images/dashboard/naira-bag.png";
|
||||||
import { Button } from "../";
|
import { Button, Icons } from "../";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import PendingList from "../paginated-list/PendingList";
|
||||||
|
import { PendingTableList } from "../../core/models";
|
||||||
|
import { NewDateTimeFormatter } from "../../lib/NewDateTimeFormatter";
|
||||||
|
import { getUserPendingLoanList } from "../../core/apiRequest";
|
||||||
|
|
||||||
export interface DashBoardCardProps {
|
export interface DashBoardCardProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -68,16 +73,40 @@ export const DashBoardCard: React.FC<DashBoardCardProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface DashboardHomeIntroProps {
|
interface DashboardHomeIntroProps {
|
||||||
handleNextStep: any;
|
handleNextStep:(value:{})=>any
|
||||||
step?:number|string
|
step?:number|string
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep, step }) => {
|
const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep, step }) => {
|
||||||
|
const { userDetails } = useSelector((state:any) => state?.userDetails); // CHECKS IF USER Details are avaliable
|
||||||
|
|
||||||
|
const [userLoanList, setUserLoanList] = useState<{loading:boolean, data:PendingTableList}>({loading: true, data:[]})
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
let token = localStorage.getItem('token')
|
||||||
|
let uid = localStorage.getItem('uid')
|
||||||
|
if(!token || !uid){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getUserPendingLoanList(uid).then(res => {
|
||||||
|
console.log('RES', res)
|
||||||
|
console.log('RES', userLoanList)
|
||||||
|
if(!res || !res.data.loans){
|
||||||
|
setUserLoanList({loading:false, data:[]})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setUserLoanList({loading:false, data:res?.data?.loans})
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
setUserLoanList({loading:false, data:[]})
|
||||||
|
})
|
||||||
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='w-full'>
|
||||||
{step == 1 ?
|
{step == 1 ?
|
||||||
<>
|
<>
|
||||||
<h1 className="font-bold my-5 text-2xl">Hello, Olanrewaju</h1>
|
<h1 className="font-bold my-5 text-2xl">Hello, {userDetails.firstname}</h1>
|
||||||
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
|
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
|
||||||
<DashBoardCard
|
<DashBoardCard
|
||||||
cardClass="bg-[#5C2684] relative"
|
cardClass="bg-[#5C2684] relative"
|
||||||
@@ -89,13 +118,13 @@ const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep, step
|
|||||||
btnTextClass="w-[11.125rem] h-[2.8125rem] flex justify-center item-center btn-W text-[#FBB700]"
|
btnTextClass="w-[11.125rem] h-[2.8125rem] flex justify-center item-center btn-W text-[#FBB700]"
|
||||||
image={NairaBag}
|
image={NairaBag}
|
||||||
imgClass="translate-y-4 -rotate-6"
|
imgClass="translate-y-4 -rotate-6"
|
||||||
onClick={handleNextStep}
|
onClick={()=>handleNextStep({})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
:
|
:
|
||||||
<>
|
<>
|
||||||
<h1 className="font-bold my-5 text-2xl">Welcome Back, Olanrewaju</h1>
|
<h1 className="font-bold my-5 text-2xl">Welcome Back, {userDetails.firstname}</h1>
|
||||||
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
|
<div className="group w-full lg:w-[27.8125rem] h-[12.75rem] mt-7 ">
|
||||||
<DashBoardCard
|
<DashBoardCard
|
||||||
cardClass="bg-[#5C2684] relative"
|
cardClass="bg-[#5C2684] relative"
|
||||||
@@ -112,7 +141,50 @@ const DashboardHomeIntro: FC<DashboardHomeIntroProps> = ({ handleNextStep, step
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</>
|
{userLoanList.loading ?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
<div className='mt-5 w-full'>
|
||||||
|
<PendingList
|
||||||
|
data={userLoanList.data}
|
||||||
|
itemsPerPage={5}
|
||||||
|
tableTitle='Current Applications'
|
||||||
|
>
|
||||||
|
{(data:any)=>(
|
||||||
|
<div className="w-full p-4 rounded-lg shadow-lg bg-white overflow-x-auto min-h-[250px] max-h-[450px]">
|
||||||
|
<table className="w-full table-auto">
|
||||||
|
<thead>
|
||||||
|
<tr className='text-left border-b-2'>
|
||||||
|
<th className='px-1 py-4'>Date</th>
|
||||||
|
<th className='px-1 py-4 text-right'>Amount</th>
|
||||||
|
<th className='px-1 py-4 text-center'>Payment Term</th>
|
||||||
|
<th className='px-1 py-4 text-center'>Status</th>
|
||||||
|
<th className='px-1 py-4'>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{data.map((item:any, index:any) =>(
|
||||||
|
<tr key={index || item} className='even:bg-slate-100'>
|
||||||
|
<td className='px-1 py-2'>{NewDateTimeFormatter(item?.added)}</td>
|
||||||
|
<td className='px-1 py-2 text-right'>{item?.loan_amount}</td>
|
||||||
|
<td className='px-1 py-2 text-center'>{item?.payment_month}</td>
|
||||||
|
<td className='px-1 py-2 text-center'>{item?.status}</td>
|
||||||
|
<td className='px-1 py-2'>
|
||||||
|
<button className='px-2 py-1 border-2 border-black flex gap-2 items-center'>
|
||||||
|
View
|
||||||
|
<Icons name='arrow-right' />
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</PendingList>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,34 +2,49 @@ import { Button, InputCompOne, Stepper } from '../../shared/index';
|
|||||||
|
|
||||||
import {Formik, Form} from 'formik'
|
import {Formik, Form} from 'formik'
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
import { applyForLoan } from '../../../core/apiRequest';
|
||||||
|
|
||||||
// import { useNavigate } from "react-router-dom";
|
// import { useNavigate } from "react-router-dom";
|
||||||
// import { RouteHandler } from '../../../router/routes';
|
// import { RouteHandler } from '../../../router/routes';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleNextStep:()=>any
|
handleNextStep:(value:{})=>any
|
||||||
|
applicationDetails: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
account_number: "",
|
account: "",
|
||||||
checked: false
|
checked: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
account_number: Yup.string()
|
account: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
checked: Yup.bool() // use bool instead of boolean
|
checked: Yup.bool() // use bool instead of boolean
|
||||||
.oneOf([true], "You must accept the terms and conditions")
|
.oneOf([true], "You must accept the terms and conditions")
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function DashboardHomeAttestation({handleNextStep}:Props) {
|
export default function DashboardHomeAttestation({handleNextStep, applicationDetails}:Props) {
|
||||||
// let navigate = useNavigate();
|
// let navigate = useNavigate();
|
||||||
// const navigateToProfile = () => navigate(RouteHandler.dashboardProfile);
|
// const navigateToProfile = () => navigate(RouteHandler.dashboardProfile);
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE LOAN APPLICATION
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values:any) => {
|
||||||
console.log(values)
|
delete values.checked
|
||||||
handleNextStep()
|
applyForLoan({...applicationDetails, disbursement: values}).then(res=>{
|
||||||
|
console.log('APPLY FOR LOAN', res)
|
||||||
|
handleNextStep({disbursement: values})
|
||||||
|
console.log('ApplicationDetails', {...applicationDetails, disbursement: values})
|
||||||
|
}).catch(err=>{
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
// applyForLoan(payload).then(res=>{
|
||||||
|
// console.log('APPLY FOR LOAN', res)
|
||||||
|
// // handleNextStep({disbursement: values})
|
||||||
|
// }).catch(err=>{
|
||||||
|
// console.log(err)
|
||||||
|
// })
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -50,15 +65,15 @@ export default function DashboardHomeAttestation({handleNextStep}:Props) {
|
|||||||
<div className="flex items-center gap-[4.125rem]">
|
<div className="flex items-center gap-[4.125rem]">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="account_number"
|
name="account"
|
||||||
floatLabel="Disbursement account number"
|
floatLabel="Disbursement account number"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="0102547896"
|
placeholder="0102547896"
|
||||||
value={props.values.account_number}
|
value={props.values.account}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.account_number && props.touched.account_number) ? props.errors.account_number : ''}
|
error={(props.errors.account && props.touched.account) ? props.errors.account : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='max-w-[25.875rem]'>
|
<div className='max-w-[25.875rem]'>
|
||||||
@@ -87,3 +102,46 @@ export default function DashboardHomeAttestation({handleNextStep}:Props) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// const payload = {
|
||||||
|
// "loan_amount": "100000",
|
||||||
|
// "payment_month": "18",
|
||||||
|
// "sales_agent": "Testing1234",
|
||||||
|
// "gender": "male",
|
||||||
|
// "address": "World bank housing Estate, Umuahia",
|
||||||
|
// "marital_status": "single",
|
||||||
|
// "state": "abia",
|
||||||
|
// "email": "test5070@gmail.com",
|
||||||
|
// "country": "NG",
|
||||||
|
// "employment": {
|
||||||
|
// "job_title": "Information Officer",
|
||||||
|
// "name": "Testing Testing",
|
||||||
|
// "sector": "private (non academic)",
|
||||||
|
// "industry": "engineering",
|
||||||
|
// "resumption_date": "2024-04-05",
|
||||||
|
// "email": "test50700@gmail.com",
|
||||||
|
// "annual_income": "600000",
|
||||||
|
// "monthly_salary": "50000",
|
||||||
|
// "salary_payment_date": "2024-04-19",
|
||||||
|
// "employment_id": "2555566",
|
||||||
|
// "highest_eductaion": "b.sc + professional qualification"
|
||||||
|
// },
|
||||||
|
// "loan_reference": [
|
||||||
|
// {
|
||||||
|
// "fullname": "John Mike",
|
||||||
|
// "relationship": "Brother",
|
||||||
|
// "phone_number": "07055566611",
|
||||||
|
// "email": "refone@gmail.com",
|
||||||
|
// "bvn": "11111111111"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "fullname": "Mary Paul",
|
||||||
|
// "relationship": "Brother",
|
||||||
|
// "phone_number": "07055577711",
|
||||||
|
// "email": "reftwo@gmail.com",
|
||||||
|
// "bvn": "22222222222"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// disbursement:{account: '1122334456'}
|
||||||
|
// }
|
||||||
@@ -4,7 +4,7 @@ import {Formik, Form} from 'formik'
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleNextStep:()=>any
|
handleNextStep:(value:{})=>any
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
@@ -12,7 +12,8 @@ const initialValues = {
|
|||||||
address: "",
|
address: "",
|
||||||
marital_status: "",
|
marital_status: "",
|
||||||
state: "",
|
state: "",
|
||||||
email:""
|
email:"",
|
||||||
|
country:""
|
||||||
};
|
};
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
@@ -28,14 +29,15 @@ const validationSchema = Yup.object().shape({
|
|||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email("Invalid")
|
.email("Invalid")
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
|
country: Yup.string()
|
||||||
|
.required("Required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function DashboardHomeDetail({handleNextStep}:Props) {
|
export default function DashboardHomeDetail({handleNextStep}:Props) {
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values:any) => {
|
||||||
console.log(values)
|
handleNextStep(values)
|
||||||
handleNextStep()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -103,18 +105,32 @@ export default function DashboardHomeDetail({handleNextStep}:Props) {
|
|||||||
error={(props.errors.state && props.touched.state) ? props.errors.state : ''}
|
error={(props.errors.state && props.touched.state) ? props.errors.state : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<InputCompOne
|
<div className="flex items-center gap-[4.125rem]">
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
<InputCompOne
|
||||||
name="email"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
label="Email address"
|
name="email"
|
||||||
labelClass="font-bold text-[1.125rem]"
|
label="Email address"
|
||||||
input
|
labelClass="font-bold text-[1.125rem]"
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
input
|
||||||
placeholder="johndoe@gmail.com"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
value={props.values.email}
|
placeholder="johndoe@gmail.com"
|
||||||
onChange={props.handleChange}
|
value={props.values.email}
|
||||||
error={(props.errors.email && props.touched.email) ? props.errors.email : ''}
|
onChange={props.handleChange}
|
||||||
/>
|
error={(props.errors.email && props.touched.email) ? props.errors.email : ''}
|
||||||
|
/>
|
||||||
|
<InputCompOne
|
||||||
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
|
name="country"
|
||||||
|
label="Select your country"
|
||||||
|
labelClass="font-bold text-[1.125rem]"
|
||||||
|
select={true}
|
||||||
|
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
|
selectOptions={country}
|
||||||
|
selectValue={props.values.country}
|
||||||
|
onChange={props.handleChange}
|
||||||
|
error={(props.errors.country && props.touched.country) ? props.errors.country : ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<Button
|
<Button
|
||||||
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
||||||
text="Next"
|
text="Next"
|
||||||
@@ -163,4 +179,12 @@ const state: SelectOption = {
|
|||||||
{ value: "imo", label: "Imo" },
|
{ value: "imo", label: "Imo" },
|
||||||
{ value: "lagos", label: "Lagos" },
|
{ value: "lagos", label: "Lagos" },
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const country: SelectOption = {
|
||||||
|
loading: false,
|
||||||
|
data: [
|
||||||
|
{ value: "", label: "Please Select" },
|
||||||
|
{ value: "NG", label: "Nigeria" },
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -4,36 +4,36 @@ import {Formik, Form} from 'formik'
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleNextStep:()=>any
|
handleNextStep:(value:{})=>any
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
job_title: "",
|
job_title: "",
|
||||||
employer_name: "",
|
name: "",
|
||||||
job_sector: "",
|
sector: "",
|
||||||
industry: "",
|
industry: "",
|
||||||
date_of_resumption: "",
|
resumption_date: "",
|
||||||
employer_email:"",
|
email:"",
|
||||||
annual_income: "",
|
annual_income: "",
|
||||||
monthly_salary: "",
|
monthly_salary: "",
|
||||||
salary_payment_date: "",
|
salary_payment_date: "",
|
||||||
employee_id: "",
|
employment_id: "",
|
||||||
qualification: ""
|
highest_eductaion: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
job_title: Yup.string()
|
job_title: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
employer_name: Yup.string()
|
name: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
job_sector: Yup.string()
|
sector: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
industry: Yup.string()
|
industry: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
date_of_resumption: Yup.string()
|
resumption_date: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
employer_email: Yup.string()
|
email: Yup.string()
|
||||||
.email("Invalid")
|
.email("Invalid")
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
annual_income: Yup.string()
|
annual_income: Yup.string()
|
||||||
@@ -54,9 +54,9 @@ const validationSchema = Yup.object().shape({
|
|||||||
}),
|
}),
|
||||||
salary_payment_date: Yup.string()
|
salary_payment_date: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
employee_id: Yup.string()
|
employment_id: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
qualification: Yup.string()
|
highest_eductaion: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,8 +65,7 @@ export default function DashboardHomeEmploymentInfo({handleNextStep}:Props) {
|
|||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values:any) => {
|
||||||
console.log(values)
|
handleNextStep({employment: values})
|
||||||
handleNextStep()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -99,29 +98,29 @@ export default function DashboardHomeEmploymentInfo({handleNextStep}:Props) {
|
|||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="employer_name"
|
name="name"
|
||||||
floatLabel="Employer name"
|
floatLabel="Employer name"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="Mr. Mark John"
|
placeholder="Mr. Mark John"
|
||||||
value={props.values.employer_name}
|
value={props.values.name}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.employer_name && props.touched.employer_name) ? props.errors.employer_name : ''}
|
error={(props.errors.name && props.touched.name) ? props.errors.name : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-[4.125rem]">
|
<div className="flex items-center gap-[4.125rem]">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="job_sector"
|
name="sector"
|
||||||
floatLabel="Job Sector"
|
floatLabel="Job Sector"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
select={true}
|
select={true}
|
||||||
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
selectOptions={jobSector}
|
selectOptions={jobSector}
|
||||||
selectValue={props.values.job_sector}
|
selectValue={props.values.sector}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.job_sector && props.touched.job_sector) ? props.errors.job_sector : ''}
|
error={(props.errors.sector && props.touched.sector) ? props.errors.sector : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
@@ -139,28 +138,28 @@ export default function DashboardHomeEmploymentInfo({handleNextStep}:Props) {
|
|||||||
<div className="flex items-center gap-[4.125rem]">
|
<div className="flex items-center gap-[4.125rem]">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="date_of_resumption"
|
name="resumption_date"
|
||||||
floatLabel="Date of resumption"
|
floatLabel="Date of resumption"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputType='date'
|
inputType='date'
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="12/12/2015"
|
placeholder="12/12/2015"
|
||||||
value={props.values.date_of_resumption}
|
value={props.values.resumption_date}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.date_of_resumption && props.touched.date_of_resumption) ? props.errors.date_of_resumption : ''}
|
error={(props.errors.resumption_date && props.touched.resumption_date) ? props.errors.resumption_date : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="employer_email"
|
name="email"
|
||||||
floatLabel="Employers official email"
|
floatLabel="Employers official email"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="example@gmail.com"
|
placeholder="example@gmail.com"
|
||||||
value={props.values.employer_email}
|
value={props.values.email}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.employer_email && props.touched.employer_email) ? props.errors.employer_email : ''}
|
error={(props.errors.email && props.touched.email) ? props.errors.email : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-[4.125rem]">
|
<div className="flex items-center gap-[4.125rem]">
|
||||||
@@ -205,28 +204,28 @@ export default function DashboardHomeEmploymentInfo({handleNextStep}:Props) {
|
|||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="employee_id"
|
name="employment_id"
|
||||||
floatLabel="Employee ID"
|
floatLabel="Employee ID"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="LS/001/005"
|
placeholder="LS/001/005"
|
||||||
value={props.values.employee_id}
|
value={props.values.employment_id}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.employee_id && props.touched.employee_id) ? props.errors.employee_id : ''}
|
error={(props.errors.employment_id && props.touched.employment_id) ? props.errors.employment_id : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="qualification"
|
name="highest_eductaion"
|
||||||
floatLabel="Highest level of education"
|
floatLabel="Highest level of education"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
select={true}
|
select={true}
|
||||||
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
selectClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
selectOptions={qualification}
|
selectOptions={highestEductaion}
|
||||||
selectValue={props.values.qualification}
|
selectValue={props.values.highest_eductaion}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.qualification && props.touched.qualification) ? props.errors.qualification : ''}
|
error={(props.errors.highest_eductaion && props.touched.highest_eductaion) ? props.errors.highest_eductaion : ''}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
className="my-8 max-w-[25.875rem] btn-Y text-black w-full h-11"
|
||||||
@@ -266,7 +265,7 @@ const industry: SelectOption = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const qualification: SelectOption = {
|
const highestEductaion: SelectOption = {
|
||||||
loading: false,
|
loading: false,
|
||||||
data: [
|
data: [
|
||||||
{ value: "", label: "Please Select" },
|
{ value: "", label: "Please Select" },
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import {Formik, Form} from 'formik'
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleNextStep:()=>any
|
handleNextStep:(value:{})=>any
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
ref_name: "",
|
ref_name: "",
|
||||||
ref_email: "",
|
ref_email: "",
|
||||||
ref_number: "",
|
ref_phone_number: "",
|
||||||
ref_relationship: "",
|
ref_relationship: "",
|
||||||
ref_bvn: "",
|
ref_bvn: "",
|
||||||
ref_two_name: "",
|
ref_two_name: "",
|
||||||
ref_two_email: "",
|
ref_two_email: "",
|
||||||
ref_two_number: "",
|
ref_two_phone_number: "",
|
||||||
ref_two_relationship: "",
|
ref_two_relationship: "",
|
||||||
ref_two_bvn: "",
|
ref_two_bvn: "",
|
||||||
};
|
};
|
||||||
@@ -27,31 +27,60 @@ const validationSchema = Yup.object().shape({
|
|||||||
ref_email: Yup.string()
|
ref_email: Yup.string()
|
||||||
.email("Invalid")
|
.email("Invalid")
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_number: Yup.string()
|
ref_phone_number: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_relationship: Yup.string()
|
ref_relationship: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_bvn: Yup.string()
|
ref_bvn: Yup.string()
|
||||||
.required("Required"),
|
.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()
|
ref_two_name: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_two_email: Yup.string()
|
ref_two_email: Yup.string()
|
||||||
.email("Invalid")
|
.email("Invalid")
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_two_number: Yup.string()
|
ref_two_phone_number: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_two_relationship: Yup.string()
|
ref_two_relationship: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
ref_two_bvn: Yup.string()
|
ref_two_bvn: Yup.string()
|
||||||
.required("Required"),
|
.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) {
|
export default function DashboardHomeRefereeInfo({handleNextStep}:Props) {
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values:any) => {
|
||||||
console.log(values)
|
let refOne = {
|
||||||
handleNextStep()
|
fullname: values.ref_name,
|
||||||
|
relationship: values.ref_relationship,
|
||||||
|
phone_number: values.ref_phone_number,
|
||||||
|
email: values.ref_email,
|
||||||
|
bvn: values.ref_bvn
|
||||||
|
}
|
||||||
|
let refTwo = {
|
||||||
|
fullname: values.ref_two_name,
|
||||||
|
relationship: values.ref_two_relationship,
|
||||||
|
phone_number: values.ref_two_phone_number,
|
||||||
|
email: values.ref_two_email,
|
||||||
|
bvn: values.ref_two_bvn
|
||||||
|
}
|
||||||
|
handleNextStep({loan_reference:[refOne, refTwo]})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -99,15 +128,15 @@ export default function DashboardHomeRefereeInfo({handleNextStep}:Props) {
|
|||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="ref_number"
|
name="ref_phone_number"
|
||||||
floatLabel="Phone number"
|
floatLabel="Phone number"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="07000000000"
|
placeholder="07000000000"
|
||||||
value={props.values.ref_number}
|
value={props.values.ref_phone_number}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.ref_number && props.touched.ref_number) ? props.errors.ref_number : ''}
|
error={(props.errors.ref_phone_number && props.touched.ref_phone_number) ? props.errors.ref_phone_number : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
@@ -164,15 +193,15 @@ export default function DashboardHomeRefereeInfo({handleNextStep}:Props) {
|
|||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
name="ref_two_number"
|
name="ref_two_phone_number"
|
||||||
floatLabel="Phone number"
|
floatLabel="Phone number"
|
||||||
// labelClass="font-bold text-[1.125rem]"
|
// labelClass="font-bold text-[1.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
inputClass="w-full h-[3.625rem] bg-[#EFEFEF] px-4 rounded-[.375rem]"
|
||||||
placeholder="07000000000"
|
placeholder="07000000000"
|
||||||
value={props.values.ref_two_number}
|
value={props.values.ref_two_phone_number}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.ref_two_number && props.touched.ref_two_number) ? props.errors.ref_two_number : ''}
|
error={(props.errors.ref_two_phone_number && props.touched.ref_two_phone_number) ? props.errors.ref_two_phone_number : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import DebitAccount from "./DebitAccount";
|
import DebitAccount from "./DebitAccount";
|
||||||
|
|
||||||
|
|
||||||
const ApplicantsAttestation: React.FC = () => {
|
const ApplicantsAttestation: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,61 +1,87 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React from "react";
|
||||||
import InputDetails from "./IntroDetails";
|
|
||||||
import OTPSection from "./OtpSection";
|
|
||||||
import SpouseDetails from "./SpouseDetails";
|
|
||||||
import { Button } from "..";
|
|
||||||
|
|
||||||
// interface Option {
|
import { Button, InputCompOne } from "..";
|
||||||
// value: string;
|
|
||||||
// label: string;
|
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 {
|
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;
|
handleNextStep: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BasicInfo: React.FC<BasicInfoProps> = ({
|
const BasicInfo: React.FC<BasicInfoProps> = ({
|
||||||
inputValues,
|
|
||||||
setInputValues,
|
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
}) => {
|
}) => {
|
||||||
const [hideOTPComponent, setHideOTPComponent] = useState<boolean>(false);
|
// const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
|
||||||
|
|
||||||
const handleChange = (e: React.FormEvent<HTMLInputElement>) => {
|
// const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target as HTMLInputElement;
|
// const { name, value } = e.target as HTMLInputElement;
|
||||||
setInputValues((prev: typeof inputValues) => ({ ...prev, [name]: value }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
|
// if (name === "bvn") {
|
||||||
const { name, value } = e.target as HTMLInputElement;
|
// const isNumeric = /^[0-9]+$/.test(value);
|
||||||
|
|
||||||
if (name === "bvn") {
|
// if (isNumeric) {
|
||||||
const isNumeric = /^[0-9]+$/.test(value);
|
// if (value.length === 10) {
|
||||||
|
// setHideOTPComponent(false);
|
||||||
|
// } else {
|
||||||
|
// setHideOTPComponent(true);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log("Invalid BVN");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
if (isNumeric) {
|
|
||||||
if (value.length === 10) {
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
setHideOTPComponent(false);
|
const handleSubmit = (values:any) => {
|
||||||
} else {
|
console.log(values)
|
||||||
setHideOTPComponent(true);
|
handleNextStep()
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("Invalid BVN");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -64,38 +90,222 @@ const BasicInfo: React.FC<BasicInfoProps> = ({
|
|||||||
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
|
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
|
||||||
Let’s Get You Started
|
Let’s Get You Started
|
||||||
</h1>
|
</h1>
|
||||||
<form>
|
<Formik
|
||||||
<InputDetails
|
initialValues={initialValues}
|
||||||
inputValues={inputValues}
|
validationSchema={validationSchema}
|
||||||
handleChange={handleChange}
|
onSubmit={handleSubmit}
|
||||||
handleInput={handleInput}
|
>
|
||||||
inputRef={inputRef}
|
{(props)=>(
|
||||||
/>
|
<Form>
|
||||||
{!hideOTPComponent && (
|
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
|
||||||
<>
|
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
|
||||||
<OTPSection
|
BASIC INFORMATION
|
||||||
inputValues={inputValues}
|
</p>
|
||||||
handleChange={handleChange}
|
</div>
|
||||||
handleInput={handleInput}
|
<div className="mt-8 grid grid-cols-2">
|
||||||
inputRef={inputRef}
|
<div className="flex flex-col gap-4 max-w-[15.6875rem]">
|
||||||
/>
|
<InputCompOne
|
||||||
<SpouseDetails
|
parentInputClass="max-w-[224px] w-full"
|
||||||
inputValues={inputValues}
|
parentClass="max-w-[25.875rem] w-full flex flex-col gap-4"
|
||||||
handleChange={handleChange}
|
name="title"
|
||||||
handleInput={handleInput}
|
label="Title"
|
||||||
inputRef={inputRef}
|
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
||||||
/>
|
select={true}
|
||||||
<Button
|
selectClass="w-full h-[36px] rounded-[6px]"
|
||||||
className="mt-8 btn-R bg-[#5A2C82]"
|
selectOptions={titleOptions}
|
||||||
text="Enter"
|
selectValue={props.values.title}
|
||||||
type="button"
|
onChange={props.handleChange}
|
||||||
onClick={handleNextStep}
|
error={(props.errors.title && props.touched.title) ? props.errors.title : ''}
|
||||||
/>
|
/>
|
||||||
</>
|
<InputCompOne
|
||||||
)}
|
parentInputClass="max-w-[224px] w-full"
|
||||||
</form>
|
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;
|
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" },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,40 @@ import {useNavigate} from 'react-router-dom'
|
|||||||
import { Button, InputCompOne } from "..";
|
import { Button, InputCompOne } from "..";
|
||||||
import { RouteHandler } from "../../router/routes";
|
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 DebitAccount: React.FC = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
|
const handleSubmit = (values:any) => {
|
||||||
|
console.log(values)
|
||||||
|
navigate(RouteHandler.letsGetStarted, {replace:true})
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full rounded py-3 mb-9 bg-[#5C2684] px-5">
|
<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 )
|
CREDIT ACCOUNT ( Your account to receive your loan )
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<InputCompOne
|
<Formik
|
||||||
parentClass="max-w-[29.4375rem] w-full my-5 ml-5"
|
initialValues={initialValues}
|
||||||
label="Disbursement Account Number "
|
validationSchema={validationSchema}
|
||||||
name="disbursementAccountNumber"
|
onSubmit={handleSubmit}
|
||||||
labelSpan="( Your FCMB Account )"
|
>
|
||||||
labelSpanClass="text-[12px] text-[#5C2684] ml-1"
|
{(props)=>(
|
||||||
parentInputClass="w-full"
|
<Form>
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
<InputCompOne
|
||||||
input
|
parentClass="max-w-[29.4375rem] w-full my-5 ml-5"
|
||||||
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
|
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="mt-9 flex flex-col gap-9">
|
||||||
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
|
<div className="w-full rounded py-3 bg-[#5C2684] px-5">
|
||||||
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
|
<p className="text-base text-[#FBB700] tracking-[3%] font-extrabold w-fit">
|
||||||
DEBIT ACCOUNT ( Your salary account for monthly repayment )
|
DEBIT ACCOUNT ( Your salary account for monthly repayment )
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[471px] w-full ml-5"
|
parentClass="max-w-[471px] w-full ml-5"
|
||||||
label="Bank Name"
|
label="Bank Name"
|
||||||
name="bankName"
|
name="bank_name"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
|
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]">
|
<div className="flex items-center gap-[59px]">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[471px] w-full ml-5"
|
parentClass="max-w-[471px] w-full ml-5"
|
||||||
label="Account Number"
|
label="Account Number"
|
||||||
name="accountNumber"
|
name="account_number"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
|
inputClass="w-full h-[36px] bg-[#EFEFEF] rounded-[6px]"
|
||||||
/>
|
value={props.values.account_number}
|
||||||
<InputCompOne
|
onChange={props.handleChange}
|
||||||
parentClass="max-w-[471px] w-full ml-5"
|
error={(props.errors.account_number && props.touched.account_number) ? props.errors.account_number : ''}
|
||||||
label="Account Name"
|
/>
|
||||||
name="accountName"
|
<InputCompOne
|
||||||
parentInputClass="w-full"
|
parentClass="max-w-[471px] w-full ml-5"
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
label="Account Name"
|
||||||
input
|
name="account_name"
|
||||||
inputClass="w-full h-[36px] bg-[#EFEFEF] px-[2px] rounded-[6px]"
|
parentInputClass="w-full"
|
||||||
/>
|
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
||||||
</div>
|
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">
|
<div className="max-w-[578px] flex items-center">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
// checked={true}
|
// checked={true}
|
||||||
defaultChecked
|
|
||||||
// onChange={onChange}
|
name='checked'
|
||||||
className="form-checkbox h-[25px] w-[25px] rounded-sm text-[#5c2684] "
|
onChange={props.handleChange}
|
||||||
style={{ backgroundColor: "#5C2684" }}
|
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{" "}
|
<label className="ml-2 text-gray-700">
|
||||||
<span className="text-[#4545CB]">applicant's attestation</span> and
|
I have read, understood and accept the{" "}
|
||||||
all the <span className="text-[#4545CB]">terms and conditions</span>{" "}
|
<span className="text-[#4545CB]">applicant's attestation</span> and
|
||||||
for FCMB premium salary loan.
|
all the <span className="text-[#4545CB]">terms and conditions</span>{" "}
|
||||||
</label>
|
for FCMB premium salary loan.
|
||||||
</div>
|
</label>
|
||||||
<Button
|
{props.errors.checked && props.touched.checked && <span className='text-[10px] text-red-500'>{props.errors.checked}</span>}
|
||||||
className="my-8 max-w-[33.875rem] btn-R bg-[#5A2C82] w-full h-11"
|
</div>
|
||||||
text="Apply"
|
<Button
|
||||||
type="button"
|
className="my-8 max-w-[33.875rem] btn-R bg-[#5A2C82] w-full h-11"
|
||||||
onClick={()=>navigate(RouteHandler.letsGetStarted, {replace:true})}
|
text="Apply"
|
||||||
/>
|
type="submit"
|
||||||
</div>
|
/>
|
||||||
|
</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="Employer’s 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="Employer’s 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;
|
|
||||||
@@ -1,35 +1,9 @@
|
|||||||
import React from "react";
|
|
||||||
import BasicInfo from "./BasicInfo";
|
import BasicInfo from "./BasicInfo";
|
||||||
import YourAreAlmostThere from "./YourAreAlmostThere";
|
import YourAreAlmostThere from "./YourAreAlmostThere";
|
||||||
import LoanAmountComp from "./LoanAmountComp";
|
import LoanAmountComp from "./LoanAmountComp";
|
||||||
import ApplicantsAttestation from "./ApplicantsAttestation";
|
import ApplicantsAttestation from "./ApplicantsAttestation";
|
||||||
|
|
||||||
const GetStarted = ({handleNextStep, step}:{handleNextStep:any, step:string|number|any}) => {
|
const GetStarted = ({handleNextStep, step}:{handleNextStep:any, step:string|number|any}) => {
|
||||||
// const [step, setStep] = React.useState(1);
|
|
||||||
|
|
||||||
// const handleNextStep = () => {
|
|
||||||
// if (step < 5) {
|
|
||||||
// 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: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex items-center justify-center">
|
<div className="w-full flex items-center justify-center">
|
||||||
@@ -38,8 +12,6 @@ const GetStarted = ({handleNextStep, step}:{handleNextStep:any, step:string|numb
|
|||||||
<main>
|
<main>
|
||||||
{step === 2 && (
|
{step === 2 && (
|
||||||
<BasicInfo
|
<BasicInfo
|
||||||
inputValues={inputValues}
|
|
||||||
setInputValues={setInputValues}
|
|
||||||
handleNextStep={handleNextStep}
|
handleNextStep={handleNextStep}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import InputCompOne from "../shared/InputCompOne";
|
|
||||||
|
|
||||||
interface SelectOption {
|
|
||||||
loading: boolean;
|
|
||||||
data: {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: {loading: false, data:[{ 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: 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" },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,56 @@
|
|||||||
import React from "react";
|
|
||||||
import { Button, InputCompOne } from "..";
|
import { Button, InputCompOne } from "..";
|
||||||
|
|
||||||
interface SliderProps {
|
import {Formik, Form} from 'formik'
|
||||||
handleSliderChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
import * as Yup from "yup";
|
||||||
value: number;
|
|
||||||
}
|
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 {
|
interface LoanAmountProps {
|
||||||
handleNextStep: any;
|
handleNextStep: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoanAmountComp: React.FC<LoanAmountProps> = ({ handleNextStep }) => {
|
const LoanAmountComp: React.FC<LoanAmountProps> = ({ handleNextStep }) => {
|
||||||
const [value, setValue] = React.useState(6);
|
// const [value, setValue] = React.useState(6);
|
||||||
|
|
||||||
const handleSliderChange = (e: any) => {
|
// const handleSliderChange = (e: any) => {
|
||||||
setValue(e.target.value);
|
// setValue(e.target.value);
|
||||||
|
// };
|
||||||
|
|
||||||
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
|
const handleSubmit = (values:any) => {
|
||||||
|
console.log(values)
|
||||||
|
handleNextStep()
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -35,95 +71,132 @@ const LoanAmountComp: React.FC<LoanAmountProps> = ({ handleNextStep }) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-[45px] justify-center ml-[40px] mb-[40px]">
|
<Formik
|
||||||
<InputCompOne
|
initialValues={initialValues}
|
||||||
parentClass="max-w-[29.4375rem] w-full"
|
validationSchema={validationSchema}
|
||||||
label="Your Monthly Salary*"
|
onSubmit={handleSubmit}
|
||||||
name="salary"
|
>
|
||||||
parentInputClass="w-full"
|
{(props)=>(
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
<Form>
|
||||||
input
|
<div className="flex flex-col gap-[45px] justify-center ml-[40px] mb-[40px]">
|
||||||
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-4"
|
<InputCompOne
|
||||||
placeholder="150,000"
|
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]">
|
<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]">
|
<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
|
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
|
information you shared with us in your loan application. We have
|
||||||
made this offer to suit your monthly remuneration and to enable you
|
made this offer to suit your monthly remuneration and to enable you
|
||||||
pay your loan on-time
|
pay your loan on-time
|
||||||
</p>
|
</p>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="max-w-[45.8125rem] w-full mb-3"
|
parentClass="max-w-[45.8125rem] w-full mb-3"
|
||||||
label="How much do you want to apply for?"
|
label="How much do you want to apply for?"
|
||||||
name="loan"
|
name="loan_amount"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
labelClass="font-bold text-[18px] leading-[21.7808px] tracking-[2%] text-[#5C2684] mb-[2px]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-9"
|
inputClass="w-full h-[51px] bg-[#EFEFEF] rounded-[6px] placeholder:text-green-600 placeholder:font-bold px-9"
|
||||||
placeholder="350,000"
|
placeholder="350,000"
|
||||||
/>
|
value={props.values.loan_amount}
|
||||||
<div className="flex items-center justify-between w-full">
|
onChange={props.handleChange}
|
||||||
<div className=" h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
|
error={(props.errors.loan_amount && props.touched.loan_amount) ? props.errors.loan_amount : ''}
|
||||||
<span>Minimum Offer:</span>
|
/>
|
||||||
<p>
|
<div className="flex items-center justify-between w-full">
|
||||||
<b>N</b>100,000
|
<div className=" h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
|
||||||
</p>
|
<span>Minimum Offer:</span>
|
||||||
</div>
|
<p>
|
||||||
|
<b>N</b>100,000
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
|
<div className="h-[68px] flex flex-col py-1 px-[13px] shadow-md text-[#5C2684]">
|
||||||
<span>Maximum Offer:</span>
|
<span>Maximum Offer:</span>
|
||||||
<p>
|
<p>
|
||||||
<b>N</b>500,000
|
<b>N</b>500,000
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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-full flex items-center justify-center flex-col">
|
||||||
<div className="w-[279px] h-[130px] mb-[76px] 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 className="text-[#FBB700]">Your Monthly Repayment</p>
|
||||||
<p>N</p>
|
<p>N</p>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
className="max-w-[462px] w-full bg-[#5C2684] rounded h-[2.75rem]"
|
className="max-w-[462px] w-full bg-[#5C2684] rounded h-[2.75rem]"
|
||||||
text="Submit"
|
text="Submit"
|
||||||
type="button"
|
type='submit'
|
||||||
onClick={handleNextStep}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoanAmountComp;
|
export default LoanAmountComp;
|
||||||
|
|
||||||
const Slider: React.FC<SliderProps> = ({ handleSliderChange, value }) => {
|
// const Slider: React.FC<SliderProps> = ({ handleSliderChange, value }) => {
|
||||||
return (
|
// return (
|
||||||
<div className="flex flex-col items-start mt-11 mb-16">
|
// <div className="flex flex-col items-start mt-11 mb-16">
|
||||||
<p className="text-lg font-semibold">For how many months?</p>
|
// <p className="text-lg font-semibold">For how many months?</p>
|
||||||
<div className="w-full">
|
// <div className="w-full">
|
||||||
<input
|
// <input
|
||||||
type="range"
|
// type="range"
|
||||||
min="6"
|
// min="6"
|
||||||
max="24"
|
// max="24"
|
||||||
value={value}
|
// value={value}
|
||||||
onChange={handleSliderChange}
|
// onChange={handleSliderChange}
|
||||||
className="slider w-full h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer"
|
// className="slider w-full h-2 bg-gray-300 rounded-lg appearance-none cursor-pointer"
|
||||||
style={{
|
// style={{
|
||||||
background: `linear-gradient(90deg, #6B21A8 ${
|
// background: `linear-gradient(90deg, #6B21A8 ${
|
||||||
((value - 6) / 18) * 100
|
// ((value - 6) / 18) * 100
|
||||||
}%, #D1D5DB ${((value - 6) / 18) * 100}%)`,
|
// }%, #D1D5DB ${((value - 6) / 18) * 100}%)`,
|
||||||
}}
|
// }}
|
||||||
/>
|
// />
|
||||||
</div>
|
// </div>
|
||||||
<div className="mt-4 text-lg font-semibold text-gray-700 w-full flex items-center text-center justify-center">
|
// <div className="mt-4 text-lg font-semibold text-gray-700 w-full flex items-center text-center justify-center">
|
||||||
{value} months
|
// {value} months
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
|
|||||||
@@ -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;
|
|
||||||
@@ -1,29 +1,400 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
// import { useNavigate } from "react-router-dom";
|
import { Button, InputCompOne } from "..";
|
||||||
import EmploymentDetails from "./EmploymentDetails";
|
|
||||||
import ReferenceDetails from "./ReferenceDetails";
|
import {Formik, Form} from 'formik'
|
||||||
import { Button } from "..";
|
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 {
|
interface YourAreAlmostThereProps {
|
||||||
handleNextStep: any;
|
handleNextStep: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const YourAreAlmostThere: React.FC<YourAreAlmostThereProps> = ({ handleNextStep }) => {
|
const YourAreAlmostThere: React.FC<YourAreAlmostThereProps> = ({ handleNextStep }) => {
|
||||||
|
|
||||||
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
|
const handleSubmit = (values:any) => {
|
||||||
|
console.log(values)
|
||||||
|
handleNextStep()
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
|
<h1 className="font-semibold text-[2.375rem] text-[#5C2684] my-[.5rem]">
|
||||||
You’re almost there
|
You’re almost there
|
||||||
</h1>
|
</h1>
|
||||||
<form action="" className="flex flex-col gap-6">
|
<Formik
|
||||||
<EmploymentDetails />
|
initialValues={initialValues}
|
||||||
<ReferenceDetails />
|
validationSchema={validationSchema}
|
||||||
<Button
|
onSubmit={handleSubmit}
|
||||||
className="my-8 max-w-[20.3125rem] btn-R bg-[#5A2C82]"
|
>
|
||||||
text="Continue"
|
{(props)=>(
|
||||||
type="button"
|
<Form>
|
||||||
onClick={handleNextStep}
|
<div className="flex flex-col gap-6">
|
||||||
/>
|
<>
|
||||||
</form>
|
<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="Employer’s 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="Employer’s 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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const Header: React.FC<HiddenMenuItems> = ({
|
|||||||
<div className="flex flex-col-reverse lg:flex-col grow lg:grow-0 justify-between items-end">
|
<div className="flex flex-col-reverse lg:flex-col grow lg:grow-0 justify-between items-end">
|
||||||
<ul className="flex gap-0 lg:gap-[10px] items-center justify-end w-full flex-wrap">
|
<ul className="flex gap-0 lg:gap-[10px] items-center justify-end w-full flex-wrap">
|
||||||
{[
|
{[
|
||||||
{ text: "Open An Account", href: RouteHandler.getStarted },
|
{ text: "Open An Account", href: RouteHandler.letsGetStarted },
|
||||||
{
|
{
|
||||||
text: "Internet Banking",
|
text: "Internet Banking",
|
||||||
href: RouteHandler.businessBanking,
|
href: RouteHandler.businessBanking,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FaCaretDown } from "react-icons/fa";
|
import { FaCaretDown, FaCaretRight } from "react-icons/fa";
|
||||||
|
|
||||||
import dashIcon from "../../assets/images/dashboard/dashDefault.svg";
|
import dashIcon from "../../assets/images/dashboard/dashDefault.svg";
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -111,6 +111,8 @@ export default function Icons({ name, fillColor, className }: Props) {
|
|||||||
</svg>
|
</svg>
|
||||||
) :name == 'arrow-down'?
|
) :name == 'arrow-down'?
|
||||||
<FaCaretDown className={`text-xl ${className && className}`} />
|
<FaCaretDown className={`text-xl ${className && className}`} />
|
||||||
|
:name == 'arrow-right'?
|
||||||
|
<FaCaretRight className={`text-xl ${className && className}`} />
|
||||||
:name == "dash-icon" ? (
|
:name == "dash-icon" ? (
|
||||||
<img src={dashIcon} alt="dash-icon" />
|
<img src={dashIcon} alt="dash-icon" />
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -1,32 +1,42 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import * as Yup from "yup";
|
import * as Yup from 'yup';
|
||||||
import { Form, Formik } from "formik";
|
import { Form, Formik } from 'formik';
|
||||||
import { InputCompOne } from "..";
|
import { InputCompOne } from '..';
|
||||||
import {useNavigate} from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { RouteHandler } from "../../router/routes";
|
import { RouteHandler } from '../../router/routes';
|
||||||
|
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { updateUserDetails } from '../../store/UserDetails';
|
||||||
|
|
||||||
|
import { validateBVN, verifyOTP } from '../../core/apiRequest';
|
||||||
|
import { RequestStatus } from '../../core/models';
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
bvn: Yup.string()
|
bvn: Yup.string()
|
||||||
.required("BVN is required")
|
.required('BVN is required')
|
||||||
.test("no-e", "Invalid number", (value:any) => {
|
.test('no-e', 'Invalid number', (value: any) => {
|
||||||
if (value && /^[0-9]*$/.test(value) == false) {
|
if (value && /^[0-9]*$/.test(value) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.min(11, "must be 11 digits")
|
.min(11, 'must be 11 digits')
|
||||||
.max(11, "must be 11 digits"),
|
.max(11, 'must be 11 digits'),
|
||||||
otp: Yup.string()
|
otp: Yup.string()
|
||||||
.required("OTP is required")
|
// .when('require_otp', {
|
||||||
.test("no-e", "Invalid number", (value:any) => {
|
// is: true,
|
||||||
if (value && /^[0-9]*$/.test(value) == false) {
|
// then: Yup.string().required("OTP is required")
|
||||||
return false;
|
// })
|
||||||
}
|
// .required("OTP is required")
|
||||||
return true;
|
.test('no-e', 'Invalid number', (value: any) => {
|
||||||
})
|
if (value && /^[0-9]*$/.test(value) == false) {
|
||||||
.min(5, "must be 5 digits")
|
return false;
|
||||||
.max(5, "must be 5 digits"),
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.min(5, 'must be 5 digits')
|
||||||
|
.max(5, 'must be 5 digits'),
|
||||||
// .test("no-e", "must be 11 characters", (value:any) => {
|
// .test("no-e", "must be 11 characters", (value:any) => {
|
||||||
// if (value.length < 11) {
|
// if (value.length < 11) {
|
||||||
// return false;
|
// return false;
|
||||||
@@ -41,123 +51,208 @@ let initialValues = {
|
|||||||
otp: '',
|
otp: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ValidBVN = {
|
||||||
|
verification_id: string;
|
||||||
|
valid: undefined | boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const LetsGetStarted: React.FC = () => {
|
const LetsGetStarted: React.FC = () => {
|
||||||
const navigate = useNavigate()
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
// const [pinValues, setPinValues] = React.useState({
|
// const [pinValues, setPinValues] = React.useState({
|
||||||
// bvn: "",
|
// bvn: "",
|
||||||
// otp: "",
|
// otp: "",
|
||||||
// });
|
// });
|
||||||
|
// const otpInputRef = React.useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [hideOTPComponent, setHideOTPComponent] = React.useState<boolean>(true);
|
const [requestStatusBVN, setRequestStatusBVN] = React.useState<RequestStatus>(
|
||||||
const firstInputRef = React.useRef<HTMLInputElement>(null);
|
{ loading: false, status: undefined, message: '' }
|
||||||
const secondInputRef = React.useRef<HTMLInputElement>(null);
|
);
|
||||||
|
|
||||||
// const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const [requestStatusOTP, setRequestStatusOTP] = React.useState<RequestStatus>(
|
||||||
// let { name, value } = e.target as HTMLInputElement;
|
{ loading: false, status: undefined, message: '' }
|
||||||
|
);
|
||||||
|
|
||||||
// setPinValues((prev) => ({ ...prev, [name]: value }));
|
const [bvnIsValid, setBvnIsValid] = React.useState<ValidBVN>({
|
||||||
// };
|
verification_id: '',
|
||||||
|
valid: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
const handleInput = (e: React.FormEvent<HTMLInputElement>) => {
|
// e: React.FormEvent<HTMLInputElement>
|
||||||
let { name, value } = e.target as HTMLInputElement;
|
// let { value } = e.target as HTMLInputElement;
|
||||||
|
const bvnValidation = (values: any) => {
|
||||||
if (name === "bvn") {
|
// Function to Validate BVN
|
||||||
const regex = /^[0-9]+$/;
|
let bvn = values.bvn;
|
||||||
|
setRequestStatusBVN({ loading: true, status: false, message: '' });
|
||||||
if (regex.test(value)) {
|
validateBVN({ bvn })
|
||||||
if (value?.length == 11) {
|
.then((res) => {
|
||||||
setHideOTPComponent(false);
|
if (!res || !res.data.call_return) {
|
||||||
// secondInputRef.current?.focus();
|
setBvnIsValid({ verification_id: '', valid: false });
|
||||||
} else setHideOTPComponent(true);
|
setRequestStatusBVN({
|
||||||
} else {
|
loading: false,
|
||||||
console.log("object not found");
|
status: false,
|
||||||
}
|
message: 'unable to verify BVN',
|
||||||
}
|
});
|
||||||
|
return setTimeout(() => {
|
||||||
|
setRequestStatusBVN({ loading: false, status: false, message: '' });
|
||||||
|
}, 4000);
|
||||||
|
}
|
||||||
|
setBvnIsValid({
|
||||||
|
verification_id: res.data.verification_id,
|
||||||
|
valid: true,
|
||||||
|
});
|
||||||
|
setRequestStatusBVN({
|
||||||
|
loading: false,
|
||||||
|
status: true,
|
||||||
|
message: 'verified',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setBvnIsValid({ verification_id: '', valid: false });
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = (values:any) => {
|
const handleSubmit = (values: any) => {
|
||||||
console.log('values', values)
|
// Function to VERIFY OTP AND LOGIN USER
|
||||||
navigate(RouteHandler.dashboardHome, {replace:true})
|
setRequestStatusOTP({ loading: true, status: false, message: '' });
|
||||||
|
// console.log('values', values)
|
||||||
|
verifyOTP({ ...values, verification_id: bvnIsValid.verification_id })
|
||||||
|
.then((res) => {
|
||||||
|
if (!res || !res.data.call_return) {
|
||||||
|
setRequestStatusOTP({
|
||||||
|
loading: false,
|
||||||
|
status: false,
|
||||||
|
message: 'wrong otp',
|
||||||
|
});
|
||||||
|
return setTimeout(() => {
|
||||||
|
setRequestStatusOTP({ loading: false, status: false, message: '' });
|
||||||
|
}, 4000);
|
||||||
|
}
|
||||||
|
// console.log(res.data)
|
||||||
|
localStorage.setItem('token', res.data?.token);
|
||||||
|
localStorage.setItem('uid', res?.data?.customer[0]?.uid);
|
||||||
|
dispatch(updateUserDetails({ ...res?.data?.customer[0] }));
|
||||||
|
navigate(RouteHandler.dashboardHome, { replace: true });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setRequestStatusOTP({
|
||||||
|
loading: false,
|
||||||
|
status: false,
|
||||||
|
message: 'something went wrong, try again',
|
||||||
|
});
|
||||||
|
console.log(err);
|
||||||
|
return setTimeout(() => {
|
||||||
|
setRequestStatusOTP({ loading: false, status: false, message: '' });
|
||||||
|
}, 4000);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={bvnIsValid.valid ? handleSubmit : bvnValidation}
|
||||||
>
|
>
|
||||||
{(props:any) => (
|
{(props: any) => (
|
||||||
<Form className="">
|
<Form className="">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="containerMode flex justify-between gap-1 xl:gap-8 flex-col">
|
<div className="containerMode flex justify-between gap-1 xl:gap-8 flex-col">
|
||||||
<div className="my-[4rem] flex items-center justify-center w-full">
|
<div className="my-[4rem] flex items-center justify-center w-full">
|
||||||
<h1 className="font-bold text-[2.375rem] text-[#5C2684] my-[.5rem] text-center">
|
<h1 className="font-bold text-[2.375rem] text-[#5C2684] my-[.5rem] text-center">
|
||||||
Let’s Get You Started
|
Let’s Get You Started
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-auto flex flex-col gap-8 max-w-[31.625rem] ">
|
<div className="mx-auto flex flex-col gap-8 max-w-[31.625rem] ">
|
||||||
<InputCompOne
|
<div className="w-full">
|
||||||
parentClass="flex flex-col gap-2"
|
<InputCompOne
|
||||||
label="Enter Your BVN "
|
parentClass="flex flex-col gap-2"
|
||||||
name="bvn"
|
label="Enter Your BVN "
|
||||||
parentInputClass="w-full"
|
name="bvn"
|
||||||
labelSpan="( To get your BVN, dial *565*0# )"
|
parentInputClass="w-full"
|
||||||
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
|
labelSpan="( To get your BVN, dial *565*0# )"
|
||||||
placeholder="Enter your BVN"
|
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
|
||||||
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
|
placeholder="Enter your BVN"
|
||||||
input
|
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
|
||||||
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
|
input
|
||||||
value={props.values.bvn}
|
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
|
||||||
onChange={props.handleChange}
|
value={props.values.bvn}
|
||||||
onInput={handleInput}
|
onChange={props.handleChange}
|
||||||
ref={firstInputRef}
|
error={
|
||||||
maxLength={11}
|
props.errors.bvn && props.touched.bvn && props.errors.bvn
|
||||||
error={(props.errors.bvn && props.touched.bvn) && props.errors.bvn}
|
}
|
||||||
/>
|
maxLength={11}
|
||||||
{!hideOTPComponent && (
|
/>
|
||||||
<InputCompOne
|
<p
|
||||||
parentClass="flex flex-col gap-2"
|
className={`p-2 ${
|
||||||
label="Enter OTP "
|
!requestStatusBVN.status
|
||||||
name="otp"
|
? 'text-red-500'
|
||||||
parentInputClass="w-full"
|
: 'text-emerald-500'
|
||||||
labelSpan="( Please check your BVN phone number for verification pin )"
|
}`}
|
||||||
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
|
>
|
||||||
placeholder="Enter your OTP"
|
{requestStatusBVN.loading
|
||||||
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
|
? 'verifying...'
|
||||||
input
|
: requestStatusBVN.message}
|
||||||
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
|
</p>
|
||||||
value={props.values.otp}
|
</div>
|
||||||
onChange={props.handleChange}
|
{bvnIsValid.valid && (
|
||||||
onInput={handleInput}
|
<InputCompOne
|
||||||
ref={secondInputRef}
|
parentClass="flex flex-col gap-2"
|
||||||
maxLength={11}
|
label="Enter OTP "
|
||||||
error={(props.errors.otp && props.touched.otp) && props.errors.otp}
|
name="otp"
|
||||||
/>
|
parentInputClass="w-full"
|
||||||
)}
|
labelSpan="( Please check your BVN phone number for verification pin )"
|
||||||
<button
|
labelSpanClass="text-[13px] text-[#5a5a5a] font-semibold"
|
||||||
type='submit'
|
placeholder="Enter your OTP"
|
||||||
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"
|
labelClass="font-bold text-[18px] leading-[21.78px] tracking-[2%] text-[#282828] mb-[2px] flex item-center gap-[4px]"
|
||||||
disabled={!props.values.otp}
|
input
|
||||||
>
|
inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4"
|
||||||
Enter
|
value={props.values.otp}
|
||||||
</button>
|
onChange={props.handleChange}
|
||||||
|
error={
|
||||||
|
props.errors.otp && props.touched.otp && props.errors.otp
|
||||||
|
}
|
||||||
|
maxLength={5}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<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={
|
||||||
|
requestStatusBVN.loading ||
|
||||||
|
(!props.values.otp && bvnIsValid.valid)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Enter
|
||||||
|
</button>
|
||||||
|
|
||||||
{hideOTPComponent ? (
|
<p
|
||||||
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
|
className={`p-2 ${
|
||||||
***Every personal information attached to your BVN is safe and
|
!requestStatusOTP.status
|
||||||
secure. It is only important for us to verify your information and
|
? 'text-red-500'
|
||||||
also give you access to your application profile/account.
|
: 'text-emerald-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{requestStatusOTP.message}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
|
||||||
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
|
{bvnIsValid.valid || bvnIsValid.valid == undefined ? (
|
||||||
***Did not receive OTP? Click to resend
|
<p className="text-[#5C2684] mt-[1.5625rem] w-fit">
|
||||||
</p>
|
***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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Form>
|
||||||
</Form>
|
)}
|
||||||
)}
|
|
||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
import { ReactNode, useEffect, useState } from "react";
|
||||||
|
import { PendingTableList } from "../../core/models";
|
||||||
|
|
||||||
|
type PaginatedListProps = {
|
||||||
|
data: PendingTableList,
|
||||||
|
itemsPerPage?: number,
|
||||||
|
filterItem?: string[],
|
||||||
|
tableTitle?: string,
|
||||||
|
titleClass?:string,
|
||||||
|
children: (data:PendingTableList) => ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PendingList({
|
||||||
|
data,
|
||||||
|
itemsPerPage = 5,
|
||||||
|
filterItem,
|
||||||
|
tableTitle,
|
||||||
|
titleClass,
|
||||||
|
children,
|
||||||
|
}:PaginatedListProps) {
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [filteredData, setFilteredData] = useState(data);
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
const [newData, setNewData] = useState<any>([]);
|
||||||
|
|
||||||
|
const numberOfSelection = itemsPerPage;
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (currentPage != 0) {
|
||||||
|
setCurrentPage((prev) => prev - numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleNext = () => {
|
||||||
|
if (currentPage < data.length) {
|
||||||
|
setCurrentPage((prev) => prev + numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = ({ target: { value } }:{target: {value:string}}, name:string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
let newFilteredData:any = data.filter((item:any) =>
|
||||||
|
item[name].toLowerCase().startsWith(value.toLowerCase())
|
||||||
|
);
|
||||||
|
setFilteredData(newFilteredData);
|
||||||
|
setCurrentPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setNewData(
|
||||||
|
filteredData?.slice(currentPage, numberOfSelection + currentPage)
|
||||||
|
);
|
||||||
|
}, [currentPage, filteredData]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setCurrentPage(0)
|
||||||
|
},[itemsPerPage])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<h1 className={`text-2xl mb-5 font-semibold ${titleClass && titleClass}`}>{tableTitle}</h1>
|
||||||
|
|
||||||
|
{data.length > 0 && filterItem && (
|
||||||
|
<div className="mb-10 flex justify-end items-center gap-2">
|
||||||
|
{filterItem.map((item, index) => (
|
||||||
|
<label
|
||||||
|
key={index}
|
||||||
|
className="flex flex-col sm:flex-row items-center gap-2 text-slate-600 dark:text-slate-100 transition-all duration-500"
|
||||||
|
>
|
||||||
|
Search by {item[0].toUpperCase() + item.slice(1)}
|
||||||
|
<input
|
||||||
|
name={item}
|
||||||
|
type="text"
|
||||||
|
className="py-1 px-2 text-sm min-w-[100px] text-black dark:text-white bg-white dark:bg-slate-800 rounded-full border-0 outline-none ring-1 ring-slate-300 dark:ring-white transition-all duration-500"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleSearch(e, item);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{children(newData)}
|
||||||
|
|
||||||
|
{/* show prev and next button if data exist */}
|
||||||
|
{(data.length > 0 && data.length > itemsPerPage) && (
|
||||||
|
<div className="mt-5 md:mt-10 w-full flex gap-4 justify-center items-center">
|
||||||
|
<button
|
||||||
|
onClick={handlePrev}
|
||||||
|
className={`w-6 h-6 md:w-12 md:h-12 text-sm md:text-lg rounded-full flex justify-center items-center transition-all duration-300 ${
|
||||||
|
currentPage == 0
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{data.length && data.map((item, index)=>{
|
||||||
|
item = item
|
||||||
|
if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`w-6 h-6 md:w-12 md:h-12 text-sm md:text-lg rounded-full flex justify-center items-center border transition-all duration-300 ${
|
||||||
|
currentPage != index
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white pointer-events-none"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{index/itemsPerPage +1}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`w-6 h-6 md:w-12 md:h-12 text-sm md:text-lg rounded-full flex justify-center items-center transition-all duration-300 ${
|
||||||
|
currentPage + numberOfSelection >= data.length
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pointer-events-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ const InputCompOne = forwardRef<HTMLInputElement, InputCompOneProps>(
|
|||||||
return (
|
return (
|
||||||
<div className={parentClass}>
|
<div className={parentClass}>
|
||||||
{label && (
|
{label && (
|
||||||
<label htmlFor={label ? label : floatLabel} className={`flex gap-2 items-center ${labelClass}`}>
|
<label htmlFor={label ? label : floatLabel} className={`flex gap-2 items-center flex-wrap ${labelClass}`}>
|
||||||
{label}
|
{label}
|
||||||
{labelSpan && <span className={labelSpanClass}>{labelSpan}</span>}
|
{labelSpan && <span className={labelSpanClass}>{labelSpan}</span>}
|
||||||
{error && label && <span className='text-[10px] text-red-500'>{error}</span>}
|
{error && label && <span className='text-[10px] text-red-500'>{error}</span>}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const Stepper: React.FC<StepperProps> = ({ step = 0 }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-between items-center gap-5">
|
<div className="flex justify-between items-center gap-5">
|
||||||
{[...Array(6)].map((_, index) => (
|
{[...Array(5)].map((_, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`w-[1.875rem] border-[.1875rem] rounded-sm ${(step === index
|
className={`w-[1.875rem] border-[.1875rem] rounded-sm ${(step === index
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { postAuxEnd, getAuxEnd } from "./axiosCall";
|
||||||
|
|
||||||
|
// FUNCTION TO START BVN VALIDATION
|
||||||
|
export const validateBVN = (postData:any) => {
|
||||||
|
let reqData = {
|
||||||
|
...postData
|
||||||
|
}
|
||||||
|
return postAuxEnd('/bvn', reqData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTION TO VERIFY OTP AND LOGIN
|
||||||
|
export const verifyOTP = (postData:any) => {
|
||||||
|
let reqData = {
|
||||||
|
...postData
|
||||||
|
}
|
||||||
|
return postAuxEnd('/bvn/verify', reqData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO APPLY FOR LOAN
|
||||||
|
export const applyForLoan = (postData:any) => {
|
||||||
|
let reqData = {
|
||||||
|
customer_uid: localStorage.getItem('uid'),
|
||||||
|
...postData
|
||||||
|
}
|
||||||
|
return postAuxEnd('/loan/apply', reqData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET USER BY CUSTOMER UID
|
||||||
|
export const getUserByID = (uid:string) => {
|
||||||
|
let reqData = {
|
||||||
|
// customer_uid: localStorage.getItem('uid'),
|
||||||
|
}
|
||||||
|
return getAuxEnd(`/profile?uid=${uid}`, reqData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION TO GET USER BY CUSTOMER UID
|
||||||
|
export const getUserPendingLoanList = (uid:string) => {
|
||||||
|
let reqData = {
|
||||||
|
// customer_uid: localStorage.getItem('uid'),
|
||||||
|
}
|
||||||
|
return getAuxEnd(`/dash?uid=${uid}`, reqData)
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export function postAuxEnd(uri: string, reqData: any): Promise<any> {
|
||||||
|
const endPoint = import.meta.env.VITE_USERS_ENDPOINT + uri;
|
||||||
|
const formData = new FormData();
|
||||||
|
for (let value in reqData) {
|
||||||
|
if (typeof reqData[value] === "object") {
|
||||||
|
// for (let innerValue in reqData[value]) {
|
||||||
|
// let innerReqData = reqData[value]
|
||||||
|
// console.log('SAMPLE',innerReqData)
|
||||||
|
// formData.append(reqData[value][innerValue], reqData[value][innerValue]);
|
||||||
|
// }
|
||||||
|
// formData.append(value, JSON.stringify(reqData[value]));
|
||||||
|
formData.append(value, reqData[value]);
|
||||||
|
} else {
|
||||||
|
formData.append(value, reqData[value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return axios
|
||||||
|
.post(endPoint, formData)
|
||||||
|
.then((response: {}) => {
|
||||||
|
// if (response.data.internal_return == "-9999") {
|
||||||
|
// localStorage.clear();
|
||||||
|
// window.location.href = `/login?sessionExpired=true`;
|
||||||
|
// }
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
if (error.response) {
|
||||||
|
//response status is an error code
|
||||||
|
console.log(
|
||||||
|
"ERROR-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
console.log(error.response.status);
|
||||||
|
console.log(
|
||||||
|
"ERROR-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
} else if (error.request) {
|
||||||
|
//response not received though the request was sent
|
||||||
|
console.log(
|
||||||
|
"ERROR2-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
console.log(error?.request);
|
||||||
|
console.log(
|
||||||
|
"ERROR2-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//an error occurred when setting up the request
|
||||||
|
console.log(
|
||||||
|
"ERROR3-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
console.log(error);
|
||||||
|
console.log(
|
||||||
|
"ERROR3-------------------------------------------------------"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getAuxEnd(uri: string, reqData: any): Promise<any> {
|
||||||
|
const endPoint = import.meta.env.VITE_USERS_ENDPOINT + uri;
|
||||||
|
const formData = new FormData();
|
||||||
|
for (let value in reqData) {
|
||||||
|
formData.append(value, reqData[value]);
|
||||||
|
}
|
||||||
|
return axios
|
||||||
|
.get(endPoint, reqData)
|
||||||
|
.then((response: {}) => {
|
||||||
|
// if (response.data.internal_return == "-9999") {
|
||||||
|
// localStorage.clear();
|
||||||
|
// window.location.href = `/login?sessionExpired=true`;
|
||||||
|
// }
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
console.log(
|
||||||
|
"ERROR3-------------------------------------------------------", error
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
export interface RequestStatus {
|
||||||
|
loading?:boolean
|
||||||
|
status?:boolean | undefined
|
||||||
|
message?:string
|
||||||
|
name?:string
|
||||||
|
data?:{}[] | [any] | {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
firstname?:string
|
||||||
|
lastname?:string
|
||||||
|
last_login?:string
|
||||||
|
message?:string
|
||||||
|
token?:string
|
||||||
|
customer_uid?:string
|
||||||
|
call_return?:string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type PendingTableList = {
|
||||||
|
status?: string | boolean;
|
||||||
|
application_uid?: string
|
||||||
|
added?: string
|
||||||
|
loan_amount?: string
|
||||||
|
payment_month?: string
|
||||||
|
}[];
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
import Logo from "../../assets/icons/logo.svg";
|
import Logo from "../../assets/icons/logo.svg";
|
||||||
import { Icons } from "../../components";
|
import { Icons } from "../../components";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
asideDisplay?: () => void;
|
asideDisplay?: () => void;
|
||||||
|
logoutUser: () => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Aside({ asideDisplay }: Props) {
|
export default function Aside({ asideDisplay, logoutUser }: Props) {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const [openNestedLink, setOpenNestedLink] = useState<{ name: string | null }>(
|
const [openNestedLink, setOpenNestedLink] = useState<{ name: string | null }>(
|
||||||
{ name: "" }
|
{ name: "" }
|
||||||
);
|
);
|
||||||
@@ -115,7 +114,7 @@ export default function Aside({ asideDisplay }: Props) {
|
|||||||
<div className="w-full flex justify-center items-center flex-col gap-3">
|
<div className="w-full flex justify-center items-center flex-col gap-3">
|
||||||
<button
|
<button
|
||||||
className="py-3 px-6 bg-red-100 text-red-500 font-medium rounded-md w-full"
|
className="py-3 px-6 bg-red-100 text-red-500 font-medium rounded-md w-full"
|
||||||
onClick={() => navigate("/login", { replace: true })}
|
onClick={() => logoutUser()}
|
||||||
>
|
>
|
||||||
Log out
|
Log out
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,11 +1,61 @@
|
|||||||
|
|
||||||
|
import {useState, useEffect} from 'react'
|
||||||
import DashboardLayout from "./DashboardLayout";
|
import DashboardLayout from "./DashboardLayout";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet, useNavigate } from "react-router-dom";
|
||||||
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
|
import { RouteHandler } from '../../router/routes';
|
||||||
|
import { updateUserDetails } from '../../store/UserDetails';
|
||||||
|
import { getUserByID } from '../../core/apiRequest';
|
||||||
|
|
||||||
|
import Logo from '../../assets/images/logo.png'
|
||||||
|
|
||||||
export default function DashboardAuth() {
|
export default function DashboardAuth() {
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
const { userDetails } = useSelector((state:any) => state?.userDetails); // CHECKS IF USER Details are avaliable
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
let token = localStorage.getItem('token')
|
||||||
|
let uid = localStorage.getItem('uid')
|
||||||
|
if(!token || !uid){
|
||||||
|
navigate(RouteHandler.letsGetStarted, {replace:true})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const getUser = () => { // FUNCTION TO GET USER BY ID
|
||||||
|
// let data = {firstname:'firstname', lastname:'lastname', uid:'28273737646466464'}
|
||||||
|
getUserByID(uid).then(res=>{
|
||||||
|
if(!res.data.call_return || !Object.keys(res.data.customer).length){
|
||||||
|
navigate(RouteHandler.letsGetStarted, {replace:true})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setLoading(false)
|
||||||
|
dispatch(updateUserDetails(res.data.customer));
|
||||||
|
}).catch(err=>{
|
||||||
|
navigate(RouteHandler.letsGetStarted, {replace:true})
|
||||||
|
console.log('USER ERROR', err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(!Object.keys(userDetails).length){
|
||||||
|
getUser()
|
||||||
|
}
|
||||||
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardLayout>
|
<>
|
||||||
<Outlet />
|
{loading && !Object.keys(userDetails).length ?
|
||||||
</DashboardLayout>
|
<div className='w-full h-screen flex flex-col justify-center items-center gap-4'>
|
||||||
|
<img className='animate-pulse' src={Logo} alt='Logo' />
|
||||||
|
<p className='animate-pulse'>loading...</p>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<DashboardLayout>
|
||||||
|
<Outlet />
|
||||||
|
</DashboardLayout>
|
||||||
|
}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
import { ReactNode, useState, useEffect } from "react";
|
import { ReactNode, useState, useEffect } from "react";
|
||||||
|
import { RouteHandler } from "../../router/routes";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import Aside from "./Aside";
|
import Aside from "./Aside";
|
||||||
|
|
||||||
export default function DashboardLayout({ children }: { children: ReactNode }) {
|
export default function DashboardLayout({ children }: { children: ReactNode }) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [showAside, setShowAside] = useState<boolean>(false);
|
const [showAside, setShowAside] = useState<boolean>(false);
|
||||||
const asideDisplay = (): void => {
|
const asideDisplay = (): void => {
|
||||||
setShowAside((prev) => !prev);
|
setShowAside((prev) => !prev);
|
||||||
@@ -30,17 +34,22 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
|
|||||||
// return child;
|
// return child;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
const logoutUser = () => {
|
||||||
|
localStorage.clear()
|
||||||
|
navigate(RouteHandler.letsGetStarted, {replace:true})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-[2000px] mx-auto h-screen flex bg-[#020202] text-black">
|
<div className="w-full max-w-[2000px] mx-auto h-screen flex bg-[#020202] text-black">
|
||||||
<aside className="max-w-[18.75rem] w-full bg-white hidden md:block border-r-2 border-[#E6E6E6]">
|
<aside className="max-w-[18.75rem] w-full bg-white hidden md:block border-r-2 border-[#E6E6E6]">
|
||||||
<Aside />
|
<Aside logoutUser={logoutUser} />
|
||||||
</aside>
|
</aside>
|
||||||
<aside
|
<aside
|
||||||
className={`max-w-[18.75rem] w-full md:hidden bg-white border-r-2 border-[#E6E6E6] fixed top-0 bottom-0 z-50 transition-all duration-500 ${
|
className={`max-w-[18.75rem] w-full md:hidden bg-white border-r-2 border-[#E6E6E6] fixed top-0 bottom-0 z-50 transition-all duration-500 ${
|
||||||
showAside ? "left-0" : "-left-[200%]"
|
showAside ? "left-0" : "-left-[200%]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Aside asideDisplay={asideDisplay} />
|
<Aside logoutUser={logoutUser} asideDisplay={asideDisplay} />
|
||||||
</aside>
|
</aside>
|
||||||
<main className="dash-bg-image bg-[#F9F9F9] relative w-full overflow-y-auto overflow-x-hidden">
|
<main className="dash-bg-image bg-[#F9F9F9] relative w-full overflow-y-auto overflow-x-hidden">
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface GetStartedLayoutProps {
|
|||||||
const GetStartedLayout: React.FC<GetStartedLayoutProps> = ({ children }) => {
|
const GetStartedLayout: React.FC<GetStartedLayoutProps> = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<div className="containerMode mb-[5.4375rem]">
|
<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} />
|
<Header hideSidebar={true} hideMenu={true} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col min-h-[70vh] justify-between">
|
<div className="flex flex-col min-h-[70vh] justify-between">
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
export function NewDateTimeFormatter(isoDateString:any, addHour = true) {
|
||||||
|
const date = new Date(isoDateString);
|
||||||
|
if (addHour) {
|
||||||
|
date.setTime(date.getTime() + 1 * 60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
const formattedDate = date.toLocaleDateString("en-US", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "numeric",
|
||||||
|
day: "numeric",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
// second: "2-digit",
|
||||||
|
hour12: true,
|
||||||
|
timeZone: "UTC",
|
||||||
|
});
|
||||||
|
return formattedDate;
|
||||||
|
}
|
||||||
+6
-1
@@ -4,10 +4,15 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import App from "./App.tsx";
|
import App from "./App.tsx";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import store from "./store/store";
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<Provider store={store}>
|
||||||
|
<App />
|
||||||
|
</Provider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
userDetails: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const userSlice = createSlice({
|
||||||
|
name: "userDetails",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
updateUserDetails: (state, action) => {
|
||||||
|
state.userDetails = { ...action.payload };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action creators are generated for each case reducer function
|
||||||
|
export const { updateUserDetails } = userSlice.actions;
|
||||||
|
|
||||||
|
export default userSlice.reducer;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
import userDetailReducer from "./UserDetails";
|
||||||
|
|
||||||
|
export default configureStore({
|
||||||
|
reducer: {
|
||||||
|
userDetails: userDetailReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user