School Commit Init
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import Box from '@mui/material/Box';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableFooter from '@mui/material/TableFooter';
|
||||
import TablePagination from '@mui/material/TablePagination';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import FirstPageIcon from '@mui/icons-material/FirstPage';
|
||||
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
|
||||
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
|
||||
import LastPageIcon from '@mui/icons-material/LastPage';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
TableHead
|
||||
} from '@mui/material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import DeleteDialog from '../Shared/DeleteDialog';
|
||||
import Drug from '../../interfaces/Drug';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import axios from 'axios';
|
||||
import { loadDrugs } from '../../redux/slices/drugSlice';
|
||||
import { getWebSocket } from '../../redux/selectors';
|
||||
|
||||
interface TablePaginationActionsProps {
|
||||
count: number;
|
||||
page: number;
|
||||
rowsPerPage: number;
|
||||
onPageChange: (
|
||||
event: React.MouseEvent<HTMLButtonElement>,
|
||||
newPage: number
|
||||
) => void;
|
||||
}
|
||||
|
||||
function TablePaginationActions(props: TablePaginationActionsProps) {
|
||||
const theme = useTheme();
|
||||
const { count, page, rowsPerPage, onPageChange } = props;
|
||||
|
||||
const handleFirstPageButtonClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
onPageChange(event, 0);
|
||||
};
|
||||
|
||||
const handleBackButtonClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
onPageChange(event, page - 1);
|
||||
};
|
||||
|
||||
const handleNextButtonClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
onPageChange(event, page + 1);
|
||||
};
|
||||
|
||||
const handleLastPageButtonClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
||||
<IconButton
|
||||
onClick={handleFirstPageButtonClick}
|
||||
disabled={page === 0}
|
||||
aria-label='first page'
|
||||
>
|
||||
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={handleBackButtonClick}
|
||||
disabled={page === 0}
|
||||
aria-label='previous page'
|
||||
>
|
||||
{theme.direction === 'rtl' ? (
|
||||
<KeyboardArrowRight />
|
||||
) : (
|
||||
<KeyboardArrowLeft />
|
||||
)}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={handleNextButtonClick}
|
||||
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
|
||||
aria-label='next page'
|
||||
>
|
||||
{theme.direction === 'rtl' ? (
|
||||
<KeyboardArrowLeft />
|
||||
) : (
|
||||
<KeyboardArrowRight />
|
||||
)}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={handleLastPageButtonClick}
|
||||
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
|
||||
aria-label='last page'
|
||||
>
|
||||
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
|
||||
</IconButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const DrugTable = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [page, setPage] = useState(
|
||||
sessionStorage.getItem('page')
|
||||
? parseInt(sessionStorage.getItem('page') as string)
|
||||
: 0
|
||||
);
|
||||
const ws = useSelector(getWebSocket);
|
||||
|
||||
const [sort, setSort] = useState('');
|
||||
const [open, setOpen] = useState(-1);
|
||||
const [drugs, setDrugs] = useState<Drug[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleViewClick = (id: number) => {
|
||||
navigate(`/details/${id}`);
|
||||
};
|
||||
const handleUpdateClick = (id: number) => {
|
||||
navigate(`/update/${id}`);
|
||||
};
|
||||
|
||||
const handleDeleteClick = (id: number) => {
|
||||
setOpen(id);
|
||||
};
|
||||
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState(
|
||||
sessionStorage.getItem('rowsPerPage')
|
||||
? parseInt(sessionStorage.getItem('rowsPerPage') as string, 10)
|
||||
: 5
|
||||
);
|
||||
|
||||
const emptyRows =
|
||||
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - total) : 0;
|
||||
|
||||
const handleChangePage = (
|
||||
_event: React.MouseEvent<HTMLButtonElement> | null,
|
||||
newPage: number
|
||||
) => {
|
||||
setPage(newPage);
|
||||
sessionStorage.setItem('page', newPage.toString());
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (
|
||||
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
setRowsPerPage(parseInt(event.target.value, 10));
|
||||
setPage(0);
|
||||
sessionStorage.setItem('rowsPerPage', event.target.value);
|
||||
};
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://silkroadapi.azurewebsites.net/Drug/get-drugs?Page=${
|
||||
page + 1
|
||||
}&PageSize=${rowsPerPage}&sorting=${sort}`,
|
||||
{ withCredentials: true }
|
||||
);
|
||||
dispatch(loadDrugs(response.data.items));
|
||||
setDrugs(response.data.items);
|
||||
setTotal(response.data.total);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setError(true);
|
||||
}
|
||||
}, [dispatch, page, rowsPerPage, sort]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [page, sort, dispatch, rowsPerPage, fetchData]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(ws);
|
||||
ws?.addEventListener('message', (event) => {
|
||||
console.log(event.data);
|
||||
fetchData();
|
||||
});
|
||||
}, [fetchData, ws]);
|
||||
|
||||
return (
|
||||
<TableContainer component={Paper}>
|
||||
<Table sx={{ minWidth: 500 }} aria-label='custom pagination table'>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell
|
||||
data-asc={'false'}
|
||||
onClick={(e) => {
|
||||
setSort(
|
||||
e.currentTarget.dataset.asc === 'false' ? 'name' : 'name_desc'
|
||||
);
|
||||
e.currentTarget.dataset.asc =
|
||||
e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
|
||||
}}
|
||||
sx={{ cursor: 'pointer' }}
|
||||
>
|
||||
Name
|
||||
</TableCell>
|
||||
<TableCell
|
||||
align='right'
|
||||
onClick={(e) => {
|
||||
setSort(
|
||||
e.currentTarget.dataset.asc === 'false'
|
||||
? 'manufacturer'
|
||||
: 'manufacturer_desc'
|
||||
);
|
||||
e.currentTarget.dataset.asc =
|
||||
e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
|
||||
}}
|
||||
sx={{ cursor: 'pointer' }}
|
||||
>
|
||||
Manufacturer
|
||||
</TableCell>
|
||||
<TableCell
|
||||
align='right'
|
||||
onClick={(e) => {
|
||||
setSort(
|
||||
e.currentTarget.dataset.asc === 'false'
|
||||
? 'price'
|
||||
: 'price_desc'
|
||||
);
|
||||
e.currentTarget.dataset.asc =
|
||||
e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
|
||||
}}
|
||||
sx={{ cursor: 'pointer' }}
|
||||
>
|
||||
Price (USD)
|
||||
</TableCell>
|
||||
<TableCell align='right'>View</TableCell>
|
||||
<TableCell align='right'>Update</TableCell>
|
||||
<TableCell align='right'>Delete</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{drugs.map((drug) => (
|
||||
<TableRow key={drug.id}>
|
||||
<TableCell component='th' scope='row'>
|
||||
{drug.name}
|
||||
</TableCell>
|
||||
<TableCell style={{ width: 160 }} align='right'>
|
||||
{drug.manufacturer}
|
||||
</TableCell>
|
||||
<TableCell style={{ width: 160 }} align='right'>
|
||||
${drug.price}
|
||||
</TableCell>
|
||||
<TableCell style={{ width: 160 }} align='right'>
|
||||
<Button
|
||||
variant='outlined'
|
||||
onClick={() => {
|
||||
handleViewClick(drug.id);
|
||||
}}
|
||||
>
|
||||
View
|
||||
</Button>
|
||||
</TableCell>
|
||||
<TableCell style={{ width: 160 }} align='right'>
|
||||
<Button
|
||||
variant='outlined'
|
||||
onClick={() => {
|
||||
handleUpdateClick(drug.id);
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</TableCell>
|
||||
<TableCell style={{ width: 160 }} align='right'>
|
||||
<Button
|
||||
variant='outlined'
|
||||
onClick={() => {
|
||||
handleDeleteClick(drug.id);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<TableRow style={{ height: 53 * emptyRows }}>
|
||||
<TableCell colSpan={6} />
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[5, 10, 25]}
|
||||
colSpan={3}
|
||||
count={total}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
inputProps: {
|
||||
'aria-label': 'rows per page'
|
||||
},
|
||||
native: true
|
||||
}
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
ActionsComponent={TablePaginationActions}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
</Table>
|
||||
<DeleteDialog
|
||||
id={open}
|
||||
handleClose={() => {
|
||||
setOpen(-1);
|
||||
}}
|
||||
handleAgree={async () => {
|
||||
await axios.delete(
|
||||
`https://silkroadapi.azurewebsites.net/Drug/delete-drug/${open}`,
|
||||
{ withCredentials: true }
|
||||
);
|
||||
await fetchData();
|
||||
setOpen(-1);
|
||||
}}
|
||||
/>
|
||||
<Dialog
|
||||
open={error}
|
||||
aria-labelledby='alert-dialog-title'
|
||||
aria-describedby='alert-dialog-description'
|
||||
>
|
||||
<DialogTitle id='alert-dialog-title'>{'Error'}</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id='alert-dialog-description'>
|
||||
Error while connecting
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setError(false);
|
||||
}}
|
||||
color='primary'
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default DrugTable;
|
||||
Reference in New Issue
Block a user