diff --git a/Client/package-lock.json b/Client/package-lock.json index 3a7eba0ef..c22ba8f78 100644 --- a/Client/package-lock.json +++ b/Client/package-lock.json @@ -19,6 +19,7 @@ "@mui/x-date-pickers": "7.3.2", "@reduxjs/toolkit": "2.2.5", "axios": "1.7.2", + "chart.js": "^4.4.3", "dayjs": "1.11.11", "joi": "17.13.1", "jwt-decode": "^4.0.0", @@ -27,7 +28,8 @@ "react-redux": "9.1.2", "react-router": "^6.23.0", "react-router-dom": "^6.23.1", - "react-toastify": "^10.0.5" + "react-toastify": "^10.0.5", + "redux-persist": "6.0.0" }, "devDependencies": { "@types/react": "^18.2.66", @@ -1089,6 +1091,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "node_modules/@mui/base": { "version": "5.0.0-beta.40", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", @@ -2352,6 +2359,17 @@ "node": ">=0.8.0" } }, + "node_modules/chart.js": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -4745,6 +4763,15 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "license": "MIT", + "peerDependencies": { + "redux": ">4.0.0" + } + }, "node_modules/redux-thunk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", diff --git a/Client/package.json b/Client/package.json index 72b5ba5bc..2edb972b7 100644 --- a/Client/package.json +++ b/Client/package.json @@ -21,6 +21,7 @@ "@mui/x-date-pickers": "7.3.2", "@reduxjs/toolkit": "2.2.5", "axios": "1.7.2", + "chart.js": "^4.4.3", "dayjs": "1.11.11", "joi": "17.13.1", "jwt-decode": "^4.0.0", @@ -29,7 +30,8 @@ "react-redux": "9.1.2", "react-router": "^6.23.0", "react-router-dom": "^6.23.1", - "react-toastify": "^10.0.5" + "react-toastify": "^10.0.5", + "redux-persist": "6.0.0" }, "devDependencies": { "@types/react": "^18.2.66", diff --git a/Client/src/Components/Charts/BarChart/BarChart.jsx b/Client/src/Components/Charts/BarChart/BarChart.jsx new file mode 100644 index 000000000..e424fef3e --- /dev/null +++ b/Client/src/Components/Charts/BarChart/BarChart.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import "./barChart.css"; +import PropTypes from "prop-types"; + +const BarChart = ({ checks = [] }) => { + return ( +
+ {checks.map((value, index) => ( +
+ ))} +
+ ); +}; + +BarChart.propTypes = { + checks: PropTypes.array, +}; + +export default BarChart; diff --git a/Client/src/Components/Charts/BarChart/barChart.css b/Client/src/Components/Charts/BarChart/barChart.css new file mode 100644 index 000000000..8dd2a2b22 --- /dev/null +++ b/Client/src/Components/Charts/BarChart/barChart.css @@ -0,0 +1,20 @@ +.bar-chart { + display: flex; + justify-content: space-around; + align-items: flex-end; + height: 50px; + width: 300px; +} + +.bar { + width: 7%; + transition: height 0.3s ease; +} + +.green { + background-color: var(--env-var-color-23); +} + +.red { + background-color: var(--env-var-color-24); +} diff --git a/Client/src/Components/Charts/Servers/serverStatus.css b/Client/src/Components/Charts/Servers/serverStatus.css index f42ae2801..deff765af 100644 --- a/Client/src/Components/Charts/Servers/serverStatus.css +++ b/Client/src/Components/Charts/Servers/serverStatus.css @@ -12,7 +12,7 @@ } .server-status-tile { - width: 230px; + width: 310px; padding: var(--spacing-general-1); border: 1px solid var(--color-border-0); border-radius: var(--border-radius-0); diff --git a/Client/src/Components/ConfigBox/index.css b/Client/src/Components/ConfigBox/index.css new file mode 100644 index 000000000..d5d6c96b2 --- /dev/null +++ b/Client/src/Components/ConfigBox/index.css @@ -0,0 +1,24 @@ +.config-box { + display: flex; + padding: 30px 40px; + border: 1px solid var(--env-var-color-16); + border-radius: var(--env-var-radius-1); + justify-content: space-between; + padding-bottom: 50px; +} + +.config-box-desc { + width: 35%; +} + +.config-box-desc-title { + color: var(--env-var-color-5); + font-size: var(--env-var-font-size-large); + font-weight: 700; + margin-bottom: var(--env-var-spacing-1); +} + +.config-box-desc-text { + color: var(--env-var-color-5); + font-size: var(--env-var-font-size-medium); +} diff --git a/Client/src/Components/ConfigBox/index.jsx b/Client/src/Components/ConfigBox/index.jsx new file mode 100644 index 000000000..7cf547232 --- /dev/null +++ b/Client/src/Components/ConfigBox/index.jsx @@ -0,0 +1,13 @@ +import "./index.css"; +import React from "react"; + +const ConfigBox = ({ leftLayout, rightLayout }) => { + return ( +
+ {leftLayout} + {rightLayout} +
+ ); +}; + +export default ConfigBox; diff --git a/Client/src/Components/CurrentMonitors/index.css b/Client/src/Components/CurrentMonitors/index.css index 7b00b1cec..8580bfcd0 100644 --- a/Client/src/Components/CurrentMonitors/index.css +++ b/Client/src/Components/CurrentMonitors/index.css @@ -8,8 +8,110 @@ display: flex; } +.current-monitors-bar { + display: flex; + justify-content: space-between; +} + .current-monitors-title { font-size: 1rem; font-weight: bold; - margin-right: var(); + margin-right: var(--env-var-spacing-1); +} + +.current-monitors-counter { + width: var(--env-var-spacing-2); + height: var(--env-var-spacing-2); + background-color: var(--env-var-color-15); + border: 1px solid var(--env-var-color-6); + border-radius: 50%; + text-align: center; + align-items: center; +} + +.monitors-v-gaping { + height: var(--env-var-spacing-3); +} + +.current-monitors-table { + width: 100%; + text-align: left; +} + +.current-monitors-table { + width: 100%; + text-align: left; + border-collapse: collapse; + border: 1px solid var(--env-var-color-16); + border-radius: var(--env-var-radius-1); +} + +.current-monitors-table th, +.current-monitors-table td { + border: 1px solid var(--env-var-color-16); + border-left: none; + border-right: none; + padding: 8px; +} + +.theader-row { + background-color: var(--env-var-color-13); + color: var(--env-var-color-2); + font-weight: 500; +} + +.theader-row td { + padding: var(--env-var-spacing-1) var(--env-var-spacing-2); + font-size: var(--env-var-font-size-medium); +} + +.host-list-item { + display: flex; + align-items: center; + cursor: pointer; +} + +.host-list-item-open { + width: var(--env-var-img-width-2); + height: var(--env-var-img-width-2); + margin-right: 8px; +} + +.host-list-item-name { + font-size: var(--env-var-font-size-medium); + font-weight: bold; + margin-right: var(--env-var-spacing-1); +} + +.host-list-item-precentage { + font-size: var(--env-var-font-size-medium); +} + +.tbody-row td { + padding: var(--env-var-spacing-2) var(--env-var-img-width-2); +} + +.host-status-box { + display: flex; + width: fit-content; + border: 1px solid var(--env-var-color-4); + border-radius: var(--env-var-radius-2); + align-items: center; + padding: calc(var(--env-var-spacing-1) / 2); +} + +.host-status-box-circle { + width: 6px; + height: 6px; + border-radius: 50%; + margin-right: calc(var(--env-var-spacing-1) / 2); +} + +.host-actions { + margin: auto; + cursor: pointer; +} + +.tbody-row-cell.actions-cell { + padding-left: 30px; } diff --git a/Client/src/Components/CurrentMonitors/index.jsx b/Client/src/Components/CurrentMonitors/index.jsx index bf376c832..868ce7a99 100644 --- a/Client/src/Components/CurrentMonitors/index.jsx +++ b/Client/src/Components/CurrentMonitors/index.jsx @@ -1,7 +1,10 @@ +import SearchTextField from "../TextFields/Search/SearchTextField"; import "./index.css"; import React from "react"; +import HostsTable from "../HostsTable"; +import Pagination from "../Pagination"; -const CurrentMonitors = () => { +const CurrentMonitors = ({ monitors }) => { return (
@@ -9,8 +12,14 @@ const CurrentMonitors = () => {
Current monitors
5
-
+
+ +
+
+ +
+
); }; diff --git a/Client/src/Components/DashboardSettingsIcon/index.css b/Client/src/Components/DashboardSettingsIcon/index.css index e69de29bb..95dc58176 100644 --- a/Client/src/Components/DashboardSettingsIcon/index.css +++ b/Client/src/Components/DashboardSettingsIcon/index.css @@ -0,0 +1,13 @@ +#dashboard-setting-menu-item { + width: 135px; + padding: 6px; + margin: 5px 12px; +} + +#dashboard-setting-menu-item:hover { + color: var(--env-var-color-26); +} + +#menu-appbar { + padding: var(--env-var-spacing-1); +} diff --git a/Client/src/Components/DashboardSettingsIcon/index.jsx b/Client/src/Components/DashboardSettingsIcon/index.jsx index e1f1d59da..f01e65900 100644 --- a/Client/src/Components/DashboardSettingsIcon/index.jsx +++ b/Client/src/Components/DashboardSettingsIcon/index.jsx @@ -1,15 +1,22 @@ -import { useState } from 'react'; -import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; -import Menu from '@mui/material/Menu'; -import Tooltip from '@mui/material/Tooltip'; -import MenuItem from '@mui/material/MenuItem'; -import Typography from '@mui/material/Typography'; -import SvgIcon from '@mui/material/SvgIcon'; -import SettingsIcon from '@mui/icons-material/Settings'; -import { useTheme } from '@mui/material/styles'; +import "./index.css"; +import { useState } from "react"; +import Box from "@mui/material/Box"; +import IconButton from "@mui/material/IconButton"; +import Menu from "@mui/material/Menu"; +import Tooltip from "@mui/material/Tooltip"; +import MenuItem from "@mui/material/MenuItem"; +import Typography from "@mui/material/Typography"; +import SvgIcon from "@mui/material/SvgIcon"; +import SettingsIcon from "@mui/icons-material/Settings"; +import { useTheme } from "@mui/material/styles"; -const settings = ['Open Site', 'Detailed View', 'Incidents', 'Configure', 'Remove']; +const settings = [ + "Open Site", + "Detailed View", + "Incidents", + "Configure", + "Remove", +]; /** * DashboardSettings component @@ -54,20 +61,29 @@ function DashboardSettings() { id="menu-appbar" anchorEl={anchorElUser} anchorOrigin={{ - vertical: 'top', - horizontal: 'right', + vertical: "top", + horizontal: "right", }} keepMounted transformOrigin={{ - vertical: 'top', - horizontal: 'right', + vertical: "top", + horizontal: "right", }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > {settings.map((setting) => ( - - {setting} + + + {setting} + ))} diff --git a/Client/src/Components/Host/index.jsx b/Client/src/Components/Host/index.jsx new file mode 100644 index 000000000..370745f4d --- /dev/null +++ b/Client/src/Components/Host/index.jsx @@ -0,0 +1,18 @@ +import React from "react"; +import OpenIt from "../../assets/Images/Icon-open-in-tab-gray.png"; + +function Host(title, precentage, statusColor, link) { + return ( +
+ + OpenIt + +
{title}
+
+ {precentage}% +
+
+ ); +} + +export default Host; diff --git a/Client/src/Components/HostActions/index.jsx b/Client/src/Components/HostActions/index.jsx new file mode 100644 index 000000000..c974906e8 --- /dev/null +++ b/Client/src/Components/HostActions/index.jsx @@ -0,0 +1,8 @@ +import React from "react"; +import DashboardSettings from "../DashboardSettingsIcon"; + +function HostActions() { + return ; +} + +export default HostActions; diff --git a/Client/src/Components/HostStatus/index.jsx b/Client/src/Components/HostStatus/index.jsx new file mode 100644 index 000000000..3b0660c33 --- /dev/null +++ b/Client/src/Components/HostStatus/index.jsx @@ -0,0 +1,18 @@ +import React from "react"; + +function HostStatus(backgroundColor, status, dotColor) { + return ( +
+
+
{status}
+
+ ); +} + +export default HostStatus; diff --git a/Client/src/Components/HostsTable/index.jsx b/Client/src/Components/HostsTable/index.jsx new file mode 100644 index 000000000..2867ef26a --- /dev/null +++ b/Client/src/Components/HostsTable/index.jsx @@ -0,0 +1,30 @@ +import React from "react"; + +const HostsTable = ({ monitors }) => { + return ( +
+ + + + + + + + + + + {monitors.map((monitor, index) => ( + + + + + + + ))} + +
HostStatusTeamActions
{monitor.host}{monitor.status}{monitor.team}{monitor.actions}
+
+ ); +}; + +export default HostsTable; diff --git a/Client/src/Components/Pagination/index.css b/Client/src/Components/Pagination/index.css new file mode 100644 index 000000000..f9289b741 --- /dev/null +++ b/Client/src/Components/Pagination/index.css @@ -0,0 +1,33 @@ +.pagination-holder { + display: flex; + width: 100%; + justify-content: center; +} + +.MuiPagination-root { + .MuiPagination-ul { + flex-wrap: nowrap; + li { + &:first-child { + flex-basis: 100%; + display: flex; + justify-content: flex-start; + align-items: center; + > button::after { + margin-left: 10px; + content: "previous"; + } + } + &:last-child { + flex-basis: 100%; + display: flex; + justify-content: flex-end; + align-items: center; + > button::before { + margin-right: 10px; + content: "next"; + } + } + } + } +} diff --git a/Client/src/Components/Pagination/index.jsx b/Client/src/Components/Pagination/index.jsx new file mode 100644 index 000000000..d2d4e18fe --- /dev/null +++ b/Client/src/Components/Pagination/index.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import { Pagination as MuiPagination } from "@mui/material"; +import "./index.css"; + +const Pagination = () => { + return ( +
+ +
+ ); +}; + +export default Pagination; diff --git a/Client/src/Components/RadioButton/index.jsx b/Client/src/Components/RadioButton/index.jsx new file mode 100644 index 000000000..038871647 --- /dev/null +++ b/Client/src/Components/RadioButton/index.jsx @@ -0,0 +1,52 @@ +/** + * RadioButton component. + * + * @component + * @example + * // Usage: + * + * + * @param {Object} props - The component props. + * @param {string} props.title - The title of the radio button. + * @param {string} [props.desc] - The description of the radio button. + * @param {string} [props.size="small"] - The size of the radio button. + * @returns {JSX.Element} - The rendered RadioButton component. + */ + +import { FormControlLabel, Radio } from "@mui/material"; +import React from "react"; +import PropTypes from "prop-types"; + +function RadioButton(props) { + return ( +
+ } + label={ +
+
{props.title}
+
{props.desc}
+
+ } + labelPlacement="end" + /> +
+ ); +} + +RadioButton.propTypes = { + title: PropTypes.string.isRequired, + desc: PropTypes.string, + size: PropTypes.string, +}; + +RadioButton.defaultProps = { + size: "small", +}; + +export default RadioButton; diff --git a/Client/src/Components/TextFields/Flexibile/FlexibileTextField.jsx b/Client/src/Components/TextFields/Flexibile/FlexibileTextField.jsx new file mode 100644 index 000000000..b59ecea2b --- /dev/null +++ b/Client/src/Components/TextFields/Flexibile/FlexibileTextField.jsx @@ -0,0 +1,17 @@ +import "./flexibileTextField.css"; +import React from "react"; + +const FlexibileTextField = ({ title, type, placeholder }) => { + return ( +
+
{title}
+ +
+ ); +}; + +export default FlexibileTextField; diff --git a/Client/src/Components/TextFields/Flexibile/flexibileTextField.css b/Client/src/Components/TextFields/Flexibile/flexibileTextField.css new file mode 100644 index 000000000..2e0422876 --- /dev/null +++ b/Client/src/Components/TextFields/Flexibile/flexibileTextField.css @@ -0,0 +1,22 @@ +.flexibile-textfield-title { + color: var(--env-var-color-5); + font-size: var(--env-var-font-size-medium); +} + +.flexibile-textfield-input { + width: 292.8px; + height: 6.8px; + padding: var(--env-var-spacing-1); + margin-top: 10px; + border: 1px solid var(--env-var-color-4); + border-radius: var(--env-var-radius-1); +} + +.flexibile-textfield-input:focus { + outline: none; +} + +.flexibile-textfield-input::placeholder { + color: var(--env-var-color-25); + font-size: var(--env-var-font-size-medium); +} diff --git a/Client/src/Components/TextFields/Search/SearchTextField.jsx b/Client/src/Components/TextFields/Search/SearchTextField.jsx new file mode 100644 index 000000000..934a19943 --- /dev/null +++ b/Client/src/Components/TextFields/Search/SearchTextField.jsx @@ -0,0 +1,14 @@ +import "./searchTextField.css"; +import React from "react"; +import Search from "../../../assets/Images/Icon-search-gray.png"; + +const SearchTextField = () => { + return ( +
+ Search + +
+ ); +}; + +export default SearchTextField; diff --git a/Client/src/Components/TextFields/Search/searchTextField.css b/Client/src/Components/TextFields/Search/searchTextField.css new file mode 100644 index 000000000..a3d560e15 --- /dev/null +++ b/Client/src/Components/TextFields/Search/searchTextField.css @@ -0,0 +1,26 @@ +.search-field-holder { + display: flex; + align-items: center; + width: 180px; + height: 9px; + padding: var(--env-var-spacing-1); + border: 1px solid var(--env-var-color-4); + border-radius: var(--env-var-radius-1); +} + +.search-field-icon { + width: var(--env-var-img-width-2); + height: var(--env-var-img-width-2); + margin-right: calc(var(--env-var-img-width-2) / 2); +} + +.search-field { + width: 150px; + border: none; + outline: none; + font-size: var(--env-var-font-size-medium); +} + +.search-field::placeholder { + color: var(--env-var-color-14); +} diff --git a/Client/src/Features/Monitors/monitorsSlice.js b/Client/src/Features/Monitors/monitorsSlice.js index 2f4fe0f3b..c025b02c2 100644 --- a/Client/src/Features/Monitors/monitorsSlice.js +++ b/Client/src/Features/Monitors/monitorsSlice.js @@ -22,13 +22,28 @@ export const getMonitors = createAsyncThunk( } ); +export const getMonitorsByUserId = createAsyncThunk( + "montiors/getMonitorsByUserId", + async (token, thunkApi) => { + try { + // TODO get userId and make request + console.log(token); + } catch (error) { + return thunkApi.rejectWithValue(error.response.data); + } + } +); + const monitorsSlice = createSlice({ name: "monitors", initialState, reducers: {}, extraReducers: (builder) => { builder - .addCase(getMonitors.pending, (state, action) => { + // ***************************************************** + // All Monitors + // ***************************************************** + .addCase(getMonitors.pending, (state) => { state.isLoading = true; }) .addCase(getMonitors.fulfilled, (state, action) => { @@ -42,6 +57,24 @@ const monitorsSlice = createSlice({ state.isLoading = false; state.success = action.payload.success; state.msg = action.payload.msg; + }) + // ***************************************************** + // Monitors by userId + // ***************************************************** + + .addCase(getMonitorsByUserId.pending, (state) => { + state.isLoading = true; + }) + .addCase(getMonitorsByUserId.fulfilled, (state, action) => { + state.isLoading = false; + state.success = action.payload.msg; + console.log(action.payload); + state.monitors = action.payload.data; + }) + .addCase(getMonitorsByUserId.rejected, (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; }); }, }); diff --git a/Client/src/Mock/sample_data.json b/Client/src/Mock/sample_data.json new file mode 100644 index 000000000..b391f4678 --- /dev/null +++ b/Client/src/Mock/sample_data.json @@ -0,0 +1,534 @@ +{ + "success": true, + "msg": "Got monitor for 666c9146c9bfa20db790b1df successfully\"", + "data": [ + { + "_id": "6671d8469ba14f9f260eed23", + "userId": "666c9146c9bfa20db790b1df", + "name": "Google Monitor", + "description": "Google", + "type": "ping", + "url": "127.0.0.1", + "isActive": true, + "interval": 10000, + "createdAt": "2024-06-18T18:56:06.212Z", + "updatedAt": "2024-06-18T18:56:06.212Z", + "__v": 0, + "checks": [ + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 143, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 70, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 143, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 70, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d8549ba14f9f260eed2d", + "monitorId": "6671d8469ba14f9f260eed23", + "status": false, + "responseTime": 120, + "createdAt": "2024-06-18T18:56:20.016Z", + "updatedAt": "2024-06-18T18:56:20.016Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 200, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d8549ba14f9f260eed2d", + "monitorId": "6671d8469ba14f9f260eed23", + "status": false, + "responseTime": 250, + "createdAt": "2024-06-18T18:56:20.016Z", + "updatedAt": "2024-06-18T18:56:20.016Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": false, + "responseTime": 180, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d8549ba14f9f260eed2d", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 200, + "createdAt": "2024-06-18T18:56:20.016Z", + "updatedAt": "2024-06-18T18:56:20.016Z", + "__v": 0 + }, + { + "_id": "6671d84a9ba14f9f260eed27", + "monitorId": "6671d8469ba14f9f260eed23", + "status": false, + "responseTime": 100, + "createdAt": "2024-06-18T18:56:10.082Z", + "updatedAt": "2024-06-18T18:56:10.082Z", + "__v": 0 + }, + { + "_id": "6671d8549ba14f9f260eed2d", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 210, + "createdAt": "2024-06-18T18:56:20.016Z", + "updatedAt": "2024-06-18T18:56:20.016Z", + "__v": 0 + }, + { + "_id": "6671d85e9ba14f9f260eed3c", + "monitorId": "6671d8469ba14f9f260eed23", + "status": true, + "responseTime": 200, + "createdAt": "2024-06-18T18:56:30.050Z", + "updatedAt": "2024-06-18T18:56:30.050Z", + "__v": 0 + } + ] + }, + { + "_id": "6671d8529ba14f9f260eed2b", + "userId": "666c9146c9bfa20db790b1df", + "name": "Google Monitor", + "description": "Google", + "type": "http", + "url": "https://www.google.com/404", + "isActive": true, + "interval": 10000, + "createdAt": "2024-06-18T18:56:18.555Z", + "updatedAt": "2024-06-18T18:56:18.555Z", + "__v": 0, + "checks": [ + { + "_id": "6671d8549ba14f9f260eed31", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 167, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:20.190Z", + "updatedAt": "2024-06-18T18:56:20.190Z", + "__v": 0 + }, + { + "_id": "6671d85e9ba14f9f260eed3e", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 228, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:30.279Z", + "updatedAt": "2024-06-18T18:56:30.279Z", + "__v": 0 + }, + { + "_id": "6671d8669ba14f9f260eed47", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 112, + "statusCode": 200, + "createdAt": "2024-06-18T18:56:38.381Z", + "updatedAt": "2024-06-18T18:56:38.381Z", + "__v": 0 + }, + { + "_id": "6671d8809ba14f9f260eed6b", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 134, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:04.846Z", + "updatedAt": "2024-06-18T18:57:04.846Z", + "__v": 0 + }, + { + "_id": "6671d86d9ba14f9f260eed50", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 301, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:45.492Z", + "updatedAt": "2024-06-18T18:56:45.492Z", + "__v": 0 + }, + { + "_id": "6671d8739ba14f9f260eed59", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 84, + "statusCode": 200, + "createdAt": "2024-06-18T18:56:51.614Z", + "updatedAt": "2024-06-18T18:56:51.614Z", + "__v": 0 + }, + { + "_id": "6671d87a9ba14f9f260eed62", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 189, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:58.734Z", + "updatedAt": "2024-06-18T18:56:58.734Z", + "__v": 0 + }, + { + "_id": "6671d8809ba14f9f260eed6b", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 134, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:04.846Z", + "updatedAt": "2024-06-18T18:57:04.846Z", + "__v": 0 + }, + { + "_id": "6671d8549ba14f9f260eed31", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 167, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:20.190Z", + "updatedAt": "2024-06-18T18:56:20.190Z", + "__v": 0 + }, + { + "_id": "6671d85e9ba14f9f260eed3e", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 228, + "statusCode": 404, + "createdAt": "2024-06-18T18:56:30.279Z", + "updatedAt": "2024-06-18T18:56:30.279Z", + "__v": 0 + }, + { + "_id": "6671d8669ba14f9f260eed47", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 112, + "statusCode": 200, + "createdAt": "2024-06-18T18:56:38.381Z", + "updatedAt": "2024-06-18T18:56:38.381Z", + "__v": 0 + }, + { + "_id": "6671d8879ba14f9f260eed74", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 247, + "statusCode": 404, + "createdAt": "2024-06-18T18:57:11.958Z", + "updatedAt": "2024-06-18T18:57:11.958Z", + "__v": 0 + } + ] + }, + { + "_id": "6671d8619ba14f9f260eed4c", + "userId": "666c9146c9bfa20db790b1df", + "name": "Amazon Monitor", + "description": "Amazon website", + "type": "http", + "url": "https://www.amazon.com", + "isActive": true, + "interval": 15000, + "createdAt": "2024-06-18T18:56:49.419Z", + "updatedAt": "2024-06-18T18:56:49.419Z", + "__v": 0, + "checks": [ + { + "_id": "6671d8919ba14f9f260eed7d", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 92, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:21.076Z", + "updatedAt": "2024-06-18T18:57:21.076Z", + "__v": 0 + }, + { + "_id": "6671d8989ba14f9f260eed86", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 205, + "statusCode": 404, + "createdAt": "2024-06-18T18:57:28.188Z", + "updatedAt": "2024-06-18T18:57:28.188Z", + "__v": 0 + }, + { + "_id": "6671d89e9ba14f9f260eed8f", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 159, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:34.300Z", + "updatedAt": "2024-06-18T18:57:34.300Z", + "__v": 0 + }, + { + "_id": "6671d8a59ba14f9f260eed98", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 271, + "statusCode": 404, + "createdAt": "2024-06-18T18:57:41.421Z", + "updatedAt": "2024-06-18T18:57:41.421Z", + "__v": 0 + }, + { + "_id": "6671d8ac9ba14f9f260eeda1", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 127, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:48.532Z", + "updatedAt": "2024-06-18T18:57:48.532Z", + "__v": 0 + }, + { + "_id": "6671d8a59ba14f9f260eed98", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 271, + "statusCode": 404, + "createdAt": "2024-06-18T18:57:41.421Z", + "updatedAt": "2024-06-18T18:57:41.421Z", + "__v": 0 + }, + { + "_id": "6671d8ac9ba14f9f260eeda1", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 127, + "statusCode": 200, + "createdAt": "2024-06-18T18:57:48.532Z", + "updatedAt": "2024-06-18T18:57:48.532Z", + "__v": 0 + }, + { + "_id": "6671d8b29ba14f9f260eedaa", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 193, + "statusCode": 404, + "createdAt": "2024-06-18T18:57:54.643Z", + "updatedAt": "2024-06-18T18:57:54.643Z", + "__v": 0 + }, + { + "_id": "6671d8b89ba14f9f260eedb3", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 104, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:00.754Z", + "updatedAt": "2024-06-18T18:58:00.754Z", + "__v": 0 + }, + { + "_id": "6671d8bf9ba14f9f260eedbc", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 231, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:07.865Z", + "updatedAt": "2024-06-18T18:58:07.865Z", + "__v": 0 + }, + { + "_id": "6671d8c59ba14f9f260eedc5", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 147, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:13.977Z", + "updatedAt": "2024-06-18T18:58:13.977Z", + "__v": 0 + }, + { + "_id": "6671d8cc9ba14f9f260eedce", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 283, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:20.088Z", + "updatedAt": "2024-06-18T18:58:20.088Z", + "__v": 0 + } + ] + }, + { + "_id": "6671d8789ba14f9f260eed66", + "userId": "666c9146c9bfa20db790b1df", + "name": "Facebook Monitor", + "description": "Facebook website", + "type": "http", + "url": "https://www.facebook.com", + "isActive": true, + "interval": 20000, + "createdAt": "2024-06-18T18:57:12.798Z", + "updatedAt": "2024-06-18T18:57:12.798Z", + "__v": 0, + "checks": [ + { + "_id": "6671d8d29ba14f9f260eedd7", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 81, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:26.199Z", + "updatedAt": "2024-06-18T18:58:26.199Z", + "__v": 0 + }, + { + "_id": "6671d8d89ba14f9f260eede0", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 218, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:32.311Z", + "updatedAt": "2024-06-18T18:58:32.311Z", + "__v": 0 + }, + { + "_id": "6671d8df9ba14f9f260eede9", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 138, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:39.422Z", + "updatedAt": "2024-06-18T18:58:39.422Z", + "__v": 0 + }, + { + "_id": "6671d8e59ba14f9f260eedf2", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 257, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:45.533Z", + "updatedAt": "2024-06-18T18:58:45.533Z", + "__v": 0 + }, + { + "_id": "6671d8eb9ba14f9f260eedfb", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 116, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:51.644Z", + "updatedAt": "2024-06-18T18:58:51.644Z", + "__v": 0 + }, + { + "_id": "6671d8f19ba14f9f260eee04", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 184, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:57.755Z", + "updatedAt": "2024-06-18T18:58:57.755Z", + "__v": 0 + }, + { + "_id": "6671d8f79ba14f9f260eee0d", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 97, + "statusCode": 200, + "createdAt": "2024-06-18T18:59:03.867Z", + "updatedAt": "2024-06-18T18:59:03.867Z", + "__v": 0 + }, + { + "_id": "6671d8fd9ba14f9f260eee16", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 240, + "statusCode": 404, + "createdAt": "2024-06-18T18:59:09.978Z", + "updatedAt": "2024-06-18T18:59:09.978Z", + "__v": 0 + }, + { + "_id": "6671d9039ba14f9f260eee1f", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 135, + "statusCode": 200, + "createdAt": "2024-06-18T18:59:16.089Z", + "updatedAt": "2024-06-18T18:59:16.089Z", + "__v": 0 + }, + { + "_id": "6671d8d89ba14f9f260eede0", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 218, + "statusCode": 404, + "createdAt": "2024-06-18T18:58:32.311Z", + "updatedAt": "2024-06-18T18:58:32.311Z", + "__v": 0 + }, + { + "_id": "6671d8df9ba14f9f260eede9", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": true, + "responseTime": 138, + "statusCode": 200, + "createdAt": "2024-06-18T18:58:39.422Z", + "updatedAt": "2024-06-18T18:58:39.422Z", + "__v": 0 + }, + { + "_id": "6671d9089ba14f9f260eee28", + "monitorId": "6671d8529ba14f9f260eed2b", + "status": false, + "responseTime": 269, + "statusCode": 404, + "createdAt": "2024-06-18T18:59:22.200Z", + "updatedAt": "2024-06-18T18:59:22.200Z", + "__v": 0 + } +] + } + ] +} \ No newline at end of file diff --git a/Client/src/Pages/Demo/Demo.jsx b/Client/src/Pages/Demo/Demo.jsx index ef6747026..8b976a0ba 100644 --- a/Client/src/Pages/Demo/Demo.jsx +++ b/Client/src/Pages/Demo/Demo.jsx @@ -27,13 +27,14 @@ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import AddIcon from "@mui/icons-material/Add"; import Divider from "@mui/material/Divider"; -import UploadIcon from '@mui/icons-material/Upload'; -import SendIcon from '@mui/icons-material/Send'; +import UploadIcon from "@mui/icons-material/Upload"; +import SendIcon from "@mui/icons-material/Send"; // Redux import { useSelector } from "react-redux"; import { useDispatch } from "react-redux"; import { getMonitors } from "../../Features/Monitors/monitorsSlice"; +import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice"; const cols = [ { @@ -226,7 +227,7 @@ const Demo = () => { level="primary" label="Get Monitors" onClick={() => { - dispatch(getMonitors()); + dispatch(getMonitorsByUserId("User ID Here")); }} /> @@ -393,7 +394,7 @@ const Demo = () => { level="primary" label="Upload" position="start" - img={} + img={} onClick={handleButtonSpinnerClick} isLoading={isLoading} /> @@ -401,11 +402,11 @@ const Demo = () => { level="secondary" label="Send" position="end" - img={} + img={} onClick={handleButtonSpinnerClick} isLoading={isLoading} /> - { + return ( +
+
+
+
Create new monitor
+
+ +
General settings
+
+ Here you can select the URL of the host, together with the type of + monitor. +
+
+ } + rightLayout={ +
+ +
+ +
+ } + /> +
+
+ +
Checks to perform
+
+ You can always add or remove checks after adding your site. +
+ + } + rightLayout={ +
+ +
+ +
+ +
+
+ } + /> +
+
+ +
Incident notifications
+
+ When there is an incident, notify users. +
+ + } + /> +
+
+ +
Advanced settings
+ + } + /> +
+
+ +
Proxy settings
+ + } + /> + + ); +}; + +export default CreateNewMonitor; diff --git a/Client/src/Pages/Monitors/CurrentStats.jsx b/Client/src/Pages/Monitors/CurrentStats.jsx new file mode 100644 index 000000000..de15d953c --- /dev/null +++ b/Client/src/Pages/Monitors/CurrentStats.jsx @@ -0,0 +1,69 @@ +import React, { useEffect, useState } from "react"; +import Host from "../../Components/Host"; +import HostStatus from "../../Components/HostStatus"; +import HostActions from "../../Components/HostActions"; +import BarChart from "../../Components/Charts/BarChart/BarChart"; +import Button from "../../Components/Button"; +import ServerStatus from "../../Components/Charts/Servers/ServerStatus"; +import CurrentMonitors from "../../Components/CurrentMonitors"; +import MockData from "../../Mock/sample_data.json"; + +const CurrentStats = (mockdata = true) => { + // The hardcoded part is passed as default value for the purpose of demonstration. + // Pass an empty array, [], before fetching the data + const [monitors, setMonitors] = useState([]); + + useEffect(() => { + if (mockdata) { + console.log(MockData.data); + setMonitors( + MockData.data.map((item) => ({ + host: Host(item.name, 100, "var(--env-var-color-17)", item.url), + status: HostStatus( + item.isActive + ? "var(--env-var-color-20)" + : "var(--env-var-color-21)", + item.isActive ? "Up" : "Down", + item.isActive + ? "var(--env-var-color-17)" + : "var(--env-var-color-19)" + ), + team: , + actions: HostActions(), + })) + ); + } + }, [mockdata]); + + // useEffect(() => { + // fetch("API_URL") + // .then((response) => response.json()) + // .then((data) => setMonitors(data)) + // .catch((error) => console.error(error)); + // }, []); + + return ( +
+
+
+
+
Hello, Jackie
+
+
+
+ + + +
+
+ +
+ ); +}; + +export default CurrentStats; diff --git a/Client/src/Pages/Monitors/index.css b/Client/src/Pages/Monitors/index.css index d6d272e7c..eef1c33d5 100644 --- a/Client/src/Pages/Monitors/index.css +++ b/Client/src/Pages/Monitors/index.css @@ -1,4 +1,5 @@ -.monitors { +.monitors, +.new-monitor { width: 70vw; padding: 4vw; } @@ -16,9 +17,25 @@ .monitors-stats { display: flex; - justify-content: space-between; + gap: 24px; } .monitors-gaps-medium { height: var(--env-var-spacing-2); } + +.new-monitor-header { + color: var(--env-var-color-1); + font-size: var(--env-var-font-size-large-plus); + font-weight: 600; +} + +.service-check-list-title { + color: var(--env-var-color-5); + font-size: var(--env-var-font-size-medium); +} + +.service-check-list-desc { + color: var(--env-var-color-25); + font-size: var(--env-var-font-size-small); +} diff --git a/Client/src/Pages/Monitors/index.jsx b/Client/src/Pages/Monitors/index.jsx index 0c0555d5a..a1dd61f0c 100644 --- a/Client/src/Pages/Monitors/index.jsx +++ b/Client/src/Pages/Monitors/index.jsx @@ -1,28 +1,13 @@ -import Button from "../../Components/Button"; -import ServerStatus from "../../Components/Charts/Servers/ServerStatus"; -import CurrentMonitors from "../../Components/CurrentMonitors"; +// import CreateNewMonitor from "./CreateNewMonitor"; +import CurrentStats from "./CurrentStats"; import "./index.css"; import React from "react"; const Monitors = () => { return (
-
-
Hello, Jackie
-
-
-
- - - -
-
- + + {/* */}
); }; diff --git a/Client/src/Pages/Settings/index.css b/Client/src/Pages/Settings/index.css index 57b448857..c966a9031 100644 --- a/Client/src/Pages/Settings/index.css +++ b/Client/src/Pages/Settings/index.css @@ -64,9 +64,8 @@ margin-top: var(--env-var-spacing-4); } .edit-team-form__wrapper.compact { - margin-top: var(--env-var-spacing-3); - justify-content: flex-start; - align-items: center; + margin-top: 30px; + color: var(--env-var-color-29); } .edit-profile-form__wrapper input, .edit-password-form__wrapper input, @@ -96,12 +95,10 @@ border-color: var(--env-var-color-27); background-color: var(--lighter-env-var-color-27); } -.MuiBox-root > .announcement-tile .announcement-content-body { +.MuiBox-root > .announcement-tile .announcement-content-body, +.MuiBox-root > .announcement-tile .announcement-close svg { color: var(--env-var-color-28); -} -.MuiBox-root > .announcement-tile .announcement-close svg, -.edit-password-form__wrapper > .announcement-tile .announcement-close svg { - display: none; + fill: var(--env-var-color-28) !important; } #org-name-flex-container .Mui-disabled { color: var(--env-var-color-2) !important; @@ -119,7 +116,8 @@ padding-left: 20px; } .edit-team-form__wrapper td { - color: var(--env-var-color-25); + font-size: (--env-var-font-size-medium); + color: var(--env-var-color-29); } #select-actions, diff --git a/Client/src/assets/Images/Icon-open-in-tab-gray.png b/Client/src/assets/Images/Icon-open-in-tab-gray.png new file mode 100644 index 000000000..3f34c2053 Binary files /dev/null and b/Client/src/assets/Images/Icon-open-in-tab-gray.png differ diff --git a/Client/src/assets/Images/Icon-search-gray.png b/Client/src/assets/Images/Icon-search-gray.png new file mode 100644 index 000000000..7207f881d Binary files /dev/null and b/Client/src/assets/Images/Icon-search-gray.png differ diff --git a/Client/src/assets/Images/Icon-setting-actions-gray.png b/Client/src/assets/Images/Icon-setting-actions-gray.png new file mode 100644 index 000000000..40ba48b62 Binary files /dev/null and b/Client/src/assets/Images/Icon-setting-actions-gray.png differ diff --git a/Client/src/index.css b/Client/src/index.css index 35279f07f..e682b2a09 100644 --- a/Client/src/index.css +++ b/Client/src/index.css @@ -3,9 +3,9 @@ line-height: 1.5; font-weight: 400; - /* color-scheme: light dark; + color-scheme: light dark; color: rgba(255, 255, 255, 0.87); - background-color: #242424; */ + background-color: #242424; font-synthesis: none; text-rendering: optimizeLegibility; @@ -41,10 +41,11 @@ --env-var-color-24: #d92d20; --env-var-color-25: #667085; --env-var-color-26: #ff1818; + --env-var-color-27: #fecf60; --lighter-env-var-color-27: rgba(254, 207, 96, 0.1); --env-var-color-28: #f79009; - --env-var-color-29: #D0D5DD; + --env-var-color-29: #667085; --env-var-radius-1: 4px; --env-var-radius-2: 8px; @@ -63,9 +64,12 @@ --env-var-font-size-medium: 13px; --env-var-font-size-medium-plus: 14px; --env-var-font-size-large: 16px; + --env-var-font-size-large-plus: 24px; --env-var-font-size-xlarge: 30px; --env-var-img-width-1: 20px; + --env-var-img-width-2: 16px; + --env-var-img-width-3: 12px; --env-var-default-1: 24px; --env-var-default-2: 40px; diff --git a/Client/src/main.jsx b/Client/src/main.jsx index 1955bdd29..601dab68d 100644 --- a/Client/src/main.jsx +++ b/Client/src/main.jsx @@ -6,16 +6,19 @@ import { BrowserRouter as Router, HashRouter } from "react-router-dom"; import theme from "./Utils/Theme.js"; import { ThemeProvider } from "@mui/material"; import { Provider } from "react-redux"; -import store from "./store"; +import { persistor, store } from "./store"; +import { PersistGate } from "redux-persist/integration/react"; ReactDOM.createRoot(document.getElementById("root")).render( - - - - - + + + + + + + ); diff --git a/Client/src/store.js b/Client/src/store.js index 385448c6e..54201761e 100644 --- a/Client/src/store.js +++ b/Client/src/store.js @@ -1,7 +1,34 @@ -import { configureStore } from "@reduxjs/toolkit"; +import { configureStore, combineReducers } from "@reduxjs/toolkit"; import monitorsReducer from "./Features/Monitors/monitorsSlice"; import authReducer from "./Features/Auth/authSlice"; +import storage from "redux-persist/lib/storage"; +import { persistReducer, persistStore } from "redux-persist"; -export default configureStore({ - reducer: { monitors: monitorsReducer, auth: authReducer }, +const persistConfig = { + key: "root", + storage, + whitielist: ["auth", "monitors"], +}; + +const rootReducer = combineReducers({ + monitors: monitorsReducer, + auth: authReducer, }); + +const persistedReducer = persistReducer(persistConfig, rootReducer); + +export const store = configureStore({ + reducer: persistedReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + serializableCheck: { + ignoredActions: [ + "persist/PERSIST", + "persist/REHYDRATE", + "persist/REGISTER", + ], + }, + }), +}); + +export const persistor = persistStore(store);