120 lines
3.8 KiB
React
120 lines
3.8 KiB
React
import "./index.css";
|
|
import { useEffect } from "react";
|
|
import { useSelector, useDispatch } from "react-redux";
|
|
import { getUptimeMonitorsByTeamId } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
|
import { useNavigate } from "react-router-dom";
|
|
import Button from "../../../Components/Button";
|
|
import { useTheme } from "@emotion/react";
|
|
import BasicTable from "../../../Components/BasicTable";
|
|
import { Box, Stack, Typography } from "@mui/material";
|
|
import PropTypes from "prop-types";
|
|
import SkeletonLayout from "./skeleton";
|
|
import Fallback from "./fallback";
|
|
import StatusBox from "./StatusBox";
|
|
import { buildData } from "./monitorData";
|
|
|
|
const Monitors = ({ isAdmin }) => {
|
|
const theme = useTheme();
|
|
const navigate = useNavigate();
|
|
const monitorState = useSelector((state) => state.uptimeMonitors);
|
|
const authState = useSelector((state) => state.auth);
|
|
const dispatch = useDispatch({});
|
|
|
|
useEffect(() => {
|
|
dispatch(getUptimeMonitorsByTeamId(authState.authToken));
|
|
}, [authState.authToken, dispatch]);
|
|
|
|
const monitorStats = monitorState.monitors.reduce(
|
|
(acc, monitor) => {
|
|
if (monitor.isActive === false) {
|
|
acc["paused"] += 1;
|
|
} else if (monitor.status === true) {
|
|
acc["up"] += 1;
|
|
} else {
|
|
acc["down"] += 1;
|
|
}
|
|
return acc;
|
|
},
|
|
{ paused: 0, up: 0, down: 0 }
|
|
);
|
|
|
|
const data = buildData(monitorState.monitors, isAdmin, navigate);
|
|
|
|
let loading = monitorState.isLoading && monitorState.monitors.length === 0;
|
|
|
|
return (
|
|
<Stack className="monitors" gap={theme.gap.large}>
|
|
{loading ? (
|
|
<SkeletonLayout />
|
|
) : (
|
|
<>
|
|
<Stack
|
|
direction="row"
|
|
justifyContent="space-between"
|
|
alignItems="center"
|
|
>
|
|
<Typography
|
|
component="h1"
|
|
sx={{ lineHeight: 1, alignSelf: "flex-end" }}
|
|
>
|
|
Hello, {authState.user.firstName}
|
|
</Typography>
|
|
{isAdmin && monitorState.monitors?.length !== 0 && (
|
|
<Button
|
|
level="primary"
|
|
label="Create monitor"
|
|
onClick={() => {
|
|
navigate("/monitors/create");
|
|
}}
|
|
sx={{ fontWeight: 500 }}
|
|
/>
|
|
)}
|
|
</Stack>
|
|
|
|
{monitorState.monitors?.length === 0 && (
|
|
<Fallback isAdmin={isAdmin} />
|
|
)}
|
|
|
|
{monitorState.monitors?.length !== 0 && (
|
|
<>
|
|
<Stack
|
|
gap={theme.gap.large}
|
|
direction="row"
|
|
justifyContent="space-between"
|
|
>
|
|
<StatusBox title="up" value={monitorStats.up} />
|
|
<StatusBox title="down" value={monitorStats.down} />
|
|
<StatusBox title="paused" value={monitorStats.paused} />
|
|
</Stack>
|
|
<Box
|
|
flex={1}
|
|
p={theme.gap.lgplus}
|
|
border={1}
|
|
borderColor={theme.palette.otherColors.graishWhite}
|
|
backgroundColor={theme.palette.otherColors.white}
|
|
sx={{
|
|
borderRadius: `${theme.shape.borderRadius}px`,
|
|
}}
|
|
>
|
|
<Stack direction="row" alignItems="center" mb={theme.gap.large}>
|
|
<Typography component="h2">Current monitors</Typography>
|
|
<Box className="current-monitors-counter">
|
|
{monitorState.monitors.length}
|
|
</Box>
|
|
{/* TODO - add search bar */}
|
|
</Stack>
|
|
<BasicTable data={data} paginated={true} table={"monitors"} />
|
|
</Box>
|
|
</>
|
|
)}
|
|
</>
|
|
)}
|
|
</Stack>
|
|
);
|
|
};
|
|
|
|
Monitors.propTypes = {
|
|
isAdmin: PropTypes.bool,
|
|
};
|
|
export default Monitors;
|