Table Component Alarm Center

This commit is contained in:
pajri
2023-05-05 17:02:40 +07:00
parent 49f3a8558d
commit c8b06f67d1
2 changed files with 268 additions and 255 deletions

View File

@@ -2,6 +2,6 @@ GENERATE_SOURCEMAP=false
PORT=8083 PORT=8083
REACT_APP_HOST_API_URL="http://lms.test" REACT_APP_HOST_API_URL="http://localhost:8001"
VITE_API_URL="http://lms.test/api/client" VITE_API_URL="http://localhost:8001/api/client"

View File

@@ -19,127 +19,166 @@ import { visuallyHidden } from '@mui/utils';
import axios from '../../utils/axios'; import axios from '../../utils/axios';
/* ---------------------------------- react --------------------------------- */ /* ---------------------------------- react --------------------------------- */
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
/* -------------------------------- component ------------------------------- */ /* -------------------------------- component ------------------------------- */
import Iconify from '../../components/Iconify'; import Iconify from '../../components/Iconify';
import BaseTablePagination from '../../components/BaseTablePagination'; import BaseTablePagination from '../../components/BaseTablePagination';
import TableComponent from '../../components/Table';
/* ---------------------------------- hooks --------------------------------- */ /* ---------------------------------- hooks --------------------------------- */
import useMap from '../../hooks/useMap'; import useMap from '../../hooks/useMap';
/* ---------------------------------- theme --------------------------------- */ /* ---------------------------------- theme --------------------------------- */
import palette from '../../theme/palette'; import palette from '../../theme/palette';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate'; import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
import { useSearchParams } from 'react-router-dom';
/* ---------------------------------- types --------------------------------- */ /* ---------------------------------- types --------------------------------- */
type PaginationTableProps = { // type PaginationTableProps = {
current_page: number; // current_page: number;
from: number; // from: number;
last_page: number; // last_page: number;
links: []; // links: [];
path: string; // path: string;
per_page: number; // per_page: number;
to: number; // to: number;
total: number; // total: number;
}; // };
type DataTableProps = { // type DataTableProps = {
fullName: string; // fullName: string;
memberId: string; // memberId: string;
service: string; // service: string;
start_date: string; // start_date: string;
end_date: string; // end_date: string;
status: boolean | number; // status: boolean | number;
}; // };
/* -------------------------------------------------------------------------- */ // /* -------------------------------------------------------------------------- */
/* -------------------------- enchanced table head -------------------------- */ // /* -------------------------- enchanced table head -------------------------- */
type Order = 'asc' | 'desc'; // type Order = 'asc' | 'desc';
interface HeadCell { // interface HeadCell {
id: string; // id: string;
label: string; // label: string;
} // }
const headCells: readonly HeadCell[] = [ // const headCells: readonly HeadCell[] = [
{ // {
id: 'name', // id: 'name',
label: 'Name', // label: 'Name',
}, // },
{ // {
id: 'member_id', // id: 'member_id',
label: 'Member ID', // label: 'Member ID',
}, // },
{ // {
id: 'service', // id: 'service',
label: 'Service', // label: 'Service',
}, // },
{ // {
id: 'start_date', // id: 'start_date',
label: 'Start Date', // label: 'Start Date',
}, // },
{ // {
id: 'end_date', // id: 'end_date',
label: 'End Date', // label: 'End Date',
}, // },
{ // {
id: 'status', // id: 'status',
label: 'Status', // label: 'Status',
}, // },
]; // ];
interface EnhancedTableProps { // interface EnhancedTableProps {
onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void; // onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void;
order: Order; // order: Order;
orderBy: string; // orderBy: string;
} // }
function EnhancedTableHead(props: EnhancedTableProps) { // function EnhancedTableHead(props: EnhancedTableProps) {
const { order, orderBy, onRequestSort } = props; // const { order, orderBy, onRequestSort } = props;
const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => { // const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
onRequestSort(event, property); // onRequestSort(event, property);
}; // };
return ( // return (
<TableHead> // <TableHead>
<TableRow> // <TableRow>
<TableCell align="center">No</TableCell> // <TableCell align="center">No</TableCell>
{headCells.map((headCell) => ( // {headCells.map((headCell) => (
<TableCell // <TableCell
key={headCell.id} // key={headCell.id}
sortDirection={orderBy === headCell.id ? order : false} // sortDirection={orderBy === headCell.id ? order : false}
align="center" // align="center"
> // >
<TableSortLabel // <TableSortLabel
active={orderBy === headCell.id} // active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : 'asc'} // direction={orderBy === headCell.id ? order : 'asc'}
onClick={createSortHandler(headCell.id)} // onClick={createSortHandler(headCell.id)}
> // >
{headCell.label} // {headCell.label}
{orderBy === headCell.id ? ( // {orderBy === headCell.id ? (
<Box component="span" sx={visuallyHidden}> // <Box component="span" sx={visuallyHidden}>
{order === 'desc' ? 'sorted descending' : 'sorted ascending'} // {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
</Box> // </Box>
) : null} // ) : null}
</TableSortLabel> // </TableSortLabel>
</TableCell> // </TableCell>
))} // ))}
</TableRow> // </TableRow>
</TableHead> // </TableHead>
); // );
} // }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
export default function List() { export default function List() {
const { corporateValue } = useContext(UserCurrentCorporateContext); const { corporateValue } = useContext(UserCurrentCorporateContext);
const [order, setOrder] = useState<Order>('asc');
const [orderBy, setOrderBy] = useState(''); const [data, setData] = useState([]);
const [customSearchParams, setCustomSearchParams] = useMap<string, any>();
/* -------------------------------------------------------------------------- */
/* setting up for the table */
/* -------------------------------------------------------------------------- */
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [dataTable, setDataTable] = useState([]);
const loadings = {
isLoading: isLoading,
setIsLoading: setIsLoading,
};
/* ------------------------------ 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 [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10); const [rowsPerPage, setRowsPerPage] = useState(10);
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({ const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
current_page: 0, current_page: 0,
from: 0, from: 0,
@@ -150,183 +189,157 @@ export default function List() {
to: 0, to: 0,
total: 0, total: 0,
}); });
/* ------------------------------- handle sort ------------------------------ */
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => { const paginations = {
const isAsc = orderBy === property && order === 'asc'; page: page,
setOrder(isAsc ? 'desc' : 'asc'); setPage: setPage,
setOrderBy(property); rowsPerPage: rowsPerPage,
const params = Object.fromEntries([ setRowsPerPage: setRowsPerPage,
...customSearchParams.entries(), paginationTable: paginationTable,
// ['order', isAsc ? 'desc' : 'asc'], setPaginationTable: setPaginationTable,
// ['orderBy', property],
]);
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 500));
loadDataTable(params);
setIsLoading(false);
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* ------------------------------ Search field ------------------------------ */ /* ------------------------------ handle search ----------------------------- */
const [searchText, setSearchText] = useState(''); const [searchText, setSearchText] = useState('');
const handleSearch = (event: any) => { const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
setSearchText(event.target.value);
};
const handleSearchSubmit = async (event: any) => {
event.preventDefault(); event.preventDefault();
const params = Object.fromEntries([...customSearchParams.entries(), ['search', searchText]]);
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 500));
loadDataTable(params);
setIsLoading(false);
};
/* -------------------------------------------------------------------------- */
/* --------------------------- Load Data Table API -------------------------- */ if (searchText === '') {
const loadDataTable = async (appliedParams: any | null = null) => { searchParams.delete('search');
setIsLoading(true); const params = Object.fromEntries([...searchParams.entries()]);
setAppliedParams(params);
const params = appliedParams } else {
? appliedParams const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
: Object.fromEntries([ setAppliedParams(params);
...customSearchParams.entries(), }
// ['order', order],
// ['orderBy', orderBy],
]);
const response = await axios.get(`/${corporateValue}/members?type=alarm-center`, {
params: params,
});
setDataTable(response.data.data);
setPaginationTable(response.data);
setRowsPerPage(response.data.per_page);
setIsLoading(false);
}; };
/* -------------------------------------------------------------------------- */
/* ------------------------ button change pagination ------------------------ */ const searchs = {
const onPageChangeHandle = async (event: unknown, newPage: number) => { searchText: searchText,
const params = Object.fromEntries([...customSearchParams.entries(), ['page', newPage + 1]]); setSearchText: setSearchText,
setPage(newPage); handleSearchSubmit: handleSearchSubmit,
setIsLoading(true);
await new Promise((resolve) => setTimeout(resolve, 500));
loadDataTable(params);
setIsLoading(false);
setCustomSearchParams.set('page', newPage + 1);
}; };
/* -------------------------------------------------------------------------- */
/* ----------------------- row page per limit on click ---------------------- */ /* -------------------------------- headCell -------------------------------- */
const onRowsPerPageChangeHandle = async (event: React.ChangeEvent<HTMLInputElement>) => { const headCells: HeadCell<never>[] = [
setPage(0); {
const params = Object.fromEntries([ id: 'fullName',
...customSearchParams.entries(), align: 'left',
['page', 0], label: 'Name',
['per_page', parseInt(event.target.value, 10)], isSort: true,
]); },
setRowsPerPage(parseInt(event.target.value, 10)); {
setIsLoading(true); id: 'memberId',
await new Promise((resolve) => setTimeout(resolve, 500)); align: 'left',
loadDataTable(params); label: 'Member ID',
setIsLoading(false); isSort: true,
setCustomSearchParams.set('per_page', parseInt(event.target.value, 10)); },
}; {
id: 'start_date',
align: 'center',
label: 'Start Date',
isSort: true,
},
{
id: 'end_date',
align: 'center',
label: 'End Date',
isSort: false,
},
{
id: 'status',
align: 'center',
label: 'Status',
isSort: true,
},
];
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
useEffect(() => { useEffect(() => {
loadDataTable(); (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 response = await axios.get(`/${corporateValue}/members?type=alarm-center`, {
params: parameters,
});
setData(
response.data.data.map((obj: any) => {
return {
...obj,
status:
obj.status === 1 ? (
<Button
startIcon={<Iconify icon="ic:round-check" />}
sx={{
backgroundColor: palette.light.grey[300],
color: palette.light.grey[800],
paddingX: 1.5,
paddingY: 1,
'&:hover': {
backgroundColor: palette.light.grey[400],
color: palette.light.grey[800],
},
}}
>
done
</Button>
) : (
<Button
startIcon={<Iconify icon="fa6-solid:clock" />}
sx={{
backgroundColor: '#CD7B2E',
color: '#FFFF',
paddingX: 1.5,
paddingY: 1,
'&:hover': {
backgroundColor: '#BF6919',
color: '#FFFF',
},
}}
>
Ongoing
</Button>
),
};
})
);
setPaginationTable(response.data);
setRowsPerPage(response.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]);
return ( return (
<Stack> <Stack>
{/* Search */} <TableComponent
<form onSubmit={handleSearchSubmit} style={{ width: '100%', padding: '20px 24px' }}> headCells={headCells}
<TextField rows={data}
id="search-input" orders={orders}
label="Search" paginations={paginations}
variant="outlined" loadings={loadings}
fullWidth params={params}
onChange={handleSearch} searchs={searchs}
value={searchText} // filters={filters}
/>
</form>
{/* The Main Table */}
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<EnhancedTableHead order={order} orderBy={orderBy} onRequestSort={handleRequestSort} />
<TableBody>
{isLoading ? (
<TableRow>
<TableCell colSpan={8} align="center">
Loading . . .
</TableCell>
</TableRow>
) : dataTable.length >= 1 ? (
dataTable.map((row: DataTableProps, index) => (
<TableRow key={index}>
<TableCell align="center">{paginationTable.from + index++}</TableCell>
<TableCell align="center">{row.fullName}</TableCell>
<TableCell align="center">{row.memberId}</TableCell>
<TableCell align="center">{row.service}</TableCell>
<TableCell align="center">{row.start_date}</TableCell>
<TableCell align="center">{row.end_date}</TableCell>
<TableCell align="center">
{row.status === 1 ? (
<Button
startIcon={<Iconify icon="ic:round-check" />}
sx={{
backgroundColor: palette.light.grey[300],
color: palette.light.grey[800],
paddingX: 1.5,
paddingY: 1,
'&:hover': {
backgroundColor: palette.light.grey[400],
color: palette.light.grey[800],
},
}}
>
done
</Button>
) : (
<Button
startIcon={<Iconify icon="fa6-solid:clock" />}
sx={{
backgroundColor: '#CD7B2E',
color: '#FFFF',
paddingX: 1.5,
paddingY: 1,
'&:hover': {
backgroundColor: '#BF6919',
color: '#FFFF',
},
}}
>
Ongoing
</Button>
)}
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={8} align="center">
No Data Found
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
{/* Pagination */}
<BaseTablePagination
count={paginationTable.total}
onPageChange={onPageChangeHandle}
page={page}
rowsPerPage={rowsPerPage}
onRowsPerPageChange={onRowsPerPageChangeHandle}
/> />
</Stack> </Stack>
); );