From e9edc036ebc4e33d10142bdedf4da61efec5f479 Mon Sep 17 00:00:00 2001 From: victorAnumudu Date: Mon, 3 Nov 2025 20:13:02 +0100 Subject: [PATCH] added recent-loans endpoint --- src/App.js | 23 ++--- src/assets/simbrella-bko-logo.png | Bin 0 -> 6155 bytes src/components/auth/LoginCom.jsx | 13 ++- src/components/layouts/DashboardHeader.jsx | 3 + .../layouts/aside/DashboardAside.jsx | 4 +- src/components/layouts/rightaside/Orders.jsx | 80 +++--------------- .../layouts/rightaside/RightAsideBar.jsx | 59 ++++++++----- .../transactions/TransactionsCom.jsx | 50 +++++------ src/services/queryKeys.js | 5 +- src/services/siteEventService.js | 4 +- src/services/siteServices.js | 6 ++ 11 files changed, 115 insertions(+), 132 deletions(-) create mode 100644 src/assets/simbrella-bko-logo.png diff --git a/src/App.js b/src/App.js index b4acaa9..ef7d8a1 100644 --- a/src/App.js +++ b/src/App.js @@ -8,6 +8,18 @@ import { generalLayoutContext } from './context/GeneralLayoutContext'; import './App.css'; +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + retry: 3, + staleTime: 300000 //5 mins + // refetchOnMount: false, + // staleTime: Infinity // can also be a number in millisecond + }, + }, +}) + function App() { const {pathname} = useLocation() @@ -18,17 +30,6 @@ function App() { window.scrollTo(0,0) },[pathname]) - const queryClient = new QueryClient({ - defaultOptions: { - queries: { - refetchOnWindowFocus: false, - retry: 3, - staleTime: 300000 //5 mins - // refetchOnMount: false, - // staleTime: Infinity // can also be a number in millisecond - }, - }, - }) return ( <> diff --git a/src/assets/simbrella-bko-logo.png b/src/assets/simbrella-bko-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5c0bd90b1bd3c8eb193ac46b5d72048ad09d5497 GIT binary patch literal 6155 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 T#dGawnAzRE^{^-bz)$@bbCvuU literal 0 HcmV?d00001 diff --git a/src/components/auth/LoginCom.jsx b/src/components/auth/LoginCom.jsx index 00aa232..f560a71 100644 --- a/src/components/auth/LoginCom.jsx +++ b/src/components/auth/LoginCom.jsx @@ -11,6 +11,7 @@ import { loginUser } from '../../services/siteServices' import RouteLinks from '../../RouteLinks' import Icons from '../Icons' +import localImgLoader from '../../helpers/localImageLoader' const initialValues = { @@ -83,13 +84,17 @@ export default function LoginCom() { {(props)=>(
+
+ +
+

Sign In

Welcome back, please login to your account

