diff --git a/src/components/GetLoanScreens.jsx b/src/components/GetLoanScreens.jsx deleted file mode 100644 index eb8065a..0000000 --- a/src/components/GetLoanScreens.jsx +++ /dev/null @@ -1,167 +0,0 @@ -import React, { useEffect, useState } from 'react' -import { useLocation, useNavigate, Link } from 'react-router-dom' -import { useQuery } from "@tanstack/react-query"; - -import { IoIosArrowBack, IoIosArrowForward } from "react-icons/io"; - -import myLinks from '../myLinks' -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'; -import GetLoan from './loan_screen/GetLoan'; -import TermsAndConditions from './loan_screen/TermsAndConditions'; -import LoanDetails from './loan_screen/LoanDetails'; - -export default function GetLoanScreens() { - - let screens = { - products: 'products-screen', - terms_conditions: 'terms_conditions', - getLoan: 'get-loan', - pin: 'pin-screen', - loan_details: 'loan_details', - offers: 'offers-screen', - selected_offer: 'selected-offer-screen', - loan_pin: 'loan-pin-screen', - finished: 'finished' - } - - const {state} = useLocation() - const navigate = useNavigate() - - const [step, setStep] = useState({ - details: {}, - screen: [], - activeUser: state.user - }) - - const handleStep = (detailsToAdd, screen) => { - setStep(prev => ({...prev, details: {...prev.details, ...detailsToAdd}, screen: [...prev.screen, screen]})) - } - - const {data, isFetching, isError, error} = useQuery({ - queryKey: queryKeys.products, - queryFn: () => getProducts() - }) - - const products = data?.data?.product_data?.products // PRODUCTS LIST - - const handleBackBtn = () => { - if(step?.screen?.length <= 0 || step?.screen[step.screen.length -1 ] == screens.finished){ - setStep({details: {}, screen: []}) - return navigate(myLinks.home, {state:{proceed:'true'}}) - } - setStep(prev => ({...prev, screen: prev.screen.slice(0, -1)})) - } - - useEffect(()=>{ - if(!state?.user){ - return navigate(myLinks.getStarted, {replace:true}) - } - },[]) - - return ( -
-
-
-
- -
-
-

{state?.user.name}

