mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-20 08:39:43 -06:00
Merge pull request #610 from bluewave-labs/feat/fe/monitor-details-stats
Feat/fe/monitor details stats
This commit is contained in:
@@ -113,6 +113,7 @@ const DetailsPage = () => {
|
||||
const { monitorId } = useParams();
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
const [dateRange, setDateRange] = useState("day");
|
||||
const [certificateExpiry, setCertificateExpiry] = useState("N/A");
|
||||
const navigate = useNavigate();
|
||||
|
||||
const fetchMonitor = useCallback(async () => {
|
||||
@@ -136,10 +137,23 @@ const DetailsPage = () => {
|
||||
fetchMonitor();
|
||||
}, [fetchMonitor]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCertificate = async () => {
|
||||
const res = await axiosInstance.get(
|
||||
`/monitors/certificate/${monitorId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
setCertificateExpiry(res.data.data.certificateDate);
|
||||
};
|
||||
fetchCertificate();
|
||||
}, [authToken, monitorId]);
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
let loading = Object.keys(monitor).length === 0;
|
||||
|
||||
return (
|
||||
<Box className="monitor-details">
|
||||
{loading ? (
|
||||
@@ -222,6 +236,35 @@ const DetailsPage = () => {
|
||||
value={`${formatDuration(monitor?.lastChecked)} ago`}
|
||||
/>
|
||||
<StatBox title="Incidents" value={monitor?.incidents} />
|
||||
<StatBox title="Certificate Expiry" value={certificateExpiry} />
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.large}
|
||||
>
|
||||
<StatBox
|
||||
title="Latest response time"
|
||||
value={monitor?.latestResponseTime}
|
||||
/>
|
||||
<StatBox
|
||||
title="Average Repsonse Time (24 hours)"
|
||||
value={parseFloat(monitor?.avgResponseTime24hours)
|
||||
.toFixed(2)
|
||||
.replace(/\.?0+$/, "")}
|
||||
/>
|
||||
<StatBox
|
||||
title="Uptime (24 hours)"
|
||||
value={`${parseFloat(monitor?.uptime24Hours)
|
||||
.toFixed(2)
|
||||
.replace(/\.?0+$/, "")}%`}
|
||||
/>
|
||||
<StatBox
|
||||
title="Uptime(30 days)"
|
||||
value={`${parseFloat(monitor?.uptime30Days)
|
||||
.toFixed(2)
|
||||
.replace(/\.?0+$/, "")}%`}
|
||||
/>
|
||||
</Stack>
|
||||
<Box>
|
||||
<Stack
|
||||
@@ -266,7 +309,9 @@ const DetailsPage = () => {
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
<Box sx={{ height: "200px" }}>
|
||||
<MonitorDetailsAreaChart checks={monitor.checks.reverse()} />
|
||||
<MonitorDetailsAreaChart
|
||||
checks={[...monitor.checks].reverse()}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Stack gap={theme.gap.ml}>
|
||||
|
||||
@@ -6,11 +6,9 @@ import { useTheme } from "@emotion/react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import {
|
||||
formatDate,
|
||||
formatDuration,
|
||||
formatDurationRounded,
|
||||
} from "../../../Utils/timeUtils";
|
||||
import { getLastChecked } from "../../../Utils/monitorUtils";
|
||||
import axiosInstance from "../../../Utils/axiosConfig";
|
||||
import Button from "../../../Components/Button";
|
||||
import WestRoundedIcon from "@mui/icons-material/WestRounded";
|
||||
|
||||
@@ -7,6 +7,7 @@ const {
|
||||
getMonitorsByUserIdQueryValidation,
|
||||
} = require("../validation/joi");
|
||||
|
||||
const sslChecker = require("ssl-checker");
|
||||
const SERVICE_NAME = "monitorController";
|
||||
const { errorMessages, successMessages } = require("../utils/messages");
|
||||
const { runInNewContext } = require("vm");
|
||||
@@ -65,6 +66,41 @@ const getMonitorStatsById = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getMonitorCertificate = async (req, res, next) => {
|
||||
try {
|
||||
//validation
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
}
|
||||
|
||||
try {
|
||||
const monitor = await req.db.getMonitorById(req, res);
|
||||
const monitorUrl = new URL(monitor.url);
|
||||
const certificate = await sslChecker(monitorUrl.hostname);
|
||||
if (certificate && certificate.validTo) {
|
||||
return res.json({
|
||||
success: true,
|
||||
msg: successMessages.MONITOR_CERTIFICATE,
|
||||
data: {
|
||||
certificateDate: new Date(certificate.validTo).toLocaleDateString(),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return res.json({
|
||||
success: true,
|
||||
msg: successMessages.MONITOR_CERTIFICATE,
|
||||
data: { certificateDate: "N/A" },
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns monitor with matching ID
|
||||
* @async
|
||||
@@ -302,6 +338,7 @@ const editMonitor = async (req, res, next) => {
|
||||
module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorStatsById,
|
||||
getMonitorCertificate,
|
||||
getMonitorById,
|
||||
getMonitorsByUserId,
|
||||
createMonitor,
|
||||
|
||||
@@ -57,6 +57,7 @@ const CheckSchema = mongoose.Schema(
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
|
||||
expiry: {
|
||||
type: Date,
|
||||
default: Date.now,
|
||||
|
||||
14
Server/package-lock.json
generated
14
Server/package-lock.json
generated
@@ -27,6 +27,7 @@
|
||||
"nodemailer": "^6.9.14",
|
||||
"ping": "0.4.4",
|
||||
"sharp": "0.33.4",
|
||||
"ssl-checker": "2.0.10",
|
||||
"winston": "^3.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -983,9 +984,10 @@
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz",
|
||||
"integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
@@ -5026,6 +5028,12 @@
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ssl-checker": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/ssl-checker/-/ssl-checker-2.0.10.tgz",
|
||||
"integrity": "sha512-SS6rrZocToJWHM1p6iVNb583ybB3UqT1fymCHSWuEdXDUqKA6O1D5Fb8KJVmhj3XKXE82IEWcr+idJrc4jUzFQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"nodemailer": "^6.9.14",
|
||||
"ping": "0.4.4",
|
||||
"sharp": "0.33.4",
|
||||
"ssl-checker": "2.0.10",
|
||||
"winston": "^3.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -5,6 +5,7 @@ const Monitor = require("../models/Monitor");
|
||||
|
||||
router.get("/", monitorController.getAllMonitors);
|
||||
router.get("/stats/:monitorId", monitorController.getMonitorStatsById);
|
||||
router.get("/certificate/:monitorId", monitorController.getMonitorCertificate);
|
||||
router.get("/:monitorId", monitorController.getMonitorById);
|
||||
router.get("/user/:userId", monitorController.getMonitorsByUserId);
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ const successMessages = {
|
||||
MONITOR_CREATE: "Monitor created successfully",
|
||||
MONITOR_DELETE: "Monitor deleted successfully",
|
||||
MONITOR_EDIT: "Monitor edited successfully",
|
||||
MONITOR_CERTIFICATE: "Got monitor certificate successfully",
|
||||
|
||||
//Job Queue
|
||||
JOB_QUEUE_DELETE_JOB: "Job removed successfully",
|
||||
|
||||
Reference in New Issue
Block a user