mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-24 19:01:01 -06:00
Resovle conflict
This commit is contained in:
@@ -1,24 +1,22 @@
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
// import "./App.css";
|
||||
import NotFound from "./Pages/NotFound";
|
||||
import Login from "./Pages/Login";
|
||||
import Register from "./Pages/Register";
|
||||
import Login from "./Pages/Auth/Login";
|
||||
import Register from "./Pages/Auth/Register";
|
||||
import HomeLayout from "./Layouts/HomeLayout";
|
||||
import Demo from "./Pages/Demo/Demo";
|
||||
import PlayGround from "./Pages/PlayGround/PlayGround";
|
||||
import Account from "./Pages/Account";
|
||||
import Monitors from "./Pages/Monitors";
|
||||
import CreateNewMonitor from "./Pages/CreateNewMonitor";
|
||||
import CreateMonitor from "./Pages/Monitors/CreateMonitor";
|
||||
import Incidents from "./Pages/Incidents";
|
||||
import Status from "./Pages/Status";
|
||||
import Integrations from "./Pages/Integrations";
|
||||
import Settings from "./Pages/Settings";
|
||||
import ForgotPassword from "./Pages/ForgotPassword";
|
||||
import CheckEmail from "./Pages/CheckEmail";
|
||||
import SetNewPassword from "./Pages/SetNewPassword";
|
||||
import NewPasswordConfirmed from "./Pages/NewPasswordConfirmed";
|
||||
import ForgotPassword from "./Pages/Auth/ForgotPassword";
|
||||
import CheckEmail from "./Pages/Auth/CheckEmail";
|
||||
import SetNewPassword from "./Pages/Auth/SetNewPassword";
|
||||
import NewPasswordConfirmed from "./Pages/Auth/NewPasswordConfirmed";
|
||||
import ProtectedRoute from "./Components/ProtectedRoute";
|
||||
import Details from "./Pages/Details";
|
||||
import Details from "./Pages/Monitors/Details";
|
||||
import Maintenance from "./Pages/Maintenance";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
@@ -39,7 +37,7 @@ function App() {
|
||||
/>
|
||||
<Route
|
||||
path="/monitors/create"
|
||||
element={<ProtectedRoute Component={CreateNewMonitor} />}
|
||||
element={<ProtectedRoute Component={CreateMonitor} />}
|
||||
/>
|
||||
<Route
|
||||
path="/monitors/:monitorId/"
|
||||
@@ -82,10 +80,8 @@ function App() {
|
||||
|
||||
<Route exact path="/login" element={<Login />} />
|
||||
<Route exact path="/register" element={<Register />} />
|
||||
<Route exact path="/demo" element={<Demo />} />
|
||||
{/* <Route path="/toast" element={<ToastComponent />} /> */}
|
||||
<Route path="*" element={<NotFound />} />
|
||||
<Route path="/playground" element={<PlayGround />} />
|
||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||
<Route path="/check-email" element={<CheckEmail />} />
|
||||
<Route path="/set-new-password/:token" element={<SetNewPassword />} />
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import "./backgroundPattern.css";
|
||||
import React from "react";
|
||||
import Pattern from "../../assets/Images/background_pattern_decorative.png";
|
||||
|
||||
const BackgroundPattern = () => {
|
||||
return <img className="background-pattern" src={Pattern} alt="Pattern" />;
|
||||
};
|
||||
|
||||
export default BackgroundPattern;
|
||||
@@ -1,7 +0,0 @@
|
||||
.background-pattern {
|
||||
position: absolute;
|
||||
top: -5%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: -1;
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.MuiTable-root .host-row a {
|
||||
width: var(--env-var-img-width-2);
|
||||
height: var(--env-var-img-width-2);
|
||||
@@ -18,6 +17,12 @@
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.MuiTable-root .label {
|
||||
border-color: var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-2);
|
||||
padding: calc(var(--env-var-spacing-1) / 2);
|
||||
}
|
||||
|
||||
.MuiTable-root .host-name {
|
||||
width: fit-content;
|
||||
margin-right: 10px;
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
import { styled, useTheme } from '@mui/material/styles';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { StatusLabel } from "../../Components/Label/";
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
||||
[`&.${tableCellClasses.head}`]: {
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
color: theme.palette.common.black,
|
||||
},
|
||||
[`&.${tableCellClasses.body}`]: {
|
||||
fontSize: 14,
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||
'&:nth-of-type(odd)': {
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
},
|
||||
'&:nth-of-type(even)': {
|
||||
backgroundColor: theme.palette.common.white,
|
||||
},
|
||||
'&:last-child td, &:last-child th': {
|
||||
border: 0,
|
||||
},
|
||||
}));
|
||||
|
||||
function createData(name, date, message) {
|
||||
return { name, date, message };
|
||||
}
|
||||
|
||||
const CustomizedTables = ({ monitor }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const rows = (monitor && monitor.checks) ? monitor.checks.map(check => createData(
|
||||
<StatusLabel status={check.status ? "Up" : "Down"} customStyles={{ backgroundColor: check.status ? '#f2f4f7' : '#fff9f9', borderColor: check.status ? '#d2d6de' : '#ffcac6', color: '#344054' }} />,
|
||||
new Date(check.createdAt).toLocaleString(),
|
||||
`HTTP ${check.statusCode} - ${check.status ? 'OK' : 'NOK'}`
|
||||
)) : [];
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: theme.spacing(4),
|
||||
marginX: 'auto',
|
||||
width: '80%',
|
||||
paddingX: theme.spacing(6),
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: '100%',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-around', marginBottom: theme.spacing(4) }}>
|
||||
{[...Array(4)].map((_, index) => (
|
||||
<Box
|
||||
key={index}
|
||||
sx={{
|
||||
width: '223.35px',
|
||||
height: '87px',
|
||||
borderRadius: '4px',
|
||||
border: '1px solid',
|
||||
borderColor: '#EAECF0',
|
||||
padding: theme.spacing(1),
|
||||
textAlign: 'left',
|
||||
boxShadow: '0px 1px 2px rgba(16, 24, 40, 0.05)',
|
||||
backdropFilter: 'blur(2px)',
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{
|
||||
fontFamily: 'Roboto',
|
||||
fontWeight: 400,
|
||||
fontSize: '16px',
|
||||
lineHeight: '24px',
|
||||
color: '#1570EF',
|
||||
marginBottom: theme.spacing(1),
|
||||
}}
|
||||
>
|
||||
Currently up for
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontFamily: 'Roboto',
|
||||
fontWeight: 600,
|
||||
fontSize: '13px',
|
||||
lineHeight: '20px',
|
||||
color: '#344054',
|
||||
}}
|
||||
>
|
||||
4h 30m 2s
|
||||
</Typography>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: theme.spacing(2) }}>
|
||||
<Typography variant="h6" component="div" sx={{ fontWeight: 600, fontSize: 16 }}>
|
||||
History
|
||||
</Typography>
|
||||
</Box>
|
||||
<TableContainer component={Paper}>
|
||||
<Table sx={{ minWidth: 700 }} aria-label="customized table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell>Status</StyledTableCell>
|
||||
<StyledTableCell align="right">Date & Time</StyledTableCell>
|
||||
<StyledTableCell align="right">Message</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map((row) => (
|
||||
<StyledTableRow key={row.name.props.status.key}>
|
||||
<StyledTableCell component="th" scope="row">
|
||||
{row.name}
|
||||
</StyledTableCell>
|
||||
<StyledTableCell align="right">{row.date}</StyledTableCell>
|
||||
<StyledTableCell align="right">{row.message}</StyledTableCell>
|
||||
</StyledTableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
CustomizedTables.propTypes = {
|
||||
monitor: PropTypes.shape({
|
||||
checks: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
status: PropTypes.bool.isRequired,
|
||||
createdAt: PropTypes.string.isRequired,
|
||||
statusCode: PropTypes.number.isRequired,
|
||||
})
|
||||
),
|
||||
}),
|
||||
};
|
||||
|
||||
CustomizedTables.defaultProps = {
|
||||
monitor: { checks: [] },
|
||||
};
|
||||
|
||||
export default CustomizedTables;
|
||||
@@ -1,15 +1,15 @@
|
||||
import "./index.css";
|
||||
import DashboardMenuButton from "../DashboardMenuButton";
|
||||
|
||||
import Monitors from "../../assets/Images/Icon-monitor-gray.png";
|
||||
import Incidents from "../../assets/Images/Icon-warning-gray.png";
|
||||
import SensorsIcon from "../../assets/Images/Icon-signal-gray.png";
|
||||
import AllInclusiveIcon from "../../assets/Images/Icon-link-gray.png";
|
||||
import MaintenanceIcon from "../../assets/Images/Icon-maintenance-gray.png";
|
||||
import SettingsIcon from "../../assets/Images/Icon-setting-gray.png";
|
||||
import Monitors from "../../../assets/Images/Icon-monitor-gray.png";
|
||||
import Incidents from "../../../assets/Images/Icon-warning-gray.png";
|
||||
import SensorsIcon from "../../../assets/Images/Icon-signal-gray.png";
|
||||
import AllInclusiveIcon from "../../../assets/Images/Icon-link-gray.png";
|
||||
import MaintenanceIcon from "../../../assets/Images/Icon-maintenance-gray.png";
|
||||
import SettingsIcon from "../../../assets/Images/Icon-setting-gray.png";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import pathMap from "../../Utils/PathMap";
|
||||
import pathMap from "../../../Utils/PathMap";
|
||||
|
||||
/**
|
||||
* @component
|
||||
@@ -1,7 +1,7 @@
|
||||
import DashboardMenu from "../../Components/DashboardMenu";
|
||||
import DashboardMenu from "../DashboardMenu";
|
||||
import SvgIcon from "@mui/material/SvgIcon";
|
||||
import "./index.css";
|
||||
import SupportIcon from "../../assets/Images/Icon-support-gray.png";
|
||||
import SupportIcon from "../../../assets/Images/Icon-support-gray.png";
|
||||
|
||||
/**
|
||||
* @component
|
||||
@@ -1,19 +0,0 @@
|
||||
import { BarChart } from "@mui/x-charts/BarChart";
|
||||
|
||||
const ChartsOverviewDemo = () => {
|
||||
return (
|
||||
<BarChart
|
||||
series={[
|
||||
{ data: [35, 44, 24, 34] },
|
||||
{ data: [51, 6, 49, 30] },
|
||||
{ data: [15, 25, 30, 50] },
|
||||
{ data: [60, 50, 15, 25] },
|
||||
]}
|
||||
height={290}
|
||||
xAxis={[{ data: ["Q1", "Q2", "Q3", "Q4"], scaleType: "band" }]}
|
||||
margin={{ top: 10, bottom: 30, left: 40, right: 10 }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChartsOverviewDemo;
|
||||
@@ -1,9 +0,0 @@
|
||||
#dashboard-setting-menu-item {
|
||||
width: 135px;
|
||||
padding: 6px;
|
||||
margin: 5px 12px;
|
||||
}
|
||||
|
||||
#menu-appbar {
|
||||
padding: var(--env-var-spacing-1);
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
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",
|
||||
];
|
||||
|
||||
/**
|
||||
* DashboardSettings component
|
||||
*
|
||||
* A component that provides a settings menu accessible from an icon.
|
||||
*
|
||||
* @component
|
||||
* @example
|
||||
* return (
|
||||
* <DashboardSettings />
|
||||
* )
|
||||
*/
|
||||
function DashboardSettings() {
|
||||
const theme = useTheme();
|
||||
const [anchorElUser, setAnchorElUser] = useState(null);
|
||||
|
||||
/**
|
||||
* Handles opening the user menu.
|
||||
*
|
||||
* @param {React.MouseEvent<HTMLElement>} event - The event triggered by clicking the user menu button.
|
||||
*/
|
||||
const handleOpenUserMenu = (event) => {
|
||||
setAnchorElUser(event.currentTarget);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles closing the user menu.
|
||||
*/
|
||||
const handleCloseUserMenu = () => {
|
||||
setAnchorElUser(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ flexGrow: 0 }}>
|
||||
<Tooltip title="Open settings">
|
||||
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
|
||||
<SvgIcon component={SettingsIcon} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
sx={{ mt: theme.spacing(5.5) }}
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorElUser}
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
open={Boolean(anchorElUser)}
|
||||
onClose={handleCloseUserMenu}
|
||||
>
|
||||
{settings.map((setting) => (
|
||||
<MenuItem
|
||||
id="dashboard-setting-menu-item"
|
||||
key={setting}
|
||||
onClick={handleCloseUserMenu}
|
||||
>
|
||||
<Typography
|
||||
style={{ fontSize: "var(--env-var-font-size-medium)" }}
|
||||
textAlign="center"
|
||||
>
|
||||
{setting}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardSettings;
|
||||
@@ -1 +0,0 @@
|
||||
/* dropdown styles*/
|
||||
@@ -1,29 +0,0 @@
|
||||
import PropTypes from "prop-types";
|
||||
import Autocomplete from "@mui/material/Autocomplete";
|
||||
import TextField from "@mui/material/TextField";
|
||||
|
||||
const Dropdown = (props) => {
|
||||
return (
|
||||
<Autocomplete
|
||||
id={props.id}
|
||||
options={props.options}
|
||||
getOptionLabel={(option) => (option.name ? option.name : "")}
|
||||
value={props.value}
|
||||
onChange={props.onChange}
|
||||
// Add isOptionEqualToValue prop
|
||||
isOptionEqualToValue={(option, value) => option.name === value}
|
||||
renderInput={(params) => <TextField {...params} label={props.label} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// Define PropTypes for DropDown component
|
||||
Dropdown.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
options: PropTypes.array.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
@@ -1 +0,0 @@
|
||||
/*Dropdown Team Member styles*/
|
||||
@@ -1,39 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import '@fontsource/roboto/300.css';
|
||||
import '@fontsource/roboto/400.css';
|
||||
import '@fontsource/roboto/500.css';
|
||||
import '@fontsource/roboto/700.css';
|
||||
// import DropDown from './Dropdown';
|
||||
import DropDown from '../Dropdown'
|
||||
|
||||
const DropdownTeamMember = () => {
|
||||
const [selectedTeamMember, setSelectedTeamMember] = useState(null);
|
||||
|
||||
const teamMembers = [
|
||||
{ id: 1, name: 'John Doe' },
|
||||
{ id: 2, name: 'Jane Smith' },
|
||||
{ id: 3, name: 'Alex Johnson' },
|
||||
// more team members...
|
||||
];
|
||||
|
||||
const handleTeamMemberChange = (event, value) => {
|
||||
setSelectedTeamMember(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="app-container" style={{ width: '500px' }}>
|
||||
<DropDown
|
||||
id="team-member-autocomplete"
|
||||
options={teamMembers}
|
||||
label="Select team member"
|
||||
value={selectedTeamMember}
|
||||
onChange={handleTeamMemberChange}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default DropdownTeamMember
|
||||
@@ -1,36 +0,0 @@
|
||||
import "./complexAlert.css";
|
||||
import React from "react";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {"red" | "green"} props.theme - The color theme for the alert (required) - must be either "red" or "green"
|
||||
* @returns {JSX.Element} - Renders the complex alert component with dynamic color theme
|
||||
*/
|
||||
const ComplexAlert = ({ theme }) => {
|
||||
if (theme === "red") {
|
||||
return (
|
||||
<div className="icon-holder-outer-red">
|
||||
<div className="icon-holder-inner-red">
|
||||
<ErrorOutlineIcon className="icon-core" style={{ fill: "#D92D20" }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (theme === "green") {
|
||||
return (
|
||||
<div className="icon-holder-outer-green">
|
||||
<div className="icon-holder-inner-green">
|
||||
<ErrorOutlineIcon className="icon-core" style={{ fill: "#079455" }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ComplexAlert.propTypes = {
|
||||
theme: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default ComplexAlert;
|
||||
@@ -1,44 +0,0 @@
|
||||
.icon-holder-outer-red {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #d92d2019;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-holder-inner-red {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #d92d204d;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-holder-outer-green {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #07945519;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-holder-inner-green {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #0794554d;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-core {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import "./searchTextField.css";
|
||||
import React from "react";
|
||||
import SearchSvg from "../../../assets/icons/search.svg?react";
|
||||
|
||||
const SearchTextField = () => {
|
||||
return (
|
||||
<div className="search-field-holder">
|
||||
<SearchSvg style={{ marginRight: "5px" }} />
|
||||
<input className="search-field" type="text" placeholder="Search" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchTextField;
|
||||
@@ -1,26 +0,0 @@
|
||||
.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);
|
||||
}
|
||||
@@ -27,10 +27,10 @@ const BaseLabel = ({ label, styles, children }) => {
|
||||
const padding = theme.spacing(1 * 0.75, 2);
|
||||
|
||||
return (
|
||||
<div
|
||||
<Box
|
||||
className="label"
|
||||
style={{
|
||||
borderRadius: borderRadius,
|
||||
sx={{
|
||||
borderRadius: `${borderRadius}px`,
|
||||
borderColor: theme.palette.tertiary.main,
|
||||
color: theme.palette.tertiary.main,
|
||||
padding: padding,
|
||||
@@ -39,7 +39,7 @@ const BaseLabel = ({ label, styles, children }) => {
|
||||
>
|
||||
{children}
|
||||
{label}
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -118,13 +118,14 @@ ColoredLabel.propTypes = {
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {'Seen' | 'Waiting' | 'New' | 'Active'} props.status - The status for the label
|
||||
* @param {string} props.dot - The color of the dot
|
||||
* @returns {JSX.Element}
|
||||
* @example
|
||||
* // Render an active label
|
||||
* <StatusLabel status="Active" />
|
||||
*/
|
||||
|
||||
const StatusLabel = ({ status, customStyles }) => {
|
||||
const StatusLabel = ({ status, dot, customStyles }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const colorLookup = {
|
||||
@@ -132,8 +133,7 @@ const StatusLabel = ({ status, customStyles }) => {
|
||||
Waiting: theme.palette.labelRed.color,
|
||||
New: theme.palette.labelOrange.color,
|
||||
Active: theme.palette.labelGreen.color,
|
||||
Down: theme.palette.error.main, // Assuming theme.palette.error.main is red
|
||||
|
||||
Down: theme.palette.error.main, // Assuming theme.palette.error.main is red
|
||||
};
|
||||
|
||||
// Look up the color for the status, default to labelGray if not found
|
||||
@@ -142,18 +142,26 @@ const StatusLabel = ({ status, customStyles }) => {
|
||||
return (
|
||||
<BaseLabel label={status} styles={customStyles}>
|
||||
<Box
|
||||
width={12}
|
||||
height={12}
|
||||
bgcolor={color}
|
||||
width={7}
|
||||
height={7}
|
||||
bgcolor={dot || color}
|
||||
borderRadius="50%"
|
||||
marginRight={1}
|
||||
marginRight="5px"
|
||||
/>
|
||||
</BaseLabel>
|
||||
);
|
||||
};
|
||||
|
||||
StatusLabel.propTypes = {
|
||||
status: PropTypes.oneOf(["Seen", "Waiting", "New", "Active", "Down", "Cannot resolve"]),
|
||||
status: PropTypes.oneOf([
|
||||
"Seen",
|
||||
"Waiting",
|
||||
"New",
|
||||
"Active",
|
||||
"Up",
|
||||
"Down",
|
||||
"Cannot resolve",
|
||||
]),
|
||||
customStyles: PropTypes.object,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/* .host-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.host-row a {
|
||||
width: var(--env-var-img-width-2);
|
||||
height: var(--env-var-img-width-2);
|
||||
color: var(--env-var-color-5);
|
||||
margin-right: 10px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.host-row a svg {
|
||||
width: var(--env-var-font-size-large);
|
||||
height: var(--env-var-font-size-large);
|
||||
}
|
||||
.host-row .host-percentage {
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.host-name {
|
||||
width: fit-content;
|
||||
margin-right: 10px;
|
||||
font-weight: 700;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.monitors .MuiPaper-root:has(table.MuiTable-root) {
|
||||
box-shadow: none;
|
||||
border: solid 1px var(--env-var-color-16);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.monitors .MuiTableBody-root .MuiTableRow-root:last-child .MuiTableCell-root {
|
||||
border: none;
|
||||
}
|
||||
.monitors .MuiTableHead-root,
|
||||
.monitors .MuiTableRow-root:hover {
|
||||
background-color: var(--env-var-color-13);
|
||||
}
|
||||
.monitors .MuiTableHead-root .MuiTableCell-root,
|
||||
.monitors .MuiTableBody-root .MuiTableCell-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.monitors .MuiTableHead-root .MuiTableCell-root {
|
||||
padding: var(--env-var-spacing-1) var(--env-var-spacing-2);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.monitors .MuiTableHead-root span {
|
||||
display: inline-block;
|
||||
height: 17px;
|
||||
width: 20px;
|
||||
overflow: hidden;
|
||||
margin-bottom: -2px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.monitors .MuiTableHead-root span svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.monitors .MuiTableBody-root .MuiTableCell-root {
|
||||
color: var(--env-var-color-5);
|
||||
padding: 6px var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.monitors .MuiPagination-root {
|
||||
flex: 1;
|
||||
margin-top: 35px;
|
||||
border: solid 1px var(--env-var-color-16);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
padding: var(--env-var-spacing-1-plus) var(--env-var-spacing-2);
|
||||
}
|
||||
.monitors .MuiPagination-root ul {
|
||||
justify-content: center;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: 500;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:first-child {
|
||||
margin-right: auto;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:first-child button,
|
||||
.monitors .MuiPagination-root ul li:last-child button {
|
||||
border: solid 1px var(--env-var-color-16);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:first-child button {
|
||||
padding: 0 var(--env-var-spacing-1) 0 var(--env-var-spacing-1-plus);
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:last-child button {
|
||||
padding: 0 var(--env-var-spacing-1-plus) 0 var(--env-var-spacing-1);
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:first-child button::after,
|
||||
.monitors .MuiPagination-root ul li:last-child button::before {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:first-child button::after {
|
||||
content: "Previous";
|
||||
margin-left: 15px;
|
||||
}
|
||||
.monitors .MuiPagination-root ul li:last-child button::before {
|
||||
content: "Next";
|
||||
margin-right: 15px;
|
||||
} */
|
||||
@@ -1,116 +0,0 @@
|
||||
import "./index.css";
|
||||
import PropTypes from "prop-types";
|
||||
import ResponseTimeChart from "../Charts/ResponseTimeChart";
|
||||
import BasicTable from "../BasicTable";
|
||||
import OpenInNewPage from "../../assets/icons/open-in-new-page.svg?react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import StatusLabel from "../StatusLabel";
|
||||
import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
|
||||
|
||||
/**
|
||||
* Host component.
|
||||
* This subcomponent receives a params object and displays the host details.
|
||||
*
|
||||
* @component
|
||||
* @param {Object} params - An object containing the following properties:
|
||||
* @param {string} params.url - The URL of the host.
|
||||
* @param {string} params.title - The name of the host.
|
||||
* @param {string} params.percentageColor - The color of the percentage text.
|
||||
* @param {number} params.precentage - The percentage to display.
|
||||
* @returns {React.ElementType} Returns a div element with the host details.
|
||||
*/
|
||||
const Host = ({ params }) => {
|
||||
return (
|
||||
<div className="host-row">
|
||||
<a href={params.url} target="_blank">
|
||||
<OpenInNewPage />
|
||||
</a>
|
||||
<div className="host-name">{params.title}</div>
|
||||
<div
|
||||
className="host-percentage"
|
||||
style={{ color: params.percentageColor }}
|
||||
>
|
||||
{params.precentage}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* MonitorTable component.
|
||||
* Takes an array of monitor objects and displays them in a table.
|
||||
* Each row in the table represents a monitor and includes the host, status, response time, and action.
|
||||
*
|
||||
* @component
|
||||
* @param {Object[]} monitors - An array of monitor objects. Each object should have the following properties:
|
||||
* @param {string} monitors[].url - The URL of the monitor.
|
||||
* @param {string} monitors[].name - The name of the monitor.
|
||||
* @param {boolean} monitors[].status - The status of the monitor. True if the monitor is up, false otherwise.
|
||||
* @param {Object[]} monitors[].checks - An array of check objects for the response time chart.
|
||||
* @returns {React.Component} Returns a table with the monitor data.
|
||||
*/
|
||||
const MonitorTable = ({ monitors = [] }) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const data = {
|
||||
cols: [
|
||||
{ id: 1, name: "Host" },
|
||||
{
|
||||
id: 2,
|
||||
name: (
|
||||
<>
|
||||
Status
|
||||
<span>
|
||||
<ArrowDownwardRoundedIcon />
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{ id: 3, name: "Response Time" },
|
||||
{ id: 4, name: "Actions" },
|
||||
],
|
||||
rows: [],
|
||||
};
|
||||
|
||||
data.rows = monitors.map((monitor, idx) => {
|
||||
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 {
|
||||
id: monitor._id,
|
||||
handleClick: () => navigate(`/monitors/${monitor._id}`),
|
||||
data: [
|
||||
{ id: idx, data: <Host params={params} /> },
|
||||
{ id: idx + 1, data: <StatusLabel params={params} /> },
|
||||
{ id: idx + 2, data: <ResponseTimeChart checks={monitor.checks} /> },
|
||||
{ id: idx + 3, data: "TODO" },
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
return <BasicTable data={data} paginated={true} />;
|
||||
};
|
||||
|
||||
MonitorTable.propTypes = {
|
||||
monitors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
};
|
||||
|
||||
Host.propTypes = { params: PropTypes.object.isRequired };
|
||||
|
||||
export default MonitorTable;
|
||||
@@ -1,33 +0,0 @@
|
||||
.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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import React from "react";
|
||||
import { Pagination as MuiPagination } from "@mui/material";
|
||||
import "./index.css";
|
||||
|
||||
const Pagination = () => {
|
||||
return (
|
||||
<div className="pagination-holder">
|
||||
<MuiPagination count={10} variant="outlined" shape="rounded" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pagination;
|
||||
@@ -1,55 +0,0 @@
|
||||
import "./dualButtonPopupModal.css";
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {boolean} [props.open=true] - Controls the visibility of the modal (defaults to true)
|
||||
* @param {string} props.subject - The title text for the modal (required)
|
||||
* @param {string} props.description - The description text for the modal (required)
|
||||
* @param {string} props.esc - The text for the discard button (usually "Cancel", "Dismiss" or "Discard") (required)
|
||||
* @param {string} props.save - The text for the save button (required)
|
||||
* @returns {JSX.Element} - Renders the dual button popup modal component
|
||||
*/
|
||||
const DualButtonPopupModal = ({
|
||||
open = true,
|
||||
subject,
|
||||
description,
|
||||
esc,
|
||||
save,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
return (
|
||||
<div
|
||||
className="dual-button-popup-modal-holder"
|
||||
style={{ fontFamily: fontFamily }}
|
||||
>
|
||||
<div className="dual-button-popup-modal-subject">{subject}</div>
|
||||
<div className="dual-button-popup-modal-description">{description}</div>
|
||||
<div className="dual-modal-spacing"></div>
|
||||
<div className="dual-button-popup-modal-controllers">
|
||||
<button className="transparent-discard-button">{esc}</button>
|
||||
<button className="blue-save-button">{save}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
DualButtonPopupModal.propTypes = {
|
||||
open: PropTypes.bool,
|
||||
subject: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
esc: PropTypes.string.isRequired,
|
||||
save: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default DualButtonPopupModal;
|
||||
@@ -1,52 +0,0 @@
|
||||
.dual-button-popup-modal-holder {
|
||||
width: 380px;
|
||||
height: 130px;
|
||||
margin: 10px 20px;
|
||||
padding: 30px;
|
||||
box-shadow: 0px 8px 8px -4px rgba(16, 24, 40, 0.03),
|
||||
0px 20px 24px -4px rgba(16, 24, 40, 0.08);
|
||||
border: 1px solid var(--env-var-color-9);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-subject {
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-description {
|
||||
color: var(--env-var-color-2);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.dual-modal-spacing {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-controllers {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.blue-save-button {
|
||||
width: 145px;
|
||||
height: 35px;
|
||||
padding: 5px 20px;
|
||||
background-color: var(--env-var-color-3);
|
||||
border: 1px solid var(--env-var-color-10);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
margin: 5px 0;
|
||||
margin-left: 20px;
|
||||
color: var(--env-var-color-8);
|
||||
cursor: pointer;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.transparent-discard-button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
margin: 5px 10px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import "./dualButtonPopupModalWithTextfields.css";
|
||||
import React from "react";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {string} props.title - The title text for the modal (required)
|
||||
* @returns {JSX.Element} - Renders a single text field component within a popup modal
|
||||
*/
|
||||
const PopupModalTextfield = ({ title }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
return (
|
||||
<div className="popup-modal-input" style={{ fontFamily: fontFamily }}>
|
||||
<div className="popup-modal-input-title">{title}</div>
|
||||
<input type="text" className="popup-modal-text-field" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {string} props.title - The title text for the modal (required)
|
||||
* @param {string} props.esc - The text for the cancel button (required)
|
||||
* @param {string} props.save - The text for the save button (required)
|
||||
* @returns {JSX.Element} - Renders the dual button popup modal component with text fields
|
||||
*/
|
||||
const DualButtonPopupModalWithTextfields = ({ title, esc, save }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const fontLookup = {
|
||||
default: theme.font.default.font,
|
||||
};
|
||||
|
||||
const fontFamily = fontLookup["default"];
|
||||
|
||||
return (
|
||||
<div className="popup-modal-holder" style={{ fontFamily: fontFamily }}>
|
||||
<div className="popup-modal-header">
|
||||
<div className="popup-modal-title">{title}</div>
|
||||
<div className="popup-modal-close">
|
||||
<CloseIcon style={{ fill: "#98A2B3" }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="spacing-height"></div>
|
||||
<PopupModalTextfield title="Name" />
|
||||
<div className="spacing-height"></div>
|
||||
<div className="spacing-height"></div>
|
||||
<div className="popup-modal-controllers">
|
||||
<button className="white-cancel-button">{esc}</button>
|
||||
<button className="blue-save-button">{save}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
DualButtonPopupModalWithTextfields.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
esc: PropTypes.string.isRequired,
|
||||
save: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default DualButtonPopupModalWithTextfields;
|
||||
@@ -1,55 +0,0 @@
|
||||
.popup-modal-holder {
|
||||
width: 480px;
|
||||
font-family: var(--popup-font-family-0);
|
||||
padding: 50px 40px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
margin: 10px 20px;
|
||||
border: 1px solid var(--env-var-color-9);
|
||||
box-shadow: 0px 8px 8px -4px rgba(16, 24, 40, 0.03),
|
||||
0px 20px 24px -4px rgba(16, 24, 40, 0.08);
|
||||
}
|
||||
|
||||
.popup-modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-modal-close {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.spacing-height {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.popup-modal-input-title {
|
||||
margin-bottom: 15px;
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
|
||||
.popup-modal-text-field {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.popup-modal-controllers {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.white-cancel-button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
font-family: var(--popup-font-family-0);
|
||||
margin: 5px 10px;
|
||||
width: 145px;
|
||||
height: 35px;
|
||||
padding: 5px 20px;
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
cursor: pointer;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { useState, useEffect } from "react";
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
useTheme,
|
||||
Typography,
|
||||
TextField,
|
||||
Switch,
|
||||
} from "@mui/material";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
||||
import Button from "../Button/";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param { Array} props.monitors - Array of monitors associated with the section
|
||||
* @returns {JSX.Element}
|
||||
* @example
|
||||
* // Renders a section component with a list of monitors
|
||||
* <Section monitors={monitors} />
|
||||
*/
|
||||
|
||||
const Section = ({ monitors }) => {
|
||||
const [monitorStates, setMonitorStates] = useState(
|
||||
monitors.map((monitor) => monitor.isActive)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Update DB here
|
||||
}, [monitorStates]);
|
||||
|
||||
const handleMonitor = (monitorIndex) => {
|
||||
setMonitorStates((prevStates) => {
|
||||
const newStates = [...prevStates];
|
||||
newStates[monitorIndex] = !newStates[monitorIndex];
|
||||
|
||||
return newStates;
|
||||
// Need to update DB with new monitor state
|
||||
});
|
||||
};
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<>
|
||||
<Container
|
||||
disableGutters
|
||||
sx={{
|
||||
border: `1px solid ${theme.palette.section.borderColor}`,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: "left",
|
||||
padding: `${theme.spacing(2)}`,
|
||||
bgcolor: `${theme.palette.section.bgColor}`,
|
||||
borderBottom: `1px solid ${theme.palette.section.borderColor}`,
|
||||
}}
|
||||
>
|
||||
<Typography>Section Name</Typography>
|
||||
<TextField
|
||||
placeholder="Service Name"
|
||||
sx={{
|
||||
"& input": {
|
||||
width: "320px",
|
||||
height: "34px",
|
||||
padding: "10px 14px 10px 14px",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "start",
|
||||
textAlign: "left",
|
||||
padding: `${theme.spacing(2)}`,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Typography>Servers List</Typography>
|
||||
<Button level="primary" label="Add new" />
|
||||
{monitors.map((monitor, index) => {
|
||||
return (
|
||||
<Box
|
||||
key={monitor.id}
|
||||
sx={{
|
||||
boxSizing: "border-box",
|
||||
width: "100%",
|
||||
padding: "10px 14px 10px 14px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
border: `1px solid ${theme.palette.section.borderColor}`,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
bgcolor: `${theme.palette.section.bgColor}`,
|
||||
}}
|
||||
>
|
||||
<MenuIcon
|
||||
sx={{ color: `${theme.palette.section.borderColor}` }}
|
||||
/>
|
||||
<Switch
|
||||
checked={monitorStates[index]}
|
||||
onChange={() => handleMonitor(index)}
|
||||
/>
|
||||
<Typography sx={{ flexGrow: 1 }}>{monitor.name}</Typography>
|
||||
<DeleteOutlineIcon
|
||||
sx={{ color: `${theme.palette.section.borderColor}` }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</Container>
|
||||
<Button
|
||||
sx={{ marginTop: theme.spacing(2) }}
|
||||
level="imageSecondary"
|
||||
label="Add new section"
|
||||
img={<AddIcon />}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Section.propTypes = {
|
||||
monitors: PropTypes.array,
|
||||
};
|
||||
|
||||
export default Section;
|
||||
@@ -1,22 +0,0 @@
|
||||
.host-status {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.host-status-details {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-2);
|
||||
padding: calc(var(--env-var-spacing-1) / 2);
|
||||
}
|
||||
|
||||
.host-status-text {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
line-height: var(--env-var-font-size-medium);
|
||||
}
|
||||
.host-status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
margin-right: calc(var(--env-var-spacing-1) / 2);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import "./index.css";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* Status component.
|
||||
* This subcomponent receives a params object and displays the status details of a monitor.
|
||||
*
|
||||
* @component
|
||||
* @param {Object} params - An object containing the following properties:
|
||||
* @param {string} params.backgroundColor - The background color of the status box.
|
||||
* @param {string} params.statusDotColor - The color of the status dot.
|
||||
* @param {string} params.status - The status text to display.
|
||||
* @returns {React.ElementType} Returns a div element with the host status.
|
||||
*/
|
||||
const StatusLabel = ({ params }) => {
|
||||
return (
|
||||
<div className="host-status">
|
||||
<div
|
||||
className="host-status-details"
|
||||
style={{ backgroundColor: params.backgroundColor }}
|
||||
>
|
||||
<div
|
||||
className="host-status-dot"
|
||||
style={{ backgroundColor: params.statusDotColor }}
|
||||
/>
|
||||
<span
|
||||
className="host-status-text"
|
||||
style={{ textTransform: "capitalize" }}
|
||||
>
|
||||
{params.status}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusLabel;
|
||||
|
||||
StatusLabel.propTypes = { params: PropTypes.object.isRequired };
|
||||
@@ -1,6 +1,6 @@
|
||||
import NavBar from "../../Components/NavBar";
|
||||
import { Outlet } from "react-router";
|
||||
import DashboardSidebar from "../../Components/DashboardSidebar";
|
||||
import DashboardSidebar from "../../Components/Dashboard/DashboardSidebar";
|
||||
import "./index.css";
|
||||
|
||||
const HomeLayout = () => {
|
||||
|
||||
@@ -1,534 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import EmailIcon from "../../assets/icons/email.svg?react";
|
||||
import Button from "../../Components/Button";
|
||||
@@ -95,7 +95,11 @@ const CheckEmail = () => {
|
||||
|
||||
return (
|
||||
<div className="check-email-page">
|
||||
<BackgroundPattern />
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="check-email-form">
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<EmailIcon alt="EmailIcon" style={{ fill: "white" }} />
|
||||
@@ -1,6 +1,5 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import Logomark from "../../assets/icons/key.svg?react";
|
||||
import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded";
|
||||
import { useState } from "react";
|
||||
@@ -100,7 +99,11 @@ const ForgotPassword = () => {
|
||||
|
||||
return (
|
||||
<div className="forgot-password-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="forgot-password-form" onSubmit={handleSubmit}>
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<Logomark alt="Logomark" style={{ fill: "white" }} />
|
||||
@@ -2,10 +2,10 @@ import { useState, useEffect } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import "./index.css";
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import Logomark from "../../assets/Images/bwl-logo-2.svg?react";
|
||||
import Button from "../../Components/Button";
|
||||
import Google from "../../assets/Images/Google.png";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import axiosInstance from "../../Utils/axiosConfig";
|
||||
import { credentials } from "../../Validation/validation";
|
||||
import { login } from "../../Features/Auth/authSlice";
|
||||
@@ -122,7 +122,11 @@ const Login = () => {
|
||||
|
||||
return (
|
||||
<div className="login-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="login-form" onSubmit={handleSubmit}>
|
||||
<Stack gap={theme.gap.large} direction="column">
|
||||
<Logomark alt="BlueWave Uptime Icon" />
|
||||
@@ -1,5 +1,5 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded";
|
||||
import ConfirmIcon from "../../assets/icons/confirm-icon.svg?react";
|
||||
import Button from "../../Components/Button";
|
||||
@@ -23,7 +23,11 @@ const NewPasswordConfirmed = () => {
|
||||
|
||||
return (
|
||||
<div className="password-confirmed-page">
|
||||
<BackgroundPattern />
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="password-confirmed-form">
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<ConfirmIcon alt="confirm icon" style={{ fill: "white" }} />
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import "./index.css";
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import Logomark from "../../assets/Images/bwl-logo-2.svg?react";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import Button from "../../Components/Button";
|
||||
@@ -132,7 +132,11 @@ const Register = () => {
|
||||
|
||||
return (
|
||||
<div className="register-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="register-form" onSubmit={handleSubmit} noValidate>
|
||||
<Stack gap={theme.gap.large} direction="column">
|
||||
<Logomark alt="BlueWave Uptime Icon" />
|
||||
@@ -1,5 +1,5 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import background from "../../assets/Images/background_pattern_decorative.png";
|
||||
import LockIcon from "../../assets/icons/lock-button-icon.svg?react";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import ButtonSpinner from "../../Components/ButtonSpinner";
|
||||
@@ -114,7 +114,11 @@ const SetNewPassword = () => {
|
||||
|
||||
return (
|
||||
<div className="set-new-password-page">
|
||||
<BackgroundPattern />
|
||||
<img
|
||||
className="background-pattern-svg"
|
||||
src={background}
|
||||
alt="background pattern"
|
||||
/>
|
||||
<form className="set-new-password-form" onSubmit={handleSubmit}>
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<LockIcon alt="lock icon" style={{ fill: "white" }} />
|
||||
138
Client/src/Pages/Auth/index.css
Normal file
138
Client/src/Pages/Auth/index.css
Normal file
@@ -0,0 +1,138 @@
|
||||
/* ////// */
|
||||
/* SHARED */
|
||||
/* ////// */
|
||||
.register-page,
|
||||
.login-page,
|
||||
.set-new-password-page,
|
||||
.password-confirmed-page,
|
||||
.forgot-password-page,
|
||||
.check-email-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.register-page h1.MuiTypography-root,
|
||||
.set-new-password-page h1.MuiTypography-root,
|
||||
.password-confirmed-page h1.MuiTypography-root,
|
||||
.forgot-password-page h1.MuiTypography-root,
|
||||
.check-email-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.register-page p.MuiTypography-root,
|
||||
.register-page span,
|
||||
.register-page button,
|
||||
.login-page p.MuiTypography-root,
|
||||
.login-page span,
|
||||
.login-page button,
|
||||
.set-new-password-page p.MuiTypography-root,
|
||||
.set-new-password-page button,
|
||||
.password-confirmed-page p.MuiTypography-root,
|
||||
.password-confirmed-page button,
|
||||
.forgot-password-page p.MuiTypography-root,
|
||||
.forgot-password-page button,
|
||||
.check-email-page p.MuiTypography-root,
|
||||
.check-email-page button,
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.register-page p.MuiTypography-root,
|
||||
.login-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.register-page button:not(.MuiIconButton-root),
|
||||
.login-page button:not(.MuiIconButton-root),
|
||||
.set-new-password-page button:not(.MuiIconButton-root),
|
||||
.password-confirmed-page button:not(.MuiIconButton-root),
|
||||
.forgot-password-page button:not(.MuiIconButton-root),
|
||||
.check-email-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.register-page svg rect,
|
||||
.login-page svg rect {
|
||||
fill: none;
|
||||
}
|
||||
.register-form,
|
||||
.login-form {
|
||||
margin-top: 95px;
|
||||
}
|
||||
|
||||
.set-new-password-form,
|
||||
.password-confirmed-form,
|
||||
.forgot-password-form,
|
||||
.check-email-form {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
.set-new-password-page p.MuiTypography-root,
|
||||
.password-confirmed-page p.MuiTypography-root,
|
||||
.forgot-password-page p.MuiTypography-root,
|
||||
.check-email-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.login-page .MuiFormControlLabel-root .MuiButtonBase-root,
|
||||
.set-new-password-page button:not(.MuiIconButton-root) svg,
|
||||
.password-confirmed-page button:not(.MuiIconButton-root) svg,
|
||||
.forgot-password-page button svg,
|
||||
.check-email-page button svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.register-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root,
|
||||
.set-new-password-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root,
|
||||
.password-confirmed-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* REGISTER */
|
||||
.register-page h1.MuiTypography-root {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* ///// */
|
||||
/* LOGIN */
|
||||
/* ///// */
|
||||
.login-page span:not(.MuiTypography-root):not(.MuiButtonBase-root) {
|
||||
color: var(--env-var-color-3);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root {
|
||||
margin: 0;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root span:not(.Mui-checked) svg {
|
||||
fill: var(--env-var-color-4);
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root svg {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root .MuiTypography-root {
|
||||
color: var(--env-var-color-5);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.google-enter {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* /////////// */
|
||||
/* Check Email */
|
||||
/* /////////// */
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
.check-email-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.check-email-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.check-email-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.check-email-page p.MuiTypography-root,
|
||||
.check-email-page button,
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-weight: 600;
|
||||
}
|
||||
.check-email-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.check-email-page button svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.check-email-form {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
@@ -1,522 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Button from "../../Components/Button/";
|
||||
import ButtonSpinner from "../../Components/ButtonSpinner";
|
||||
import Link from "../../Components/Link";
|
||||
import {
|
||||
useTheme,
|
||||
Switch,
|
||||
Checkbox,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
FormControlLabel,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Tab,
|
||||
Tabs,
|
||||
Typography,
|
||||
Stack,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import { ColoredLabel, StatusLabel } from "../../Components/Label/";
|
||||
import Avatar from "../../Components/Avatar/";
|
||||
import ProgressStepper from "../../Components/ProgressStepper";
|
||||
import avatarImage from "../../assets/Images/avatar_placeholder.png";
|
||||
import Section from "../../Components/Section";
|
||||
import { DataGrid } from "@mui/x-data-grid";
|
||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||
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 ImageIcon from "@mui/icons-material/Image";
|
||||
|
||||
// Redux
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { getMonitors } from "../../Features/Monitors/monitorsSlice";
|
||||
import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
|
||||
import ImageField from "../../Components/Inputs/Image";
|
||||
import ProgressUpload from "../../Components/ProgressBars";
|
||||
import Alert from "../../Components/Alert";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
const cols = [
|
||||
{
|
||||
field: "name",
|
||||
headerName: "Name",
|
||||
renderCell: (params) => {
|
||||
return (
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<Avatar
|
||||
src={params.value.avatarImage}
|
||||
firstName={params.value.firstName}
|
||||
lastName={params.value.lastName}
|
||||
/>
|
||||
<div style={{ marginLeft: "1rem" }}>
|
||||
{params.value.firstName} {params.value.lastName}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
flex: 1,
|
||||
},
|
||||
{
|
||||
field: "status",
|
||||
headerName: "Status",
|
||||
renderCell: (params) => {
|
||||
return <StatusLabel status={params.value} />;
|
||||
},
|
||||
flex: 1,
|
||||
},
|
||||
{ field: "role", headerName: "Role", flex: 1 },
|
||||
{ field: "team", headerName: "Team", flex: 1 },
|
||||
{ field: "hireDate", headerName: "Hire date", flex: 1 },
|
||||
];
|
||||
|
||||
const rows = ((count) => {
|
||||
const arr = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
let row = {
|
||||
id: i,
|
||||
name: {
|
||||
avatarImage: i % 2 === 0 ? avatarImage : null,
|
||||
firstName: "Placeholder Name",
|
||||
lastName: i.toString(),
|
||||
},
|
||||
status: "Active",
|
||||
role: "Product Designer",
|
||||
team: "Marketing",
|
||||
hireDate: new Date().toLocaleDateString(),
|
||||
};
|
||||
arr.push(row);
|
||||
}
|
||||
return arr;
|
||||
})(100);
|
||||
|
||||
const steps = [
|
||||
{ label: "Your details", content: "Please provide your name and email" },
|
||||
{ label: "Company details", content: "A few details about your company" },
|
||||
{ label: "Invite your team", content: "Start collaborating with your team" },
|
||||
];
|
||||
|
||||
const demoMonitors = [
|
||||
{ id: 0, name: "Google", isActive: true },
|
||||
{ id: 1, name: "Yahoo", isActive: false },
|
||||
{ id: 2, name: "Reddit", isActive: true },
|
||||
];
|
||||
|
||||
const Demo = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [radio, setRadio] = React.useState(1);
|
||||
const [tab, setTab] = React.useState("departments");
|
||||
const [date, setDate] = React.useState("Pick a date!");
|
||||
|
||||
const handleRadio = (event) => {
|
||||
setRadio(event.target.value);
|
||||
};
|
||||
|
||||
const handleTab = (event, newValue) => {
|
||||
setTab(newValue);
|
||||
};
|
||||
|
||||
const handleDate = (newValue) => {
|
||||
setDate(newValue.toString());
|
||||
};
|
||||
|
||||
const change = (event, type) => {
|
||||
alert(event.target.checked ? `${type} checked` : `${type} unchecked`);
|
||||
};
|
||||
|
||||
const links = [
|
||||
{
|
||||
name: "Buttons",
|
||||
url: "#buttons",
|
||||
},
|
||||
{
|
||||
name: "Disabled Buttons",
|
||||
url: "#disabled-buttons",
|
||||
},
|
||||
{
|
||||
name: "Labels",
|
||||
url: "#labels",
|
||||
},
|
||||
{
|
||||
name: "Status Labels",
|
||||
url: "#status-labels",
|
||||
},
|
||||
{
|
||||
name: "Avatar",
|
||||
url: "#avatar",
|
||||
},
|
||||
{
|
||||
name: "Switches",
|
||||
url: "#switches",
|
||||
},
|
||||
{
|
||||
name: "Checkboxes",
|
||||
url: "#checkboxes",
|
||||
},
|
||||
{
|
||||
name: "Radio",
|
||||
url: "#radio",
|
||||
},
|
||||
{
|
||||
name: "Table",
|
||||
url: "#table",
|
||||
},
|
||||
{
|
||||
name: "Tabs",
|
||||
url: "#tabs",
|
||||
},
|
||||
{
|
||||
name: "Date Picker",
|
||||
url: "#date-picker",
|
||||
},
|
||||
{
|
||||
name: "Stepper",
|
||||
url: "#stepper",
|
||||
},
|
||||
{
|
||||
name: "Section",
|
||||
url: "#section",
|
||||
},
|
||||
];
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
// *********************************
|
||||
// Redux Demo
|
||||
// *********************************
|
||||
const monitorState = useSelector((state) => state.monitors);
|
||||
const { monitors, msg } = monitorState;
|
||||
|
||||
//Button Spinner state
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const handleButtonSpinnerClick = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 4000);
|
||||
};
|
||||
|
||||
//fields
|
||||
const [visibility, setVisibility] = useState(false);
|
||||
return (
|
||||
<div>
|
||||
<div style={{ padding: "4rem", border: "1px solid black" }}>
|
||||
<Typography variant="h4">Redux Demo</Typography>
|
||||
<Typography variant="h6">Monitors</Typography>
|
||||
<table
|
||||
style={{ border: "1px solid black", borderCollapse: "collapse" }}
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style={{ border: "1px solid black" }}>Name</th>
|
||||
<th style={{ border: "1px solid black" }}>URL</th>
|
||||
</tr>
|
||||
{monitors &&
|
||||
monitors.map((monitor) => {
|
||||
return (
|
||||
<tr key={monitor._id}>
|
||||
<td style={{ border: "1px solid black" }}>
|
||||
{monitor.name}
|
||||
</td>
|
||||
<td style={{ border: "1px solid black" }}>{monitor.url}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Message: {msg}</p>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Get Monitors"
|
||||
onClick={() => {
|
||||
dispatch(getMonitorsByUserId("User ID Here"));
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ul style={{ listStyle: "none" }}>
|
||||
{links.map((link) => (
|
||||
<li key={link.url}>
|
||||
<Link level="primary" label={link.name} url={link.url} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="buttons">Buttons</h4>
|
||||
<div>
|
||||
<Button level="primary" label="Primary" />
|
||||
<Button level="secondary" label="Secondary" />
|
||||
<Button level="tertiary" label="Tertiary" />
|
||||
<Button level="error" label="Error" />
|
||||
<Button level="imageTertiary" label="Image Button" img={<AddIcon />} />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="disabled-buttons">Disabled Buttons</h4>
|
||||
<div>
|
||||
<Button level="primary" label="Primary" disabled />
|
||||
<Button level="secondary" label="Secondary" disabled />
|
||||
<Button level="tertiary" label="Tertiary" disabled />
|
||||
<Button level="error" label="Error" disabled />
|
||||
</div>
|
||||
<div>
|
||||
<Link
|
||||
level="tertiary"
|
||||
label="Tertiary Link"
|
||||
url={"https://www.google.com"}
|
||||
/>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="labels">Labels</h4>
|
||||
<div>
|
||||
<ColoredLabel label="Label" color={theme.palette.labelGray.color} />
|
||||
<ColoredLabel label="Label" color={theme.palette.labelPurple.color} />
|
||||
<ColoredLabel label="Label" color={theme.palette.labelGreen.color} />
|
||||
<ColoredLabel label="Label" color={theme.palette.labelOrange.color} />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="status-labels">Status Lables</h4>
|
||||
<div>
|
||||
<StatusLabel status="Seen" />
|
||||
<StatusLabel status="Waiting" />
|
||||
<StatusLabel status="New" />
|
||||
<StatusLabel status="Active" />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="avatar">Avatar</h4>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Avatar src={avatarImage} firstName="Alex" lastName="Holliday" />
|
||||
<Avatar firstName="Alex" lastName="Holliday" />
|
||||
<Avatar src={avatarImage} firstName="Alex" lastName="Holliday" small />
|
||||
<Avatar firstName="Alex" lastName="Holliday" small />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="switches">Switches</h4>
|
||||
<div>
|
||||
<Switch onChange={(event) => change(event, "Switch")} />
|
||||
<Switch size="small" />
|
||||
<Switch disabled />
|
||||
<Switch checked />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="checkboxes">Checkboxes</h4>
|
||||
<div>
|
||||
<Checkbox onChange={(event) => change(event, "Checkbox")} />
|
||||
<Checkbox size="small" />
|
||||
<Checkbox disabled />
|
||||
<Checkbox checked />
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="radio">Radio</h4>
|
||||
<div>
|
||||
<FormControl>
|
||||
<FormLabel>Demo Radio</FormLabel>
|
||||
<RadioGroup value={radio} onChange={handleRadio}>
|
||||
<div>
|
||||
<FormControlLabel value={1} control={<Radio />} label="1" />
|
||||
<FormControlLabel value={2} control={<Radio />} label="2" />
|
||||
<FormControlLabel
|
||||
value={3}
|
||||
control={<Radio size="small" />}
|
||||
label="3"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={4}
|
||||
control={<Radio disabled />}
|
||||
label="4"
|
||||
/>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="table">Table</h4>
|
||||
<div style={{ width: "75vw" }}>
|
||||
<DataGrid
|
||||
autoHeight
|
||||
columns={cols}
|
||||
rows={rows}
|
||||
initialState={{
|
||||
pagination: {
|
||||
paginationModel: { page: 0, pageSize: 10 },
|
||||
},
|
||||
}}
|
||||
pageSizeOptions={[5, 10]}
|
||||
/>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="tabs">Tabs</h4>
|
||||
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||
{" "}
|
||||
<Tabs value={tab} onChange={handleTab}>
|
||||
<Tab label="My details" value="details" />
|
||||
<Tab label="My team" value="team" />
|
||||
<Tab label="Departments" value="departments" />
|
||||
<Tab label="Approvals" value="approvals" />
|
||||
</Tabs>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="date-picker">Date Picker</h4>
|
||||
<div>
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<DatePicker onChange={handleDate} />
|
||||
</LocalizationProvider>
|
||||
<h4>{date}</h4>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="stepper">Stepper</h4>
|
||||
<div>
|
||||
<ProgressStepper steps={steps}></ProgressStepper>
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="section">Section</h4>
|
||||
<Section monitors={demoMonitors} />
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="section">Loading Buttons</h4>
|
||||
<Stack direction="row" justifyContent="center" spacing={3}>
|
||||
<ButtonSpinner
|
||||
level="primary"
|
||||
label="Submit"
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ButtonSpinner
|
||||
level="secondary"
|
||||
label="Fetch Data"
|
||||
loadingText="Fetching..."
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ButtonSpinner
|
||||
level="tertiary"
|
||||
label="Add"
|
||||
loadingText="Adding..."
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ButtonSpinner
|
||||
level="primary"
|
||||
label="Upload"
|
||||
position="start"
|
||||
img={<UploadIcon />}
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ButtonSpinner
|
||||
level="secondary"
|
||||
label="Send"
|
||||
position="end"
|
||||
img={<SendIcon />}
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<ButtonSpinner
|
||||
level="error"
|
||||
label="Disabled"
|
||||
onClick={handleButtonSpinnerClick}
|
||||
isLoading={isLoading}
|
||||
disabled={true}
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<Stack justifyContent="center" alignItems="center">
|
||||
<ImageField
|
||||
id="test-image-field"
|
||||
onChange={() => console.log("changed")}
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<Stack justifyContent="center" alignItems="center">
|
||||
<ProgressUpload
|
||||
icon={<ImageIcon />}
|
||||
label="image.jpg"
|
||||
size="2 MB"
|
||||
progress={50}
|
||||
onClick={() => console.log("click")}
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<Stack direction="row" gap="10px" flexWrap="wrap">
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
title="SSO login"
|
||||
body="Since you logged in via SSO, you cannot reset or modify your password."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="warning"
|
||||
body="New password must contain at least 8 characters and must have at least one uppercase letter, one number and one symbol."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="error"
|
||||
title="Error"
|
||||
body="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
title="We've just released a new feature"
|
||||
body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor."
|
||||
isToast={true}
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px">
|
||||
<Alert
|
||||
variant="info"
|
||||
body="Your password is incorrect."
|
||||
isToast={true}
|
||||
hasIcon={false}
|
||||
/>
|
||||
</Box>
|
||||
<Box width="500px" mt="5px">
|
||||
<Button
|
||||
level="primary"
|
||||
label="Toast"
|
||||
onClick={() =>
|
||||
createToast({
|
||||
variant: "info",
|
||||
body: "Your password is incorrect.",
|
||||
hasIcon: false,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<Stack direction="row" justifyContent="center" gap="20px">
|
||||
<Field type="text" label="Name" placeholder="Enter a name" />
|
||||
<Field
|
||||
type="email"
|
||||
label="Email"
|
||||
isRequired={true}
|
||||
placeholder="name.surname@companyname.com"
|
||||
error="This is an error message."
|
||||
/>
|
||||
<Field
|
||||
type="password"
|
||||
label="Password"
|
||||
isRequired={true}
|
||||
placeholder="Create a password"
|
||||
/>
|
||||
<Field
|
||||
type="url"
|
||||
label="Website"
|
||||
placeholder="google.com"
|
||||
/>
|
||||
</Stack>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default Demo;
|
||||
@@ -1,31 +0,0 @@
|
||||
.forgot-password-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.forgot-password-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.forgot-password-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.forgot-password-page p.MuiTypography-root,
|
||||
.forgot-password-page button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.forgot-password-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.forgot-password-page button svg{
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.forgot-password-form {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
.login-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
.login-page svg rect {
|
||||
fill: none;
|
||||
}
|
||||
.login-page p.MuiTypography-root,
|
||||
.login-page span,
|
||||
.login-page button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.login-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.login-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.login-page span:not(.MuiTypography-root):not(.MuiButtonBase-root) {
|
||||
color: var(--env-var-color-3);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root {
|
||||
margin: 0;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root .MuiButtonBase-root {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root span:not(.Mui-checked) svg{
|
||||
fill: var(--env-var-color-4);
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root svg{
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.login-page .MuiFormControlLabel-root .MuiTypography-root {
|
||||
color: var(--env-var-color-5);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* .login-form-inputs .field h3.MuiTypography-root{
|
||||
font-weight: 600;
|
||||
} */
|
||||
|
||||
.login-form{
|
||||
margin-top: 95px;
|
||||
}
|
||||
|
||||
.google-enter {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 10px;
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
import "./index.css";
|
||||
import ConfigBox from "../../Components/ConfigBox";
|
||||
import ConfigBox from "../../../Components/ConfigBox";
|
||||
import React, { useState } from "react";
|
||||
import RadioButton from "../../Components/RadioButton";
|
||||
import CustomizableCheckBox from "../../Components/Checkbox/CustomizableCheckbox";
|
||||
import Button from "../../Components/Button";
|
||||
import RadioButton from "../../../Components/RadioButton";
|
||||
import Button from "../../../Components/Button";
|
||||
import { Box, MenuItem, Select, Stack, Typography } from "@mui/material";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { createMonitorValidation } from "../../Validation/validation";
|
||||
import { createMonitor } from "../../Features/Monitors/monitorsSlice";
|
||||
import { createMonitorValidation } from "../../../Validation/validation";
|
||||
import { createMonitor } from "../../../Features/Monitors/monitorsSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import WestRoundedIcon from "@mui/icons-material/WestRounded";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
import Field from "../../../Components/Inputs/Field";
|
||||
|
||||
const CreateNewMonitor = () => {
|
||||
const CreateMonitor = () => {
|
||||
const MS_PER_MINUTE = 60000;
|
||||
const { user, authToken } = useSelector((state) => state.auth);
|
||||
const dispatch = useDispatch();
|
||||
@@ -81,7 +80,7 @@ const CreateNewMonitor = () => {
|
||||
// }));
|
||||
// };
|
||||
|
||||
const handleCreateNewMonitor = async (event) => {
|
||||
const handleCreateMonitor = async (event) => {
|
||||
event.preventDefault();
|
||||
//obj to submit
|
||||
let monitor = {
|
||||
@@ -126,7 +125,7 @@ const CreateNewMonitor = () => {
|
||||
return (
|
||||
<form
|
||||
className="create-monitor-form"
|
||||
onSubmit={handleCreateNewMonitor}
|
||||
onSubmit={handleCreateMonitor}
|
||||
noValidate
|
||||
spellCheck="false"
|
||||
style={{
|
||||
@@ -441,7 +440,7 @@ const CreateNewMonitor = () => {
|
||||
level="primary"
|
||||
label="Create new monitor"
|
||||
sx={{ width: "210px", fontSize: "var(--env-var-font-size-medium)" }}
|
||||
onClick={handleCreateNewMonitor}
|
||||
onClick={handleCreateMonitor}
|
||||
disabled={Object.keys(errors).length !== 0 && true}
|
||||
/>
|
||||
</div>
|
||||
@@ -449,4 +448,4 @@ const CreateNewMonitor = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateNewMonitor;
|
||||
export default CreateMonitor;
|
||||
@@ -3,12 +3,12 @@ import PropTypes from "prop-types";
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useParams } from "react-router-dom";
|
||||
import axiosInstance from "../../Utils/axiosConfig";
|
||||
import BasicTable from "../../Components/BasicTable";
|
||||
import MonitorDetailsAreaChart from "../../Components/Charts/MonitorDetailsAreaChart";
|
||||
import StatusLabel from "../../Components/StatusLabel";
|
||||
import axiosInstance from "../../../Utils/axiosConfig";
|
||||
import BasicTable from "../../../Components/BasicTable";
|
||||
import MonitorDetailsAreaChart from "../../../Components/Charts/MonitorDetailsAreaChart";
|
||||
import { StatusLabel } from "../../../Components/Label";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
import Button from "../../Components/Button";
|
||||
import Button from "../../../Components/Button";
|
||||
|
||||
const formatDuration = (ms) => {
|
||||
const seconds = Math.floor(ms / 1000);
|
||||
@@ -62,7 +62,7 @@ const DetailsPage = () => {
|
||||
],
|
||||
rows: res.data.data.checks.map((check, idx) => {
|
||||
const params = {
|
||||
status: check.status === true ? "up" : "down",
|
||||
status: check.status === true ? "Up" : "Down",
|
||||
backgroundColor:
|
||||
check.status === true
|
||||
? "var(--env-var-color-20)"
|
||||
@@ -76,7 +76,18 @@ const DetailsPage = () => {
|
||||
return {
|
||||
id: check._id,
|
||||
data: [
|
||||
{ id: idx, data: <StatusLabel params={params} /> },
|
||||
{
|
||||
id: idx,
|
||||
data: (
|
||||
<StatusLabel
|
||||
status={params.status}
|
||||
dot={params.statusDotColor}
|
||||
customStyles={{
|
||||
backgroundColor: params.backgroundColor,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{ id: idx + 1, data: new Date(check.createdAt).toLocaleString() },
|
||||
{ id: idx + 2, data: check.statusCode },
|
||||
],
|
||||
@@ -101,3 +101,105 @@
|
||||
width: 226.8px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
.current-monitors {
|
||||
margin-top: var(--env-var-spacing-2);
|
||||
border: 1px solid #eaecf0;
|
||||
padding: 40px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.current-monitors-title-holder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.current-monitors-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.current-monitors-title {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-right: var(--env-var-spacing-1);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.current-monitors-counter {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2px;
|
||||
min-width: 22px;
|
||||
min-height: 22px;
|
||||
background-color: var(--env-var-color-15);
|
||||
border: 1px solid var(--env-var-color-6);
|
||||
border-radius: 50%;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
|
||||
.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-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-actions {
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tbody-row-cell.actions-cell {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,45 @@
|
||||
import "./index.css";
|
||||
import "./monitors.css";
|
||||
import { useEffect } from "react";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Button from "../../Components/Button";
|
||||
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
|
||||
import SearchTextField from "../../Components/Inputs/Search/SearchTextField";
|
||||
import MonitorTable from "../../Components/MonitorTable";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
|
||||
import OpenInNewPage from "../../assets/icons/open-in-new-page.svg?react";
|
||||
import BasicTable from "../../Components/BasicTable";
|
||||
import { StatusLabel } from "../../Components/Label";
|
||||
import ResponseTimeChart from "../../Components/Charts/ResponseTimeChart";
|
||||
|
||||
/**
|
||||
* Host component.
|
||||
* This subcomponent receives a params object and displays the host details.
|
||||
*
|
||||
* @component
|
||||
* @param {Object} params - An object containing the following properties:
|
||||
* @param {string} params.url - The URL of the host.
|
||||
* @param {string} params.title - The name of the host.
|
||||
* @param {string} params.percentageColor - The color of the percentage text.
|
||||
* @param {number} params.precentage - The percentage to display.
|
||||
* @returns {React.ElementType} Returns a div element with the host details.
|
||||
*/
|
||||
const Host = ({ params }) => {
|
||||
return (
|
||||
<div className="host-row">
|
||||
<a href={params.url} target="_blank" rel="noreferrer">
|
||||
<OpenInNewPage />
|
||||
</a>
|
||||
<div className="host-name">{params.title}</div>
|
||||
<div
|
||||
className="host-percentage"
|
||||
style={{ color: params.percentageColor }}
|
||||
>
|
||||
{params.precentage}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Monitors = () => {
|
||||
const theme = useTheme();
|
||||
@@ -26,6 +57,70 @@ const Monitors = () => {
|
||||
}, 0);
|
||||
|
||||
const down = monitorState.monitors.length - up;
|
||||
|
||||
const data = {
|
||||
cols: [
|
||||
{ id: 1, name: "Host" },
|
||||
{
|
||||
id: 2,
|
||||
name: (
|
||||
<>
|
||||
Status
|
||||
<span>
|
||||
<ArrowDownwardRoundedIcon />
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{ id: 3, name: "Response Time" },
|
||||
{ id: 4, name: "Actions" },
|
||||
],
|
||||
rows: [],
|
||||
};
|
||||
|
||||
data.rows = monitorState.monitors.map((monitor, idx) => {
|
||||
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 {
|
||||
id: monitor._id,
|
||||
handleClick: () => navigate(`/monitors/${monitor._id}`),
|
||||
data: [
|
||||
{ id: idx, data: <Host params={params} /> },
|
||||
{
|
||||
id: idx + 1,
|
||||
data: (
|
||||
<StatusLabel
|
||||
status={params.status}
|
||||
dot={params.statusDotColor}
|
||||
customStyles={{
|
||||
backgroundColor: params.backgroundColor,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{ id: idx + 2, data: <ResponseTimeChart checks={monitor.checks} /> },
|
||||
{ id: idx + 3, data: "TODO" },
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="monitors"
|
||||
@@ -62,11 +157,11 @@ const Monitors = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="current-monitors-search-bar">
|
||||
<SearchTextField />
|
||||
{/* TODO - add search bar */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="monitors-v-gaping" />
|
||||
<MonitorTable monitors={monitorState.monitors} />
|
||||
<BasicTable data={data} paginated={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
.current-monitors {
|
||||
margin-top: var(--env-var-spacing-2);
|
||||
border: 1px solid #eaecf0;
|
||||
padding: 40px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.current-monitors-title-holder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.current-monitors-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.current-monitors-title {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-right: var(--env-var-spacing-1);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.current-monitors-counter {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2px;
|
||||
min-width: 22px;
|
||||
min-height: 22px;
|
||||
background-color: var(--env-var-color-15);
|
||||
border: 1px solid var(--env-var-color-6);
|
||||
border-radius: 50%;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
|
||||
.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-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-actions {
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tbody-row-cell.actions-cell {
|
||||
padding-left: 30px;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
.password-confirmed-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.password-confirmed-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.password-confirmed-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.password-confirmed-page p.MuiTypography-root,
|
||||
.password-confirmed-page button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.password-confirmed-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.password-confirmed-page button:not(.MuiIconButton-root) svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.password-confirmed-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.password-confirmed-form {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import "./playGround.css";
|
||||
import Statistic from "../../Components/Charts/Statistics/Statistic";
|
||||
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
|
||||
|
||||
function PlayGroundCharts() {
|
||||
return (
|
||||
<>
|
||||
<div className="play-ground-charts">
|
||||
<Statistic title="Currently up for" value="4h 30m 2s" />
|
||||
<Statistic title="Last checked" value="15 seconds ago" />
|
||||
<Statistic title="Incidents" value="2" />
|
||||
<Statistic title="Certificate expiry" value="284 days" />
|
||||
</div>
|
||||
<div className="play-ground-charts-spacing" />
|
||||
<div className="play-ground-charts">
|
||||
<ServerStatus title="Up" value="4" state="up" />
|
||||
<ServerStatus title="Down" value="0" state="down" />
|
||||
<ServerStatus title="Paused" value="0" state="pause" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayGroundCharts;
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import DualButtonPopupModal from "../../Components/PopupModals/DualButtonPopupModal/DualButtonPopupModal";
|
||||
import DualButtonPopupModalWithTextfields from "../../Components/PopupModals/DualButtonPopupModalWithTextfields/DualButtonPopupModalWithTextfields";
|
||||
|
||||
function PlayGroundPopupModals() {
|
||||
return (
|
||||
<div style={{ display: "flex" }}>
|
||||
<DualButtonPopupModal
|
||||
subject="Unsaved changes"
|
||||
description="Do you want to save or discard changes?"
|
||||
esc="Discard"
|
||||
save="Save changes"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<DualButtonPopupModalWithTextfields
|
||||
title="Create new organization"
|
||||
esc="Cancel"
|
||||
save="Save"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayGroundPopupModals;
|
||||
@@ -1,34 +0,0 @@
|
||||
import React from "react";
|
||||
import TooltipWithTail from "../../Components/Tooltips/TooltipWithTail/TooltipWithTail";
|
||||
import "./playGround.css";
|
||||
|
||||
function PlayGroundTooltips() {
|
||||
return (
|
||||
<div className="tooltip-playground">
|
||||
<br />
|
||||
<TooltipWithTail
|
||||
placement="left"
|
||||
arrow={true}
|
||||
title="This is a tooltip"
|
||||
text="This is a tooltip"
|
||||
/>
|
||||
<br />
|
||||
<TooltipWithTail placement="top" arrow={true} text="This is a tooltip" />
|
||||
<br />
|
||||
<TooltipWithTail
|
||||
placement="bottom"
|
||||
arrow={false}
|
||||
text="This is a tooltip"
|
||||
/>
|
||||
<br />
|
||||
<TooltipWithTail
|
||||
placement="right"
|
||||
arrow={true}
|
||||
title="This is a tooltip"
|
||||
text="Tooltips are used to describe or identify an element. In most scenarios, tooltips help the user understand meaning, function or alt-text."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayGroundTooltips;
|
||||
@@ -1,73 +0,0 @@
|
||||
import "./playGround.css";
|
||||
import React from "react";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
||||
import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert";
|
||||
import AnnouncementsMessageBar from "../../Components/Announcements/AnnouncementsMessageBar/AnnouncementsMessageBar";
|
||||
import AnnouncementsDualButton from "../../Components/Announcements/AnnouncementsDualButton/AnnouncementsDualButton";
|
||||
import AnnouncementUpdateSubscription from "../../Components/Announcements/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription";
|
||||
|
||||
function PlayGroundAnnouncements() {
|
||||
return (
|
||||
<div className="playground">
|
||||
<AnnouncementsDualButtonWithIcon
|
||||
icon={
|
||||
<div className="info-icon-frame">
|
||||
<InfoOutlinedIcon style={{ fill: "#344054" }} />
|
||||
</div>
|
||||
}
|
||||
subject="We’ve just released a new feature"
|
||||
body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
|
||||
pariatur, ipsum dolor."
|
||||
esc="Dismiss"
|
||||
primary="View changes"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<AnnouncementsDualButtonWithIcon
|
||||
icon={<ComplexAlert theme="red" />}
|
||||
subject="There was a problem with that action"
|
||||
body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
|
||||
pariatur, ipsum dolor."
|
||||
esc="Dismiss"
|
||||
primary="Learn more"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<AnnouncementsDualButtonWithIcon
|
||||
icon={<ComplexAlert theme="green" />}
|
||||
subject="Successfully updated profile"
|
||||
body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
|
||||
pariatur, ipsum dolor."
|
||||
esc="Dismiss"
|
||||
primary="Learn more"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<AnnouncementsDualButton
|
||||
subject="We’ve just released a new feature"
|
||||
body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
|
||||
pariatur, ipsum dolor."
|
||||
esc="Dismiss"
|
||||
primary="View changes"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<AnnouncementsMessageBar message="New employee created successfully" />
|
||||
<br />
|
||||
<br />
|
||||
<AnnouncementUpdateSubscription
|
||||
title="We’ve just released a new update!"
|
||||
text="Check out the all new dashboard view. Pages and now load faster."
|
||||
cancel="Dismiss"
|
||||
positive="Changelog"
|
||||
header="Subscribe to updates"
|
||||
button="Subscribe"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayGroundAnnouncements;
|
||||
@@ -1,89 +0,0 @@
|
||||
import React from "react";
|
||||
import PlayGroundCharts from "./PlayGround-Charts";
|
||||
import PlayGroundPopupModals from "./PlayGround-Popup-Modals";
|
||||
import PlayGroundTooltips from "./PlayGround-Tooltips";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
|
||||
// This Component is just for the development and test
|
||||
// purposes and just to see what my components look like while development
|
||||
// and will be removed in the end
|
||||
function PlayGround() {
|
||||
return (
|
||||
<div>
|
||||
{/* Default state of Email Text Fields */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field
|
||||
type="email"
|
||||
id="outlined-basic"
|
||||
label="Email"
|
||||
placeholder="olivia@untitledui.com"
|
||||
/>
|
||||
{/* Email Text Field when validation error occures */}
|
||||
<Field
|
||||
type="email"
|
||||
id="outlined-basic"
|
||||
label="Email"
|
||||
placeholder="olivia@untitledui.com"
|
||||
error="This is an error message"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
{/* Now, illustration of the Website text fields */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field type="url" label="Website" />
|
||||
<Field type="url" label="Website" hasCopy={true} />
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
{/* Now, illustration of the Description text fields */}
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
maxWidth: "400px",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
<Field
|
||||
type="description"
|
||||
label="Description"
|
||||
placeholder="Enter a description... "
|
||||
/>
|
||||
<Field
|
||||
type="description"
|
||||
label="Description"
|
||||
placeholder="Enter a description... "
|
||||
error="This is an error message"
|
||||
/>
|
||||
</div>
|
||||
<hr />
|
||||
<PlayGroundCharts />
|
||||
<hr />
|
||||
<PlayGroundPopupModals />
|
||||
<hr />
|
||||
<PlayGroundTooltips />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayGround;
|
||||
@@ -1,19 +0,0 @@
|
||||
.play-ground-charts {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.play-ground-charts-spacing {
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.tooltip-playground {
|
||||
margin: auto;
|
||||
padding: 5%;
|
||||
width: 5%;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.playground {
|
||||
padding: 40px;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
.register-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.register-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.register-page p.MuiTypography-root,
|
||||
.register-page span,
|
||||
.register-page button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.register-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.register-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.register-page svg rect {
|
||||
fill: none;
|
||||
}
|
||||
.register-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.register-form {
|
||||
margin-top: 95px;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
.set-new-password-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.set-new-password-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.set-new-password-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.set-new-password-page p.MuiTypography-root,
|
||||
.set-new-password-page button {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.set-new-password-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.set-new-password-page button:not(.MuiIconButton-root) svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.set-new-password-page
|
||||
.MuiFormControl-root:has(#register-password-input)
|
||||
+ span.MuiTypography-root {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.set-new-password-form {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ button:focus-visible {
|
||||
.Toastify__toast-container {
|
||||
width: auto;
|
||||
}
|
||||
.Toastify__toast-body .alert{
|
||||
.Toastify__toast-body .alert {
|
||||
min-width: 150px;
|
||||
}
|
||||
.Toastify [class^="Toastify__toast"] {
|
||||
@@ -140,6 +140,14 @@ button:focus-visible {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.background-pattern-svg {
|
||||
position: absolute;
|
||||
top: -5%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
|
||||
Reference in New Issue
Block a user