get loan more screens added
This commit is contained in:
+37
-23
@@ -5,25 +5,33 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import { IoIosArrowBack, IoIosArrowForward } from "react-icons/io";
|
||||
|
||||
import myLinks from '../myLinks'
|
||||
import Label from './Label'
|
||||
import InputText from './InputText'
|
||||
import queryKeys from '../services/queryKeys';
|
||||
import { getProducts } from '../services/siteServices';
|
||||
import Pin from './loan_screen/Pin';
|
||||
import Offers from './loan_screen/Offers';
|
||||
import LoanPin from './loan_screen/LoanPin';
|
||||
import SelectedOffer from './loan_screen/SelectedOffer';
|
||||
|
||||
export default function LoginCom() {
|
||||
export default function GetLoan() {
|
||||
|
||||
let screens = {
|
||||
products: 'products-screen',
|
||||
pin: 'pin-screen',
|
||||
offers: 'offers-screen',
|
||||
selected_offer: 'selected-offer-screen',
|
||||
loan_pin: 'loan-pin-screen'
|
||||
}
|
||||
|
||||
const {state} = useLocation()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [pin, setPin] = useState('')
|
||||
|
||||
const [step, setStep] = useState({
|
||||
details: {},
|
||||
page: 1
|
||||
screen: []
|
||||
})
|
||||
|
||||
const handleStep = (details, page) => {
|
||||
setStep({details, page})
|
||||
const handleStep = (details, screen) => {
|
||||
setStep(prev => ({...prev, details, screen: [...prev.screen, screen]}))
|
||||
}
|
||||
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
@@ -34,11 +42,11 @@ export default function LoginCom() {
|
||||
const products = data?.data?.product_data?.products // PRODUCTS LIST
|
||||
|
||||
const handleBackBtn = () => {
|
||||
if(step?.page == 1){
|
||||
navigate(myLinks.home, {state:{proceed:'true'}})
|
||||
}else{
|
||||
setStep(prev => ({...prev, page: prev.page-1}))
|
||||
if(step?.screen?.length <= 0 || step?.screen[step.screen.length -1 ] == screens.loan_pin){
|
||||
setStep({details: {}, screen: []})
|
||||
return navigate(myLinks.home, {state:{proceed:'true'}})
|
||||
}
|
||||
setStep(prev => ({...prev, screen: prev.screen.slice(0, -1)}))
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
@@ -52,7 +60,7 @@ export default function LoginCom() {
|
||||
<div className='flex flex-col gap-4 w-[80%] sm:w-[400px] min-h-[600px] bg-white rounded-xl p-4 sm:p-8 shadow'>
|
||||
<div className="relative pb-3 card-title w-full border-b-2 flex gap-4 items-center">
|
||||
<div className='absolute left-2 top-1/2 -translate-y-1/2 p-1 cursor-pointer' onClick={handleBackBtn}>
|
||||
<IoIosArrowBack className='text-3xl sm:text-5xl font-bold text-orange-500' />
|
||||
<IoIosArrowBack className='text-3xl sm:text-5xl font-bold text-orange-500 cursor-pointer' />
|
||||
</div>
|
||||
<div className='w-full text-center'>
|
||||
<h1 className="mb-[1px] text-2xl font-bold">{state?.user.name}</h1>
|
||||
@@ -60,7 +68,7 @@ export default function LoginCom() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{step?.page == 1 ?
|
||||
{!step?.screen?.length || step?.screen[step.screen.length -1 ] == screens.products ?
|
||||
<>
|
||||
<div className='mt-3 flex flex-col gap-3'>
|
||||
{isFetching ?
|
||||
@@ -81,7 +89,7 @@ export default function LoginCom() {
|
||||
<button
|
||||
key={product?.cid}
|
||||
disabled={isDisabled}
|
||||
onClick={()=>handleStep(product, 2)}
|
||||
onClick={()=>handleStep(product, screens.pin)}
|
||||
className={`w-full flex gap-2 justify-between items-center p-2 bg-purple-800 text-base sm:text-xl text-white font-bold rounded ${isDisabled && 'opacity-50'}`}
|
||||
>
|
||||
<span>{product?.description}</span>
|
||||
@@ -99,15 +107,21 @@ export default function LoginCom() {
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
: step?.page == 2 ?
|
||||
: step?.screen[step.screen.length -1 ] == screens.pin ?
|
||||
<>
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<Label name='Enter your pin' htmlfor='pin' />
|
||||
<InputText id='pin' name='pin' type='text' value={pin} handleChange={(e)=>setPin(e.target.value)} />
|
||||
<button onClick={()=>console.log('working')} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
<Pin step={step} handleStep={handleStep} screens={screens} />
|
||||
</>
|
||||
: step?.screen[step.screen.length -1 ] == screens.offers ?
|
||||
<>
|
||||
<Offers step={step} handleStep={handleStep} screens={screens} />
|
||||
</>
|
||||
: step?.screen[step.screen.length -1 ] == screens.selected_offer ?
|
||||
<>
|
||||
<SelectedOffer step={step} handleStep={handleStep} screens={screens} />
|
||||
</>
|
||||
: step?.screen[step.screen.length -1 ] == screens.loan_pin ?
|
||||
<>
|
||||
<LoanPin step={step} handleStep={handleStep} screens={screens} />
|
||||
</>
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function Label({name, htmlfor}) {
|
||||
export default function Label({name, htmlfor, error}) {
|
||||
return (
|
||||
<label className='text-black' htmlFor={htmlfor}>{name}</label>
|
||||
<label className='text-black flex gap-1 items-center' htmlFor={htmlfor}>{name} {error && <span className='text-red-500 text-sm'>{error}</span>}</label>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ export default function LoginCom() {
|
||||
}
|
||||
|
||||
<div className='mt-5 flex justify-end items-center'>
|
||||
<button onClick={()=>{login.mutate(fields)}} className='px-3 py-2 bg-purple-800 text-white font-bold rounded'>{login.isPending ? 'loading...' : 'Login'}</button>
|
||||
<button onClick={()=>{login.mutate(fields)}} disabled={login.isPending} className='px-3 py-2 bg-purple-800 text-white font-bold rounded'>{login.isPending ? 'loading...' : 'Login'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import React, { useState } from 'react'
|
||||
import Label from '../Label'
|
||||
import InputText from '../InputText'
|
||||
|
||||
export default function LoanPin({step, handleStep, screens}) {
|
||||
|
||||
const [error, SetError] = useState('')
|
||||
|
||||
const [pin, setPin] = useState('')
|
||||
|
||||
const handlePinChange = ({target:{value}}) => {
|
||||
SetError('')
|
||||
setPin(value)
|
||||
}
|
||||
|
||||
const [isSuccess, setIsSuccess] = useState(false)
|
||||
|
||||
const handleContinue = () => {
|
||||
if(!pin){
|
||||
SetError('enter pin')
|
||||
return setTimeout(()=>{
|
||||
SetError('')
|
||||
}, 5000)
|
||||
}
|
||||
setIsSuccess(prev => !prev)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isSuccess ?
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<Label name='Enter your pin' htmlfor='pin' error={error} />
|
||||
<InputText id='pin' name='pin' type='text' value={pin} handleChange={handlePinChange} />
|
||||
<button onClick={handleContinue} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<p className='text-center text-base md:text-xl'>Loan request has been accepted</p>
|
||||
<p className='text-center text-base md:text-xl'>You will get an sms with result shortly</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { TiArrowSortedDown } from "react-icons/ti";
|
||||
|
||||
import { getOffers } from '../../services/siteServices'
|
||||
import queryKeys from '../../services/queryKeys'
|
||||
import Label from '../Label';
|
||||
|
||||
export default function Offers({step, handleStep, screens}) {
|
||||
|
||||
const [isEmpty, setIsEmpty] = useState('')
|
||||
|
||||
const [selectedOffer, setSelectedOffer] = useState('')
|
||||
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.offers,
|
||||
queryFn: () => getOffers()
|
||||
})
|
||||
|
||||
const offers = data?.data?.product_data?.offers // OFFERS LIST
|
||||
|
||||
const handleContinue = () => {
|
||||
if(!selectedOffer){
|
||||
setIsEmpty('*')
|
||||
return setTimeout(()=>{
|
||||
setIsEmpty('')
|
||||
}, 5000)
|
||||
}
|
||||
handleStep({selectedOffer, ...step.details}, screens.selected_offer)
|
||||
}
|
||||
|
||||
const handleChange = ({target:{value}}) => {
|
||||
setIsEmpty('')
|
||||
setSelectedOffer(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<Label name='Enter Loan Amount' htmlfor='pin' error={isEmpty} />
|
||||
{isFetching ?
|
||||
<>
|
||||
<div className="w-full py-4">
|
||||
<p className='text-slate-800 text-center'>Loading...</p>
|
||||
</div>
|
||||
</>
|
||||
: isError ?
|
||||
<div className="w-full py-4">
|
||||
<p className='text-red-500 text-center'>{error.message}</p>
|
||||
</div>
|
||||
:
|
||||
<div className='relative w-full h-12'>
|
||||
<TiArrowSortedDown className='text-sm absolute right-1 top-1/2 -translate-y-1/2' />
|
||||
<select className='px-2 w-full h-full appearance-none rounded' value={selectedOffer} onChange={handleChange}>
|
||||
<option value={''}>Select offer</option>
|
||||
{offers.map(item => {
|
||||
if(item.active){
|
||||
return (
|
||||
<option key={item.cid} value={item.description}>{item.description}</option>
|
||||
)
|
||||
}
|
||||
}
|
||||
)}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
<>
|
||||
</>
|
||||
<button onClick={handleContinue} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const dummyData = [
|
||||
'100,000 Naira for 30 Days', '200,000 Naira for 30 Days', '100,000 Naira for 60 Days', '200,000 Naira for 60 Days'
|
||||
]
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
|
||||
import Label from '../Label'
|
||||
import InputText from '../InputText'
|
||||
|
||||
export default function Pin({step, handleStep, screens}) {
|
||||
|
||||
const [error, SetError] = useState('')
|
||||
|
||||
const [pin, setPin] = useState('')
|
||||
|
||||
const handlePinChange = ({target:{value}}) => {
|
||||
SetError('')
|
||||
setPin(value)
|
||||
}
|
||||
|
||||
const proceed = useMutation({
|
||||
mutationFn: () => {
|
||||
let fields = {pin, ...step.details}
|
||||
if(!fields.pin){
|
||||
throw new Error('Please enter pin *')
|
||||
}
|
||||
// return loginUser(fields)
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error)
|
||||
},
|
||||
onSuccess: (res) => {
|
||||
handleStep(step.details, screens.offers)
|
||||
}
|
||||
})
|
||||
|
||||
const handleContinue = () => {
|
||||
if(!pin){
|
||||
SetError('enter pin')
|
||||
return setTimeout(()=>{
|
||||
SetError('')
|
||||
}, 5000)
|
||||
}
|
||||
handleStep(step.details, screens.offers)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<Label name='Enter your pin' htmlfor='pin' error={error} />
|
||||
<InputText id='pin' name='pin' type='text' value={pin} handleChange={handlePinChange} />
|
||||
{/* <button onClick={()=>{proceed.mutate()}} disabled={proceed.isPending} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>{proceed.isPending ? 'loading...' : 'Continue'}</button> */}
|
||||
<button onClick={handleContinue} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>Continue</button>
|
||||
</div>
|
||||
|
||||
{proceed.error &&
|
||||
<>
|
||||
<div className="w-full text-center p-2">
|
||||
<p className='text-red-500 text-sm'>{proceed.error.message}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { useState } from 'react'
|
||||
import Label from '../Label'
|
||||
import InputText from '../InputText'
|
||||
|
||||
export default function SelectedOffer({step, handleStep, screens}) {
|
||||
|
||||
const [pin, setPin] = useState('')
|
||||
|
||||
console.log(step.details)
|
||||
const handleContinue = () => {
|
||||
handleStep(step.details, screens.loan_pin)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<div className='text-input font-semibold w-[70%] mx-auto flex flex-col gap-4 justify-center items-center'>
|
||||
<p className='text-center text-base'>Tenor: 30 Days</p>
|
||||
<Label name='Enter Loan Amount' htmlfor='pin' />
|
||||
<InputText id='pin' name='pin' type='text' value={pin} handleChange={(e)=>setPin(e.target.value)} />
|
||||
<div className='flex flex-col gap-4'>
|
||||
<p className='text-center text-base'>Upfront Interest 200 Naira</p>
|
||||
<p className='text-center text-base'>Due Date: Next Salary or 30 Days</p>
|
||||
</div>
|
||||
<button onClick={handleContinue} className='p-3 bg-purple-800 text-base sm:text-xl text-white font-bold rounded'>Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
const queryKeys = {
|
||||
demoUsers: ['demo-users'],
|
||||
products: ['products']
|
||||
products: ['products'],
|
||||
offers: ['offers'],
|
||||
}
|
||||
|
||||
export default queryKeys
|
||||
@@ -60,4 +60,10 @@ export const demoUsersList = (reqData) => {
|
||||
export const getProducts = (reqData) => {
|
||||
const postData = { ...reqData }
|
||||
return getAuxEnd(`/salary/products`, postData)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET MY OFFERS DATA
|
||||
export const getOffers = (reqData) => {
|
||||
const postData = { ...reqData }
|
||||
return getAuxEnd(`/salary/loanoffers`, postData)
|
||||
}
|
||||
Reference in New Issue
Block a user