Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8abee4eb25 | |||
| 1d6960c31e | |||
| b93604162e | |||
| 56acd6414a |
@@ -6,50 +6,44 @@ import {Formik, Form} from 'formik'
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
title: "",
|
salary_acct: "",
|
||||||
marital_status: "",
|
confirm_salary_acct: false,
|
||||||
agent_id: "",
|
qualification: "",
|
||||||
bvn: "",
|
doe: "",
|
||||||
first_name: "",
|
gl: "",
|
||||||
phone: "",
|
ippis: "",
|
||||||
email: "",
|
employer_name: "",
|
||||||
surname: "",
|
designation: "",
|
||||||
dob: "",
|
|
||||||
second_name: "",
|
|
||||||
spouse_bvn: "",
|
|
||||||
checked: false
|
checked: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// To get the validation schema
|
// To get the validation schema
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
title: Yup.string()
|
salary_acct: Yup.string()
|
||||||
.required("Required"),
|
.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) => {
|
.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(10, "must be 10 digits")
|
||||||
.max(11, "must be 11 digits"),
|
.max(10, "must be 10 digits"),
|
||||||
first_name: Yup.string()
|
confirm_salary_acct: Yup.bool() // use bool instead of boolean
|
||||||
|
.oneOf([true], "You must check the box"),
|
||||||
|
qualification: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
phone: Yup.string()
|
doe: Yup.string()
|
||||||
|
.required("BVN is required"),
|
||||||
|
gl: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
email: Yup.string()
|
ippis: Yup.string(),
|
||||||
.required("Required")
|
employer_name: Yup.string()
|
||||||
.email("Wrong email format"),
|
|
||||||
surname: Yup.string()
|
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
dob: Yup.string()
|
designation: Yup.string()
|
||||||
.required("Required"),
|
.required("Required"),
|
||||||
checked: Yup.bool(),
|
checked: Yup.bool() // use bool instead of boolean
|
||||||
|
.oneOf([true], "You must accept that the information here is correct"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -103,27 +97,30 @@ const EmployerValidation: React.FC= () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full my-10">
|
<div className="w-full my-10">
|
||||||
<p className="mb-1 text-[12px] font-bold">Confirms Employee's salary account number</p>
|
<p className="mb-1 text-[12px] font-bold flex items-center gap-4">Confirms Employee's salary account number
|
||||||
|
{(props.errors.salary_acct && props.touched.salary_acct) && <span className='text-[10px] text-red-500'>{props.errors.salary_acct}</span> }
|
||||||
|
</p>
|
||||||
<div className="w-full flex items-center gap-8">
|
<div className="w-full flex items-center gap-8">
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full max-w-[25rem]"
|
parentClass="w-full max-w-[25rem]"
|
||||||
// label="First Name"
|
// label="First Name"
|
||||||
name="first_name"
|
name="salary_acct"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
||||||
value={props.values.first_name}
|
value={props.values.first_name}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.first_name && props.touched.first_name) ? props.errors.first_name : ''}
|
// error={(props.errors.first_name && props.touched.first_name) ? props.errors.first_name : ''}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
name="checked"
|
name="confirm_salary_acct"
|
||||||
className='w-6 h-6 p-2 accent-purple-600 text-purple-600 bg-gray-100 border-gray-300 rounded-lg focus:ring-purple-500'
|
className='w-6 h-6 p-2 accent-purple-600 text-purple-600 bg-gray-100 border-gray-300 rounded-lg focus:ring-purple-500'
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{(props.errors.confirm_salary_acct && props.touched.confirm_salary_acct) && <span className='text-[10px] text-red-500'>{props.errors.confirm_salary_acct}</span> }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="my-10">
|
<div className="my-10">
|
||||||
@@ -146,7 +143,7 @@ const EmployerValidation: React.FC= () => {
|
|||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
name="title"
|
name="qualification"
|
||||||
label="Applicant's Educational Qualification"
|
label="Applicant's Educational Qualification"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
labelSpan={`(Please select the emplyee's highest qualification)`}
|
labelSpan={`(Please select the emplyee's highest qualification)`}
|
||||||
@@ -154,22 +151,22 @@ const EmployerValidation: React.FC= () => {
|
|||||||
select={true}
|
select={true}
|
||||||
selectClass="w-full h-[36px] rounded-[6px]"
|
selectClass="w-full h-[36px] rounded-[6px]"
|
||||||
selectOptions={titleOptions}
|
selectOptions={titleOptions}
|
||||||
selectValue={props.values.title}
|
selectValue={props.values.qualification}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.title && props.touched.title) ? props.errors.title : ''}
|
error={(props.errors.qualification && props.touched.qualification) ? props.errors.qualification : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
label="Applicant's Date of Employment"
|
label="Applicant's Date of Employment"
|
||||||
name="dob"
|
name="doe"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
input
|
input
|
||||||
inputType='date'
|
inputType='date'
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem] px-3"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem] px-3"
|
||||||
value={props.values.dob}
|
value={props.values.doe}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.dob && props.touched.dob) ? props.errors.dob : ''}
|
error={(props.errors.doe && props.touched.doe) ? props.errors.doe : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -178,26 +175,26 @@ const EmployerValidation: React.FC= () => {
|
|||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
label="Applicant's Grade Level"
|
label="Applicant's Grade Level"
|
||||||
name="first_name"
|
name="gl"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
||||||
value={props.values.first_name}
|
value={props.values.gl}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.first_name && props.touched.first_name) ? props.errors.first_name : ''}
|
error={(props.errors.gl && props.touched.gl) ? props.errors.gl : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
label="Applicant's IPPIS Number (optional)"
|
label="Applicant's IPPIS Number (optional)"
|
||||||
name="phone"
|
name="ippis"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
||||||
value={props.values.phone}
|
value={props.values.ippis}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.phone && props.touched.phone) ? props.errors.phone : ''}
|
error={(props.errors.ippis && props.touched.ippis) ? props.errors.ippis : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -219,30 +216,30 @@ const EmployerValidation: React.FC= () => {
|
|||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
label="Employer's Name"
|
label="Employer's Name"
|
||||||
name="first_name"
|
name="employer_name"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
labelSpan={`(your full name)`}
|
labelSpan={`(your full name)`}
|
||||||
labelSpanClass='text-[10px]'
|
labelSpanClass='text-[10px]'
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
||||||
value={props.values.first_name}
|
value={props.values.employer_name}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.first_name && props.touched.first_name) ? props.errors.first_name : ''}
|
error={(props.errors.employer_name && props.touched.employer_name) ? props.errors.employer_name : ''}
|
||||||
/>
|
/>
|
||||||
<InputCompOne
|
<InputCompOne
|
||||||
parentClass="w-full md:max-w-[25rem]"
|
parentClass="w-full md:max-w-[25rem]"
|
||||||
label="Desgination"
|
label="Designation"
|
||||||
name="phone"
|
name="designation"
|
||||||
parentInputClass="w-full"
|
parentInputClass="w-full"
|
||||||
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
labelClass="font-bold text-base md:text-[1.125rem] leading-[1.3613rem] tracking-[2%] text-[#5C2684] mb-[.125rem]"
|
||||||
labelSpan={`(your position)`}
|
labelSpan={`(your position)`}
|
||||||
labelSpanClass='text-[10px]'
|
labelSpanClass='text-[10px]'
|
||||||
input
|
input
|
||||||
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
inputClass="w-full h-[2.25rem] bg-[#EFEFEF] rounded-[.375rem]"
|
||||||
value={props.values.phone}
|
value={props.values.designation}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
error={(props.errors.phone && props.touched.phone) ? props.errors.phone : ''}
|
error={(props.errors.designation && props.touched.designation) ? props.errors.designation : ''}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Button, CustomSpinner, FloatLabelInput } from "..";
|
import { Button, CustomSpinner, FloatLabelInput } from "..";
|
||||||
import CustomModal from "../modal/CustomModal";
|
import CustomModal from "../modal/CustomModal";
|
||||||
import { useNavigate, useLocation } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
import { RouteHandler } from "../../router/routes";
|
import { RouteHandler } from "../../router/routes";
|
||||||
import { RequestStatus } from "../../core/models";
|
import { RequestStatus } from "../../core/models";
|
||||||
import { employerLogin } from "../../core/apiRequest";
|
import { employerLogin } from "../../core/apiRequest";
|
||||||
|
import ErrorMsg from "../shared/ErrorMsg";
|
||||||
|
|
||||||
|
|
||||||
type FormType = {
|
type FormType = {
|
||||||
@@ -23,6 +24,7 @@ export default function Login() {
|
|||||||
const {state} = useLocation()
|
const {state} = useLocation()
|
||||||
|
|
||||||
const [modal, setModal] = useState<boolean>(false)
|
const [modal, setModal] = useState<boolean>(false)
|
||||||
|
const [expiredLinkModal, setExpiredLinkModal] = useState<boolean>(false)
|
||||||
|
|
||||||
const [requestStatus, setRequestStatus] = useState<RequestStatus>({loading:false, status:null, message:'', data:{}})
|
const [requestStatus, setRequestStatus] = useState<RequestStatus>({loading:false, status:null, message:'', data:{}})
|
||||||
|
|
||||||
@@ -50,7 +52,7 @@ export default function Login() {
|
|||||||
employerLogin(reqData).then(res => {
|
employerLogin(reqData).then(res => {
|
||||||
// console.log('RES', res)
|
// console.log('RES', res)
|
||||||
if(!res?.data?.call_return){
|
if(!res?.data?.call_return){
|
||||||
setRequestStatus({loading:false, status:false, message:'Email/Password is wrong', data:{}})
|
setRequestStatus({loading:false, status:false, message:res?.data?.status_message || 'Invalid Details', data:{}})
|
||||||
return setTimeout(()=>{
|
return setTimeout(()=>{
|
||||||
setRequestStatus({loading:false, status:null, message:'', data:{}})
|
setRequestStatus({loading:false, status:null, message:'', data:{}})
|
||||||
},4000)
|
},4000)
|
||||||
@@ -66,6 +68,12 @@ export default function Login() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(!state?.application_uid){
|
||||||
|
setExpiredLinkModal(true)
|
||||||
|
}
|
||||||
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`w-full overflow-y-auto bg-top bg-cover`}>
|
<div className={`w-full overflow-y-auto bg-top bg-cover`}>
|
||||||
@@ -73,57 +81,70 @@ export default function Login() {
|
|||||||
<div className="w-full md:max-w-[570px]">
|
<div className="w-full md:max-w-[570px]">
|
||||||
<div className="bg-white w-full rounded-2xl border-2 border-black">
|
<div className="bg-white w-full rounded-2xl border-2 border-black">
|
||||||
<div className="w-full p-5 sm:p-10 lg:p-20 flex flex-col justify-between items-center h-full">
|
<div className="w-full p-5 sm:p-10 lg:p-20 flex flex-col justify-between items-center h-full">
|
||||||
<div className="mb-4">
|
{expiredLinkModal &&
|
||||||
<h1 className="text-2xl text-center font-bold leading-3 tracking-wide text-black dark:text-black">
|
<p className="text-xl mb-4 text-center font-medium text-red-500 dark:text-black">
|
||||||
Welcome!
|
Invalid Link, Please proceed to your email and click on the link to continue
|
||||||
</h1>
|
|
||||||
<p className="text-xl mt-4 text-center font-medium text-black dark:text-black">
|
|
||||||
Please login with your email and default password provided to you
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
}
|
||||||
|
<div className={`${expiredLinkModal && 'hidden'} w-full`}>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h1 className="text-2xl text-center font-bold leading-3 tracking-wide text-black dark:text-black">
|
||||||
|
Welcome!
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl mt-4 text-center font-medium text-black dark:text-black">
|
||||||
|
Please login with your email and default password provided to you
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="w-full">
|
|
||||||
{/* INPUTS */}
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="relative my-2 py-2">
|
{/* INPUTS */}
|
||||||
<FloatLabelInput
|
<div className="w-full">
|
||||||
id="email"
|
<div className="relative my-2 py-2">
|
||||||
name="email"
|
<FloatLabelInput
|
||||||
type="email"
|
id="email"
|
||||||
placeHolder="Email"
|
name="email"
|
||||||
labelName="Email"
|
type="email"
|
||||||
value={formDetails.email}
|
placeHolder="Email"
|
||||||
inputClass=""
|
labelName="Email"
|
||||||
onChange={handleFormChange}
|
value={formDetails.email}
|
||||||
/>
|
inputClass=""
|
||||||
|
onChange={handleFormChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative my-2 py-2">
|
||||||
|
<FloatLabelInput
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
placeHolder="Password"
|
||||||
|
labelName="Password"
|
||||||
|
value={formDetails.password}
|
||||||
|
inputClass=""
|
||||||
|
onChange={handleFormChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative my-2 py-2">
|
|
||||||
<FloatLabelInput
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
placeHolder="Password"
|
|
||||||
labelName="Password"
|
|
||||||
value={formDetails.password}
|
|
||||||
inputClass=""
|
|
||||||
onChange={handleFormChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-10 w-full flex items-center gap-2">
|
<div className="mt-10 w-full flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
text="Enter"
|
text="Enter"
|
||||||
className="rounded-md w-full sm:w-2/5 text-xl capitalize font-bold"
|
className="rounded-md w-full sm:w-2/5 text-xl capitalize font-bold"
|
||||||
onClick={loginFxn}
|
onClick={loginFxn}
|
||||||
disabled={!formDetails.password || !formDetails.email || requestStatus.loading}
|
disabled={!formDetails.password || !formDetails.email || requestStatus.loading}
|
||||||
/>
|
/>
|
||||||
{requestStatus.loading &&
|
{requestStatus.loading &&
|
||||||
<CustomSpinner />
|
<CustomSpinner />
|
||||||
}
|
}
|
||||||
{/* <Link to='' className='text-black text-sm'>Forget your password?</Link> */}
|
{/* <Link to='' className='text-black text-sm'>Forget your password?</Link> */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='w-full'>
|
||||||
|
<ErrorMsg
|
||||||
|
message={requestStatus.message}
|
||||||
|
status={requestStatus.status}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,7 +157,7 @@ export default function Login() {
|
|||||||
<div className="px-5 md:px-10 w-full flex justify-end">
|
<div className="px-5 md:px-10 w-full flex justify-end">
|
||||||
<button
|
<button
|
||||||
className="font-bold text-[11px] lg:text-[13px] text-[#5A2C82]"
|
className="font-bold text-[11px] lg:text-[13px] text-[#5A2C82]"
|
||||||
onClick={()=>{navigate(RouteHandler.otppage, { state: {verify_uid: requestStatus?.data?.verify_uid, application_uid: requestStatus?.data?.records?.application_uid }, replace:true })}}
|
onClick={()=>{navigate(RouteHandler.otppage, { state: {verify_uid: requestStatus?.data?.verify_uid, application_uid: state?.application_uid }, replace:true })}}
|
||||||
>
|
>
|
||||||
Ok
|
Ok
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Button, CustomSpinner } from "..";
|
import { Button, CustomSpinner } from "..";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { RouteHandler } from "../../router/routes";
|
import { RouteHandler } from "../../router/routes";
|
||||||
@@ -6,6 +6,7 @@ import { updateUserDetails } from "../../store/UserDetails";
|
|||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { verifyOTP } from "../../core/apiRequest";
|
import { verifyOTP } from "../../core/apiRequest";
|
||||||
import { RequestStatus } from "../../core/models";
|
import { RequestStatus } from "../../core/models";
|
||||||
|
import ErrorMsg from "../shared/ErrorMsg";
|
||||||
|
|
||||||
type FormType = {
|
type FormType = {
|
||||||
[index: string] : string
|
[index: string] : string
|
||||||
@@ -38,6 +39,23 @@ export default function Login() {
|
|||||||
setValues((prev:FormType) => ({ ...prev, [name]: value }));
|
setValues((prev:FormType) => ({ ...prev, [name]: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (e.key === "Backspace") {
|
||||||
|
const { name } = e.target as HTMLInputElement;
|
||||||
|
if(values[name]){
|
||||||
|
setValues((prev: FormType) => ({ ...prev, [name]: "" }));
|
||||||
|
}else{
|
||||||
|
const keys = Object.keys(values)
|
||||||
|
for(let i=keys.length-1; i>=0; i--){
|
||||||
|
if(values[keys[i]]){
|
||||||
|
setValues((prev: FormType) => ({ ...prev, [keys[i]]: "" }));
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
let reqData = {
|
let reqData = {
|
||||||
verify_uid: state?.verify_uid,
|
verify_uid: state?.verify_uid,
|
||||||
@@ -110,6 +128,7 @@ export default function Login() {
|
|||||||
value={values.otp1}
|
value={values.otp1}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
maxLength={1}
|
maxLength={1}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id='otp2'
|
id='otp2'
|
||||||
@@ -120,6 +139,7 @@ export default function Login() {
|
|||||||
value={values.otp2}
|
value={values.otp2}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
maxLength={1}
|
maxLength={1}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id='otp3'
|
id='otp3'
|
||||||
@@ -130,6 +150,7 @@ export default function Login() {
|
|||||||
value={values.otp3}
|
value={values.otp3}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
maxLength={1}
|
maxLength={1}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id='otp4'
|
id='otp4'
|
||||||
@@ -140,6 +161,7 @@ export default function Login() {
|
|||||||
value={values.otp4}
|
value={values.otp4}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
maxLength={1}
|
maxLength={1}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -159,6 +181,13 @@ export default function Login() {
|
|||||||
{/* <Link to='#' className='text-black text-sm'>Forget your password?</Link> */}
|
{/* <Link to='#' className='text-black text-sm'>Forget your password?</Link> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='w-full'>
|
||||||
|
<ErrorMsg
|
||||||
|
message={requestStatus.message}
|
||||||
|
status={requestStatus.status}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
size?: string
|
width?: string
|
||||||
|
height?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CustomSpinner({size='8'}:Props) {
|
export default function CustomSpinner({width='w-6', height='h-6'}:Props) {
|
||||||
let width = `w-${size}`
|
|
||||||
let height = `h-${size}`
|
|
||||||
return (
|
return (
|
||||||
<div role="status">
|
<div role="status">
|
||||||
<svg aria-hidden="true" className={`inline ${width} ${height} text-gray-200 animate-spin dark:text-gray-600 fill-blue-600`} viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg aria-hidden="true" className={`inline ${width} ${height} text-gray-200 animate-spin dark:text-gray-600 fill-blue-600`} viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
type Error = {
|
||||||
|
message?: string
|
||||||
|
status?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ErrorMsg({message, status}:Error) {
|
||||||
|
return (
|
||||||
|
<div className={`${!message && 'hidden'} w-full`}>
|
||||||
|
<p className={`${status ? 'text-green-600' : 'text-red-500'} pt-2 text-base text-center`}>
|
||||||
|
{message && message}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -45,6 +45,10 @@ export default function DashboardAuth() {
|
|||||||
navigate(RouteHandler.loginpage, {state:{application_uid}, replace:true})
|
navigate(RouteHandler.loginpage, {state:{application_uid}, replace:true})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if(!application_uid){ // IF NO TOKEN || UID RETURN TO LOGIN PAGE
|
||||||
|
navigate(RouteHandler.loginpage, {replace:true})
|
||||||
|
return
|
||||||
|
}
|
||||||
const getUser = () => { // FUNCTION TO GET USER BY ID
|
const getUser = () => { // FUNCTION TO GET USER BY ID
|
||||||
let data = {firstname:'firstname', lastname:'lastname', uid:'28273737646466464'}
|
let data = {firstname:'firstname', lastname:'lastname', uid:'28273737646466464'}
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Route, Routes } from "react-router-dom";
|
import { Route, Routes, Navigate } from "react-router-dom";
|
||||||
import { RouteHandler } from "./routes";
|
import { RouteHandler } from "./routes";
|
||||||
import { DashboardAuth, Layout } from "../layouts";
|
import { DashboardAuth, Layout } from "../layouts";
|
||||||
|
|
||||||
@@ -12,7 +12,8 @@ import {
|
|||||||
const Routers = () => {
|
const Routers = () => {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path='auth' element={<Layout />}>
|
<Route path='/auth' element={<Layout />}>
|
||||||
|
<Route exact path={'auth'} element={<LoginPage />} />
|
||||||
<Route path={RouteHandler.loginpage} element={<LoginPage />} />
|
<Route path={RouteHandler.loginpage} element={<LoginPage />} />
|
||||||
<Route path={RouteHandler.otppage} element={<OTPPage />} />
|
<Route path={RouteHandler.otppage} element={<OTPPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
@@ -22,7 +23,7 @@ const Routers = () => {
|
|||||||
<Route element={<DashboardAuth />}>
|
<Route element={<DashboardAuth />}>
|
||||||
<Route path={RouteHandler.homepage} element={<StartValidationPage />} />
|
<Route path={RouteHandler.homepage} element={<StartValidationPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="*" element={<>Error Page</>} />
|
<Route path="*" element={<Navigate to={RouteHandler.loginpage} />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user