diff --git a/Client/src/Components/BasicTable/index.css b/Client/src/Components/BasicTable/index.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/Client/src/Components/BasicTable/index.jsx b/Client/src/Components/BasicTable/index.jsx
new file mode 100644
index 000000000..a80c7bfb6
--- /dev/null
+++ b/Client/src/Components/BasicTable/index.jsx
@@ -0,0 +1,146 @@
+import {
+ TableContainer,
+ Paper,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableBody,
+ TablePagination,
+} from "@mui/material";
+import React, { useState } from "react";
+import PropTypes from "prop-types";
+
+/**
+ * BasicTable Component
+ * Renders a table with optional pagination.
+ *
+ * @component
+ * @param {Object} props - Component props.
+ * @param {Array} props.headers - Array of header titles for the table.
+ * @param {Array} props.rowItems - Array of row data objects for the table.
+ * @param {boolean} props.paginated - Flag to enable pagination.
+ *
+ * @example
+ *
+ * Headers is an array of objets that have a unique ID and a name
+ * Rows is an array of objects that have a unique ID and some data to display
+ * Row data can be any valid React node
+ * Rows are split into groups according to the number of headers, so if you have 3 headers then
+ * Rows will go under the index % 3 column.
+ * ie: Row 0 -> col 0 % 3 = 0
+ * ie: Row 1 -> col 1 % 3 = 1
+ * ie: Row 2 -> col 2 % 3 = 2
+ * ie: Row 3 -> col 3 % 3 = 0
+ *
+ * Thus items are put in their correct columns
+ *
+ *
+ * const headers = [
+ * { id: 1, name: "ID" },
+ * { id: 2, name: "Name" },
+ * { id: 3, name: "Age" },
+ * ];
+ * const rows = [
+ * { id: 1, data: 999 },
+ * { id: 2, data:
Alex Holliday
},
+ * { id: 3, data: 5
},
+ * // More rows...
+ * ];
+ *
+ */
+
+const BasicTable = ({ headers, rowItems, paginated }) => {
+ // Add headers to props validation
+
+ const [page, setPage] = useState(0);
+ const [rowsPerPage, setRowsPerPage] = useState(5);
+
+ const handleChangePage = (event, newPage) => {
+ setPage(newPage);
+ };
+
+ const handleChangeRowsPerPage = (event) => {
+ setRowsPerPage(parseInt(event.target.value, 10));
+ setPage(0); // Reset to first page after changing rows per page
+ };
+
+ const numOfCols = headers.length;
+
+ const groupedRowItems = rowItems.reduce((acc, item, idx) => {
+ const rowIndex = Math.floor((item.id - 1) / numOfCols);
+ if (!acc[rowIndex]) acc[rowIndex] = { items: [], idx };
+ acc[rowIndex].items.push({ item });
+ return acc;
+ }, {});
+
+ const paginatedRowsKeys = Object.keys(groupedRowItems).slice(
+ page * rowsPerPage,
+ page * rowsPerPage + rowsPerPage
+ );
+
+ return (
+ <>
+
+
+
+
+ {headers.map((header) => {
+ return {header.name};
+ })}
+
+
+
+ {paginated === false &&
+ Object.keys(groupedRowItems).map((key) => {
+ return (
+
+ {groupedRowItems[key].items.map(({ item }) => {
+ return {item.data};
+ })}
+
+ );
+ })}
+ {paginated === true &&
+ paginatedRowsKeys.map((key) => (
+
+ {groupedRowItems[key].items.map(({ item }) => (
+ {item.data}
+ ))}
+
+ ))}
+
+
+
+ {paginated === true && (
+
+ )}
+ >
+ );
+};
+
+BasicTable.propTypes = {
+ headers: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
+ name: PropTypes.string.isRequired,
+ })
+ ).isRequired,
+ rowItems: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
+ data: PropTypes.node,
+ })
+ ).isRequired,
+ paginated: PropTypes.bool,
+};
+
+export default BasicTable;
diff --git a/Client/src/Components/MonitorTable/index.jsx b/Client/src/Components/MonitorTable/index.jsx
index 5bb06935b..338ebb793 100644
--- a/Client/src/Components/MonitorTable/index.jsx
+++ b/Client/src/Components/MonitorTable/index.jsx
@@ -1,23 +1,8 @@
import "./index.css";
-import { useState } from "react";
import PropTypes from "prop-types";
import ResponseTimeChart from "../Charts/ResponseTimeChart";
-import {
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Paper,
- Pagination,
- PaginationItem,
-} from "@mui/material";
-import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
+import BasicTable from "../BasicTable";
import OpenInNewPage from "../../assets/icons/open-in-new-page.svg?react";
-import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded";
-import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded";
-import { useNavigate } from "react-router-dom";
/**
* Host component.
@@ -95,100 +80,42 @@ const Status = ({ params }) => {
* @returns {React.Component} Returns a table with the monitor data.
*/
const MonitorTable = ({ monitors = [] }) => {
- const navigate = useNavigate();
- const [page, setPage] = useState(0);
- const rowsPerPage = 5;
-
- const handleChangePage = (event, newPage) => {
- setPage(newPage);
- };
-
- const mappedRows = monitors
- .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
- .map((monitor) => {
- const params = {
- url: monitor.url,
- title: monitor.name,
- precentage: 100,
- percentageColor:
- monitor.status === true
- ? "var(--env-var-color-17)"
- : "var(--env-var-color-19)",
- status: monitor.status === true ? "up" : "down",
- backgroundColor:
- monitor.status === true
- ? "var(--env-var-color-20)"
- : "var(--env-var-color-21)",
- statusDotColor:
- monitor.status === true
- ? "var(--env-var-color-17)"
- : "var(--env-var-color-19)",
- };
-
- return (
- {
- navigate(`/monitors/${monitor._id}`);
- }}
- >
-
-
-
-
-
-
-
-
-
- TODO Add Actions
-
- );
+ const headers = [
+ { id: 1, name: "Host" },
+ { id: 2, name: "Status" },
+ { id: 3, name: "Response Time" },
+ { id: 4, name: "Actions" },
+ ];
+ const data = [];
+ monitors.forEach((monitor) => {
+ const params = {
+ url: monitor.url,
+ title: monitor.name,
+ precentage: 100,
+ percentageColor:
+ monitor.status === true
+ ? "var(--env-var-color-17)"
+ : "var(--env-var-color-19)",
+ status: monitor.status === true ? "up" : "down",
+ backgroundColor:
+ monitor.status === true
+ ? "var(--env-var-color-20)"
+ : "var(--env-var-color-21)",
+ statusDotColor:
+ monitor.status === true
+ ? "var(--env-var-color-17)"
+ : "var(--env-var-color-19)",
+ };
+ data.push({ id: data.length + 1, data: });
+ data.push({ id: data.length + 1, data: });
+ data.push({
+ id: data.length + 1,
+ data: ,
});
+ data.push({ id: data.length + 1, data: "TODO" });
+ });
- return (
- <>
-
-
-
-
- Host
-
- Status
-
-
-
-
- Response Time
- Actions
-
-
- {mappedRows}
-
-
- handleChangePage(event, value - 1)}
- shape="rounded"
- renderItem={(item) => (
-
- )}
- />
- >
- );
+ return ;
};
MonitorTable.propTypes = {