394 lines
12 KiB
TypeScript
394 lines
12 KiB
TypeScript
// @mui
|
|
import { styled } from '@mui/material/styles';
|
|
import {
|
|
Typography,
|
|
Container,
|
|
Grid,
|
|
Button,
|
|
IconButton,
|
|
LinearProgress,
|
|
linearProgressClasses,
|
|
SelectChangeEvent,
|
|
} from '@mui/material';
|
|
// hooks
|
|
import useSettings from '../../hooks/useSettings';
|
|
// components
|
|
import Page from '../../components/Page';
|
|
// theme
|
|
import CardNotification from '../../sections/dashboard/CardNotification';
|
|
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 { useSearchParams } from 'react-router-dom';
|
|
import palette from '../../theme/palette';
|
|
import { MoreVert as MoreVertIcon } from '@mui/icons-material';
|
|
import { fSplit } from '../../utils/formatNumber';
|
|
|
|
const itemList = [
|
|
{ info: 'Mohon lengkapi dokumen Alison Born', date: 'Selasa, 13 Februari 23', time: '09:43 WIB' },
|
|
{ info: 'Mohon lengkapi dokumen Alison Born', date: 'Selasa, 13 Februari 23', time: '09:43 WIB' },
|
|
{ info: 'Mohon lengkapi dokumen Alison Born', date: 'Selasa, 13 Februari 23', time: '09:43 WIB' },
|
|
{ info: 'Mohon lengkapi dokumen Alison Born', date: 'Selasa, 13 Februari 23', time: '09:43 WIB' },
|
|
];
|
|
|
|
/* ------------------------------ 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 [memberData, setMemberData] = useState([]);
|
|
const [policyData, setPolicyData] = useState<CardPolicyProps>();
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* setting up for the table */
|
|
/* -------------------------------------------------------------------------- */
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
const loadings = {
|
|
isLoading: isLoading,
|
|
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({});
|
|
|
|
const params = {
|
|
searchParams: searchParams,
|
|
setSearchParams: setSearchParams,
|
|
appliedParams: appliedParams,
|
|
setAppliedParams: setAppliedParams,
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* ------------------------------ handle order ------------------------------ */
|
|
const [order, setOrder] = useState<Order>('asc');
|
|
const [orderBy, setOrderBy] = useState('fullName');
|
|
|
|
const orders = {
|
|
order: order,
|
|
setOrder: setOrder,
|
|
orderBy: orderBy,
|
|
setOrderBy: setOrderBy,
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* ---------------------------- handle pagination --------------------------- */
|
|
const [page, setPage] = useState(0);
|
|
const [rowsPerPage, setRowsPerPage] = useState(10);
|
|
|
|
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
|
|
current_page: 0,
|
|
from: 0,
|
|
last_page: 0,
|
|
links: [],
|
|
path: '',
|
|
per_page: 0,
|
|
to: 0,
|
|
total: 0,
|
|
});
|
|
|
|
const paginations = {
|
|
page: page,
|
|
setPage: setPage,
|
|
rowsPerPage: rowsPerPage,
|
|
setRowsPerPage: setRowsPerPage,
|
|
paginationTable: paginationTable,
|
|
setPaginationTable: setPaginationTable,
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* ------------------------------ handle search ----------------------------- */
|
|
const [searchText, setSearchText] = useState('');
|
|
|
|
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
|
event.preventDefault();
|
|
|
|
if (searchText === '') {
|
|
searchParams.delete('search');
|
|
const params = Object.fromEntries([...searchParams.entries()]);
|
|
setAppliedParams(params);
|
|
} else {
|
|
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
|
|
setAppliedParams(params);
|
|
}
|
|
};
|
|
|
|
const searchs = {
|
|
searchText: searchText,
|
|
setSearchText: setSearchText,
|
|
handleSearchSubmit: handleSearchSubmit,
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* ------------------------------ handle filter ----------------------------- */
|
|
const [divisionValue, setDivisionValue] = useState('all');
|
|
const [divisionData, setDivisionData] = useState([]);
|
|
|
|
const handleDivisionChange = (event: SelectChangeEvent) => {
|
|
setDivisionValue(event.target.value as string);
|
|
|
|
if (event.target.value === 'all') {
|
|
searchParams.delete('division');
|
|
const params = Object.fromEntries([...searchParams.entries()]);
|
|
setAppliedParams(params);
|
|
} else {
|
|
const params = Object.fromEntries([
|
|
...searchParams.entries(),
|
|
['division', event.target.value as string],
|
|
]);
|
|
setAppliedParams(params);
|
|
}
|
|
};
|
|
|
|
const filters = {
|
|
useFilter: true,
|
|
config: {
|
|
label: 'Division',
|
|
divisionValue: divisionValue,
|
|
divisionData: divisionData,
|
|
handleDivisionChange: handleDivisionChange,
|
|
},
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* -------------------------------- headCell -------------------------------- */
|
|
const headCells: HeadCell<never>[] = [
|
|
{
|
|
id: 'memberId',
|
|
align: 'left',
|
|
label: 'Member ID',
|
|
isSort: true,
|
|
},
|
|
{
|
|
id: 'fullName',
|
|
align: 'center',
|
|
label: 'Name',
|
|
isSort: true,
|
|
},
|
|
{
|
|
id: 'division',
|
|
align: 'center',
|
|
label: 'Divisi',
|
|
isSort: true,
|
|
},
|
|
{
|
|
id: 'limit',
|
|
align: 'center',
|
|
label: 'Limit',
|
|
isSort: false,
|
|
},
|
|
{
|
|
id: 'status',
|
|
align: 'center',
|
|
label: 'Status',
|
|
isSort: true,
|
|
},
|
|
{
|
|
id: 'action',
|
|
align: 'right',
|
|
label: '',
|
|
isSort: false,
|
|
},
|
|
];
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* ----------------------------- handler action ----------------------------- */
|
|
const handleAction = () => {
|
|
alert('action');
|
|
};
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
setIsLoading(true);
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
|
|
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 },
|
|
});
|
|
|
|
// console.log('member', corporateMembers);
|
|
const corporateTopUpLimit = await axios.get(`${corporateValue}/topup`);
|
|
|
|
setSearchParams(parameters);
|
|
setPolicyData({
|
|
limit: corporatePolicyLimit.data.data,
|
|
topUpLimit: corporateTopUpLimit.data.data,
|
|
});
|
|
setDivisionData(corporateDivision.data);
|
|
setMemberData(
|
|
corporateMembers.data.data.map((obj: any) => {
|
|
return {
|
|
...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);
|
|
}
|
|
|
|
setIsLoading(false);
|
|
})();
|
|
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);
|
|
|
|
// console.log(policyData);
|
|
|
|
return (
|
|
<Page title="Dashboard">
|
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography variant="h3" component="h1" paragraph>
|
|
Dashboard
|
|
</Typography>
|
|
</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}
|
|
rows={memberData}
|
|
orders={orders}
|
|
paginations={paginations}
|
|
loadings={loadings}
|
|
params={params}
|
|
searchs={searchs}
|
|
filters={filters}
|
|
/>
|
|
</Grid>
|
|
</Grid>
|
|
</Container>
|
|
</Page>
|
|
);
|
|
}
|