Compare commits

...

10 Commits

Author SHA1 Message Date
victorAnumudu 1a55cb6a9c added login input fields max length and users page 2025-09-13 16:35:43 +01:00
ameye b303af13f0 Merge branch 'usecontext-fix' of MERMS/MermsFirstOffice into master 2025-09-09 16:48:00 +00:00
victorAnumudu f2671c44a2 fixed use context error 2025-09-09 17:40:41 +01:00
CHIEFSOFT\ameye 59184d38aa Text xhANGES 2025-09-09 12:05:18 -04:00
CHIEFSOFT\ameye 73bc359a77 fix data 2025-09-02 17:03:43 -04:00
CHIEFSOFT\ameye 80fdd6e817 Fix text 2025-09-02 16:52:15 -04:00
ameye 0efa3ffa27 Merge branch 'bug-fix' of MERMS/MermsFirstOffice into master 2025-09-02 20:41:04 +00:00
victorAnumudu 96e6b6853c fixed page error 2025-09-02 20:49:25 +01:00
ameye eddbc7e13f Merge branch 'subscription-table-fix' of MERMS/MermsFirstOffice into master 2025-09-02 19:20:17 +00:00
CHIEFSOFT\ameye e4d6725dea fix names 2025-09-02 13:40:09 -04:00
32 changed files with 566 additions and 130 deletions
+2 -1
View File
@@ -22,7 +22,8 @@
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build_RE": "react-scripts build",
"build": "GENERATE_SOURCEMAP=false react-scripts build -e .env.production",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
+1 -1
View File
@@ -7,7 +7,7 @@
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
name="description" name="description"
content="digiFi global back office systems" content="MERMS BackOffice Systems"
/> />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- <!--
+2 -2
View File
@@ -4,7 +4,7 @@ import { QueryClientProvider, QueryClient } from '@tanstack/react-query'
import SiteRoutes from './SiteRoutes'; import SiteRoutes from './SiteRoutes';
import LogoutModal from './components/layouts/LogoutModal'; import LogoutModal from './components/layouts/LogoutModal';
import { generalLayoutContext } from './context/GeneralLayoutContext'; import { GeneralLayoutContext } from './context/GeneralLayoutContext';
import './App.css'; import './App.css';
@@ -24,7 +24,7 @@ function App() {
const {pathname} = useLocation() const {pathname} = useLocation()
const {logoutModal, setLogoutModal} = generalLayoutContext() const {logoutModal, setLogoutModal} = GeneralLayoutContext()
useEffect(()=>{ useEffect(()=>{
window.scrollTo(0,0) window.scrollTo(0,0)
+3 -2
View File
@@ -4,10 +4,11 @@ const RouteLinks = {
customerPage: '/customer', customerPage: '/customer',
subscriptions: '/subscriptions', subscriptions: '/subscriptions',
billings: '/billings', billings: '/billings',
products: '/products',
users: '/users',
recentSignupPage: '/recent-signup',
loansPage: '/loans', loansPage: '/loans',
transactionsPage: '/transactions',
offers: '/offers',
transaction_details_page: '/transaction/details', transaction_details_page: '/transaction/details',
errorPage: '*', errorPage: '*',
} }
+6 -2
View File
@@ -10,11 +10,13 @@ import HomePage from './pages/HomePage' // Home PAGE
import CustomerPage from './pages/CustomerPage' // REPAYMENTS PAGE import CustomerPage from './pages/CustomerPage' // REPAYMENTS PAGE
import SubscriptionsPage from './pages/SubscriptionsPage' // TRANSACTIONS PAGE import SubscriptionsPage from './pages/SubscriptionsPage' // TRANSACTIONS PAGE
import BillingsPage from './pages/BillingsPage' // LOAN CHARGES PAGE import BillingsPage from './pages/BillingsPage' // LOAN CHARGES PAGE
import UsersPage from './pages/UsersPage' // USERS PAGE
import ProductsPage from './pages/ProductsPage' // PRODUCTS PAGE
import LoansPage from './pages/LoansPage' // SELECTED LOANS PAGE import LoansPage from './pages/LoansPage' // SELECTED LOANS PAGE
import TransactionDetailsPage from './pages/TransactionDetailsPage' // TRANSACTION DETAILS PAGE import TransactionDetailsPage from './pages/TransactionDetailsPage' // TRANSACTION DETAILS PAGE
import OffersPage from './pages/OffersPage' // LOAN OFFERS PAGE
import ErrorPage from './pages/ErrorPage' // ERROR PAGE import ErrorPage from './pages/ErrorPage' // ERROR PAGE
import RecentSignupPage from './pages/RecentSignupPage'
// const Home = lazy(() => import('./pages/Home')); // const Home = lazy(() => import('./pages/Home'));
@@ -29,10 +31,12 @@ export default function SiteRoutes() {
<Route path={RouteLinks.subscriptions} element={<SubscriptionsPage />} /> {`*/SUBSCRIPTIONS PAGE*/`} <Route path={RouteLinks.subscriptions} element={<SubscriptionsPage />} /> {`*/SUBSCRIPTIONS PAGE*/`}
<Route path={RouteLinks.customerPage} element={<CustomerPage />} /> {`*/CUSTOMER PAGE*/`} <Route path={RouteLinks.customerPage} element={<CustomerPage />} /> {`*/CUSTOMER PAGE*/`}
<Route path={RouteLinks.billings} element={<BillingsPage />} /> {`*/BILLINGS PAGE*/`} <Route path={RouteLinks.billings} element={<BillingsPage />} /> {`*/BILLINGS PAGE*/`}
<Route path={RouteLinks.products} element={<ProductsPage />} /> {`*/PRODUCTS PAGE*/`}
<Route path={RouteLinks.users} element={<UsersPage />} /> {`*/USERS PAGE*/`}
<Route path={RouteLinks.recentSignupPage} element={<RecentSignupPage />} /> {`*/RECENT SIGNUP PAGE*/`}
<Route path={RouteLinks.loansPage} element={<LoansPage />} /> {`*/LOANS PAGE*/`} <Route path={RouteLinks.loansPage} element={<LoansPage />} /> {`*/LOANS PAGE*/`}
<Route path={RouteLinks.transaction_details_page} element={<TransactionDetailsPage />} /> {`*/TRANSACTION PAGE*/`} <Route path={RouteLinks.transaction_details_page} element={<TransactionDetailsPage />} /> {`*/TRANSACTION PAGE*/`}
<Route path={RouteLinks.offers} element={<OffersPage />} /> {`*/LOAN OFFERS PAGE*/`}
</Route> </Route>
{/* ERROR PAGE */} {/* ERROR PAGE */}
+2 -2
View File
@@ -20,8 +20,8 @@ const initialValues = {
// To get the validation schema // To get the validation schema
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
username: Yup.string().required("username is required"), username: Yup.string().required("username is required").min(6, 'must be upto 6 characters').max(25, 'must not exceed 25 characters'),
password: Yup.string().required("password is required").min(6, 'must be upto 6 characters').max(12, 'must not exceed 12 characters'), password: Yup.string().required("password is required").min(6, 'must be upto 6 characters').max(25, 'must not exceed 25 characters'),
}); });
export default function LoginCom() { export default function LoginCom() {
+2 -2
View File
@@ -1,7 +1,7 @@
import { LuSunDim } from "react-icons/lu"; import { LuSunDim } from "react-icons/lu";
import { IoMdSunny } from "react-icons/io"; import { IoMdSunny } from "react-icons/io";
import { generalLayoutContext } from "../../context/GeneralLayoutContext" import { GeneralLayoutContext } from "../../context/GeneralLayoutContext"
import UserAvatar from '../../assets/user_avatar.jpg' import UserAvatar from '../../assets/user_avatar.jpg'
import HandBurger from "./HandBurger" import HandBurger from "./HandBurger"
@@ -15,7 +15,7 @@ export default function DashboardHeader() {
// let {pathname} = useLocation() // let {pathname} = useLocation()
const {theme, handleTheme, setLogoutModal, activeMenu, handleActiveMenu, showAsideDrawer, setShowAsideDrawer} = generalLayoutContext() const {theme, handleTheme, setLogoutModal, activeMenu, handleActiveMenu, showAsideDrawer, setShowAsideDrawer} = GeneralLayoutContext()
return ( return (
<> <>
+2 -2
View File
@@ -1,7 +1,7 @@
import { Outlet } from 'react-router-dom' import { Outlet } from 'react-router-dom'
import DashboardHeader from './DashboardHeader' import DashboardHeader from './DashboardHeader'
import { generalLayoutContext } from '../../context/GeneralLayoutContext' import { GeneralLayoutContext } from '../../context/GeneralLayoutContext'
import DashboardAside from './aside/DashboardAside' import DashboardAside from './aside/DashboardAside'
import RightAsideBar from './rightaside/RightAsideBar' import RightAsideBar from './rightaside/RightAsideBar'
@@ -9,7 +9,7 @@ export default function DashboardLayout() {
// let {pathname} = useLocation() // let {pathname} = useLocation()
const {showAsideDrawer, setShowAsideDrawer} = generalLayoutContext() const {showAsideDrawer, setShowAsideDrawer} = GeneralLayoutContext()
return ( return (
<div className='w-full flex gap-10 relative m-auto h-screen overflow-x-hidden overflow-y-auto bg-white-body dark:bg-black-body p-8 pt-0 lg:p-10'> <div className='w-full flex gap-10 relative m-auto h-screen overflow-x-hidden overflow-y-auto bg-white-body dark:bg-black-body p-8 pt-0 lg:p-10'>
@@ -4,7 +4,6 @@ import { FaArrowRight, FaArrowLeft } from "react-icons/fa6";
import DashboardAside from './aside/DashboardAside' import DashboardAside from './aside/DashboardAside'
import DashboardHeader from './DashboardHeader' import DashboardHeader from './DashboardHeader'
import { generalLayoutContext } from '../../context/GeneralLayoutContext'
export default function DashboardLayout() { export default function DashboardLayout() {
const [shrinkAside, setShrinkAside] = useState(false) const [shrinkAside, setShrinkAside] = useState(false)
+2 -2
View File
@@ -1,10 +1,10 @@
import { Link, useLocation } from "react-router-dom" import { Link, useLocation } from "react-router-dom"
import Icons from "../../Icons" import Icons from "../../Icons"
import { generalLayoutContext } from "../../../context/GeneralLayoutContext" import { GeneralLayoutContext } from "../../../context/GeneralLayoutContext"
export default function AsideLink({name, to, icon}) { export default function AsideLink({name, to, icon}) {
const {shrinkAside, setShowAsideDrawer} = generalLayoutContext() const {shrinkAside, setShowAsideDrawer} = GeneralLayoutContext()
const {pathname} = useLocation() const {pathname} = useLocation()
@@ -2,12 +2,12 @@ import { useState } from "react";
import { useLocation } from "react-router-dom" import { useLocation } from "react-router-dom"
import { FaCaretDown } from "react-icons/fa"; import { FaCaretDown } from "react-icons/fa";
import Icons from "../../Icons"; import Icons from "../../Icons";
import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { GeneralLayoutContext } from "../../../context/GeneralLayoutContext";
export default function AsideLinkWithSubLinks({name, icon, to, children, isOpen}) { export default function AsideLinkWithSubLinks({name, icon, to, children, isOpen}) {
const {shrinkAside} = generalLayoutContext() const {shrinkAside} = GeneralLayoutContext()
const {pathname} = useLocation() const {pathname} = useLocation()
@@ -5,7 +5,7 @@ import MainBtn from "../../MainBtn";
import AsideLink from "./AsideLink"; import AsideLink from "./AsideLink";
import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks"; import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { GeneralLayoutContext } from "../../../context/GeneralLayoutContext";
import { TbLogout2 } from "react-icons/tb"; import { TbLogout2 } from "react-icons/tb";
import UserAvatar from '../../../assets/user_avatar.jpg' import UserAvatar from '../../../assets/user_avatar.jpg'
import Icons from "../../Icons"; import Icons from "../../Icons";
@@ -14,7 +14,7 @@ export default function DashboardAside() {
const {pathname} = useLocation() const {pathname} = useLocation()
const {setLogoutModal, activeMenu, handleActiveMenu} = generalLayoutContext() const {setLogoutModal, activeMenu, handleActiveMenu} = GeneralLayoutContext()
const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS
const {role}= userDetails const {role}= userDetails
@@ -138,13 +138,13 @@ export default function DashboardAside() {
const asideNavLinks = [ const asideNavLinks = [
{name:'Dashboard', status:1, icon: 'dashboard', to: RouteLinks.homePage}, {name:'Dashboard', status:1, icon: 'dashboard', to: RouteLinks.homePage},
{name:'Deployments', title:'Activities', status:1, icon: 'arrow-right', subLinks: [ {name:'Deployments', title:'Activities', status:1, icon: 'arrow-right', subLinks: [
{name: 'Active', status:1, icon: 'dot', to: RouteLinks.transactionsPage}, {name: 'Recent Signup', status:1, icon: 'dot', to: RouteLinks.recentSignupPage},
{name: 'Subscriptions', status:1, icon: 'dot', to: RouteLinks.subscriptions}, {name: 'Provisions', status:1, icon: 'dot', to: RouteLinks.subscriptions},
{name: 'Customers', status:1, icon: 'dot', to: RouteLinks.customerPage}, {name: 'Customers', status:1, icon: 'dot', to: RouteLinks.customerPage},
{name: 'Billings', status:1, icon: 'dot', to: RouteLinks.billings}, {name: 'Billings', status:1, icon: 'dot', to: RouteLinks.billings},
{name: 'Configurations', status:1, icon: 'arrow-right', subLinks: [ {name: 'Configurations', status:1, icon: 'arrow-right', subLinks: [
{name: 'Sub. Settings', status:1, icon: 'dot', to: RouteLinks.offers }, {name: 'Product Settings', status:1, icon: 'dot', to: RouteLinks.products },
{name: 'Users Manager', status:1, icon: 'dot', to: RouteLinks.offers }, {name: 'Admin Manager', status:1, icon: 'dot', to: RouteLinks.users },
] ]
}, },
], ],
@@ -6,7 +6,7 @@ import MainBtn from "../../MainBtn";
import AsideLink from "./AsideLink"; import AsideLink from "./AsideLink";
import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks"; import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { GeneralLayoutContext } from "../../../context/GeneralLayoutContext";
import { TbLogout2 } from "react-icons/tb"; import { TbLogout2 } from "react-icons/tb";
@@ -14,7 +14,7 @@ export default function DashboardAside({shrinkAside=false}) {
const {pathname} = useLocation() const {pathname} = useLocation()
const {setLogoutModal} = generalLayoutContext() const {setLogoutModal} = GeneralLayoutContext()
const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS
const {role}= userDetails const {role}= userDetails
@@ -6,7 +6,7 @@ import MainBtn from "../../MainBtn";
import AsideLink from "./AsideLink"; import AsideLink from "./AsideLink";
import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks"; import AsideLinkWithSubLinks from "./AsideLinkWithSubLinks";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { generalLayoutContext } from "../../../context/GeneralLayoutContext"; import { GeneralLayoutContext } from "../../../context/GeneralLayoutContext";
import { TbLogout2 } from "react-icons/tb"; import { TbLogout2 } from "react-icons/tb";
@@ -14,7 +14,7 @@ export default function DashboardAside({shrinkAside=false}) {
const {pathname} = useLocation() const {pathname} = useLocation()
const {setLogoutModal} = generalLayoutContext() const {setLogoutModal} = GeneralLayoutContext()
const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS const {userDetails} = useSelector((state) => state.userDetails) // GETS LOGGED IN USER ROLE DETAILS
const {role}= userDetails const {role}= userDetails
@@ -2,11 +2,21 @@ import React from 'react'
import Img from '../../../assets/user_avatar.jpg' import Img from '../../../assets/user_avatar.jpg'
import CustomCounter from '../../CustomCounter' import CustomCounter from '../../CustomCounter'
export default function Orders() { export default function RecentChecks({data, isFetching, isError, error}) {
return ( 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='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'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Recent Checks</p> <p className='text-base text-white-body font-bold'>Recent Checks</p>
{isFetching ?
// <p className='text-base text-white-body font-bold'>Loading...</p>
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='grid grid-cols-2 gap-4 sm:gap-6 large:gap-8'> <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'> <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'> <p className='text-base font-bold text-white-body'>
@@ -33,9 +43,18 @@ export default function Orders() {
<p className='text-sm text-slate-500'>Created</p> <p className='text-sm text-slate-500'>Created</p>
</div> </div>
</div> </div>
}
</div> </div>
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Recent Login</p> <p className='text-base text-white-body font-bold'>Recent Login</p>
{isFetching ?
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<div className='flex gap-3 items-center'> <div className='flex gap-3 items-center'>
<div className='px-4 py-2 bg-[#0E172E] rounded-md'> <div className='px-4 py-2 bg-[#0E172E] rounded-md'>
@@ -74,6 +93,7 @@ export default function Orders() {
</div> </div>
</div> </div>
</div> </div>
}
</div> </div>
</div> </div>
) )
@@ -1,6 +1,9 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import queryKeys from '../../../services/queryKeys'
import { getRightSidebar } from '../../../services/siteServices'
import Icons from '../../Icons' import Icons from '../../Icons'
import Orders from './Orders' import RecentChecks from './RecentChecks'
import Tickets from './Tickets' import Tickets from './Tickets'
import Tasks from './Tasks' import Tasks from './Tasks'
@@ -13,6 +16,25 @@ export default function RightAsideBar() {
setActive(lowerStr) setActive(lowerStr)
} }
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.right_sidebar],
queryFn: () => {
// const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
// const reqData = {
// page,
// ...filterData
// }
return getRightSidebar()
},
// staleTime: 0 //0 mins
})
const recentData = [] // RECENT LIST
// const recentData = data?.data // RECENT LIST
// const pagination = data?.data?.pagination
// console.log('RIGHT', data?.data)
return ( return (
<div className='w-full h-full flex flex-col gap-8'> <div className='w-full h-full flex flex-col gap-8'>
{/* Menu */} {/* Menu */}
@@ -29,9 +51,9 @@ export default function RightAsideBar() {
</div> </div>
{/* Body */} {/* Body */}
{active == 'orders' && <Orders />} {active == 'orders' && <RecentChecks data={recentData} isFetching={isFetching} isError={isError} error={error} />}
{active == 'tickets' && <Tickets />} {active == 'tickets' && <Tickets data={recentData} isFetching={isFetching} isError={isError} error={error} />}
{active == 'tasks' && <Tasks />} {active == 'tasks' && <Tasks data={recentData} isFetching={isFetching} isError={isError} error={error} />}
</div> </div>
) )
} }
@@ -7,6 +7,14 @@ export default function Tasks() {
<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='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'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Support Tasks</p> <p className='text-base text-white-body font-bold'>Support Tasks</p>
{isFetching ?
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='grid grid-cols-2 gap-4 sm:gap-6 large:gap-8'> <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'> <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'> <p className='text-base font-bold text-white-body'>
@@ -33,9 +41,18 @@ export default function Tasks() {
<p className='text-sm text-slate-500'>Created</p> <p className='text-sm text-slate-500'>Created</p>
</div> </div>
</div> </div>
}
</div> </div>
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Best Tasks</p> <p className='text-base text-white-body font-bold'>Best Tasks</p>
{isFetching ?
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<div className='flex gap-3 items-center'> <div className='flex gap-3 items-center'>
<div className='px-4 py-2 bg-[#0E172E] rounded-md'> <div className='px-4 py-2 bg-[#0E172E] rounded-md'>
@@ -74,6 +91,7 @@ export default function Tasks() {
</div> </div>
</div> </div>
</div> </div>
}
</div> </div>
</div> </div>
) )
@@ -7,6 +7,14 @@ export default function Tickets() {
<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='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'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Recent Repayment</p> <p className='text-base text-white-body font-bold'>Recent Repayment</p>
{isFetching ?
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='grid grid-cols-2 gap-4 sm:gap-6 large:gap-8'> <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'> <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'> <p className='text-base font-bold text-white-body'>
@@ -33,9 +41,18 @@ export default function Tickets() {
<p className='text-sm text-slate-500'>Rejected</p> <p className='text-sm text-slate-500'>Rejected</p>
</div> </div>
</div> </div>
}
</div> </div>
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<p className='text-base text-white-body font-bold'>Tracked Errors</p> <p className='text-base text-white-body font-bold'>Tracked Errors</p>
{isFetching ?
<div className='w-full flex justify-center'>
<div className="w-6 h-6 border-2 border-gray-300 border-b-gray-500 rounded-full animate-spin"></div>
</div>
:
isError ?
<p className='text-base text-white-body font-bold'>{error?.message}</p>
:
<div className='flex flex-col gap-4'> <div className='flex flex-col gap-4'>
<div className='flex gap-3 items-center'> <div className='flex gap-3 items-center'>
<div className='px-4 py-2 bg-[#0E172E] rounded-md'> <div className='px-4 py-2 bg-[#0E172E] rounded-md'>
@@ -74,6 +91,7 @@ export default function Tickets() {
</div> </div>
</div> </div>
</div> </div>
}
</div> </div>
</div> </div>
) )
+5 -5
View File
@@ -64,8 +64,8 @@ export default function BillingsCom() {
<div className='w-full sm:max-w-48'> <div className='w-full sm:max-w-48'>
<select name='type' value={filter?.type} className='h-10 w-full p-2 rounded-md' onChange={handleFilter}> <select name='type' value={filter?.type} className='h-10 w-full p-2 rounded-md' onChange={handleFilter}>
<option value=''>All</option> <option value=''>All</option>
<option value='transaction_id'>Transaction ID</option> <option value='option_name'>Option Name</option>
<option value='account_id'>Account ID</option> <option value='member_id'>Member ID</option>
</select> </select>
</div> </div>
<div className='w-full sm:max-w-48'> <div className='w-full sm:max-w-48'>
@@ -88,7 +88,7 @@ export default function BillingsCom() {
Option Name Option Name
</th> </th>
<th scope="col" className="px-2"> <th scope="col" className="px-2">
Product ID Member ID
</th> </th>
<th scope="col" className="px-2 text-right"> <th scope="col" className="px-2 text-right">
Amount Amount
@@ -115,12 +115,12 @@ export default function BillingsCom() {
</td> </td>
<td className="px-2"> <td className="px-2">
<div className="text-left"> <div className="text-left">
<div className="text-base font-semibold">{item?.product_id}</div> <div className="text-base font-semibold">{item?.member_id}</div>
</div> </div>
</td> </td>
<td className="px-2"> <td className="px-2">
<div className="text-right"> <div className="text-right">
<div className="text-base font-semibold">{item?.amount}</div> <div className="text-base font-semibold">${item?.amount}</div>
{/* <div className="font-normal text-gray-500">{item?.external_url}</div> */} {/* <div className="font-normal text-gray-500">{item?.external_url}</div> */}
</div> </div>
</td> </td>
+154
View File
@@ -0,0 +1,154 @@
import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import queryKeys from '../../services/queryKeys'
import BreadcrumbCom from '../breadcrumb/BreadcrumbCom'
import TablePaginatedWrapper from '../tableWrapper/TablePaginatedWrapper'
import Icons from '../Icons'
import { getProducts } from '../../services/siteServices'
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
// import formatNumber from '../../helpers/formatNumber'
// import Avatar from '../../assets/user_avatar.jpg'
// import localImgLoader from '../../helpers/localImageLoader'
export default function ProductsCom() {
const [page, setPage] = useState(1)
const [filter, setFilter] = useState({type: '', id: ''})
const [willFilter, setWillFilter] = useState(false)
const handleFilter = ({target:{name, value}}) => {
setFilter(prev => ({...prev, [name]:value}))
}
const handleFilterByParams = () => {
if(filter.type && !filter.id){
return
}else if(!filter.type){
setPage(1)
setWillFilter(prev => !prev)
setFilter({type: '', id: ''})
}else{
setPage(1)
setWillFilter(prev => !prev)
}
}
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.products, page, willFilter],
queryFn: () => {
const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
const reqData = {
page,
...filterData
}
return getProducts(reqData)
},
staleTime: 0 //0 mins
})
const productsData = data?.data?.products // PRODUCTS LIST
const pagination = data?.data?.pagination
return (
<div className='w-full flex flex-col gap-8'>
<BreadcrumbCom title='Products' paths={['Dashboard', 'Products']} />
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{ isError ?
<p className='text-red-500'>{error?.message}</p>
:
<>
{/* filter section */}
<div className='px-2 py-2 mb-4 flex flex-col sm:flex-row flex-wrap sm:items-center gap-2'>
<Icons name='filter' className='text-3xl' />
<div className='w-full sm:max-w-48'>
<select name='type' value={filter?.type} className='h-10 w-full p-2 rounded-md' onChange={handleFilter}>
<option value=''>All</option>
<option value='product_id'>Product ID</option>
</select>
</div>
<div className='w-full sm:max-w-48'>
<input name='id' value={filter?.id} disabled={!filter.type} className={`h-10 w-full p-2 rounded-md outline-none border border-black-aside ${!filter.type && 'opacity-30'}`} onChange={handleFilter} />
</div>
<button onClick={handleFilterByParams} disabled={filter.type && !filter.id} className={`h-10 bg-primary px-2 py-1 rounded-md text-white font-medium sm:self-end ${(filter.type && !filter.id) && 'opacity-50'}`}>Submit</button>
</div>
{/* end of filter section */}
<TablePaginatedWrapper data={productsData} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}>
{({ data }) => (
<>
<table className="py-2 w-full text-sm">
<thead className="py-2 text-sm text-slate-500 text-left">
<tr>
<th scope="col" className="px-2 py-2">
Added
</th>
<th scope="col" className="px-2">
Name
</th>
<th scope="col" className="px-2">
Product ID
</th>
{/* <th scope="col" className="px-2 text-right">
Amount
</th> */}
<th scope="col" className="px-2 text-right">
Status
</th>
</tr>
</thead>
<tbody>
{(data && data.length > 0) ? data?.map((item, index) => (
<tr key={index} className="py-2 border-t border-dashed border-slate-300">
<td className="px-2 py-2">
<div className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
{/* <img className="w-10 h-10 rounded-md" src={localImgLoader(`loan_icons/${item?.type}.png`)} alt="Icon" /> */}
<div className="text-left">
<div className="text-base font-semibold">{getDateTimeFromDateString(item?.added)}</div>
</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">{item?.name}</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">{item?.product_id}</div>
</div>
</td>
{/* <td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">${item?.amount}</div>
<div className="font-normal text-gray-500">{item?.external_url}</div>
</div>
</td> */}
<td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">{item?.status}</div>
</div>
</td>
</tr>
))
:
<tr className="py-2 border-t border-dashed border-slate-300">
<td className="px-3 py-2" colSpan={4}>
<div className="flex justify-center items-center">
No Record Found
</div>
</td>
</tr>
}
</tbody>
</table>
</>
)}
</TablePaginatedWrapper>
</>
}
</div>
</div>
)
}
@@ -0,0 +1,143 @@
import { useEffect, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import queryKeys from '../../services/queryKeys'
import BreadcrumbCom from '../breadcrumb/BreadcrumbCom'
import TablePaginatedWrapper from '../tableWrapper/TablePaginatedWrapper'
import Icons from '../Icons'
import { getRecentSignup } from '../../services/siteServices'
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
import formatNumber from '../../helpers/formatNumber'
import Avatar from '../../assets/user_avatar.jpg'
export default function RecentSignupCom() {
const [page, setPage] = useState(1)
const [filter, setFilter] = useState({type: '', id: ''})
const [willFilter, setWillFilter] = useState(false)
const handleFilter = ({target:{name, value}}) => {
setFilter(prev => ({...prev, [name]:value}))
}
const handleFilterByParams = () => {
if(filter.type && !filter.id){
return
}else if(!filter.type){
setPage(1)
setWillFilter(prev => !prev)
setFilter({type: '', id: ''})
}else{
setPage(1)
setWillFilter(prev => !prev)
}
}
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.recent_signup, page, willFilter],
queryFn: () => {
const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
const reqData = {
page,
...filterData
}
return getRecentSignup(reqData)
},
staleTime: 0 //0 mins
})
const recentSignupData = data?.data?.payments // RECENT SIGNUP LIST
const pagination = data?.data?.pagination
return (
<div className='w-full flex flex-col gap-8'>
<BreadcrumbCom title='Billings' paths={['Dashboard', 'Billings']} />
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{ isError ?
<p className='text-red-500'>{error?.message}</p>
:
<>
{/* filter section */}
<div className='px-2 py-2 mb-4 flex flex-col sm:flex-row flex-wrap sm:items-center gap-2'>
<Icons name='filter' className='text-3xl' />
<div className='w-full sm:max-w-48'>
<select name='type' value={filter?.type} className='h-10 w-full p-2 rounded-md' onChange={handleFilter}>
<option value=''>All</option>
<option value='username'>Username</option>
</select>
</div>
<div className='w-full sm:max-w-48'>
<input name='id' value={filter?.id} disabled={!filter.type} className={`h-10 w-full p-2 rounded-md outline-none border border-black-aside ${!filter.type && 'opacity-30'}`} onChange={handleFilter} />
</div>
<button onClick={handleFilterByParams} disabled={filter.type && !filter.id} className={`h-10 bg-primary px-2 py-1 rounded-md text-white font-medium sm:self-end ${(filter.type && !filter.id) && 'opacity-50'}`}>Submit</button>
</div>
{/* end of filter section */}
<TablePaginatedWrapper data={recentSignupData} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}>
{({ data }) => (
<>
<table className="py-2 w-full text-sm">
<thead className="py-2 text-sm text-slate-500 text-left">
<tr>
<th scope="col" className="px-2 py-2">
Added
</th>
<th scope="col" className="px-2">
Option Name
</th>
<th scope="col" className="px-2">
Member ID
</th>
<th scope="col" className="px-2 text-right">
Status
</th>
</tr>
</thead>
<tbody>
{(data && data.length > 0) ? data?.map((item, index) => (
<tr key={index} className="py-2 border-t border-dashed border-slate-300">
<td className="px-2 py-2">
<div className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
<div className="text-left">
<div className="text-base font-semibold">{getDateTimeFromDateString(item?.added)}</div>
</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">{item?.option_name}</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">{item?.member_id}</div>
</div>
</td>
<td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">{item?.status}</div>
</div>
</td>
</tr>
))
:
<tr className="py-2 border-t border-dashed border-slate-300">
<td className="px-3 py-2" colSpan={4}>
<div className="flex justify-center items-center">
No Record Found
</div>
</td>
</tr>
}
</tbody>
</table>
</>
)}
</TablePaginatedWrapper>
</>
}
</div>
</div>
)
}
@@ -27,7 +27,7 @@ export default function TablePaginatedWrapper({
<div className='w-full flex flex-col lg:flex-row justify-center items-center gap-3 md:gap-6'> <div className='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"> <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">
{isFetching ? '----' : `page ${pagination?.current_page}`}</span> of <span className="font-semibold text-gray-900 dark:text-white">{pagination?.total_pages}</span> {isFetching ? '----' : `page ${pagination?.current_page}`}</span> of <span className="font-semibold text-gray-900 dark:text-white">{isFetching ? '----' : pagination?.total_pages}</span>
</div> </div>
<div className='flex items-center gap-3 md:gap-6'> <div className='flex items-center gap-3 md:gap-6'>
<MainBtn <MainBtn
@@ -51,7 +51,7 @@ export default function SubscriptionsCom() {
return ( return (
<div className='w-full flex flex-col gap-8'> <div className='w-full flex flex-col gap-8'>
<BreadcrumbCom title='Subscriptions' paths={['Dashboard', 'Subscriptions']} /> <BreadcrumbCom title='Provisions' paths={['Dashboard', 'Provisions']} />
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'> <div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{ isError ? { isError ?
@@ -1,69 +1,101 @@
import React, { useState } from 'react' import { useState } from 'react'
import { useQuery } from "@tanstack/react-query"; import { useQuery } from '@tanstack/react-query'
import queryKeys from '../../services/queryKeys'
import BreadcrumbCom from '../breadcrumb/BreadcrumbCom' import BreadcrumbCom from '../breadcrumb/BreadcrumbCom'
import TablePaginatedWrapper from '../tableWrapper/TablePaginatedWrapper' import TablePaginatedWrapper from '../tableWrapper/TablePaginatedWrapper'
import Icons from '../Icons' import Icons from '../Icons'
import { getUsers } from '../../services/siteServices'
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
// import formatNumber from '../../helpers/formatNumber'
// import Avatar from '../../assets/user_avatar.jpg'
// import localImgLoader from '../../helpers/localImageLoader'
import Avatar from '../../assets/user_avatar.jpg'
import queryKeys from '../../services/queryKeys'
import { getOffers } from '../../services/siteServices'
import getDateFromDateString from '../../helpers/GetDateFromDateString';
import formatNumber from '../../helpers/formatNumber';
export default function OffersCom() { export default function UsersCom() {
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [filter, setFilter] = useState({type: '', id: ''})
const [willFilter, setWillFilter] = useState(false)
const handleFilter = ({target:{name, value}}) => {
setFilter(prev => ({...prev, [name]:value}))
}
const handleFilterByParams = () => {
if(filter.type && !filter.id){
return
}else if(!filter.type){
setPage(1)
setWillFilter(prev => !prev)
setFilter({type: '', id: ''})
}else{
setPage(1)
setWillFilter(prev => !prev)
}
}
const {data, isFetching, isError, error} = useQuery({ const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.offers, page], queryKey: [...queryKeys.users, page, willFilter],
queryFn: () => getOffers({page}), queryFn: () => {
staleTime: 0, const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
// placeholderData: keepPreviousData, const reqData = {
page,
...filterData
}
return getUsers(reqData)
},
staleTime: 0 //0 mins
}) })
const usersData = data?.data?.users // USERS LIST
const offers = data?.data?.offers // LOAN CHARGES LIST
const pagination = data?.data?.pagination const pagination = data?.data?.pagination
console.log('offers', offers) // console.log('DATA', data?.data)
return ( return (
<div className='w-full flex flex-col gap-8'> <div className='w-full flex flex-col gap-8'>
<BreadcrumbCom title='Offers' paths={['Dashboard', 'Offers']} /> <BreadcrumbCom title='Users' paths={['Dashboard', 'Users']} />
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'> <div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{isFetching ? { isError ?
<> <p className='text-red-500'>{error?.message}</p>
<p className='text-slate-800'>Loading...</p>
</>
: isError ?
<p className='text-red-500'>{error.message}</p>
: :
<TablePaginatedWrapper data={offers} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}> <>
{/* filter section */}
<div className='px-2 py-2 mb-4 flex flex-col sm:flex-row flex-wrap sm:items-center gap-2'>
<Icons name='filter' className='text-3xl' />
<div className='w-full sm:max-w-48'>
<select name='type' value={filter?.type} className='h-10 w-full p-2 rounded-md' onChange={handleFilter}>
<option value=''>All</option>
<option value='email'>Email</option>
</select>
</div>
<div className='w-full sm:max-w-48'>
<input name='id' value={filter?.id} disabled={!filter.type} className={`h-10 w-full p-2 rounded-md outline-none border border-black-aside ${!filter.type && 'opacity-30'}`} onChange={handleFilter} />
</div>
<button onClick={handleFilterByParams} disabled={filter.type && !filter.id} className={`h-10 bg-primary px-2 py-1 rounded-md text-white font-medium sm:self-end ${(filter.type && !filter.id) && 'opacity-50'}`}>Submit</button>
</div>
{/* end of filter section */}
<TablePaginatedWrapper data={usersData} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}>
{({ data }) => ( {({ data }) => (
<> <>
<table className="py-2 w-full text-sm"> <table className="py-2 w-full text-sm">
<thead className="py-2 text-sm text-slate-500 text-left"> <thead className="py-2 text-sm text-slate-500 text-left">
<tr> <tr>
<th scope="col" className="px-2 py-2"> <th scope="col" className="px-2 py-2">
Added
</th>
<th scope="col" className="px-2">
Name Name
</th> </th>
<th scope="col" className="px-2 text-right"> <th scope="col" className="px-2">
Interest Rate Email
</th> </th>
{/* <th scope="col" className="px-2 text-right">
Amount
</th> */}
<th scope="col" className="px-2 text-right"> <th scope="col" className="px-2 text-right">
Insurance Rate Status
</th>
<th scope="col" className="px-2 text-right">
Mgt. Rate
</th>
<th scope="col" className="px-2 text-right">
Max/Min Amount
</th>
<th scope="col" className="px-2 text-right">
Tenor
</th>
<th scope="col" className="px-2 text-right">
Action
</th> </th>
</tr> </tr>
</thead> </thead>
@@ -72,51 +104,38 @@ export default function OffersCom() {
<tr key={index} className="py-2 border-t border-dashed border-slate-300"> <tr key={index} className="py-2 border-t border-dashed border-slate-300">
<td className="px-2 py-2"> <td className="px-2 py-2">
<div className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'> <div className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
<img className="w-10 h-10 rounded-md" src={Avatar} alt="Jese image" /> {/* <img className="w-10 h-10 rounded-md" src={localImgLoader(`loan_icons/${item?.type}.png`)} alt="Icon" /> */}
<div className="text-left"> <div className="text-left">
<div className="text-base font-semibold">{item?.product_id || ''}</div> <div className="text-base font-semibold">{getDateTimeFromDateString(item?.added)}</div>
{/* <div className="font-normal text-gray-500 line-clamp-1">{item?.description}</div> */}
</div> </div>
</div> </div>
</td> </td>
<td className="px-2"> <td className="px-2">
<div className="text-right"> <div className="text-left">
<div className="font-normal text-gray-500">{formatNumber(item?.interest_rate)}</div> <div className="text-base font-semibold">{item?.name}</div>
</div> </div>
</td> </td>
<td className="px-2"> <td className="px-2">
<div className="text-right"> <div className="text-left">
<div className="font-normal text-gray-500">{formatNumber(item?.insurance_rate)}</div> <div className="text-base font-semibold">{item?.product_id}</div>
</div> </div>
</td> </td>
{/* <td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">${item?.amount}</div>
<div className="font-normal text-gray-500">{item?.external_url}</div>
</div>
</td> */}
<td className="px-2"> <td className="px-2">
<div className="text-right"> <div className="text-right">
<div className="font-normal text-gray-500">{formatNumber(item?.management_rate)}</div> <div className="text-base font-semibold">{item?.status}</div>
</div>
</td>
<td className="px-2">
<div className="text-right">
<div className="font-normal text-gray-500">{formatNumber(item?.maximum_amount)}</div>
<div className="font-normal text-gray-500">{formatNumber(item?.minimum_amount)}</div>
</div>
</td>
<td className="px-2">
<div className="text-right">
<div className="font-normal text-gray-500">{item?.tenor}</div>
</div>
</td>
<td className="px-2 text-right">
<div className='flex items-center justify-end gap-3 md:gap-4'>
<div className='p-2 flex justify-center items-center text-slate-500 bg-white-body dark:text-white-body dark:bg-black-body rounded-md'>
<Icons name='eye' />
</div>
</div> </div>
</td> </td>
</tr> </tr>
)) ))
: :
<tr className="py-2 border-t border-dashed border-slate-300"> <tr className="py-2 border-t border-dashed border-slate-300">
<td className="px-3 py-2" colSpan={7}> <td className="px-3 py-2" colSpan={4}>
<div className="flex justify-center items-center"> <div className="flex justify-center items-center">
No Record Found No Record Found
</div> </div>
@@ -128,6 +147,7 @@ export default function OffersCom() {
</> </>
)} )}
</TablePaginatedWrapper> </TablePaginatedWrapper>
</>
} }
</div> </div>
</div> </div>
+6 -6
View File
@@ -1,8 +1,8 @@
import { createContext, useContext, useEffect, useState } from 'react' import { createContext, useContext, useEffect, useState } from 'react'
const GeneralContextProvider = createContext({}) const GeneralContextProviderInt = createContext({})
export default function GeneralLayoutContext({children}) { export default function GeneralLayoutContextInt({children}) {
const [theme, setTheme] = useState(null) const [theme, setTheme] = useState(null)
@@ -101,13 +101,13 @@ export default function GeneralLayoutContext({children}) {
} }
return ( return (
<GeneralContextProvider.Provider value={value}> <GeneralContextProviderInt.Provider value={value}>
{children} {children}
</GeneralContextProvider.Provider> </GeneralContextProviderInt.Provider>
) )
} }
export const generalLayoutContext = () => { export const GeneralLayoutContext = () => {
return useContext(GeneralContextProvider) return useContext(GeneralContextProviderInt)
} }
+3 -3
View File
@@ -6,7 +6,7 @@ import { Provider } from "react-redux";
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import store from './store/store.js' import store from './store/store.js'
import GeneralLayoutContext from './context/GeneralLayoutContext.jsx'; import GeneralLayoutContextInt from './context/GeneralLayoutContext.jsx';
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
@@ -14,9 +14,9 @@ root.render(
<React.StrictMode> <React.StrictMode>
<BrowserRouter> <BrowserRouter>
<Provider store={store}> <Provider store={store}>
<GeneralLayoutContext> <GeneralLayoutContextInt>
<App /> <App />
</GeneralLayoutContext> </GeneralLayoutContextInt>
</Provider> </Provider>
</BrowserRouter> </BrowserRouter>
</React.StrictMode> </React.StrictMode>
-8
View File
@@ -1,8 +0,0 @@
import React from 'react'
import OffersCom from '../components/offers/OffersCom'
export default function OffersPage() {
return (
<OffersCom />
)
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import ProductsCom from '../components/products/ProductsCom'
export default function ProductsPage() {
return (
<ProductsCom />
)
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import RecentSignupCom from '../components/recent_signup/RecentSignupCom'
export default function RecentSignupPage() {
return (
<RecentSignupCom />
)
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import UsersCom from '../components/users/UsersCom'
export default function UsersPage() {
return (
<UsersCom />
)
}
+4 -1
View File
@@ -5,7 +5,6 @@ const queryKeys = {
transactions: ['transactions'], transactions: ['transactions'],
repayment_schedule: ['repayment-schedule'], repayment_schedule: ['repayment-schedule'],
loan_charges: ['loan-charges'], loan_charges: ['loan-charges'],
offers: ['offers'],
apply_loan: ['apply'], apply_loan: ['apply'],
select_loan: ['select-loan'], select_loan: ['select-loan'],
approved_loan: ['approved-loan'], approved_loan: ['approved-loan'],
@@ -14,6 +13,10 @@ const queryKeys = {
// new // new
subscriptions: ['subscriptions'], subscriptions: ['subscriptions'],
billings: ['billings'], billings: ['billings'],
products: ['products'],
users: ['users'],
right_sidebar: ['right_sidebar'],
recent_signup: ['recent_signup'],
} }
export default queryKeys export default queryKeys
+23 -6
View File
@@ -74,6 +74,29 @@ export const getSubscriptions = (reqData) => {
return getAuxEnd(`/subcriptions`, postData) return getAuxEnd(`/subcriptions`, postData)
} }
// FUNCTION TO GET PRODUCTS LIST TABLE
export const getProducts = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/products`, postData)
}
// FUNCTION TO GET USERS LIST TABLE
export const getUsers = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/users`, postData)
}
// FUNCTION TO GET USERS LIST TABLE
export const getRightSidebar = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/right-sidebar`, postData)
}
// FUNCTION TO GET RECNET SIGNUP LIST TABLE
export const getRecentSignup = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/recent-signup`, postData)
}
@@ -93,12 +116,6 @@ export const getRepayments = (reqData) => {
return getAuxEnd(`/repayments`, postData) return getAuxEnd(`/repayments`, postData)
} }
// FUNCTION TO GET OFFERS LIST TABLE
export const getOffers = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/offers`, postData)
}
// FUNCTION TO GET REPAYMENT SCHEDULE TABLE // FUNCTION TO GET REPAYMENT SCHEDULE TABLE
export const getRepaymentSchedule = (reqData) => { export const getRepaymentSchedule = (reqData) => {
const postData = { ...reqData } const postData = { ...reqData }