Recent Loans API Added #35
+12
-11
@@ -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 (
|
||||
<>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
@@ -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)=>(
|
||||
<Form>
|
||||
<div className='flex flex-col gap-8 w-full bg-white rounded-xl p-16 sm:px-20 sm:py-16 shadow'>
|
||||
<div className='flex justify-center w-full mb-10'>
|
||||
<img className='w-auto h-8 xs:h-16' src={localImgLoader('simbrella-bko-logo.png')} />
|
||||
</div>
|
||||
|
||||
<div className='w-full flex flex-col gap-1 items-center'>
|
||||
<h1 className='text-2xl md:text-3xl font-bold text-black-body'>Sign In</h1>
|
||||
<p className='text-sm font-medium text-slate-500'>Welcome back, please login to your account</p>
|
||||
</div>
|
||||
|
||||
{/* social login */}
|
||||
<div className='grid grid-cols-2 gap-4 text-sm'>
|
||||
{/* <div className='grid grid-cols-2 gap-4 text-sm'>
|
||||
<div className='px-4 py-2 flex gap-2 items-center justify-center text-black-body font-medium border border-slate-300/50 rounded-md hover:text-primary hover:bg-sky-50 cursor-pointer'>
|
||||
<Icons name='google' />
|
||||
<span>Sign in with Google</span>
|
||||
@@ -102,7 +107,7 @@ export default function LoginCom() {
|
||||
|
||||
<div className='relative h-[1px] bg-slate-300/50'>
|
||||
<p className='absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 bg-white p-4 text-12 text-slate-500'>Or with email</p>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className='flex flex-col gap-6'>
|
||||
<div className='relative text-input flex flex-col gap-2'>
|
||||
@@ -146,11 +151,11 @@ export default function LoginCom() {
|
||||
|
||||
{/* <p className='text-sm text-center font-medium text-slate-500'>Not yet a member? <span className='text-primary'>Sign Up</span></p> */}
|
||||
|
||||
<div className='flex justify-end gap-4 mt-6 text-[13px] font-medium'>
|
||||
{/* <div className='flex justify-end gap-4 mt-6 text-[13px] font-medium'>
|
||||
<Link className='text-primary' to=''>Terms</Link>
|
||||
<Link className='text-primary' to=''>Plans</Link>
|
||||
<Link className='text-primary' to=''>Contact Us</Link>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -57,6 +57,8 @@ export default function DashboardHeader() {
|
||||
<div onClick={()=>handleActiveMenu('avatar')} className='relative cursor-pointer w-10 h-10 rounded shadow-round_black dark:shadow-round_white'>
|
||||
<img src={UserAvatar} alt='user avatar' className='w-full h-full p-1 rounded-full' />
|
||||
{activeMenu == 'avatar' &&
|
||||
<>
|
||||
<div className="fixed top-0 left-0 right-0 bottom-0 bg-black/10"></div>
|
||||
<div className="pop-modal z-[777] absolute p-4 w-52 sm:w-96 bg-white dark:bg-black-box right-0 top-16 rounded shadow-round_black dark:shadow-round_white">
|
||||
<div className="w-full h-full flex flex-col gap-4">
|
||||
<div className="flex flex-col text-black dark:text-white text-base sm:text-lg">
|
||||
@@ -74,6 +76,7 @@ export default function DashboardHeader() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 (
|
||||
<div className='w-full h-full flex flex-col'>
|
||||
<div className="mb-3 w-full h-24 logo flex items-center">
|
||||
<DummyLogo />
|
||||
{/* <DummyLogo /> */}
|
||||
<img className='w-2/3 h-auto' src={localImgLoader('simbrella-bko-logo.png')} />
|
||||
</div>
|
||||
{/* <hr className="border-slate-400" /> */}
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<div className='h-full p-2 sm:p-4 large:p-8 flex flex-col gap-16 overflow-y-auto aside-scroll-design'>
|
||||
{/*<div className='flex flex-col gap-4'>*/}
|
||||
{/* <p className='text-base text-white-body font-bold'>Recent Eligibility</p>*/}
|
||||
{/* <div className='grid grid-cols-2 gap-4 sm:gap-6 large:gap-8'>*/}
|
||||
{/* <div className='p-2 sm:p-3 large:p-4 flex flex-col border border-slate-500 border-dashed'>*/}
|
||||
{/* <p className='text-base font-bold text-white-body'>*/}
|
||||
{/* <CustomCounter targetNumber={18} timeInSeconds={1} />*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className='text-sm text-slate-500'>Pending</p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className='p-2 sm:p-3 large:p-4 flex flex-col border border-slate-500 border-dashed'>*/}
|
||||
{/* <p className='text-base font-bold text-white-body'>*/}
|
||||
{/* <CustomCounter targetNumber={5} timeInSeconds={1} />*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className='text-sm text-slate-500'>Approved</p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className='p-2 sm:p-3 large:p-4 flex flex-col border border-slate-500 border-dashed'>*/}
|
||||
{/* <p className='text-base font-bold text-white-body'>*/}
|
||||
{/* <CustomCounter targetNumber={1} timeInSeconds={1} />*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className='text-sm text-slate-500'>Rejected</p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className='p-2 sm:p-3 large:p-4 flex flex-col border border-slate-500 border-dashed'>*/}
|
||||
{/* <p className='text-base font-bold text-white-body'>*/}
|
||||
{/* <CustomCounter targetNumber={1} timeInSeconds={1} />*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className='text-sm text-slate-500'>Created</p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div className='flex flex-col gap-4'>
|
||||
<p className='text-base text-white-body font-bold'>Recent Loans</p>
|
||||
<div className='flex flex-col gap-4'>
|
||||
<div className='flex gap-3 items-center'>
|
||||
<div className='px-4 py-2 bg-[#0E172E] rounded-md'>
|
||||
<img src={Img} className='w-8' alt="Order Image" />
|
||||
</div>
|
||||
<div className='flex-col'>
|
||||
<p className='text-base font-bold text-white-body'>Project Briefing</p>
|
||||
<p className='text-sm text-slate-500'>Project Manager</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex gap-3 items-center'>
|
||||
<div className='px-4 py-2 bg-[#0E172E] rounded-md'>
|
||||
<img src={Img} className='w-8' alt="Order Image" />
|
||||
</div>
|
||||
<div className='flex-col'>
|
||||
<p className='text-base font-bold text-white-body'>Project Briefing</p>
|
||||
<p className='text-sm text-slate-500'>Project Manager</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex gap-3 items-center'>
|
||||
<div className='px-4 py-2 bg-[#0E172E] rounded-md'>
|
||||
<img src={Img} className='w-8' alt="Order Image" />
|
||||
</div>
|
||||
<div className='flex-col'>
|
||||
<p className='text-base font-bold text-white-body'>Project Briefing</p>
|
||||
<p className='text-sm text-slate-500'>Project Manager</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex gap-3 items-center'>
|
||||
<div className='px-4 py-2 bg-[#0E172E] rounded-md'>
|
||||
<img src={Img} className='w-8' alt="Order Image" />
|
||||
</div>
|
||||
<div className='flex-col'>
|
||||
<p className='text-base font-bold text-white-body'>Project Briefing</p>
|
||||
<p className='text-sm text-slate-500'>Project Manager</p>
|
||||
</div>
|
||||
</div>
|
||||
{data.map((item, index)=>{
|
||||
return (
|
||||
<div key={index} className='flex gap-3 items-center'>
|
||||
<div className='px-4 py-2 bg-[#0E172E] rounded-md'>
|
||||
<img src={Img} className='w-8' alt="Order Image" />
|
||||
</div>
|
||||
<div className='flex-col'>
|
||||
<p className='text-base font-bold text-white-body'>Project Briefing</p>
|
||||
<p className='text-sm text-slate-500'>Project Manager</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 (
|
||||
<div className='w-full h-full flex flex-col gap-8'>
|
||||
{/* Menu */}
|
||||
<div className='grid grid-cols-3 gap-8'>
|
||||
<button name='orders' onClick={() => handleActiveMenu('orders')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'orders' && 'scale-[1.2]'}`}>
|
||||
<Icons name='dashboard' className='text-3xl' />
|
||||
</button>
|
||||
{/*<button name='tickets' onClick={() => handleActiveMenu('tickets')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'tickets' && 'scale-[1.2]'}`}>*/}
|
||||
{/* <Icons name='settings' className='text-3xl' />*/}
|
||||
{/*</button>*/}
|
||||
{/*<button name='tasks' onClick={() => handleActiveMenu('tasks')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'tasks' && 'scale-[1.2]'}`}>*/}
|
||||
{/* <Icons name='dashboard' className='text-3xl' />*/}
|
||||
{/*</button>*/}
|
||||
</div>
|
||||
const {data, isFetching, isError, error} = useQuery({
|
||||
queryKey: queryKeys.recent_loans,
|
||||
queryFn: () => getRecentLoans()
|
||||
})
|
||||
|
||||
{/* Body */}
|
||||
{active === 'orders' && <Orders />}
|
||||
{/*{active == 'tickets' && <Tickets />}*/}
|
||||
{/*{active == 'tasks' && <Tasks />}*/}
|
||||
</div>
|
||||
)
|
||||
console.log('data', data?.data)
|
||||
|
||||
return (
|
||||
<div className='w-full h-full flex flex-col gap-8'>
|
||||
{/* Menu */}
|
||||
<div className='grid grid-cols-3 gap-8'>
|
||||
<button name='orders' onClick={() => handleActiveMenu('orders')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'orders' && 'scale-[1.2]'}`}>
|
||||
<Icons name='dashboard' className='text-3xl' />
|
||||
</button>
|
||||
{/*<button name='tickets' onClick={() => handleActiveMenu('tickets')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'tickets' && 'scale-[1.2]'}`}>*/}
|
||||
{/* <Icons name='settings' className='text-3xl' />*/}
|
||||
{/*</button>*/}
|
||||
{/*<button name='tasks' onClick={() => handleActiveMenu('tasks')} className={`flex justify-center items-center px-2 py-3 large:px-4 large:py-5 rounded-md shadow-round_white bg-[#0E172E] text-white-body hover:scale-[1.1] ${active == 'tasks' && 'scale-[1.2]'}`}>*/}
|
||||
{/* <Icons name='dashboard' className='text-3xl' />*/}
|
||||
{/*</button>*/}
|
||||
</div>
|
||||
|
||||
{/* Body */}
|
||||
{(isFetching || isError) ?
|
||||
<div className=''>
|
||||
{isError ? <p className='p-8 bg-white text-red-500'>{error.message}</p> :
|
||||
<p className='text-white'>Loading...</p>}
|
||||
</div>
|
||||
:
|
||||
<div className='w-full'>
|
||||
{active === 'orders' && <Orders data={[1,2,3,4,5]} />}
|
||||
{/*{active == 'tickets' && <Tickets />}*/}
|
||||
{/*{active == 'tasks' && <Tasks />}*/}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<div className='w-full flex flex-col gap-8'>
|
||||
@@ -61,7 +57,7 @@ export default function TransactionsCom() {
|
||||
|
||||
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
|
||||
{isError ?
|
||||
<p className='text-red-500'>{allTransactions?.error}</p>
|
||||
<p className='text-red-500'>{error?.message}</p>
|
||||
:
|
||||
<>
|
||||
{/* filter section */}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user