diff --git a/Client/src/Components/BasicTable/index.css b/Client/src/Components/BasicTable/index.css
index fd1f75b53..14adc440c 100644
--- a/Client/src/Components/BasicTable/index.css
+++ b/Client/src/Components/BasicTable/index.css
@@ -72,7 +72,7 @@
}
.MuiPaper-root + .MuiPagination-root {
- margin-top: 35px;
+ margin-top: 24px;
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);
diff --git a/Client/src/Components/Charts/MonitorDetails60MinChart/index.jsx b/Client/src/Components/Charts/MonitorDetails60MinChart/index.jsx
new file mode 100644
index 000000000..f7fc0d3d8
--- /dev/null
+++ b/Client/src/Components/Charts/MonitorDetails60MinChart/index.jsx
@@ -0,0 +1,50 @@
+import { BarChart, Bar, Cell, ReferenceLine, Label } from "recharts";
+
+import PropTypes from "prop-types";
+
+const MonitorDetails60MinChart = ({ data }) => {
+ const labelStyle = {
+ fontSize: "10px",
+ fill: "#475467",
+ };
+
+ const color = {
+ true: "var(--env-var-color-23)",
+ false: "var(--env-var-color-24)",
+ undefined: "var(--env-var-color-33)",
+ };
+ return (
+
+
+ {data.map((check, index) => (
+ |
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+MonitorDetails60MinChart.propTypes = {
+ data: PropTypes.array.isRequired,
+};
+
+export default MonitorDetails60MinChart;
diff --git a/Client/src/Pages/Monitors/Details/index.css b/Client/src/Pages/Monitors/Details/index.css
index 359a002bc..127b7377a 100644
--- a/Client/src/Pages/Monitors/Details/index.css
+++ b/Client/src/Pages/Monitors/Details/index.css
@@ -3,12 +3,10 @@
color: var(--env-var-color-1);
font-weight: 600;
}
-.monitor-details h2.MuiTypography-root,
-.monitor-details h6.MuiTypography-root {
+.monitor-details h2.MuiTypography-root {
font-size: var(--env-var-font-size-large);
}
-.monitor-details h2.MuiTypography-root,
-.monitor-details h4.MuiTypography-root {
+.monitor-details h2.MuiTypography-root{
font-weight: 600;
}
.monitor-details h2.MuiTypography-root,
@@ -35,15 +33,21 @@
}
.monitor-details .stat-box {
- flex: 1;
+ flex: 1 20%;
min-width: 100px;
border: solid 1px;
border-radius: var(--env-var-radius-1);
- padding: var(--env-var-spacing-1) 18px;
+ padding: var(--env-var-spacing-1) 16px;
background-color: var(--env-var-color-8);
}
-.monitor-details .stat-box h6.MuiTypography-root {
- margin-bottom: var(--env-var-spacing-1);
+.monitor-details h6.MuiTypography-root {
+ font-size: var(--env-var-font-size-medium-plus);
+}
+.monitor-details h6.MuiTypography-root span.MuiTypography-root {
+ font-style: italic;
+ font-size: var(--env-var-font-size-medium);
+ color: var(--env-var-color-5);
+ opacity: 0.7;
}
.monitor-details button.MuiButtonBase-root,
.monitor-details .stat-box {
diff --git a/Client/src/Pages/Monitors/Details/index.jsx b/Client/src/Pages/Monitors/Details/index.jsx
index 5f3ddf9fc..15cfd2c82 100644
--- a/Client/src/Pages/Monitors/Details/index.jsx
+++ b/Client/src/Pages/Monitors/Details/index.jsx
@@ -17,20 +17,23 @@ import {
formatDurationRounded,
} from "../../../Utils/timeUtils";
import "./index.css";
+import MonitorDetails60MinChart from "../../../Components/Charts/MonitorDetails60MinChart";
const StatBox = ({ title, value }) => {
return (
-
+
{title}
- {value}
+
+ {value}
+
);
};
StatBox.propTypes = {
- title: PropTypes.string,
+ title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
@@ -162,12 +165,12 @@ const DetailsPage = () => {
<>
}
onClick={() => navigate("/monitors")}
sx={{
- backgroundColor: "#f4f4f4",
+ backgroundColor: theme.palette.otherColors.fillGray,
px: theme.gap.ml,
"& svg.MuiSvgIcon-root": {
mr: theme.gap.small,
@@ -176,12 +179,23 @@ const DetailsPage = () => {
}}
/>
-
+
{monitor?.status ? : }
-
- {monitor.url?.replace(/^https?:\/\//, "") || "..."}
-
+
+
+ {monitor.url?.replace(/^https?:\/\//, "") || "..."}
+
+
+
{
Your site is {monitor?.status ? "up" : "down"}.
{" "}
Checking every {formatDurationRounded(monitor?.interval)}.
- Last time checked{" "}
- {formatDurationRounded(monitor?.lastChecked)} ago.
-
+ Avg. Response Time{" "}
+ (24-hr)
+ >
+ }
value={parseFloat(monitor?.avgResponseTime24hours)
.toFixed(2)
.replace(/\.?0+$/, "")}
/>
+ Uptime (24-hr)
+ >
+ }
value={`${parseFloat(monitor?.uptime24Hours)
.toFixed(2)
.replace(/\.?0+$/, "")}%`}
/>
+ Uptime (30-day)
+ >
+ }
value={`${parseFloat(monitor?.uptime30Days)
.toFixed(2)
.replace(/\.?0+$/, "")}%`}
@@ -272,7 +292,7 @@ const DetailsPage = () => {
justifyContent="space-between"
mb={theme.gap.ml}
>
-
+
Response Times
@@ -308,7 +328,15 @@ const DetailsPage = () => {
/>
-
+
diff --git a/Client/src/index.css b/Client/src/index.css
index 9e404d61c..58e26ed71 100644
--- a/Client/src/index.css
+++ b/Client/src/index.css
@@ -58,6 +58,7 @@
--env-var-color-30: #fcfcfd;
--env-var-color-31: #1a1919;
--env-var-color-32: #f5f5f5;
+ --env-var-color-33: rgba(83, 83, 83, 0.1);
--env-var-radius-1: 4px;
--env-var-radius-2: 8px;
diff --git a/Server/db/mongo/modules/monitorModule.js b/Server/db/mongo/modules/monitorModule.js
index 1d53db978..65b20d471 100644
--- a/Server/db/mongo/modules/monitorModule.js
+++ b/Server/db/mongo/modules/monitorModule.js
@@ -126,10 +126,22 @@ const getIncidents = (checks) => {
* @param {Array} checks Array of check objects.
* @returns {Array} Array of booleans representing up/down.
*/
-const getStatusBarValues = (checks) => {
- return checks.map((check) => {
- return check.status;
+const getStatusBarValues = (monitor, checks) => {
+ const checksIn60Mins = Math.floor((60 * 60 * 1000) / monitor.interval);
+ const noBlankChecks = checksIn60Mins - checks.length;
+
+ const statusBarValues = checks.map((check) => {
+ return {
+ status: check.status,
+ responseTime: check.responseTime,
+ value: 75,
+ };
});
+
+ for (let i = 0; i < noBlankChecks; i++) {
+ statusBarValues.push({ status: undefined, responseTime: 0, value: 75 });
+ }
+ return statusBarValues.reverse();
};
/**
* Get stats by monitor ID
@@ -205,7 +217,7 @@ const getMonitorStatsById = async (req) => {
getAverageResponseTime24Hours(checks24Hours);
monitorStats.uptime24Hours = getUptimePercentage(checks24Hours);
monitorStats.uptime30Days = getUptimePercentage(checks30Days);
- monitorStats.statusBar = getStatusBarValues(checks60Mins);
+ monitorStats.statusBar = getStatusBarValues(monitor, checks60Mins);
}
//Get checks for dateRange