Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import "swiper/css/pagination";
function Announcements() {
return (
<>
<Box sx={{ mt: { xs: "-2.7rem", md: "-2rem" } }}>
<Box sx={{ mt: { xs: "-2.8rem", md: "-2.8rem" } }}>
<Swiper
effect={"creative"}
speed={1250}
Expand Down
177 changes: 177 additions & 0 deletions client/src/components/SignupApproval/SignupApproval.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import * as React from "react";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import Paper from "@mui/material/Paper";
import PropTypes from "prop-types";
import TableData from "./TableData";
import TableDescription from "./TableDescription";
import TableToolbar from "./TableToolbar";
import TableContainer from "@mui/material/TableContainer";
import TablePagination from "@mui/material/TablePagination";
import TableColumnHeadings from "./TableColumnHeadings";

import { signupData } from "../../constants/Data/signupApproavl";
import { Container } from "@mui/material";

function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}

function getComparator(order, orderBy) {
return order === "desc"
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}

function stableSort(array, comparator) {
const stabilizedThis = array.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) {
return order;
}
return a[1] - b[1];
});
return stabilizedThis.map((el) => el[0]);
}

// main table
export default function ApprovalTable({ signupRole }) {
const [order, setOrder] = React.useState("asc");
const [orderBy, setOrderBy] = React.useState("calories");
const [selected, setSelected] = React.useState([]);
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);

const handleRequestSort = (event, property) => {
const isAsc = orderBy === property && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(property);
};

const handleSelectAllClick = (event) => {
if (event.target.checked) {
const newSelected = signupData[signupRole].map((n) => n.id);
setSelected(newSelected);
return;
}
setSelected([]);
};

//function to handle individual row select
const handleClick = (event, id) => {
const selectedIndex = selected.indexOf(id);
//saves the id of selected row
let newSelected = [];
if (selectedIndex === -1) {
newSelected = newSelected.concat(selected, id);
} else if (selectedIndex === 0) {
newSelected = newSelected.concat(selected.slice(1));
} else if (selectedIndex === selected.length - 1) {
newSelected = newSelected.concat(selected.slice(0, -1));
} else if (selectedIndex > 0) {
newSelected = newSelected.concat(
selected.slice(0, selectedIndex),
selected.slice(selectedIndex + 1)
);
}
setSelected(newSelected);
};

const handleChangePage = (event, newPage) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

const isSelected = (id) => selected.indexOf(id) !== -1;

// Avoid a layout jump when reaching the last page with empty rows.
const emptyRows =
page > 0
? Math.max(0, (1 + page) * rowsPerPage - signupData[signupRole].length)
: 0;

const visibleRows = React.useMemo(
() =>
stableSort(signupData[signupRole], getComparator(order, orderBy)).slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage
),
[order, orderBy, page, rowsPerPage, signupRole]
);

return (
<>
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
alignContent: "center",
}}
>
<Box sx={{ width: "96%" }}>
{/* table description */}
<TableDescription signupRole={signupRole} />
<Paper sx={{ width: "100%", mb: 2 }}>
{/* table toolbar */}
<TableToolbar
numSelected={selected.length}
signupRole={signupRole}
/>
<TableContainer>
<Table
stickyHeader
sx={{ minWidth: 750 }}
aria-labelledby="tableTitle"
>
{/* table column headings */}
<TableColumnHeadings
numSelected={selected.length}
order={order}
orderBy={orderBy}
onSelectAllClick={handleSelectAllClick}
onRequestSort={handleRequestSort}
rowCount={signupData[signupRole].length}
signupRole={signupRole}
/>

{/* table rows */}
<TableData
signupRole={signupRole}
visibleRows={visibleRows}
isSelected={isSelected}
handleClick={handleClick}
emptyRows={emptyRows}
/>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={signupData[signupRole].length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
</Box>
</Box>
</>
);
}

ApprovalTable.propTypes = {
signupRole: PropTypes.string.isRequired,
};
92 changes: 92 additions & 0 deletions client/src/components/SignupApproval/TableColumnHeadings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import Box from "@mui/material/Box";
import PropTypes from "prop-types";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import TableCell from "@mui/material/TableCell";
import Checkbox from "@mui/material/Checkbox";
import TableSortLabel from "@mui/material/TableSortLabel";
import { visuallyHidden } from "@mui/utils";
import { colorScheme } from "../../constants/colorScheme";
import { headCells, additionDetailsCells } from "./columnHeadings";

