Compare commits

..

9 Commits

Author SHA1 Message Date
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
victorAnumudu 691d9e72fe table fixed 2025-09-02 20:07:49 +01:00
CHIEFSOFT\ameye e4d6725dea fix names 2025-09-02 13:40:09 -04:00
CHIEFSOFT\ameye 607d64c709 removed unsused 2025-08-31 17:51:23 -04:00
CHIEFSOFT\ameye 882f781b75 removed unsused 2025-08-31 17:24:56 -04:00
Olusesan Ameye e9d30d6169 Envrionment support infrastructure 2025-08-27 03:00:35 +00:00
CHIEFSOFT\ameye baf96da5eb fix filter 2025-08-23 04:35:55 -04:00
ameye 88182bdbdf Merge branch 'customers-page' of MERMS/MermsFirstOffice into master 2025-08-22 16:46:21 +00:00
14 changed files with 317 additions and 137 deletions
+17 -1
View File
@@ -3,8 +3,22 @@
# FROM node:alpine
FROM node:22-alpine
# Build args
ARG NODE_ENV
ENV NODE_VERSION 14.19.0
ENV NODE_ENV=$NODE_ENV
# install nginx
RUN apk update
RUN apk add nginx
WORKDIR /app
COPY nginx.conf ./
COPY run.sh ./
COPY package.json .
RUN npm install
@@ -15,5 +29,7 @@ COPY . .
# CMD [ "npm", "run", "preview" ]
CMD [ "npm", "run", "start" ,"--", "--host"]
##CMD [ "npm", "run", "start" ,"--", "--host"]
CMD /bin/sh ./run.sh
+4
View File
@@ -5,10 +5,13 @@ services:
build:
context: .
dockerfile: Dockerfile
args:
- NODE_ENV=development
restart: unless-stopped
volumes:
- ./:/app
- '/app/node_modules'
- ./run.sh:/app/run.sh
ports:
- 8092:5173
expose:
@@ -21,6 +24,7 @@ services:
- socket.mermsemr.com:10.10.33.15
environment:
- PORT=${DIGIFI_PORT}
- NODE_ENV=${NODE_ENV:-production}
tty: true
stdin_open: true
volumes:
+29
View File
@@ -0,0 +1,29 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
gzip on;
listen 3000;
server_name localhost;
root /usr/src/app/build;
include /etc/nginx/mime.types;
location /nginx_status {
stub_status on;
access_log off;
}
location / {
try_files $uri $uri/ /index.html;
}
}
}
+110 -14
View File
@@ -10,10 +10,13 @@
"dependencies": {
"@reduxjs/toolkit": "^2.5.1",
"@tanstack/react-query": "^5.66.0",
"apexcharts": "^4.5.0",
"axios": "^1.7.9",
"cra-template": "1.2.0",
"formik": "^2.4.6",
"react": "^19.0.0",
"react-apexcharts": "^1.7.0",
"react-countup": "^6.5.3",
"react-dom": "^19.0.0",
"react-icons": "^5.4.0",
"react-redux": "^9.2.0",
@@ -3255,6 +3258,62 @@
"string.prototype.matchall": "^4.0.6"
}
},
"node_modules/@svgdotjs/svg.draggable.js": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.draggable.js/-/svg.draggable.js-3.0.6.tgz",
"integrity": "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==",
"license": "MIT",
"peerDependencies": {
"@svgdotjs/svg.js": "^3.2.4"
}
},
"node_modules/@svgdotjs/svg.filter.js": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.9.tgz",
"integrity": "sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw==",
"license": "MIT",
"dependencies": {
"@svgdotjs/svg.js": "^3.2.4"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/@svgdotjs/svg.js": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz",
"integrity": "sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Fuzzyma"
}
},
"node_modules/@svgdotjs/svg.resize.js": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.resize.js/-/svg.resize.js-2.0.5.tgz",
"integrity": "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA==",
"license": "MIT",
"engines": {
"node": ">= 14.18"
},
"peerDependencies": {
"@svgdotjs/svg.js": "^3.2.4",
"@svgdotjs/svg.select.js": "^4.0.1"
}
},
"node_modules/@svgdotjs/svg.select.js": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.3.tgz",
"integrity": "sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg==",
"license": "MIT",
"engines": {
"node": ">= 14.18"
},
"peerDependencies": {
"@svgdotjs/svg.js": "^3.2.4"
}
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz",
@@ -4301,6 +4360,12 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"license": "Apache-2.0"
},
"node_modules/@yr/monotone-cubic-spline": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
"license": "MIT"
},
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -4562,6 +4627,20 @@
"node": ">= 8"
}
},
"node_modules/apexcharts": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.7.0.tgz",
"integrity": "sha512-iZSrrBGvVlL+nt2B1NpqfDuBZ9jX61X9I2+XV0hlYXHtTwhwLTHDKGXjNXAgFBDLuvSYCB/rq2nPWVPRv2DrGA==",
"license": "MIT",
"dependencies": {
"@svgdotjs/svg.draggable.js": "^3.0.4",
"@svgdotjs/svg.filter.js": "^3.0.8",
"@svgdotjs/svg.js": "^3.2.4",
"@svgdotjs/svg.resize.js": "^2.0.2",
"@svgdotjs/svg.select.js": "^4.0.1",
"@yr/monotone-cubic-spline": "^1.0.3"
}
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@@ -5949,6 +6028,12 @@
"node": ">=10"
}
},
"node_modules/countup.js": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/countup.js/-/countup.js-2.9.0.tgz",
"integrity": "sha512-llqrvyXztRFPp6+i8jx25phHWcVWhrHO4Nlt0uAOSKHB8778zzQswa4MU3qKBvkXfJKftRYFJuVHez67lyKdHg==",
"license": "MIT"
},
"node_modules/cra-template": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/cra-template/-/cra-template-1.2.0.tgz",
@@ -13776,6 +13861,19 @@
"node": ">=0.10.0"
}
},
"node_modules/react-apexcharts": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.7.0.tgz",
"integrity": "sha512-03oScKJyNLRf0Oe+ihJxFZliBQM9vW3UWwomVn4YVRTN1jsIR58dLWt0v1sb8RwJVHDMbeHiKQueM0KGpn7nOA==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"apexcharts": ">=4.0.0",
"react": ">=0.13"
}
},
"node_modules/react-app-polyfill": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz",
@@ -13799,6 +13897,18 @@
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
"license": "MIT"
},
"node_modules/react-countup": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/react-countup/-/react-countup-6.5.3.tgz",
"integrity": "sha512-udnqVQitxC7QWADSPDOxVWULkLvKUWrDapn5i53HE4DPRVgs+Y5rr4bo25qEl8jSh+0l2cToJgGMx+clxPM3+w==",
"license": "MIT",
"dependencies": {
"countup.js": "^2.8.0"
},
"peerDependencies": {
"react": ">= 16.3.0"
}
},
"node_modules/react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -16472,20 +16582,6 @@
"is-typedarray": "^1.0.0"
}
},
"node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
Executable
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env sh
set -e
set -x
export NODE_ENV="${NODE_ENV:-development}"
if [ $NODE_ENV = "development" ]; then
# this runs webpack-dev-server with hot reloading
echo "Development build"
npm install --legacy-peer-deps
npm run start -- --host
# npm run build
elif [ $NODE_ENV = "qa" -o $NODE_ENV = "test" ]; then
echo "QA build"
export NODE_ENV="test"
npm install --legacy-peer-deps
npm run start -- --host
else
# build the app and serve it via nginx
echo "Production build"
npm install --legacy-peer-deps
npm run build
# Testing sometimes
# npm run start
nginx -g 'daemon off;' -c /usr/src/app/nginx.conf
nginx -c /usr/src/app/nginx.conf
fi
@@ -144,22 +144,9 @@ const asideNavLinks = [
{name: 'Billings', status:1, icon: 'dot', to: RouteLinks.billings},
{name: 'Configurations', status:1, icon: 'arrow-right', subLinks: [
{name: 'Product Settings', status:1, icon: 'dot', to: RouteLinks.offers },
{name: 'Manage 2', status:1, icon: 'dot', to: RouteLinks.offers },
{name: 'Admin Manager', status:1, icon: 'dot', to: RouteLinks.offers },
]
},
],
},
// {name:'Product 2', title:'Product 2', status:1, icon: 'product', subLinks: [
// {name: 'Applications', status:1, icon: 'dot', to: ''},
// ]
// },
// {name:'Product 3', title:'Product 3', status:1, icon: 'product', subLinks: [
// {name: 'Applications', status:1, icon: 'dot', to: ''},
// {name: 'Configuration', status:1, icon: 'dot', to: ''},
// ]
// },
// {name:'Administration', title:'Admin', status:1, icon: 'people', subLinks: [
// {name: 'Users', status:1, icon: 'dot', to: RouteLinks.usersPage},
// ]
// },
]
+43 -47
View File
@@ -1,10 +1,12 @@
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 { getBillings } from '../../services/siteServices'
import getDateFromDateString from '../../helpers/GetDateFromDateString';
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
import formatNumber from '../../helpers/formatNumber'
import Avatar from '../../assets/user_avatar.jpg'
@@ -12,10 +14,9 @@ import Avatar from '../../assets/user_avatar.jpg'
export default function BillingsCom() {
const [page, setPage] = useState(1)
const [allBillings, setAllBillings] = useState({loading:true, error:'', data:{}})
const [willFilter, setWillFilter] = useState(false)
const [filter, setFilter] = useState({type: '', id: ''})
const [willFilter, setWillFilter] = useState(false)
const handleFilter = ({target:{name, value}}) => {
setFilter(prev => ({...prev, [name]:value}))
}
@@ -33,25 +34,20 @@ export default function BillingsCom() {
}
}
const billings = allBillings?.data?.loan_charges // LOAN CHARGES LIST
const pagination = allBillings?.data?.pagination
const isFetching = allBillings?.loading
const isError = allBillings?.error
useEffect(()=>{
setAllBillings(prev => ({...prev, loading:true}))
const payload = filter?.type ? {[filter?.type]: filter.id} : {}
getBillings({...payload, page}).then(res => {
if(res?.status != 200){
setAllBillings(prev => ({...prev, error:'Opps, an error occurred', loading:false}))
return
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.billings, page, willFilter],
queryFn: () => {
const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
const reqData = {
page,
...filterData
}
setAllBillings({loading:false, error:'', data:res?.data})
}).catch(err => {
setAllBillings({loading:false, error:'error occurred', data:{}})
console.log('ERR', err)
})
},[page, willFilter])
return getBillings(reqData)
},
staleTime: 0 //0 mins
})
const billingData = data?.data?.payments // BILLINGS LIST
const pagination = data?.data?.pagination
return (
<div className='w-full flex flex-col gap-8'>
@@ -59,7 +55,7 @@ export default function BillingsCom() {
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{ isError ?
<p className='text-red-500'>{allBillings?.error}</p>
<p className='text-red-500'>{error?.message}</p>
:
<>
{/* filter section */}
@@ -68,8 +64,7 @@ export default function BillingsCom() {
<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='transaction_id'>Transaction ID</option>
<option value='account_id'>Account ID</option>
<option value='option_name'>Option Name</option>
</select>
</div>
<div className='w-full sm:max-w-48'>
@@ -79,26 +74,26 @@ export default function BillingsCom() {
</div>
{/* end of filter section */}
<TablePaginatedWrapper data={billings} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}>
<TablePaginatedWrapper data={billingData} 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">
Name
Added
</th>
<th scope="col" className="px-2">
Option Name
</th>
<th scope="col" className="px-2">
Product ID
</th>
{/* <th scope="col" className="px-2">
Loan
</th> */}
<th scope="col" className="px-2 text-right">
Amount
</th>
<th scope="col" className="px-2 text-right">
Added
</th>
<th scope="col" className="px-2 text-right">
Action
Status
</th>
</tr>
</thead>
@@ -107,31 +102,32 @@ export default function BillingsCom() {
<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={Avatar} alt="Jese image" />
<div className="text-left">
<div className="text-base font-semibold">{item?.transaction_id || ''}</div>
<div className="font-normal text-gray-500 line-clamp-1">{item?.code}</div>
<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?.product_id}</div>
</div>
</td>
<td className="px-2">
<div className="text-right">
{/* <div className="text-base font-semibold">{formatNumber(item?.initial_loan_amount)}</div> */}
<div className="font-normal text-gray-500">{formatNumber(item?.amount)}</div>
<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="font-normal text-gray-500">{getDateFromDateString(item?.created_at)}</div>
<div className="text-base font-semibold">{item?.status}</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>
</td>
</tr>
))
:
@@ -5,7 +5,7 @@ import Icons from '../Icons'
import Avatar from '../../assets/user_avatar.jpg'
import queryKeys from '../../services/queryKeys'
import { getLoanCharges } from '../../services/siteServices'
//import { getLoanCharges } from '../../services/siteServices'
import getDateFromDateString from '../../helpers/GetDateFromDateString';
import formatNumber from '../../helpers/formatNumber';
@@ -15,7 +15,7 @@ export default function LoanChargeDetails({transactionID}) {
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.loan_charges, page],
queryFn: () => getLoanCharges({transaction_id: transactionID, page}),
// queryFn: () => getLoanCharges({transaction_id: transactionID, page}),
staleTime: 0,
// placeholderData: keepPreviousData,
})
@@ -4,7 +4,7 @@ import { useQuery } from "@tanstack/react-query";
import Icons from '../Icons'
import queryKeys from '../../services/queryKeys'
import { getTransactions } from '../../services/siteServices'
//import { getTransactions } from '../../services/siteServices'
import getDateFromDateString from '../../helpers/GetDateFromDateString';
import getTimeFromDateString from '../../helpers/GetTimeFromDateString';
import localImgLoader from '../../helpers/localImageLoader';
@@ -15,7 +15,7 @@ export default function TransactionDetails({transactionID}) {
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.transactions, page],
queryFn: () => getTransactions({transaction_id: transactionID, page}),
//queryFn: () => getTransactions({transaction_id: transactionID, page}),
staleTime: 0,
// placeholderData: keepPreviousData,
})
@@ -1,22 +1,22 @@
import { useEffect, useState } from 'react'
import {Link} from 'react-router-dom'
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 { getSubcriptions } from '../../services/siteServices'
import getDateFromDateString from '../../helpers/GetDateFromDateString';
import getTimeFromDateString from '../../helpers/GetTimeFromDateString';
import { getSubscriptions } from '../../services/siteServices'
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
import localImgLoader from '../../helpers/localImageLoader';
import RouteLinks from '../../RouteLinks';
export default function SubscriptionsCom() {
const [page, setPage] = useState(1)
const [allSubcriptions, setAllSubcriptions] = useState({loading:true, error:'', data:{}})
const [willFilter, setWillFilter] = useState(false)
const [filter, setFilter] = useState({type: '', id: ''})
const [willFilter, setWillFilter] = useState(false)
const handleFilter = ({target:{name, value}}) => {
setFilter(prev => ({...prev, [name]:value}))
}
@@ -34,25 +34,20 @@ export default function SubscriptionsCom() {
}
}
const subcriptions = allSubcriptions?.data?.transactions // TRANSACTIONS LIST
const pagination = allSubcriptions?.data?.pagination
const isFetching = allSubcriptions?.loading
const isError = allSubcriptions?.error
useEffect(()=>{
setAllSubcriptions(prev => ({...prev, loading:true}))
const payload = filter?.type ? {[filter?.type]: filter.id} : {}
getSubcriptions({...payload, page}).then(res => {
if(res?.status != 200){
setAllSubcriptions(prev => ({...prev, error:'Opps, an error occurred', loading:false}))
return
const {data, isFetching, isError, error} = useQuery({
queryKey: [...queryKeys.subscriptions, page, willFilter],
queryFn: () => {
const filterData = filter?.type ? {[filter?.type]: filter.id} : {}
const reqData = {
page,
...filterData
}
setAllSubcriptions({loading:false, error:'', data:res?.data})
}).catch(err => {
setAllSubcriptions({loading:false, error:'error occurred', data:{}})
console.log('ERR', err)
})
},[page, willFilter])
return getSubscriptions(reqData)
},
staleTime: 0 //0 mins
})
const subscriptionData = data?.data?.subscriptions // SUBSCRIPTION LIST
const pagination = data?.data?.pagination
return (
<div className='w-full flex flex-col gap-8'>
@@ -60,7 +55,7 @@ export default function SubscriptionsCom() {
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
{ isError ?
<p className='text-red-500'>{allSubcriptions?.error}</p>
<p className='text-red-500'>{error?.message}</p>
:
<>
{/* filter section */}
@@ -69,8 +64,8 @@ export default function SubscriptionsCom() {
<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='transaction_id'>Transaction ID</option>
<option value='account_id'>Account ID</option>
<option value='member_id'>Member ID</option>
<option value='product_id'>Product ID</option>
</select>
</div>
<div className='w-full sm:max-w-48'>
@@ -80,23 +75,23 @@ export default function SubscriptionsCom() {
</div>
{/* end of filter section */}
<TablePaginatedWrapper data={subcriptions} isFetching={isFetching} setPage={setPage} itemsPerPage={pagination?.limit} pagination={pagination}>
<TablePaginatedWrapper data={subscriptionData} 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">
Request
Added
</th>
<th scope="col" className="px-2">
Account
Product
</th>
<th scope="col" className="px-2">
Activity
URL
</th>
<th scope="col" className="px-2 text-right">
Action
Status
</th>
</tr>
</thead>
@@ -105,36 +100,28 @@ export default function SubscriptionsCom() {
<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" />
{/* <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">{item?.transaction_id}</div>
<div className="font-normal text-gray-500">{getDateFromDateString(item?.created_at)} {getTimeFromDateString(item?.created_at)}</div>
<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?.account_id}</div>
<div className="font-normal text-gray-500">{item?.type}</div>
<div className="text-base font-semibold">{item?.product_id}</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">{item?.internal_url}</div>
<div className="font-normal text-gray-500">{item?.external_url}</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="font-normal text-gray-500">50%</div>
<div className="relative h-[6px] w-full bg-white-body dark:bg-black-body rounded-full overflow-hidden">
<div className={`absolute left-0 h-full w-1/2 bg-emerald-600`}></div>
</div>
<div className="text-right">
<div className="text-base font-semibold">{item?.status}</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'>
<Link to={RouteLinks.transaction_details_page} state={{transactionID: item?.transaction_id}}>
<Icons name='eye' />
</Link>
</div>
</div>
</td>
</tr>
))
:
+5 -5
View File
@@ -1,8 +1,8 @@
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)
@@ -101,13 +101,13 @@ export default function GeneralLayoutContext({children}) {
}
return (
<GeneralContextProvider.Provider value={value}>
<GeneralContextProviderInt.Provider value={value}>
{children}
</GeneralContextProvider.Provider>
</GeneralContextProviderInt.Provider>
)
}
export const generalLayoutContext = () => {
return useContext(GeneralContextProvider)
return useContext(GeneralContextProviderInt)
}
+33
View File
@@ -0,0 +1,33 @@
function getDateTimeFromDateString(dateString) {
const date = new Date(dateString);
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const dayName = days[date.getDay()];
const monthName = months[date.getMonth()];
const day = date.getDate();
const year = date.getFullYear();
// Add ordinal suffix
function getOrdinal(n) {
if (n > 3 && n < 21) return "th"; // 4-20 are all "th"
switch (n % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
// Format time in 12hr with AM/PM
let hours = date.getHours();
const minutes = date.getMinutes().toString().padStart(2, "0");
const ampm = hours >= 12 ? "PM" : "AM";
hours = hours % 12 || 12;
return `${dayName}, ${monthName} ${day}${getOrdinal(day)} ${year} ${hours}:${minutes}${ampm}`;
}
export default getDateTimeFromDateString
+4
View File
@@ -10,6 +10,10 @@ const queryKeys = {
select_loan: ['select-loan'],
approved_loan: ['approved-loan'],
loan_offers: ['loan-offers'],
// new
subscriptions: ['subscriptions'],
billings: ['billings'],
}
export default queryKeys
+1 -1
View File
@@ -69,7 +69,7 @@ export const getBillings = (reqData) => {
}
// FUNCTION TO GET SUBSCRIPTIONS
export const getSubcriptions = (reqData) => {
export const getSubscriptions = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/subcriptions`, postData)
}