[Client Portal] Fix Dashboard change url & first default corporate & table loading
This commit is contained in:
@@ -5,5 +5,5 @@ PORT=8083
|
||||
REACT_APP_HOST_API_URL="https://aso-api.linksehat.dev/api/client"
|
||||
|
||||
# VITE_API_URL="https://aso-api.linksehat.dev/api/client"
|
||||
VITE_API_URL="https://primecenter-api.linksehat.com/api/client"
|
||||
VITE_API_URL="http://localhost:8000/api/client"
|
||||
|
||||
|
||||
@@ -288,7 +288,11 @@ export default function Table<T>({
|
||||
{exportReport && exportReport.useExport ? (
|
||||
<Grid item xs={12} lg={2} xl={2}>
|
||||
<FormControl fullWidth>
|
||||
<Button variant="contained" sx={{ p: 2 }} onClick={exportReport.handleExportReport}>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ p: 2 }}
|
||||
onClick={() => exportReport.handleExportReport}
|
||||
>
|
||||
<Download />
|
||||
<Typography variant="inherit" sx={{ marginLeft: 1 }}>
|
||||
Export
|
||||
@@ -329,12 +333,18 @@ export default function Table<T>({
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
) : loadings.isLoading === false && rows && rows.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} align="center">
|
||||
No Data Found
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} align="center">
|
||||
Loading . . .
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
{/* End Table Body */}
|
||||
|
||||
@@ -14,24 +14,35 @@ type CorporateDataProps = {
|
||||
export default function CorporatePopover() {
|
||||
const { corporateValue, setCorporateValue } = useContext(UserCurrentCorporateContext);
|
||||
const [corporateData, setCorporateData] = useState([]);
|
||||
//Check route in profile
|
||||
const controller = new AbortController();
|
||||
|
||||
const navigate = useNavigate();
|
||||
const currentPathname = window.location.pathname;
|
||||
const desiredPart = currentPathname.split('/')[1];
|
||||
|
||||
const handleCorporateChange = (event: SelectChangeEvent) => {
|
||||
setCorporateValue(event.target.value as string);
|
||||
if(desiredPart === 'user-profile')
|
||||
{
|
||||
if (desiredPart === 'user-profile') {
|
||||
navigate('/alarm-center');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
// @ts-ignore
|
||||
const corporateManages = await axios.get(`/corporate-manage`);
|
||||
setCorporateData(corporateManages.data);
|
||||
try {
|
||||
const corporateManages = await axios.get(`/corporate-manage`, {
|
||||
signal: controller.signal,
|
||||
});
|
||||
setCorporateData(corporateManages.data);
|
||||
|
||||
setCorporateValue(corporateManages.data[0].id);
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching data:', error.message);
|
||||
}
|
||||
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
})();
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -1,83 +1,25 @@
|
||||
// @mui
|
||||
import { styled } from '@mui/material/styles';
|
||||
import {
|
||||
Typography,
|
||||
Container,
|
||||
Grid,
|
||||
Button,
|
||||
LinearProgress,
|
||||
linearProgressClasses,
|
||||
SelectChangeEvent,
|
||||
} from '@mui/material';
|
||||
import { Typography, Container, Grid, Button, SelectChangeEvent } from '@mui/material';
|
||||
// hooks
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
// components
|
||||
import Page from '../../components/Page';
|
||||
// theme
|
||||
import CardPolicy from '../../sections/dashboard/CardPolicy';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import axios from '../../utils/axios';
|
||||
import { Stack } from '@mui/system';
|
||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||
import Table from '../../components/Table';
|
||||
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
|
||||
import { useLocation, useSearchParams } from 'react-router-dom';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import palette from '../../theme/palette';
|
||||
import { fSplit } from '../../utils/formatNumber';
|
||||
import { closeSnackbar, enqueueSnackbar } from 'notistack';
|
||||
|
||||
/* ------------------------------ default data ------------------------------ */
|
||||
type DataMember = {
|
||||
id: number;
|
||||
fullName: string;
|
||||
memberId: string;
|
||||
limit: {
|
||||
current: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
avatar?: {
|
||||
url?: string;
|
||||
title?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type CardPolicyProps = {
|
||||
limit: {
|
||||
myLimit: {
|
||||
balance: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
lockLimit: {
|
||||
balance: number;
|
||||
percentage: number;
|
||||
};
|
||||
};
|
||||
topUpLimit: {
|
||||
companyName: string;
|
||||
policyNumber: number;
|
||||
totalMembers: number;
|
||||
totalCases: number;
|
||||
totalPersen: number;
|
||||
myLimit: {
|
||||
balance: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
maxTopUp: number;
|
||||
};
|
||||
members?: DataMember[];
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
export default function Index() {
|
||||
const { themeStretch } = useSettings();
|
||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||
const { pathname } = useLocation();
|
||||
const controller = new AbortController();
|
||||
|
||||
const [memberData, setMemberData] = useState([]);
|
||||
const [policyData, setPolicyData] = useState<CardPolicyProps>();
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* setting up for the table */
|
||||
@@ -89,20 +31,6 @@ export default function Index() {
|
||||
setIsLoading: setIsLoading,
|
||||
};
|
||||
|
||||
/* ----------------------------- limit progress ----------------------------- */
|
||||
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
||||
height: 10,
|
||||
borderRadius: 6,
|
||||
[`&.${linearProgressClasses.colorPrimary}`]: {
|
||||
backgroundColor: '#D1F1F1',
|
||||
},
|
||||
[`& .${linearProgressClasses.bar}`]: {
|
||||
borderRadius: 6,
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
},
|
||||
}));
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------ handle params ----------------------------- */
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [appliedParams, setAppliedParams] = useState({});
|
||||
@@ -227,12 +155,6 @@ export default function Index() {
|
||||
label: 'Divisi',
|
||||
isSort: true,
|
||||
},
|
||||
// {
|
||||
// id: 'limit',
|
||||
// align: 'center',
|
||||
// label: 'Limit',
|
||||
// isSort: false,
|
||||
// },
|
||||
{
|
||||
id: 'status',
|
||||
align: 'center',
|
||||
@@ -250,106 +172,83 @@ export default function Index() {
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
setIsLoading(true);
|
||||
const loadNotif = enqueueSnackbar('Data sedang di load, harap tunggu!', {
|
||||
variant: 'info',
|
||||
autoHideDuration: null,
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'bottom' },
|
||||
});
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const parameters =
|
||||
Object.keys(appliedParams).length !== 0
|
||||
? appliedParams
|
||||
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
|
||||
const parameters =
|
||||
Object.keys(appliedParams).length !== 0
|
||||
? appliedParams
|
||||
: Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['order', order],
|
||||
['orderBy', orderBy],
|
||||
]);
|
||||
|
||||
const corporatePolicyLimit = await axios.get(`${corporateValue}/policy`);
|
||||
const corporateDivision = await axios.get(`${corporateValue}/division`);
|
||||
const corporateMembers = await axios.get(`${corporateValue}/members`, {
|
||||
params: { ...parameters },
|
||||
});
|
||||
const [divisionResponse, membersResponse] = await Promise.all([
|
||||
axios.get(`${corporateValue}/division`, { signal: controller.signal }),
|
||||
axios.get(`${corporateValue}/members`, {
|
||||
params: { ...parameters },
|
||||
signal: controller.signal,
|
||||
}),
|
||||
]);
|
||||
|
||||
const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`);
|
||||
|
||||
if (pathname === '/dashboard') {
|
||||
setSearchParams(parameters);
|
||||
setDivisionData(divisionResponse.data);
|
||||
setMemberData(
|
||||
membersResponse.data.data.map((obj: any) => ({
|
||||
...obj,
|
||||
status:
|
||||
obj.status === 1 ? (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.16)',
|
||||
color: palette.dark.success.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.32)',
|
||||
color: palette.dark.success.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Active
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.16)',
|
||||
color: palette.dark.error.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.32)',
|
||||
color: palette.dark.error.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Inactive
|
||||
</Button>
|
||||
),
|
||||
}))
|
||||
);
|
||||
setPaginationTable(membersResponse.data);
|
||||
setRowsPerPage(membersResponse.data.per_page);
|
||||
|
||||
if (searchParams.get('page')) {
|
||||
// @ts-ignore
|
||||
const currentPage = parseInt(searchParams.get('page')) - 1;
|
||||
paginationTable.current_page = currentPage;
|
||||
setPage(currentPage);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching data:', error.message);
|
||||
}
|
||||
|
||||
setPolicyData({
|
||||
limit: corporatePolicyLimit.data.data,
|
||||
topUpLimit: corporateTopUpLimit.data.data,
|
||||
});
|
||||
setDivisionData(corporateDivision.data);
|
||||
setMemberData(
|
||||
corporateMembers.data.data.map((obj: any) => ({
|
||||
...obj,
|
||||
// limit: (
|
||||
// <Stack>
|
||||
// <BorderLinearProgress
|
||||
// variant="determinate"
|
||||
// value={obj.limit.percentage}
|
||||
// sx={{ mb: 1 }}
|
||||
// />
|
||||
// <Typography sx={{ typography: 'caption', color: '#637381' }}>
|
||||
// {fSplit(obj.limit.current)} / {fSplit(obj.limit.total)}
|
||||
// </Typography>
|
||||
// </Stack>
|
||||
// ),
|
||||
status:
|
||||
obj.status === 1 ? (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.16)',
|
||||
color: palette.dark.success.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.32)',
|
||||
color: palette.dark.success.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Active
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.16)',
|
||||
color: palette.dark.error.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.32)',
|
||||
color: palette.dark.error.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Inactive
|
||||
</Button>
|
||||
),
|
||||
/* action: (
|
||||
<IconButton onClick={handleAction}>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
), */
|
||||
}))
|
||||
);
|
||||
setPaginationTable(corporateMembers.data);
|
||||
setRowsPerPage(corporateMembers.data.per_page);
|
||||
|
||||
if (searchParams.get('page')) {
|
||||
//@ts-ignore
|
||||
const currentPage = parseInt(searchParams.get('page')) - 1;
|
||||
|
||||
paginationTable.current_page = currentPage;
|
||||
setPage(currentPage);
|
||||
}
|
||||
|
||||
closeSnackbar(loadNotif);
|
||||
setIsLoading(false);
|
||||
enqueueSnackbar('Data sudah di load!', {
|
||||
variant: 'info',
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'bottom' },
|
||||
});
|
||||
})();
|
||||
}, [appliedParams, searchParams, order, orderBy, pathname, setSearchParams, corporateValue]);
|
||||
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);
|
||||
|
||||
return (
|
||||
<Page title="Dashboard">
|
||||
@@ -361,12 +260,6 @@ export default function Index() {
|
||||
</Stack>
|
||||
|
||||
<Grid container spacing={2}>
|
||||
{/* <Grid item xs={12} lg={6} md={12}>
|
||||
<CardNotification data={itemList} />
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={6} md={12}>
|
||||
<CardPolicy data={policyData} />
|
||||
</Grid> */}
|
||||
<Grid item xs={12} lg={12} md={12}>
|
||||
<Table
|
||||
headCells={headCells}
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- Favicon -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- Favicon -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<!-- Using Google Font -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Using Google Font -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<!-- Using Local Font -->
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/index.css" />
|
||||
|
||||
<!-- Using Local Font -->
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/index.css" />
|
||||
<title>Dashboard</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style"
|
||||
/>
|
||||
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
|
||||
<meta name="author" content="Minimal UI Kit" />
|
||||
</head>
|
||||
|
||||
<title>Dashboard</title>
|
||||
<meta name="description"
|
||||
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style" />
|
||||
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
|
||||
<meta name="author" content="Minimal UI Kit" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
</body>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- Favicon -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- Favicon -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<!-- Using Google Font -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Using Google Font -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<!-- Using Local Font -->
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/index.css" />
|
||||
|
||||
<!-- Using Local Font -->
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/index.css" />
|
||||
<title>Dashboard</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style"
|
||||
/>
|
||||
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
|
||||
<meta name="author" content="Minimal UI Kit" />
|
||||
</head>
|
||||
|
||||
<title>Dashboard</title>
|
||||
<meta name="description"
|
||||
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style" />
|
||||
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
|
||||
<meta name="author" content="Minimal UI Kit" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="/src/index.tsx?v=<?php echo time(); ?>"></script>
|
||||
</body>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
14
frontend/hospital-portal/pnpm-lock.yaml
generated
14
frontend/hospital-portal/pnpm-lock.yaml
generated
@@ -113,6 +113,9 @@ dependencies:
|
||||
react-lazy-load-image-component:
|
||||
specifier: ^1.5.6
|
||||
version: 1.5.6(react-dom@17.0.2)(react@17.0.2)
|
||||
react-number-format:
|
||||
specifier: ^5.3.1
|
||||
version: 5.3.1(react-dom@17.0.2)(react@17.0.2)
|
||||
react-quill:
|
||||
specifier: 2.0.0-beta.4
|
||||
version: 2.0.0-beta.4(react-dom@17.0.2)(react@17.0.2)
|
||||
@@ -5313,6 +5316,17 @@ packages:
|
||||
react-dom: 17.0.2(react@17.0.2)
|
||||
dev: false
|
||||
|
||||
/react-number-format@5.3.1(react-dom@17.0.2)(react@17.0.2):
|
||||
resolution: {integrity: sha512-qpYcQLauIeEhCZUZY9jXZnnroOtdy3jYaS1zQ3M1Sr6r/KMOBEIGNIb7eKT19g2N1wbYgFgvDzs19hw5TrB8XQ==}
|
||||
peerDependencies:
|
||||
react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2(react@17.0.2)
|
||||
dev: false
|
||||
|
||||
/react-quill@2.0.0-beta.4(react-dom@17.0.2)(react@17.0.2):
|
||||
resolution: {integrity: sha512-KyAHvAlPjP4xLElKZJefMth91Z6FbbXRvq9OSu6xN3KBaoasLP9p+3dcxg4Ywr4tBlpMGXcPszYSAgd5CpJ45Q==}
|
||||
peerDependencies:
|
||||
|
||||
Reference in New Issue
Block a user