diff --git a/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
new file mode 100644
index 000000000..29c651add
--- /dev/null
+++ b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
@@ -0,0 +1,289 @@
+import PropTypes from "prop-types";
+import {
+ TableContainer,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableBody,
+ Paper,
+ Box,
+ TablePagination,
+ Stack,
+ Typography,
+ Button,
+} from "@mui/material";
+import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
+import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded";
+
+import { useState, useEffect, memo, useCallback, useRef } from "react";
+import { useDispatch } from "react-redux";
+import { useTheme } from "@emotion/react";
+import LeftArrowDouble from "../../../assets/icons/left-arrow-double.svg?react";
+import RightArrowDouble from "../../../assets/icons/right-arrow-double.svg?react";
+import LeftArrow from "../../../assets/icons/left-arrow.svg?react";
+import RightArrow from "../../../assets/icons/right-arrow.svg?react";
+import SelectorVertical from "../../../assets/icons/selector-vertical.svg?react";
+// import ActionsMenu from "../actionsMenu";
+
+/**
+ * Component for pagination actions (first, previous, next, last).
+ *
+ * @component
+ * @param {Object} props
+ * @param {number} props.count - Total number of items.
+ * @param {number} props.page - Current page number.
+ * @param {number} props.rowsPerPage - Number of rows per page.
+ * @param {function} props.onPageChange - Callback function to handle page change.
+ *
+ * @returns {JSX.Element} Pagination actions component.
+ */
+const TablePaginationActions = (props) => {
+ const { count, page, rowsPerPage, onPageChange } = props;
+ const handleFirstPageButtonClick = (event) => {
+ onPageChange(event, 0);
+ };
+ const handleBackButtonClick = (event) => {
+ onPageChange(event, page - 1);
+ };
+ const handleNextButtonClick = (event) => {
+ onPageChange(event, page + 1);
+ };
+ const handleLastPageButtonClick = (event) => {
+ onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
+ };
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+TablePaginationActions.propTypes = {
+ count: PropTypes.number.isRequired,
+ page: PropTypes.number.isRequired,
+ rowsPerPage: PropTypes.number.isRequired,
+ onPageChange: PropTypes.func.isRequired,
+};
+
+const MaintenanceTable = ({
+ page,
+ setPage,
+ rowsPerPage,
+ setRowsPerPage,
+ sort,
+ setSort,
+ maintenanceWindows,
+ maintenanceWindowCount,
+}) => {
+ const theme = useTheme();
+ const dispatch = useDispatch();
+
+ const handleChangePage = (event, newPage) => {
+ setPage(newPage);
+ };
+
+ const handleChangeRowsPerPage = (event) => {
+ dispatch(
+ setRowsPerPage({
+ value: parseInt(event.target.value, 10),
+ table: "monitors",
+ })
+ );
+ setPage(0);
+ };
+
+ /**
+ * Helper function to calculate the range of displayed rows.
+ * @returns {string}
+ */
+ const getRange = () => {
+ let start = page * rowsPerPage + 1;
+ let end = Math.min(
+ page * rowsPerPage + rowsPerPage,
+ maintenanceWindowCount
+ );
+ return `${start} - ${end}`;
+ };
+
+ const handleSort = async (field) => {
+ let order = "";
+ if (sort.field !== field) {
+ order = "desc";
+ } else {
+ order = sort.order === "asc" ? "desc" : "asc";
+ }
+ setSort({ field, order });
+ };
+
+ return (
+ <>
+
+
+
+
+ handleSort("name")}
+ >
+
+ Host
+
+ {sort.order === "asc" ? (
+
+ ) : (
+
+ )}
+
+
+
+ handleSort("status")}
+ >
+ {" "}
+
+ {" "}
+ Status
+
+ {sort.order === "asc" ? (
+
+ ) : (
+
+ )}
+
+
+
+ Response Time
+ Type
+ Actions
+
+
+
+
+
+
+
+ Showing {getRange()} of {maintenanceWindowCount} maintenance window(s)
+
+
+ `Page ${page + 1} of ${Math.max(0, Math.ceil(count / rowsPerPage))}`
+ }
+ slotProps={{
+ select: {
+ MenuProps: {
+ keepMounted: true,
+ disableScrollLock: true,
+ PaperProps: {
+ className: "pagination-dropdown",
+ sx: {
+ mt: 0,
+ mb: theme.spacing(2),
+ },
+ },
+ transformOrigin: { vertical: "bottom", horizontal: "left" },
+ anchorOrigin: { vertical: "top", horizontal: "left" },
+ sx: { mt: theme.spacing(-2) },
+ },
+ inputProps: { id: "pagination-dropdown" },
+ IconComponent: SelectorVertical,
+ sx: {
+ ml: theme.spacing(4),
+ mr: theme.spacing(12),
+ minWidth: theme.spacing(20),
+ textAlign: "left",
+ "&.Mui-focused > div": {
+ backgroundColor: theme.palette.background.main,
+ },
+ },
+ },
+ }}
+ sx={{
+ mt: theme.spacing(6),
+ color: theme.palette.text.secondary,
+ "& svg path": {
+ stroke: theme.palette.text.tertiary,
+ strokeWidth: 1.3,
+ },
+ "& .MuiSelect-select": {
+ border: 1,
+ borderColor: theme.palette.border.light,
+ borderRadius: theme.shape.borderRadius,
+ },
+ }}
+ />
+
+ >
+ );
+};
+
+MaintenanceTable.propTypes = {
+ isAdmin: PropTypes.bool,
+ page: PropTypes.number,
+ setPage: PropTypes.func,
+ rowsPerPage: PropTypes.number,
+ setRowsPerPage: PropTypes.func,
+ sort: PropTypes.object,
+ setSort: PropTypes.func,
+ maintenanceWindows: PropTypes.array,
+ maintenanceWindowCount: PropTypes.number,
+};
+
+const MemoizedMaintenanceTable = memo(MaintenanceTable);
+export default MemoizedMaintenanceTable;
diff --git a/Client/src/Pages/Maintenance/index.jsx b/Client/src/Pages/Maintenance/index.jsx
index 5c23a789c..d34035258 100644
--- a/Client/src/Pages/Maintenance/index.jsx
+++ b/Client/src/Pages/Maintenance/index.jsx
@@ -1,10 +1,22 @@
import { Box } from "@mui/material";
import { useTheme } from "@emotion/react";
import Fallback from "../../Components/Fallback";
+import { useState, useEffect } from "react";
import "./index.css";
+import MaintenanceTable from "./MaintenanceTable";
+import { useSelector } from "react-redux";
const Maintenance = ({ isAdmin }) => {
const theme = useTheme();
+ const authState = useSelector((state) => state.auth);
+
+ const [maintenanceWindows, setMaintenanceWindows] = useState([]);
+ const [maintenanceWindowCount, setMaintenanceWindowCount] = useState(0);
+ const [page, setPage] = useState(0);
+ const [rowsPerPage, setRowsPerPage] = useState(5);
+ const [sort, setSort] = useState({});
+
+ useEffect(() => {});
return (
{
},
}}
>
-
+ {maintenanceWindows.length > 0 && (
+
+ )}
+ {isAdmin && maintenanceWindows.length === 0 && (
+
+ )}
);
};