remove old table dashboard
This commit is contained in:
@@ -1,443 +0,0 @@
|
|||||||
/* ---------------------------------- @mui ---------------------------------- */
|
|
||||||
import { styled } from '@mui/material/styles';
|
|
||||||
import {
|
|
||||||
Paper,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
TextField,
|
|
||||||
Button,
|
|
||||||
TableSortLabel,
|
|
||||||
Box,
|
|
||||||
IconButton,
|
|
||||||
Card,
|
|
||||||
Grid,
|
|
||||||
FormControl,
|
|
||||||
InputLabel,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
SelectChangeEvent,
|
|
||||||
Stack,
|
|
||||||
Typography,
|
|
||||||
LinearProgress,
|
|
||||||
linearProgressClasses,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { visuallyHidden } from '@mui/utils';
|
|
||||||
/* ---------------------------------- axios --------------------------------- */
|
|
||||||
import axios from '../../utils/axios';
|
|
||||||
/* ---------------------------------- react --------------------------------- */
|
|
||||||
import { useContext, useEffect, useState } from 'react';
|
|
||||||
/* -------------------------------- component ------------------------------- */
|
|
||||||
import Iconify from '../../components/Iconify';
|
|
||||||
import BaseTablePagination from '../../components/BaseTablePagination';
|
|
||||||
/* ---------------------------------- theme --------------------------------- */
|
|
||||||
import palette from '../../theme/palette';
|
|
||||||
import { useSearchParams } from 'react-router-dom';
|
|
||||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
|
||||||
import { fSplit } from '../../utils/formatNumber';
|
|
||||||
|
|
||||||
/* ---------------------------------- types --------------------------------- */
|
|
||||||
type PaginationTableProps = {
|
|
||||||
current_page: number;
|
|
||||||
from: number;
|
|
||||||
last_page: number;
|
|
||||||
links: [];
|
|
||||||
path: string;
|
|
||||||
per_page: number;
|
|
||||||
to: number;
|
|
||||||
total: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DataTableProps = {
|
|
||||||
fullName: string;
|
|
||||||
memberId: string;
|
|
||||||
division: string;
|
|
||||||
limit: {
|
|
||||||
current: number;
|
|
||||||
total: number;
|
|
||||||
percentage: number;
|
|
||||||
};
|
|
||||||
status: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Order = 'asc' | 'desc';
|
|
||||||
|
|
||||||
interface HeadCell {
|
|
||||||
id: string;
|
|
||||||
align: string;
|
|
||||||
label: string;
|
|
||||||
isSort: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EnhancedTableProps {
|
|
||||||
onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void;
|
|
||||||
order: Order;
|
|
||||||
orderBy: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type DivisionDataProps = {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* --------------------------------- styled --------------------------------- */
|
|
||||||
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
|
||||||
height: 10,
|
|
||||||
borderRadius: 6,
|
|
||||||
[`&.${linearProgressClasses.colorPrimary}`]: {
|
|
||||||
backgroundColor: '#D1F1F1',
|
|
||||||
},
|
|
||||||
[`& .${linearProgressClasses.bar}`]: {
|
|
||||||
borderRadius: 6,
|
|
||||||
backgroundColor: theme.palette.primary.main,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* -------------------------- enchanced table head -------------------------- */
|
|
||||||
const headCells: readonly HeadCell[] = [
|
|
||||||
{
|
|
||||||
id: 'member_id',
|
|
||||||
align: 'left',
|
|
||||||
label: 'Member ID',
|
|
||||||
isSort: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'name',
|
|
||||||
align: 'center',
|
|
||||||
label: 'Name',
|
|
||||||
isSort: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'division',
|
|
||||||
align: 'center',
|
|
||||||
label: 'Divisi',
|
|
||||||
isSort: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'limit',
|
|
||||||
align: 'center',
|
|
||||||
label: 'Limit',
|
|
||||||
isSort: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'active',
|
|
||||||
align: 'center',
|
|
||||||
label: 'Status',
|
|
||||||
isSort: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function EnhancedTableHead({ order, orderBy, onRequestSort }: EnhancedTableProps) {
|
|
||||||
const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
|
|
||||||
onRequestSort(event, property);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
{headCells.map((headCell) => (
|
|
||||||
<TableCell
|
|
||||||
key={headCell.id}
|
|
||||||
sortDirection={orderBy === headCell.id ? order : false}
|
|
||||||
// @ts-ignore
|
|
||||||
align={headCell.align}
|
|
||||||
sx={{ padding: 2 }}
|
|
||||||
>
|
|
||||||
{headCell.isSort ? (
|
|
||||||
<TableSortLabel
|
|
||||||
active={orderBy === headCell.id}
|
|
||||||
direction={orderBy === headCell.id ? order : 'asc'}
|
|
||||||
onClick={createSortHandler(headCell.id)}
|
|
||||||
>
|
|
||||||
{headCell.label}
|
|
||||||
{orderBy === headCell.id ? (
|
|
||||||
<Box component="span" sx={visuallyHidden}>
|
|
||||||
{order === 'desc' ? 'sorted descending' : 'sorted ascending'}
|
|
||||||
</Box>
|
|
||||||
) : null}
|
|
||||||
</TableSortLabel>
|
|
||||||
) : (
|
|
||||||
headCell.label
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
<TableCell align="center">{''}</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
export default function TableList(props: any) {
|
|
||||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
|
||||||
|
|
||||||
const [dataTable, setDataTable] = useState([]);
|
|
||||||
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
|
|
||||||
current_page: 0,
|
|
||||||
from: 0,
|
|
||||||
last_page: 0,
|
|
||||||
links: [],
|
|
||||||
path: '',
|
|
||||||
per_page: 0,
|
|
||||||
to: 0,
|
|
||||||
total: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
|
||||||
const [appliedParams, setAppliedParams] = useState({});
|
|
||||||
|
|
||||||
const [order, setOrder] = useState<Order>('asc');
|
|
||||||
const [orderBy, setOrderBy] = useState('name');
|
|
||||||
const [page, setPage] = useState(0);
|
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
|
||||||
|
|
||||||
/* ------------------------------- handle sort ------------------------------ */
|
|
||||||
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
|
|
||||||
const isAsc = orderBy === property && order === 'asc';
|
|
||||||
setOrder(isAsc ? 'desc' : 'asc');
|
|
||||||
setOrderBy(property);
|
|
||||||
const params = Object.fromEntries([
|
|
||||||
...searchParams.entries(),
|
|
||||||
['order', isAsc ? 'desc' : 'asc'],
|
|
||||||
['orderBy', property],
|
|
||||||
]);
|
|
||||||
setAppliedParams(params);
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* ----------------------------- division field ----------------------------- */
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* ------------------------------ Search field ------------------------------ */
|
|
||||||
const [searchText, setSearchText] = useState('');
|
|
||||||
|
|
||||||
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
|
||||||
event.preventDefault();
|
|
||||||
setIsLoading(true);
|
|
||||||
if (searchText === '') {
|
|
||||||
searchParams.delete('search');
|
|
||||||
const params = Object.fromEntries([...searchParams.entries()]);
|
|
||||||
setAppliedParams(params);
|
|
||||||
} else {
|
|
||||||
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
|
|
||||||
setAppliedParams(params);
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
||||||
setIsLoading(false);
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* ------------------------ button change pagination ------------------------ */
|
|
||||||
const onPageChangeHandle = async (
|
|
||||||
event: React.MouseEvent<HTMLButtonElement> | null,
|
|
||||||
newPage: number
|
|
||||||
) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
const params = Object.fromEntries([...searchParams.entries(), ['page', newPage + 1]]);
|
|
||||||
setPage(newPage);
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
||||||
setAppliedParams(params);
|
|
||||||
setIsLoading(false);
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* --------------------------- row page per limit --------------------------- */
|
|
||||||
const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
searchParams.delete('page');
|
|
||||||
const params = Object.fromEntries([
|
|
||||||
...searchParams.entries(),
|
|
||||||
['per_page', parseInt(event.target.value, 10)],
|
|
||||||
]);
|
|
||||||
setRowsPerPage(parseInt(event.target.value, 10));
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
||||||
setAppliedParams(params);
|
|
||||||
setIsLoading(false);
|
|
||||||
};
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
setIsLoading(true);
|
|
||||||
|
|
||||||
const division = await axios.get(`${corporateValue}/division`);
|
|
||||||
setDivisionData(division.data);
|
|
||||||
|
|
||||||
const params =
|
|
||||||
Object.keys(appliedParams).length !== 0
|
|
||||||
? appliedParams
|
|
||||||
: Object.fromEntries([...searchParams.entries(), ['order', order], ['orderBy', orderBy]]);
|
|
||||||
|
|
||||||
const corporateMembers = await axios.get(`${corporateValue}/members`, {
|
|
||||||
params: { ...params, claimMember: false },
|
|
||||||
});
|
|
||||||
|
|
||||||
setSearchParams(params);
|
|
||||||
setDataTable(corporateMembers.data.data);
|
|
||||||
setPaginationTable(corporateMembers.data);
|
|
||||||
setRowsPerPage(corporateMembers.data.per_page);
|
|
||||||
setIsLoading(false);
|
|
||||||
})();
|
|
||||||
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<Grid container>
|
|
||||||
{/* Field 1 */}
|
|
||||||
<Grid item xs={12} paddingX="24px" paddingY="20px">
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12} lg={3} xl={2}>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<InputLabel id="simple-division-select-lable">Division</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="simple-division-select-lable"
|
|
||||||
id="division-select-lable"
|
|
||||||
value={divisionValue}
|
|
||||||
label="Division"
|
|
||||||
onChange={handleDivisionChange}
|
|
||||||
>
|
|
||||||
<MenuItem value="all">All</MenuItem>
|
|
||||||
{divisionData.map((row: DivisionDataProps, index) => (
|
|
||||||
<MenuItem key={index} value={row.id}>
|
|
||||||
{row.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} lg={9} xl={10}>
|
|
||||||
<form onSubmit={handleSearchSubmit}>
|
|
||||||
<TextField
|
|
||||||
id="search-input"
|
|
||||||
label="Search"
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(event) => setSearchText(event.target.value)}
|
|
||||||
value={searchText}
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
{/* End Field 1 */}
|
|
||||||
{/* Field 2 */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<TableContainer component={Paper}>
|
|
||||||
<Table aria-label="collapsible table" size="small">
|
|
||||||
<EnhancedTableHead
|
|
||||||
order={order}
|
|
||||||
orderBy={orderBy}
|
|
||||||
onRequestSort={handleRequestSort}
|
|
||||||
/>
|
|
||||||
<TableBody>
|
|
||||||
{isLoading ? (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={6} align="center">
|
|
||||||
Loading . . .
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
) : dataTable.length >= 1 ? (
|
|
||||||
dataTable.map((row: DataTableProps, index) => (
|
|
||||||
<TableRow key={index}>
|
|
||||||
<TableCell align="left">{row.memberId}</TableCell>
|
|
||||||
<TableCell align="center">{row.fullName}</TableCell>
|
|
||||||
<TableCell align="center">{row.division}</TableCell>
|
|
||||||
<TableCell align="center" width={170}>
|
|
||||||
<Stack>
|
|
||||||
<BorderLinearProgress
|
|
||||||
variant="determinate"
|
|
||||||
value={row.limit.percentage}
|
|
||||||
sx={{ mb: 1 }}
|
|
||||||
/>
|
|
||||||
<Typography sx={{ typography: 'caption', color: '#637381' }}>
|
|
||||||
{fSplit(row.limit.current)} / {fSplit(row.limit.total)}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="center">
|
|
||||||
{row.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>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
{/* <TableCell align="right">
|
|
||||||
<IconButton>
|
|
||||||
<Iconify icon="ic:baseline-more-vert" />
|
|
||||||
</IconButton>
|
|
||||||
</TableCell> */}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={6} align="center">
|
|
||||||
No Data Found
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
|
|
||||||
{/* Pagination */}
|
|
||||||
<BaseTablePagination
|
|
||||||
count={paginationTable.total}
|
|
||||||
onPageChange={onPageChangeHandle}
|
|
||||||
page={page}
|
|
||||||
rowsPerPage={rowsPerPage}
|
|
||||||
onRowsPerPageChange={onRowsPerPageChangeHandle}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
{/* End Field 2 */}
|
|
||||||
</Grid>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user