backend endpoint added to env file

This commit is contained in:
victorAnumudu
2025-02-18 19:13:08 +01:00
parent 07c3db6ee0
commit 8fb9e42ec4
11 changed files with 204 additions and 10 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ TWITTER_URL=https://twitter.com
INSTAGRAM_URL=https://www.instagram.com
# BACKEND END POINTS
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
REACT_APP_MAIN_API='https://devcore.digifi.chiefsoft.net'
# ENQUIRIES CONTACTS
VITE_CALL_ENDPOINT='09099000000'
+1 -1
View File
@@ -6,7 +6,7 @@ VITE_TWITTER_URL=https://twitter.com
VITE_INSTAGRAM_URL=https://www.instagram.com
# BACKEND END POINTS
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
REACT_APP_MAIN_API='https://devcore.digifi.chiefsoft.net'
# ENQUIRIES CONTACTS
VITE_CALL_ENDPOINT='09099000000'
+1 -1
View File
@@ -6,7 +6,7 @@ TWITTER_URL=https://twitter.com
INSTAGRAM_URL=https://www.instagram.com
# BACKEND END POINTS
VITE_USERS_ENDPOINT='https://digifi-apidev.chiefsoft.net/digiusers/v1'
REACT_APP_MAIN_API='https://devcore.digifi.chiefsoft.net'
# ENQUIRIES CONTACTS
VITE_CALL_ENDPOINT='09099000000'
+14
View File
@@ -1,5 +1,6 @@
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { QueryClientProvider, QueryClient } from '@tanstack/react-query'
import SiteRoutes from './SiteRoutes';
import LogoutModal from './components/layouts/LogoutModal';
@@ -17,12 +18,25 @@ function App() {
window.scrollTo(0,0)
},[pathname])
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 3,
// refetchOnMount: false,
staleTime: Infinity // can also be a number in millisecond
},
},
})
return (
<>
<QueryClientProvider client={queryClient}>
<SiteRoutes />
{/* LOGOUT MODAL */}
{logoutModal && <LogoutModal close={()=>setLogoutModal(false)} />}
</QueryClientProvider>
</>
);
}
+1 -1
View File
@@ -4,7 +4,7 @@ const RouteLinks = {
homePage: '/',
usersPage: '/users',
approvedLoans: '/loans/approved',
disbursements: '/loans/disbursements',
apply: '/loans/apply',
}
export default RouteLinks
+2 -2
View File
@@ -9,7 +9,7 @@ import LoginPage from './pages/LoginPage' // LOGIN PAGE
import HomePage from './pages/HomePage' // Home PAGE
import UsersPage from './pages/UsersPage' // Users PAGE
import ApprovedLoansPage from './pages/ApprovedLoansPage' // APPROVED LOANS PAGE
import Disbursements from './pages/Disbursements' // DISBURSEMENTS LOANS PAGE
import ApplyPage from './pages/ApplyPage' // APPLY LOANS PAGE
// const Home = lazy(() => import('./pages/Home'));
@@ -23,7 +23,7 @@ export default function SiteRoutes() {
<Route path={RouteLinks.homePage} element={<HomePage />} /> {`*/HOME PAGE*/`}
<Route path={RouteLinks.usersPage} element={<UsersPage />} /> {`*/USERS PAGE*/`}
<Route path={RouteLinks.approvedLoans} element={<ApprovedLoansPage />} /> {`*/APPROVED LOANS PAGE*/`}
<Route path={RouteLinks.disbursements} element={<Disbursements />} /> {`*/DISBURSEMENTS LOANS PAGE*/`}
<Route path={RouteLinks.apply} element={<ApplyPage />} /> {`*/APPLY LOANS PAGE*/`}
</Route>
{/* ERROR PAGE */}
@@ -93,9 +93,9 @@ export default function DashboardAside({shrinkAside=false}) {
const asideNavLinks = [
{name:'Dashboard', status:1, icon: 'dashboard', to: RouteLinks.homePage},
{name:'Salary Loan', title:'Loan', status:1, icon: 'money', subLinks: [
{name: 'Applications', status:1, icon: 'dot', to: '#'},
{name: 'Select', status:1, icon: 'dot', to: '#'},
{name: 'Apply', status:1, icon: 'dot', to: RouteLinks.apply},
{name: 'Approved', status:1, icon: 'dot', to: RouteLinks.approvedLoans},
{name: 'Disbursements', status:1, icon: 'dot', to: RouteLinks.disbursements},
{name: 'Payments', status:1, icon: 'dot', to: '#'},
{name: 'Configuration', status:1, icon: 'dot', to: '#'},
],
@@ -0,0 +1,118 @@
import { ReactNode, useEffect, useState } from "react";
import MainBtn from "../MainBtn";
export default function TableWrapper({
data = [],
itemsPerPage = 5,
filterItem,
children,
}) {
const [isLoading, setIsLoading] = useState(true)
const [searchTerm, setSearchTerm] = useState("");
const [filteredData, setFilteredData] = useState(data);
const [currentPage, setCurrentPage] = useState(0);
const [newData, setNewData] = useState([]);
const numberOfSelection = itemsPerPage;
const handlePrev = () => {
if (currentPage != 0) {
setCurrentPage((prev) => prev - numberOfSelection);
}
};
const handleNext = () => {
if (currentPage < data.length) {
setCurrentPage((prev) => prev + numberOfSelection);
}
};
const handleSearch = ({ target: { value } }, name) => {
setSearchTerm(value);
let newFilteredData = data.filter((item) =>
item[name].toLowerCase().startsWith(value.toLowerCase())
);
setFilteredData(newFilteredData);
setCurrentPage(0);
};
useEffect(() => {
setIsLoading(true)
setTimeout(()=>{
setNewData(
filteredData?.slice(currentPage, numberOfSelection + currentPage)
);
setIsLoading(false)
},1000)
}, [currentPage, filteredData]);
useEffect(()=>{
setCurrentPage(0)
},[itemsPerPage])
return (
<div className="p-2 w-full bg-white border-b dark:bg-gray-800 rounded-md">
{data.length > 0 && filterItem && (
<div className="mb-10 flex justify-end items-center gap-2">
{filterItem.map((item, index) => (
<label
key={index}
className="flex flex-col sm:flex-row items-center gap-2 text-slate-600 dark:text-slate-100 transition-all duration-500"
>
Search by {item[0].toUpperCase() + item.slice(1)}
<input
name={item}
type="text"
className="py-1 px-2 text-sm min-w-[100px] text-black dark:text-white bg-white dark:bg-slate-800 rounded-full border-0 outline-none ring-1 ring-slate-300 dark:ring-white transition-all duration-500"
value={searchTerm}
onChange={(e) => {
handleSearch(e, item);
}}
/>
</label>
))}
</div>
)}
<div className="flex flex-col">
<div className="w-full">
{children({ data: newData })}
</div>
{/* PAGINATION BUTTON */}
{newData.length > 0 &&
<div className='p-2 w-full flex flex-col lg:flex-row justify-center items-center gap-3 md:gap-6'>
<div className="text-sm text-center lg:text-left font-normal text-gray-500 dark:text-gray-400 block w-full">Showing <span className="font-semibold text-gray-900 dark:text-white">
{isLoading ? '----' : `${currentPage + 1}-${currentPage + numberOfSelection >= data.length ? data.length : (currentPage + numberOfSelection)}`}</span> of <span className="font-semibold text-gray-900 dark:text-white">{data.length}</span>
</div>
<div className='flex items-center gap-3 md:gap-6'>
<MainBtn
onClick={handlePrev}
text='Prev'
className={`${currentPage == 0 ? 'bg-sky-600/50 pointer-events-none' : 'bg-sky-600'} text-white-light`}
disabled={isLoading}
/>
<MainBtn
onClick={handleNext}
text='Next'
className={`${currentPage + numberOfSelection >= data.length ? 'bg-sky-600/50 pointer-events-none' : 'bg-sky-600'} text-white-light`}
disabled={isLoading}
/>
</div>
</div>
}
</div>
{isLoading && <TableIsLoading />}
</div>
);
}
const TableIsLoading = () => {
return (
<div className="w-full fixed z-[991] inset-0 flex justify-center items-center">
<p className="rounded-md shadow-md p-4 bg-white/90 dark:bg-gray-900 text-brown dark:text-white">Loading...</p>
</div>
)
}
@@ -1,10 +1,10 @@
import React from 'react'
import BreadcrumbCom from '../components/breadcrumb/BreadcrumbCom'
export default function Disbursements() {
export default function ApplyPage() {
return (
<div className='w-full'>
<BreadcrumbCom title='Disbursements' paths={['Dashboard', 'Disbursements']} />
<BreadcrumbCom title='Apply' paths={['Dashboard', 'Apply']} />
<p className=''>
coming soon ...
</p>
+5
View File
@@ -0,0 +1,5 @@
const queryKeys = {
dummy: ['']
}
export default queryKeys
+57
View File
@@ -0,0 +1,57 @@
import axios from "axios"
axios.interceptors.request.use(
config => {
config.headers = {
Accept: "application/json",
"Access-Control-Allow-Origin": "*",
// "Access-Control-Expose-Headers": "Access-Control-Allow-Origin",
// "Access-Control-Allow-Headers": "Origin, X-API-KEY, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Allow-Headers, Authorization, observe, enctype, Content-Length, X-Csrf-Token",
"Content-Type": "application/json;charset=UTF-8",
// 'Authorization': `Bearer ${localStorage.getItem('token')}`
};
// config.headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`;
// config.baseURL = process.env.REACT_APP_MAIN_API
return config;
},
error => {
return Promise.reject(error);
}
);
const postAuxEnd = (path, postData, media=false) => {
const basePath = media ? process.env.REACT_APP_MAIN_API : process.env.REACT_APP_MAIN_API
return axios.post(`${basePath}${path}`, postData).then(res => {
return res
}).catch(err => {
throw new Error(err.response.data.message);
})
}
const getAuxEnd = (path, reqData= null) => {
const basePath = process.env.REACT_APP_MAIN_API
return axios.get(`${basePath}${path}`,{ params: reqData }).then(res => {
return res
// localStorage.clear();
// window.location.href = `/login?sessionExpired=true`;
}).catch(err => {
throw new Error(err);
// throw new Error(err.response.data.message);
// return err
})
}
// FUNCTION TO LOGIN USER IN
export const loginUser = (reqData) => {
let postData = {
...reqData
}
return postAuxEnd('/salary/login', postData, false)
}
// FUNCTION TO GET DEMO USERS
export const demoUsersList = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/salary/demousers`, postData)
}