function TableColumnHeadings(props) {
const {
onSelectAllClick,
order,
orderBy,
numSelected,
rowCount,
onRequestSort,
signupRole,
} = props;

const createSortHandler = (property) => (event) => {
onRequestSort(event, property);
};

const columnHeadings = additionDetailsCells[signupRole]
? [...headCells, ...additionDetailsCells[signupRole]]
: headCells;

return (
<TableHead>
<TableRow>
{/* bulk selection check box */}
<TableCell padding="checkbox">
<Checkbox
indeterminate={numSelected > 0 && numSelected < rowCount}
checked={rowCount > 0 && numSelected === rowCount}
onChange={onSelectAllClick}
inputProps={{
"aria-label": "select all desserts",
}}
sx={{
color: colorScheme.secondaryGrey,
"&.Mui-checked": {
color: colorScheme.primaryOrange,
},
"&.MuiCheckbox-indeterminate": {
color: colorScheme.secondaryGrey,
},
}}
/>
</TableCell>
{/* columns mapping */}
{columnHeadings.map((headCell) => (
<TableCell
key={headCell.id}
align={"left"}
padding={headCell.disablePadding ? "none" : "normal"}
sortDirection={orderBy === headCell.id ? order : false}
>
<TableSortLabel
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : "asc"}
onClick={createSortHandler(headCell.id)}
sx={{ fontWeight: "bold" }}
>
{headCell.label}
{orderBy === headCell.id ? (
<Box component="span" sx={visuallyHidden}>
{order === "desc" ? "sorted descending" : "sorted ascending"}
</Box>
) : null}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
);
}

TableColumnHeadings.propTypes = {
numSelected: PropTypes.number.isRequired,
onRequestSort: PropTypes.func.isRequired,
onSelectAllClick: PropTypes.func.isRequired,
order: PropTypes.oneOf(["asc", "desc"]).isRequired,
orderBy: PropTypes.string.isRequired,
rowCount: PropTypes.number.isRequired,
signupRole: PropTypes.string.isRequired,
};

export default TableColumnHeadings;
86 changes: 86 additions & 0 deletions client/src/components/SignupApproval/TableData.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableRow from "@mui/material/TableRow";
import Checkbox from "@mui/material/Checkbox";
import PropTypes from "prop-types";
import { colorScheme } from "../../constants/colorScheme";
import { headCells, additionDetailsCells } from "./columnHeadings";

function TableData({
signupRole,
visibleRows,
isSelected,
handleClick,
emptyRows,
}) {
const columnHeadings = additionDetailsCells[signupRole]
? [...headCells, ...additionDetailsCells[signupRole]]
: headCells;

return (
<TableBody>
{visibleRows.map((row, index) => {
const isItemSelected = isSelected(row.id);
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
onClick={(event) => handleClick(event, row.id)}
role="checkbox"
aria-checked={isItemSelected}
tabIndex={-1}
key={row.id}
selected={isItemSelected}
sx={{
cursor: "pointer",
"&.Mui-selected": {
backgroundColor: colorScheme.primaryOrangeLight,
"&:hover": {
backgroundColor: "#FFEAD6",
},
},
}}
>
<TableCell padding="checkbox">
<Checkbox
checked={isItemSelected}
inputProps={{
"aria-labelledby": labelId,
}}
sx={{
color: colorScheme.secondaryGrey,
"&.Mui-checked": {
color: colorScheme.primaryOrange,
},
}}
/>
</TableCell>
{/* row cell names mapping */}
{columnHeadings.map((cell) => (
<TableCell key={cell.id} align={cell.numeric ? "right" : "left"}>
{row[cell.id]}
</TableCell>
))}
</TableRow>
);
})}
{emptyRows > 0 && (
<TableRow
style={{
height: 53 * emptyRows,
}}
>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
);
}
TableData.propTypes = {
signupRole: PropTypes.string.isRequired,
handleClick: PropTypes.func.isRequired,
visibleRows: PropTypes.array.isRequired,
isSelected: PropTypes.func.isRequired,
emptyRows: PropTypes.number.isRequired,
};
export default TableData;
Loading