- ID: {state?.user.bvn} -
-
- {!step?.screen?.length || step?.screen[step.screen.length -1 ] == screens.products ? - <> -
- {isFetching ? - <> -
-

Loading...

-
- - : isError ? -
-

{error.message}

-
- : - <> - {products && products.map(product => { - let isDisabled = product.active == '0' ? true : false - return ( - - ) - } - )} - - } - {/* */} -
- {/* {products && -
- -
- } */} - - : step?.screen[step.screen.length -1 ] == screens.getLoan ? - <> - - - :step?.screen[step.screen.length -1 ] == screens.terms_conditions ? - <> - - - :step?.screen[step.screen.length -1 ] == screens.pin ? - <> - - - : step?.screen[step.screen.length -1 ] == screens.offers ? - <> - - - : step?.screen[step.screen.length -1 ] == screens.selected_offer ? - <> - - - : step?.screen[step.screen.length -1 ] == screens.loan_details? - <> - - - :step?.screen[step.screen.length -1 ] == screens.loan_pin ? - <> - - - :step?.screen[step.screen.length -1 ] == screens.finished ? - <> - - - : null - } - -
- Back to Home -
- - -
-
- ) -} diff --git a/src/components/HomeCom.jsx b/src/components/HomeCom.jsx index 63ce8f6..74ef2a5 100644 --- a/src/components/HomeCom.jsx +++ b/src/components/HomeCom.jsx @@ -48,7 +48,7 @@ export default function HomeCom() { {data.map((user, index) => { let hasSalaryAcct = user.salary_account === 0 ? false : true return ( -
getLoanPage(user)} key={user?.uid || index} className={`${hasSalaryAcct ? 'bg-white' : 'bg-red-50'} w-full rounded p-3 sm:p-5 shadow flex flex-col gap-5 hover:scale-105 hover:cursor-pointer`}> +
getLoanPage(user)} key={user?.uid || index} className={`${hasSalaryAcct ? 'bg-white hover:cursor-pointer' : 'bg-red-50 pointer-events-none'} w-full rounded p-3 sm:p-5 shadow flex flex-col gap-5 hover:scale-105`}>

{user.name}

ID: {user.bvn} diff --git a/src/components/LoanScreens.jsx b/src/components/LoanScreens.jsx new file mode 100644 index 0000000..a23dc42 --- /dev/null +++ b/src/components/LoanScreens.jsx @@ -0,0 +1,109 @@ +import React, { useEffect, useState } from 'react' +import { useLocation, useNavigate, Link } from 'react-router-dom' + +import { IoIosArrowBack } from "react-icons/io"; + +import myLinks from '../myLinks' +import PayloanScreens from './loan_screen/PayloanScreens'; +import GetLoanScreens from './loan_screen/GetLoanScreens'; +import LoanInfoScreens from './loan_screen/LoanInfoScreens'; + +export default function LoanScreens() { + + const {state} = useLocation() + const navigate = useNavigate() + + const [step, setStep] = useState({ + details: {}, + screen: [], + activeUser: state.user + }) + + const typeToShow = { + getloan: 'getloan', + payloan: 'payloan', + loaninfo: 'loaninfo', + } + + const [showtype, setShowType] = useState(typeToShow.getloan) + + const handleStep = (detailsToAdd, screen) => { + setStep(prev => ({...prev, details: {...prev.details, ...detailsToAdd}, screen: [...prev.screen, screen]})) + } + + const handleBackBtn = () => { + // if(step?.screen?.length <= 0 || step?.screen[step.screen.length -1 ] == screens.finished){ + // setStep({details: {}, screen: []}) + // return navigate(myLinks.home, {state:{proceed:'true'}}) + // } + setStep(prev => ({...prev, screen: prev.screen.slice(0, -1)})) + } + + let screens = showtype == typeToShow.getloan ? { + products: 'products-screen', + terms_conditions: 'terms_conditions', + getLoan: 'get-loan', + pin: 'pin-screen', + loan_details: 'loan_details', + offers: 'offers-screen', + selected_offer: 'selected-offer-screen', + loan_pin: 'loan-pin-screen', + finished: 'finished' + } : showtype == typeToShow.payloan ? { + loan_list: 'loan_list', + repay_pin: 'repay_pin', + finished: 'finished' + }: showtype == typeToShow.loaninfo ? { + loan_info: 'loan_info', + finished: 'finished' + }: null + + useEffect(()=>{ + if(!state?.user){ + return navigate(myLinks.getStarted, {replace:true}) + } + },[]) + + useEffect(()=>{ // reset set details whenever the type of screen route to display changes + setStep({ details: {}, screen: [], activeUser: state.user}) + },[showtype]) + + return ( +
+
+
+
+ +
+
+

{state?.user.name}

+ ID: {state?.user.bvn} +
+
+ + {showtype == typeToShow.getloan && + <> + + + } + + {showtype == typeToShow.payloan && + <> + + + } + + {showtype == typeToShow.loaninfo && + <> + + + } + +
+ Back to Home +
+ +
+
+ ) +} diff --git a/src/components/loan_screen/GetLoan.jsx b/src/components/loan_screen/GetLoan.jsx deleted file mode 100644 index 836bcc6..0000000 --- a/src/components/loan_screen/GetLoan.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' - -export default function GetLoan({step, handleStep, screens}) { - - const handleGetLoan = () => { - // handleStep({...step.details}, screens.pin) - handleStep({...step.details}, screens.terms_conditions) - } - - return ( -
-
- -
- -
- -
-
- ) -} diff --git a/src/components/loan_screen/GetLoanScreens.jsx b/src/components/loan_screen/GetLoanScreens.jsx new file mode 100644 index 0000000..4e21e35 --- /dev/null +++ b/src/components/loan_screen/GetLoanScreens.jsx @@ -0,0 +1,54 @@ +import React from 'react' + +import Pin from './getloan/Pin'; +import Offers from './getloan/Offers'; +import LoanPin from './getloan/LoanPin'; +import SelectedOffer from './getloan/SelectedOffer'; +import GetLoan from './getloan/GetLoan'; +import TermsAndConditions from './getloan/TermsAndConditions'; +import LoanDetails from './getloan/LoanDetails'; +import ProductDetails from './getloan/ProductDetails'; + +export default function GetLoanScreens({step, screens, typeToShow, setShowType, handleStep}) { + + return ( + <> + {!step?.screen?.length || step?.screen[step.screen.length -1 ] == screens.products ? + + : step?.screen[step.screen.length -1 ] == screens.getLoan ? + <> + + + :step?.screen[step.screen.length -1 ] == screens.terms_conditions ? + <> + + + :step?.screen[step.screen.length -1 ] == screens.pin ? + <> + + + : step?.screen[step.screen.length -1 ] == screens.offers ? + <> + + + : step?.screen[step.screen.length -1 ] == screens.selected_offer ? + <> + + + : step?.screen[step.screen.length -1 ] == screens.loan_details? + <> + + + :step?.screen[step.screen.length -1 ] == screens.loan_pin ? + <> + + + :step?.screen[step.screen.length -1 ] == screens.finished ? + <> + + + : null + } + + ) +} diff --git a/src/components/loan_screen/LoanInfoScreens.jsx b/src/components/loan_screen/LoanInfoScreens.jsx new file mode 100644 index 0000000..b921c7a --- /dev/null +++ b/src/components/loan_screen/LoanInfoScreens.jsx @@ -0,0 +1,21 @@ +import React from 'react' + +import LoanInfoList from './loaninfo/LoanInfoList'; + + +export default function LoanInfoScreens({step, screens, typeToShow, setShowType, handleStep}) { + + return ( + <> + {!step?.screen?.length || step?.screen[step.screen.length -1 ] == screens.loan_list ? + + : step?.screen[step.screen.length -1 ] == screens.repay_pin ? + <> + {/* */} + {null} + + : null + } + + ) +} diff --git a/src/components/loan_screen/PayloanScreens.jsx b/src/components/loan_screen/PayloanScreens.jsx new file mode 100644 index 0000000..b3c483c --- /dev/null +++ b/src/components/loan_screen/PayloanScreens.jsx @@ -0,0 +1,22 @@ +import React from 'react' + +import RepayLoanList from './payloan/RepayLoanList'; +import PinRepayment from './payloan/PinRepayment'; + + +export default function PayloanScreens({step, screens, typeToShow, setShowType, handleStep}) { + + return ( + <> + {!step?.screen?.length || step?.screen[step.screen.length -1 ] == screens.loan_list ? + + : step?.screen[step.screen.length -1 ] == screens.repay_pin ? + <> + {/* */} + + + : null + } + + ) +} diff --git a/src/components/loan_screen/getloan/GetLoan.jsx b/src/components/loan_screen/getloan/GetLoan.jsx new file mode 100644 index 0000000..03bc61e --- /dev/null +++ b/src/components/loan_screen/getloan/GetLoan.jsx @@ -0,0 +1,31 @@ +import React from 'react' + +export default function GetLoan({step, handleStep, screens, typeToShow, setShowType}) { + + const handleGetLoan = () => { + // handleStep({...step.details}, screens.pin) + handleStep({...step.details}, screens.terms_conditions) + } + + const handlePayLoan = () => { + // setShowType(typeToShow.payloan) + } + + const handleLoanInfo = () => { + // setShowType(typeToShow.loaninfo) + } + + return ( +
+
+ +
+ +
+ + +
+ +
+ ) +} diff --git a/src/components/loan_screen/LoanDetails.jsx b/src/components/loan_screen/getloan/LoanDetails.jsx similarity index 100% rename from src/components/loan_screen/LoanDetails.jsx rename to src/components/loan_screen/getloan/LoanDetails.jsx diff --git a/src/components/loan_screen/LoanPin.jsx b/src/components/loan_screen/getloan/LoanPin.jsx similarity index 91% rename from src/components/loan_screen/LoanPin.jsx rename to src/components/loan_screen/getloan/LoanPin.jsx index ab66ee9..ed833bf 100644 --- a/src/components/loan_screen/LoanPin.jsx +++ b/src/components/loan_screen/getloan/LoanPin.jsx @@ -1,8 +1,8 @@ import React, { useState } from 'react' import { useMutation } from '@tanstack/react-query' -import Label from '../Label' -import InputText from '../InputText' -import { verifyLoan } from '../../services/siteServices' +import Label from '../../Label' +import InputText from '../../InputText' +import { verifyLoan } from '../../../services/siteServices' export default function LoanPin({step, handleStep, screens}) { @@ -56,7 +56,6 @@ export default function LoanPin({step, handleStep, screens}) {

Your loan is being disbursed. You will receive a confirmation SMS shortly.

- {/*

You will get an sms with result shortly

*/}
} diff --git a/src/components/loan_screen/Offers.jsx b/src/components/loan_screen/getloan/Offers.jsx similarity index 92% rename from src/components/loan_screen/Offers.jsx rename to src/components/loan_screen/getloan/Offers.jsx index 8ec0ab9..600a199 100644 --- a/src/components/loan_screen/Offers.jsx +++ b/src/components/loan_screen/getloan/Offers.jsx @@ -3,8 +3,8 @@ import { useQuery } from "@tanstack/react-query"; import { useMutation } from '@tanstack/react-query' import { IoIosArrowForward } from "react-icons/io"; -import { getOffers, loanSelect } from '../../services/siteServices' -import queryKeys from '../../services/queryKeys' +import { getOffers, loanSelect } from '../../../services/siteServices' +import queryKeys from '../../../services/queryKeys' export default function Offers({step, handleStep, screens}) { @@ -83,8 +83,6 @@ export default function Offers({step, handleStep, screens}) {
} - - {/* */}
) diff --git a/src/components/loan_screen/Pin.jsx b/src/components/loan_screen/getloan/Pin.jsx similarity index 93% rename from src/components/loan_screen/Pin.jsx rename to src/components/loan_screen/getloan/Pin.jsx index fc3ca0b..82f5568 100644 --- a/src/components/loan_screen/Pin.jsx +++ b/src/components/loan_screen/getloan/Pin.jsx @@ -1,9 +1,9 @@ import React, { useState } from 'react' import { useMutation } from '@tanstack/react-query' -import Label from '../Label' -import InputText from '../InputText' -import { verifyPin } from '../../services/siteServices' +import Label from '../../Label' +import InputText from '../../InputText' +import { verifyPin } from '../../../services/siteServices' export default function Pin({step, handleStep, screens}) { diff --git a/src/components/loan_screen/getloan/ProductDetails.jsx b/src/components/loan_screen/getloan/ProductDetails.jsx new file mode 100644 index 0000000..d6977ab --- /dev/null +++ b/src/components/loan_screen/getloan/ProductDetails.jsx @@ -0,0 +1,51 @@ +import React from 'react' +import { useQuery } from "@tanstack/react-query"; +import queryKeys from '../../../services/queryKeys'; +import { getProducts } from '../../../services/siteServices'; +import { IoIosArrowForward } from "react-icons/io"; + +export default function ProductDetails({step, handleStep, screens}) { + + const {data, isFetching, isError, error} = useQuery({ + queryKey: queryKeys.products, + queryFn: () => getProducts() + }) + + const products = data?.data?.product_data?.products // PRODUCTS LIST + + return ( + <> +
+ {isFetching ? + <> +
+

Loading...

+
+ + : isError ? +
+

{error.message}

+
+ : + <> + {products && products.map(product => { + let isDisabled = product.active == '0' ? true : false + return ( + + ) + } + )} + + } +
+ + ) +} diff --git a/src/components/loan_screen/SelectedOffer.jsx b/src/components/loan_screen/getloan/SelectedOffer.jsx similarity index 95% rename from src/components/loan_screen/SelectedOffer.jsx rename to src/components/loan_screen/getloan/SelectedOffer.jsx index f8d5b2f..9be42e7 100644 --- a/src/components/loan_screen/SelectedOffer.jsx +++ b/src/components/loan_screen/getloan/SelectedOffer.jsx @@ -1,8 +1,8 @@ import React, { useState } from 'react' import { useMutation } from '@tanstack/react-query' -import Label from '../Label' -import InputText from '../InputText' -import { loanApply } from '../../services/siteServices' +import Label from '../../Label' +import InputText from '../../InputText' +import { loanApply } from '../../../services/siteServices' export default function SelectedOffer({step, handleStep, screens}) { diff --git a/src/components/loan_screen/TermsAndConditions.jsx b/src/components/loan_screen/getloan/TermsAndConditions.jsx similarity index 100% rename from src/components/loan_screen/TermsAndConditions.jsx rename to src/components/loan_screen/getloan/TermsAndConditions.jsx diff --git a/src/components/loan_screen/loaninfo/LoanInfoList.jsx b/src/components/loan_screen/loaninfo/LoanInfoList.jsx new file mode 100644 index 0000000..da219bc --- /dev/null +++ b/src/components/loan_screen/loaninfo/LoanInfoList.jsx @@ -0,0 +1,101 @@ +import React, { useState } from 'react' +import { useQuery } from "@tanstack/react-query"; +import { useMutation } from '@tanstack/react-query' +import { IoIosArrowForward } from "react-icons/io"; + +import { getOffers, loanSelect } from '../../../services/siteServices' +import queryKeys from '../../../services/queryKeys' + +export default function LoanInfoList({step, handleStep, screens}) { + + const [selectedAmount, setSelectedAmount] = useState('') + + const {data, isFetching, isError, error} = useQuery({ + queryKey: queryKeys.offers, + queryFn: () => getOffers() + }) + + // const list = data?.data?.product_data?.offers // OFFERS LIST + + const selectedLoan = useMutation({ + mutationFn: (details) => { + let fields = {bvn:step.activeUser.bvn, loan: details.loan} + // if(!fields.bvn){ + // throw new Error('*') + // } + setSelectedAmount(details.amount) + return loanSelect(fields) + }, + onError: (error) => { + // setError('*') + }, + onSuccess: (res) => { + const selectedOffer = res.data.loan + handleStep({selectedAmount, selectedOffer, ...res.data}, screens.repay_pin) + } + }) + + const handleClick = (selectedAmount) => { // remove later + handleStep({selectedAmount}, screens.repay_pin) + } + + return ( +
+
+ {isFetching ? + <> +
+

Loading...

+
+ + : isError ? +
+

{error.message}

+
+ : + <> +

Loan to repay

+ {offers.map(item => { + let isDisabled = item.active == '0' ? true : false + return ( + + ) + })} + + } + <> + + + {selectedLoan.isPending && +
+

loading...

+
+ } + + {selectedLoan.error && + <> +
+

{selectedLoan.error.message}

+
+ + } +
+
+ ) +} + +const offers = [ // remove later + {cid: '1', amount: 50000, description: 'Total amount to replay N50,000'}, + {cid: '2', amount: 25000, description: 'Total amount to replay N25,000'} +] \ No newline at end of file diff --git a/src/components/loan_screen/payloan/PinRepayment.jsx b/src/components/loan_screen/payloan/PinRepayment.jsx new file mode 100644 index 0000000..5010c67 --- /dev/null +++ b/src/components/loan_screen/payloan/PinRepayment.jsx @@ -0,0 +1,82 @@ +import React, { useState } from 'react' +import { useMutation } from '@tanstack/react-query' +import Label from '../../Label' +import InputText from '../../InputText' +import { verifyLoan } from '../../../services/siteServices' + +export default function PinRepayment({step, handleStep, screens}) { + + const [isSuccess, setIsSuccess] = useState(false) + + const [error, setError] = useState('') + + const [pin, setPin] = useState('') + + const handlePinChange = ({target:{value}}) => { + setError('') + setPin(value) + } + + const proceed = useMutation({ + mutationFn: () => { + let fields = {pin, bvn:step.activeUser.bvn, loan_application_id:step.details.loan_application_id} + if(!fields.pin){ + throw ({message:'Please enter pin'}) + } + // if(isNaN(fields.pin)){ + // throw ({message:'Amount must be a valid figure'}) + // } + if(fields.pin.length != 4){ + throw ({message:'Pin must be 4 digits'}) + } + return verifyLoan(fields) + }, + onError: (error) => { + setError(error.message) + setTimeout(()=>{setError('')},3000) + }, + onSuccess: (res) => { + setIsSuccess(true) + handleStep({...step}, screens.finished) + } + }) + + const handleClick = (selectedAmount) => { // remove later + if(!pin){ + return setError('Enter Pin') + } + setIsSuccess(true) + // handleStep({selectedAmount}, screens.finished) + } + + return ( + <> + {!isSuccess ? +
+
+

{`Your loan amount due is ₦${step.details.selectedAmount}`}

+
+
+ : +
+
+

Your loan repayment is being processed. You will receive a confirmation SMS shortly.

+
+
+ } + + {error && + <> +
+

{error}

+
+ + } + + + ) +} diff --git a/src/components/loan_screen/payloan/RepayLoanList.jsx b/src/components/loan_screen/payloan/RepayLoanList.jsx new file mode 100644 index 0000000..d467c64 --- /dev/null +++ b/src/components/loan_screen/payloan/RepayLoanList.jsx @@ -0,0 +1,100 @@ +import React, { useState } from 'react' +import { useQuery } from "@tanstack/react-query"; +import { useMutation } from '@tanstack/react-query' +import { IoIosArrowForward } from "react-icons/io"; + +import { getOffers, loanSelect } from '../../../services/siteServices' +import queryKeys from '../../../services/queryKeys' + +export default function RepayLoanList({step, handleStep, screens}) { + + const [selectedAmount, setSelectedAmount] = useState('') + + const {data, isFetching, isError, error} = useQuery({ + queryKey: queryKeys.offers, + queryFn: () => getOffers() + }) + + // const list = data?.data?.product_data?.offers // OFFERS LIST + + const selectedLoan = useMutation({ + mutationFn: (details) => { + let fields = {bvn:step.activeUser.bvn, loan: details.loan} + // if(!fields.bvn){ + // throw new Error('*') + // } + setSelectedAmount(details.amount) + return loanSelect(fields) + }, + onError: (error) => { + // setError('*') + }, + onSuccess: (res) => { + const selectedOffer = res.data.loan + handleStep({selectedAmount, selectedOffer, ...res.data}, screens.repay_pin) + } + }) + + const handleClick = (selectedAmount) => { // remove later + handleStep({selectedAmount}, screens.repay_pin) + } + + return ( +
+
+ {isFetching ? + <> +
+

Loading...

+
+ + : isError ? +
+

{error.message}

+
+ : + <> +

Select Loan to repay

+ {offers.map(item => { + let isDisabled = item.active == '0' ? true : false + return ( + + ) + })} + + } + <> + + + {selectedLoan.isPending && +
+

loading...

+
+ } + + {selectedLoan.error && + <> +
+

{selectedLoan.error.message}

+
+ + } +
+
+ ) +} + +const offers = [ // remove later + {cid: '1', amount: 50000, description: 'Total amount to replay N50,000'}, + {cid: '2', amount: 25000, description: 'Total amount to replay N25,000'} +] \ No newline at end of file diff --git a/src/pages/GetLoanPage.jsx b/src/pages/GetLoanPage.jsx index c835e4b..fe26525 100644 --- a/src/pages/GetLoanPage.jsx +++ b/src/pages/GetLoanPage.jsx @@ -1,8 +1,8 @@ import React from 'react' -import GetLoanScreens from '../components/GetLoanScreens' +import LoanScreens from '../components/LoanScreens' export default function GetLoanPage() { return ( - + ) }