{/* social login */} -
+ {/*
Sign in with Google @@ -102,7 +107,7 @@ export default function LoginCom() {

Or with email

-
+
*/}
@@ -146,11 +151,11 @@ export default function LoginCom() { {/*

Not yet a member? Sign Up

*/} -
+ {/*
Terms Plans Contact Us -
+
*/}
diff --git a/src/components/layouts/DashboardHeader.jsx b/src/components/layouts/DashboardHeader.jsx index 67c0190..b0b9142 100644 --- a/src/components/layouts/DashboardHeader.jsx +++ b/src/components/layouts/DashboardHeader.jsx @@ -57,6 +57,8 @@ export default function DashboardHeader() {
handleActiveMenu('avatar')} className='relative cursor-pointer w-10 h-10 rounded shadow-round_black dark:shadow-round_white'> user avatar {activeMenu == 'avatar' && + <> +
@@ -74,6 +76,7 @@ export default function DashboardHeader() {
+ }
diff --git a/src/components/layouts/aside/DashboardAside.jsx b/src/components/layouts/aside/DashboardAside.jsx index 5d35fc9..3756ae6 100644 --- a/src/components/layouts/aside/DashboardAside.jsx +++ b/src/components/layouts/aside/DashboardAside.jsx @@ -9,6 +9,7 @@ import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { TbLogout2 } from "react-icons/tb"; import UserAvatar from '../../../assets/user_avatar.jpg' import Icons from "../../Icons"; +import localImgLoader from '../../../helpers/localImageLoader'; export default function DashboardAside() { @@ -22,7 +23,8 @@ export default function DashboardAside() { return (
- + {/* */} +
{/*
*/} diff --git a/src/components/layouts/rightaside/Orders.jsx b/src/components/layouts/rightaside/Orders.jsx index 420064b..15215c4 100644 --- a/src/components/layouts/rightaside/Orders.jsx +++ b/src/components/layouts/rightaside/Orders.jsx @@ -2,77 +2,25 @@ import React from 'react' import Img from '../../../assets/user_avatar.jpg' import CustomCounter from '../../CustomCounter' -export default function Orders() { +export default function Orders({data}) { return (
- {/*
*/} - {/*

Recent Eligibility

*/} - {/*
*/} - {/*
*/} - {/*

*/} - {/* */} - {/*

*/} - {/*

Pending

*/} - {/*
*/} - {/*
*/} - {/*

*/} - {/* */} - {/*

*/} - {/*

Approved

*/} - {/*
*/} - {/*
*/} - {/*

*/} - {/* */} - {/*

*/} - {/*

Rejected

*/} - {/*
*/} - {/*
*/} - {/*

*/} - {/* */} - {/*

*/} - {/*

Created

*/} - {/*
*/} - {/*
*/} - {/*
*/}

Recent Loans

-
-
- Order Image -
-
-

Project Briefing

-

Project Manager

-
-
-
-
- Order Image -
-
-

Project Briefing

-

Project Manager

-
-
-
-
- Order Image -
-
-

Project Briefing

-

Project Manager

-
-
-
-
- Order Image -
-
-

Project Briefing

-

Project Manager

-
-
+ {data.map((item, index)=>{ + return ( +
+
+ Order Image +
+
+

Project Briefing

+

Project Manager

+
+
+ ) + })}
diff --git a/src/components/layouts/rightaside/RightAsideBar.jsx b/src/components/layouts/rightaside/RightAsideBar.jsx index f0b7df9..e39a145 100644 --- a/src/components/layouts/rightaside/RightAsideBar.jsx +++ b/src/components/layouts/rightaside/RightAsideBar.jsx @@ -1,4 +1,7 @@ import React, { useState } from 'react' +import { useQuery } from "@tanstack/react-query"; +import queryKeys from '../../../services/queryKeys' +import { getRecentLoans } from '../../../services/siteServices' import Icons from '../../Icons' import Orders from './Orders' import Tickets from './Tickets' @@ -13,25 +16,41 @@ export default function RightAsideBar() { setActive(lowerStr) } - return ( -
- {/* Menu */} -
- - {/**/} - {/**/} -
+ const {data, isFetching, isError, error} = useQuery({ + queryKey: queryKeys.recent_loans, + queryFn: () => getRecentLoans() + }) - {/* Body */} - {active === 'orders' && } - {/*{active == 'tickets' && }*/} - {/*{active == 'tasks' && }*/} -
- ) + console.log('data', data?.data) + + return ( +
+ {/* Menu */} +
+ + {/**/} + {/**/} +
+ + {/* Body */} + {(isFetching || isError) ? +
+ {isError ?

{error.message}

: +

Loading...

} +
+ : +
+ {active === 'orders' && } + {/*{active == 'tickets' && }*/} + {/*{active == 'tasks' && }*/} +
+ } +
+ ) } diff --git a/src/components/transactions/TransactionsCom.jsx b/src/components/transactions/TransactionsCom.jsx index 3dbb178..a07ac37 100644 --- a/src/components/transactions/TransactionsCom.jsx +++ b/src/components/transactions/TransactionsCom.jsx @@ -1,4 +1,5 @@ import {useEffect, useState} from 'react' +import { useQuery } from '@tanstack/react-query' import {Link} from 'react-router-dom' import BreadcrumbCom from '../breadcrumb/BreadcrumbCom' @@ -10,50 +11,45 @@ import getTimeFromDateString from '../../helpers/GetTimeFromDateString'; import localImgLoader from '../../helpers/localImageLoader'; import RouteLinks from '../../RouteLinks'; import localSiteIcons from '../../helpers/localSiteIcons'; +import queryKeys from '../../services/queryKeys' export default function TransactionsCom() { const [page, setPage] = useState(1) - const [allTransactions, setAllTransaction] = useState({loading: true, error: '', data: {}}) - - const [willFilter, setWillFilter] = useState(false) const [filter, setFilter] = useState({type: '', id: ''}) - const handleFilter = ({target: {name, value}}) => { - setFilter(prev => ({...prev, [name]: value})) + const [willFilter, setWillFilter] = useState(false) + + const handleFilter = ({target:{name, value}}) => { + setFilter(prev => ({...prev, [name]:value})) } const handleFilterByParams = () => { - if (filter.type && !filter.id) { + if(filter.type && !filter.id){ return - } else if (!filter.type) { + }else if(!filter.type){ setPage(1) setWillFilter(prev => !prev) setFilter({type: '', id: ''}) - } else { + }else{ setPage(1) setWillFilter(prev => !prev) } } - const transactions = allTransactions?.data?.transactions // TRANSACTIONS LIST - const pagination = allTransactions?.data?.pagination - const isFetching = allTransactions?.loading - const isError = allTransactions?.error - - useEffect(() => { - setAllTransaction(prev => ({...prev, loading: true})) - const payload = filter?.type ? {[filter?.type]: filter.id} : {} - getTransactions({...payload, page}).then(res => { - if (res?.status != 200) { - setAllTransaction(prev => ({...prev, loading: false})) - return + const {data, isFetching, isError, error} = useQuery({ + queryKey: [...queryKeys.transactions, page, willFilter], + queryFn: () => { + const filterData = filter?.type ? {[filter?.type]: filter.id} : {} + const reqData = { + page, + ...filterData } - setAllTransaction({loading: false, error: '', data: res?.data}) - }).catch(err => { - setAllTransaction({loading: false, error: 'error occurred', data: {}}) - console.log('ERR', err) - }) - }, [page, willFilter]) + return getTransactions(reqData) + }, + staleTime: 0 //0 mins + }) + const transactions = data?.data?.transactions // TRANSACTIONS LIST + const pagination = data?.data?.pagination return (
@@ -61,7 +57,7 @@ export default function TransactionsCom() {
{isError ? -

{allTransactions?.error}

+

{error?.message}

: <> {/* filter section */} diff --git a/src/services/queryKeys.js b/src/services/queryKeys.js index 86ff66a..e4146f0 100644 --- a/src/services/queryKeys.js +++ b/src/services/queryKeys.js @@ -1,7 +1,6 @@ const queryKeys = { dashboard: ['dashboard'], loans: ['loans'], - transactions: ['transactions'], repayment_schedule: ['repayment-schedule'], loan_charges: ['loan-charges'], offers: ['offers'], @@ -9,6 +8,10 @@ const queryKeys = { select_loan: ['select-loan'], approved_loan: ['approved-loan'], loan_offers: ['loan-offers'], + + //new + transactions: ['transactions'], + recent_loans: ['recent_loans'], } export default queryKeys \ No newline at end of file diff --git a/src/services/siteEventService.js b/src/services/siteEventService.js index 032b796..a73150d 100644 --- a/src/services/siteEventService.js +++ b/src/services/siteEventService.js @@ -15,7 +15,7 @@ axios.interceptors.request.use( } ); const postAuxEnd = (path, postData, media=false) => { - const basePath = media ? process.env.REACT_APP_EVENT_API : 'http://10.2.249.133:5000' + const basePath = media ? process.env.REACT_APP_EVENT_API : process.env.REACT_APP_EVENT_API return axios.post(`${basePath}${path}`, postData).then(res => { return res }).catch(err => { @@ -25,7 +25,7 @@ const postAuxEnd = (path, postData, media=false) => { } const getAuxEnd = (path, reqData= null) => { - const basePath = media ? process.env.REACT_APP_EVENT_API : 'http://10.2.249.133:5000' + const basePath = media ? process.env.REACT_APP_EVENT_API : process.env.REACT_APP_EVENT_API return axios.get(`${basePath}${path}`,{ params: reqData }).then(res => { return res diff --git a/src/services/siteServices.js b/src/services/siteServices.js index 0ce3a2f..3655008 100644 --- a/src/services/siteServices.js +++ b/src/services/siteServices.js @@ -90,4 +90,10 @@ export const getOffers = (reqData) => { export const getRepaymentSchedule = (reqData) => { const postData = { ...reqData } return getAuxEnd(`/repayment-schedules`, postData) +} + +// FUNCTION TO GET RECENT LOANS +export const getRecentLoans = (reqData) => { + const postData = { ...reqData } + return getAuxEnd(`/recent-loans`, postData) } \ No newline at end of file -- 2.34.1