From 82dd11a7728901d424ef3e94ec36021ce31d36f3 Mon Sep 17 00:00:00 2001 From: victorAnumudu Date: Fri, 26 Apr 2024 23:41:41 +0100 Subject: [PATCH] added axios package and api for start bvn verification --- package.json | 1 + .../LetsGetStated/LetsGetStarted.tsx | 105 +++++++++++------- src/core/apiRequest.ts | 19 ++++ src/core/axiosCall.ts | 49 ++++++++ src/core/models.ts | 7 ++ src/layouts/DashboardLayout/Aside.tsx | 9 +- .../DashboardLayout/DashboardLayout.tsx | 12 +- 7 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 src/core/apiRequest.ts create mode 100644 src/core/axiosCall.ts create mode 100644 src/core/models.ts diff --git a/package.json b/package.json index 2e2862e..9ed843d 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@reduxjs/toolkit": "^2.2.1", + "axios": "^1.6.8", "clsx": "2.1.0", "formik": "2.4.5", "react": "^18.2.0", diff --git a/src/components/LetsGetStated/LetsGetStarted.tsx b/src/components/LetsGetStated/LetsGetStarted.tsx index e145eb7..9c4f31c 100644 --- a/src/components/LetsGetStated/LetsGetStarted.tsx +++ b/src/components/LetsGetStated/LetsGetStarted.tsx @@ -5,6 +5,9 @@ import { InputCompOne } from ".."; import {useNavigate} from 'react-router-dom' import { RouteHandler } from "../../router/routes"; +import { validateBVN, verifyOTP } from "../../core/apiRequest"; +import { RequestStatus } from "../../core/models"; + // To get the validation schema const validationSchema = Yup.object().shape({ bvn: Yup.string() @@ -41,6 +44,11 @@ let initialValues = { otp: '', }; +type ValidBVN = { + verification_id:string + valid: undefined | boolean +} + const LetsGetStarted: React.FC = () => { const navigate = useNavigate() // const [pinValues, setPinValues] = React.useState({ @@ -48,36 +56,47 @@ const LetsGetStarted: React.FC = () => { // otp: "", // }); - const [hideOTPComponent, setHideOTPComponent] = React.useState(true); + const firstInputRef = React.useRef(null); const secondInputRef = React.useRef(null); - // const handleChange = (e: React.ChangeEvent) => { - // let { name, value } = e.target as HTMLInputElement; + const [requestStatusBVN, setRequestStatusBVN] = React.useState({loading:false, status:undefined, message:''}); - // setPinValues((prev) => ({ ...prev, [name]: value })); - // }; + const [bvnIsValid, setBvnIsValid] = React.useState({ + verification_id: '', + valid: undefined + }); const handleInput = (e: React.FormEvent) => { - let { name, value } = e.target as HTMLInputElement; - - if (name === "bvn") { - const regex = /^[0-9]+$/; - - if (regex.test(value)) { - if (value?.length == 11) { - setHideOTPComponent(false); - // secondInputRef.current?.focus(); - } else setHideOTPComponent(true); - } else { - console.log("object not found"); - } + let { value } = e.target as HTMLInputElement; + let bvn = value + if(value.length == 11){ + setRequestStatusBVN({loading:true, status:false, message:''}) + validateBVN({bvn}).then(res => { + if(!res || !res.data.call_return){ + setBvnIsValid({verification_id:'', valid: false}) + setRequestStatusBVN({loading:false, 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) => { - console.log('values', values) - navigate(RouteHandler.dashboardHome, {replace:true}) + // console.log('values', values) + verifyOTP({...values, verification_id:bvnIsValid.verification_id}).then(res=>{ + console.log(res.data) + navigate(RouteHandler.dashboardHome, {replace:true}) + }).catch(err => { + console.log(err) + }) }; return ( @@ -96,25 +115,28 @@ const LetsGetStarted: React.FC = () => {
- - {!hideOTPComponent && ( +
+ +

{requestStatusBVN.loading ? 'verifying...' : requestStatusBVN.message}

+
+ {bvnIsValid.valid && ( { inputClass="w-full h-[3.625rem] rounded bg-[#EFEFEF] px-4" value={props.values.otp} onChange={props.handleChange} - onInput={handleInput} ref={secondInputRef} maxLength={11} error={(props.errors.otp && props.touched.otp) && props.errors.otp} @@ -137,12 +158,12 @@ const LetsGetStarted: React.FC = () => { - {hideOTPComponent ? ( + {bvnIsValid.valid || bvnIsValid.valid == undefined ? (

***Every personal information attached to your BVN is safe and secure. It is only important for us to verify your information and diff --git a/src/core/apiRequest.ts b/src/core/apiRequest.ts new file mode 100644 index 0000000..20c3e92 --- /dev/null +++ b/src/core/apiRequest.ts @@ -0,0 +1,19 @@ +import { postAuxEnd } from "./axiosCall"; + + +// FUNCTION TO START BVN VALIDATION +export const validateBVN = (postData:any) => { + let reqData = { + ...postData + } + return postAuxEnd('https://digifi-apidev.chiefsoft.net/digiusers/v1/bvn', reqData) +} + + +// FUNCTION TO VERIFY OTP AND LOGIN +export const verifyOTP = (postData:any) => { + let reqData = { + ...postData + } + return postAuxEnd('https://digifi-apidev.chiefsoft.net/digiusers/v1/bvn/verify', reqData) +} \ No newline at end of file diff --git a/src/core/axiosCall.ts b/src/core/axiosCall.ts new file mode 100644 index 0000000..ff9bb45 --- /dev/null +++ b/src/core/axiosCall.ts @@ -0,0 +1,49 @@ +import axios from "axios"; + +export function postAuxEnd(uri:string, reqData:any):Promise { + // const endPoint = import.meta.env.REACT_APP_USERS_ENDPOINT + uri; + const formData = new FormData(); + for (let value in reqData) { + formData.append(value, reqData[value]); + } + return axios.post(uri, 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-------------------------------------------------------" + ); + } + }); + } + + diff --git a/src/core/models.ts b/src/core/models.ts new file mode 100644 index 0000000..3e8f627 --- /dev/null +++ b/src/core/models.ts @@ -0,0 +1,7 @@ +export interface RequestStatus { + loading?:boolean + status?:boolean | undefined + message?:string + name?:string + data?:{}[] | [any] | {} + } \ No newline at end of file diff --git a/src/layouts/DashboardLayout/Aside.tsx b/src/layouts/DashboardLayout/Aside.tsx index 56d2673..fdd80c5 100644 --- a/src/layouts/DashboardLayout/Aside.tsx +++ b/src/layouts/DashboardLayout/Aside.tsx @@ -1,17 +1,16 @@ 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 { Icons } from "../../components"; type Props = { asideDisplay?: () => void; + logoutUser: () => void }; -export default function Aside({ asideDisplay }: Props) { +export default function Aside({ asideDisplay, logoutUser }: Props) { const { pathname } = useLocation(); - const navigate = useNavigate(); - const [openNestedLink, setOpenNestedLink] = useState<{ name: string | null }>( { name: "" } ); @@ -115,7 +114,7 @@ export default function Aside({ asideDisplay }: Props) {

diff --git a/src/layouts/DashboardLayout/DashboardLayout.tsx b/src/layouts/DashboardLayout/DashboardLayout.tsx index b12412f..b48af3e 100644 --- a/src/layouts/DashboardLayout/DashboardLayout.tsx +++ b/src/layouts/DashboardLayout/DashboardLayout.tsx @@ -1,8 +1,12 @@ import { ReactNode, useState, useEffect } from "react"; +import { RouteHandler } from "../../router/routes"; +import { useNavigate } from "react-router-dom"; import Aside from "./Aside"; export default function DashboardLayout({ children }: { children: ReactNode }) { + const navigate = useNavigate(); + const [showAside, setShowAside] = useState(false); const asideDisplay = (): void => { setShowAside((prev) => !prev); @@ -30,17 +34,21 @@ export default function DashboardLayout({ children }: { children: ReactNode }) { // return child; // }); + const logoutUser = () => { + navigate(RouteHandler.letsGetStarted, {replace:true}) + } + return (