Refactored pages styling 3/3

This commit is contained in:
Daniel Cojocea committed 2024-08-28 14:42:38 -04:00
1 parent bd1d1d8082
commit a4c5dd3ee7
23 files changed
+611 -577

No files matched your search

+2 -59
View File
@@ -1,52 +1,17 @@
.configure-monitor h1.MuiTypography-root {
font-size: var(--env-var-font-size-large-plus);
color: var(--primary-color);
font-weight: 600;
}
.configure-monitor h2.MuiTypography-root {
font-size: var(--env-var-font-size-large);
font-weight: 600;
}
.configure-monitor h2.MuiTypography-root,
.configure-monitor .config-box p.MuiTypography-root,
.configure-monitor .MuiSelect-select {
color: var(--secondary-color);
}
.configure-monitor .MuiModal-root h2.MuiTypography-root {
color: var(--primary-color);
}
.configure-monitor p.MuiTypography-root,
.configure-monitor .MuiSelect-select {
.configure-monitor p.MuiTypography-root {
font-size: var(--env-var-font-size-medium);
}
.configure-monitor h6.MuiTypography-root {
opacity: 0.6;
}
.configure-monitor h6.MuiTypography-root,
.configure-monitor h1.MuiTypography-root + span.MuiTypography-root {
font-size: var(--env-var-font-size-small-plus);
}
.configure-monitor button.MuiButtonBase-root {
font-size: var(--env-var-font-size-medium);
}
.configure-monitor button.MuiButtonBase-root {
height: var(--env-var-height-2);
}
.configure-monitor .config-box {
border: 1px solid var(--border-color);
border-radius: var(--env-var-radius-1);
background-color: var(--primary-bg);
}
.configure-monitor .config-box > .MuiBox-root,
.configure-monitor .config-box > .MuiStack-root {
flex: 1;
padding: 24px 30px;
padding-bottom: 40px;
}
.configure-monitor .config-box > *:first-child {
flex: 0.7;
border-right: solid 1px var(--border-color);
}
.configure-monitor .MuiStack-root:has(span.MuiTypography-root.input-error) {
position: relative;
}
@@ -54,25 +19,3 @@
position: absolute;
top: 100%;
}
.configure-monitor .MuiInputBase-root:has(> .Mui-disabled) {
background-color: var(--primary-bg-accent);
}
.MuiInputBase-root:has(#monitor-interval) {
height: 34px;
width: 100%;
}
#monitor-interval {
padding: 0 10px;
height: 100%;
display: flex;
align-items: center;
}
.MuiInputBase-root:not(.Mui-focused):has(#monitor-interval):hover fieldset {
border-color: var(--border-color-dark);
}
body:has(.configure-monitor) .select-dropdown .MuiMenuItem-root,
.configure-monitor .select-wrapper .select-component > .MuiSelect-select {
text-transform: lowercase;
}
+59 -55
View File
@@ -6,6 +6,7 @@ import { Box, Modal, Skeleton, Stack, Typography } from "@mui/material";
import { monitorValidation } from "../../../Validation/validation";
import { createToast } from "../../../Utils/toastUtils";
import { logger } from "../../../Utils/Logger";
import { ConfigBox } from "../styled";
import {
updateUptimeMonitor,
getUptimeMonitorsByTeamId,
@@ -45,8 +46,8 @@ const SkeletonLayout = () => {
return (
<>
<Skeleton variant="rounded" width="15%" height={34} />
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
<Stack gap={theme.spacing(20)} mt={theme.spacing(6)}>
<Stack direction="row" gap={theme.spacing(4)} mt={theme.spacing(4)}>
<Skeleton
variant="circular"
style={{ minWidth: 24, minHeight: 24 }}
@@ -56,13 +57,13 @@ const SkeletonLayout = () => {
variant="rounded"
width="50%"
height={24}
sx={{ mb: theme.gap.small }}
sx={{ mb: theme.spacing(4) }}
/>
<Skeleton variant="rounded" width="50%" height={18} />
</Box>
<Stack
direction="row"
gap={theme.gap.medium}
gap={theme.spacing(6)}
sx={{
ml: "auto",
alignSelf: "flex-end",
@@ -209,7 +210,7 @@ const Configure = () => {
let loading = Object.keys(monitor).length === 0;
return (
<Stack className="configure-monitor" gap={theme.gap.large}>
<Stack className="configure-monitor" gap={theme.spacing(12)}>
{loading ? (
<SkeletonLayout />
) : (
@@ -225,20 +226,25 @@ const Configure = () => {
component="form"
noValidate
spellCheck="false"
gap={theme.gap.large}
gap={theme.spacing(12)}
flex={1}
>
<Stack direction="row" gap={theme.gap.xs}>
<Stack direction="row" gap={theme.spacing(2)}>
<PulseDot
color={
monitor?.status
? theme.label.up.dotColor
: theme.label.down.dotColor
? theme.palette.success.main
: theme.palette.error.main
}
/>
<Box>
{parsedUrl?.host ? (
<Typography component="h1" mb={theme.gap.xs} lineHeight={1}>
<Typography
component="h1"
mb={theme.spacing(2)}
lineHeight={1}
color={theme.palette.text.primary}
>
{parsedUrl.host || "..."}
</Typography>
) : (
@@ -246,11 +252,11 @@ const Configure = () => {
)}
<Typography
component="span"
lineHeight={theme.gap.large}
lineHeight={theme.spacing(12)}
sx={{
color: monitor?.status
? "var(--success-color)"
: "var(--error-color)",
? theme.palette.success.main
: theme.palette.error.text,
}}
>
Your site is {monitor?.status ? "up" : "down"}.
@@ -268,12 +274,12 @@ const Configure = () => {
animate="rotate180"
img={<PauseCircleOutlineIcon />}
sx={{
backgroundColor: theme.palette.otherColors.fillGray,
pl: theme.gap.small,
pr: theme.gap.medium,
mr: theme.gap.medium,
backgroundColor: theme.palette.background.main,
pl: theme.spacing(4),
pr: theme.spacing(6),
mr: theme.spacing(6),
"& svg": {
mr: theme.gap.xs,
mr: theme.spacing(2),
},
}}
/>
@@ -282,25 +288,21 @@ const Configure = () => {
label="Remove"
sx={{
boxShadow: "none",
px: theme.gap.ml,
px: theme.spacing(8),
}}
onClick={() => setIsOpen(true)}
/>
</Box>
</Stack>
<Stack
className="config-box"
direction="row"
justifyContent="space-between"
>
<ConfigBox>
<Box>
<Typography component="h2">General settings</Typography>
<Typography component="p" sx={{ mt: theme.gap.xs }}>
<Typography component="p">
Here you can select the URL of the host, together with the
type of monitor.
</Typography>
</Box>
<Stack gap={theme.gap.xl}>
<Stack gap={theme.spacing(20)}>
<Field
type={monitor?.type === "http" ? "url" : "text"}
https={protocol === "https"}
@@ -322,20 +324,16 @@ const Configure = () => {
error={errors["name"]}
/>
</Stack>
</Stack>
<Stack
className="config-box"
direction="row"
justifyContent="space-between"
>
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Incident notifications</Typography>
<Typography component="p" mt={theme.gap.xs}>
<Typography component="p">
When there is an incident, notify users.
</Typography>
</Box>
<Stack gap={theme.gap.medium}>
<Typography component="p" mt={theme.gap.small}>
<Stack gap={theme.spacing(6)}>
<Typography component="p">
When there is a new incident,
</Typography>
<Checkbox
@@ -368,7 +366,7 @@ const Configure = () => {
{monitor?.notifications?.some(
(notification) => notification.type === "emails"
) ? (
<Box mx={`calc(${theme.gap.ml} * 2)`}>
<Box mx={theme.spacing(16)}>
<Field
id="notify-email-list"
type="text"
@@ -376,7 +374,7 @@ const Configure = () => {
value=""
onChange={() => logger.warn("disabled")}
/>
<Typography mt={theme.gap.small}>
<Typography mt={theme.spacing(4)}>
You can separate multiple emails with a comma
</Typography>
</Box>
@@ -384,16 +382,12 @@ const Configure = () => {
""
)}
</Stack>
</Stack>
<Stack
className="config-box"
direction="row"
justifyContent="space-between"
>
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Advanced settings</Typography>
</Box>
<Stack gap={theme.gap.xl}>
<Stack gap={theme.spacing(20)}>
<Select
id="monitor-interval-configure"
label="Check frequency"
@@ -402,12 +396,12 @@ const Configure = () => {
items={frequencies}
/>
</Stack>
</Stack>
</ConfigBox>
<Stack direction="row" justifyContent="flex-end" mt="auto">
<Button
level="primary"
label="Save"
sx={{ px: theme.gap.large }}
sx={{ px: theme.spacing(12) }}
onClick={handleSubmit}
/>
</Stack>
@@ -422,33 +416,43 @@ const Configure = () => {
disablePortal
>
<Stack
gap={theme.gap.xs}
gap={theme.spacing(2)}
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "white",
border: "solid 1px #f2f2f2",
borderRadius: `${theme.shape.borderRadius}px`,
bgcolor: theme.palette.background.main,
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
boxShadow: 24,
p: "30px",
p: theme.spacing(15),
"&:focus": {
outline: "none",
},
}}
>
<Typography id="modal-delete-monitor" component="h2">
<Typography
id="modal-delete-monitor"
component="h2"
fontSize={16}
color={theme.palette.text.primary}
fontWeight={600}
>
Do you really want to delete this monitor?
</Typography>
<Typography id="delete-monitor-confirmation">
<Typography
id="delete-monitor-confirmation"
color={theme.palette.text.tertiary}
>
Once deleted, this monitor cannot be retrieved.
</Typography>
<Stack
direction="row"
gap={theme.gap.small}
mt={theme.gap.large}
gap={theme.spacing(4)}
mt={theme.spacing(12)}
justifyContent="flex-end"
>
<Button
@@ -1,23 +1,11 @@
.create-monitor h1.MuiTypography-root {
font-size: var(--env-var-font-size-large-plus);
color: var(--primary-color);
font-weight: 500;
}
.create-monitor h2.MuiTypography-root {
font-size: var(--env-var-font-size-large);
font-weight: 600;
}
.create-monitor p.MuiTypography-root,
.create-monitor button.MuiButtonBase-root {
font-size: var(--env-var-font-size-medium);
}
.create-monitor h2.MuiTypography-root {
color: var(--secondary-color);
}
.create-monitor h6.MuiTypography-root,
.create-monitor p.MuiTypography-root {
color: var(--secondary-color-light);
}
.create-monitor h6.MuiTypography-root,
.create-monitor .MuiBox-root .field + p.MuiTypography-root {
font-size: var(--env-var-font-size-small-plus);
@@ -26,11 +14,11 @@
.create-monitor button.MuiButtonBase-root {
height: 34px;
}
.create-monitor .error-container {
position: relative;
}
.create-monitor .error-container p.MuiTypography-root.input-error {
color: var(--error-color);
opacity: 0.8;
position: absolute;
top: 0;
@@ -42,30 +30,9 @@
position: absolute;
top: 100%;
}
.create-monitor .config-box {
flex-direction: row;
border: 1px solid var(--border-color);
border-radius: var(--env-var-radius-1);
background-color: var(--primary-bg);
}
.create-monitor .config-box > .MuiBox-root,
.create-monitor .config-box > .MuiStack-root {
flex: 1;
padding: 24px 30px;
padding-bottom: 40px;
}
.create-monitor .config-box > *:first-child {
flex: 0.7;
border-right: solid 1px var(--border-color);
}
.create-monitor .MuiStack-root .MuiButtonGroup-root button {
font-size: var(--env-var-font-size-small);
height: 28px;
padding: 8px;
}
body:has(.create-monitor) .select-dropdown .MuiMenuItem-root,
.create-monitor .select-wrapper .select-component > .MuiSelect-select {
text-transform: lowercase;
}
@@ -1,19 +1,20 @@
import "./index.css";
import { useState } from "react";
import Radio from "../../../Components/Inputs/Radio";
import Button from "../../../Components/Button";
import { Box, ButtonGroup, Stack, Typography } from "@mui/material";
import { useSelector, useDispatch } from "react-redux";
import { monitorValidation } from "../../../Validation/validation";
import { createUptimeMonitor } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
import { useNavigate } from "react-router-dom";
import { useTheme } from "@emotion/react";
import { createToast } from "../../../Utils/toastUtils";
import { logger } from "../../../Utils/Logger";
import { ConfigBox } from "../styled";
import Radio from "../../../Components/Inputs/Radio";
import Button from "../../../Components/Button";
import Field from "../../../Components/Inputs/Field";
import Select from "../../../Components/Inputs/Select";
import Checkbox from "../../../Components/Inputs/Checkbox";
import { createToast } from "../../../Utils/toastUtils";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import { logger } from "../../../Utils/Logger";
import "./index.css";
const CreateMonitor = () => {
const MS_PER_MINUTE = 60000;
@@ -33,7 +34,7 @@ const CreateMonitor = () => {
const [monitor, setMonitor] = useState({
url: "",
name: "",
type: "",
type: "http",
notifications: [],
interval: 1,
});
@@ -144,7 +145,14 @@ const CreateMonitor = () => {
];
return (
<Box className="create-monitor">
<Box
className="create-monitor"
sx={{
"& h1": {
color: theme.palette.text.primary,
},
}}
>
<Breadcrumbs
list={[
{ name: "monitors", path: "/monitors" },
@@ -157,14 +165,14 @@ const CreateMonitor = () => {
onSubmit={handleCreateMonitor}
noValidate
spellCheck="false"
gap={theme.gap.large}
mt={theme.gap.medium}
gap={theme.spacing(12)}
mt={theme.spacing(6)}
>
<Typography component="h1">
<Typography
component="span"
fontSize="inherit"
color={theme.palette.otherColors.bluishGray}
color={theme.palette.text.secondary}
>
Create your{" "}
</Typography>
@@ -172,15 +180,15 @@ const CreateMonitor = () => {
monitor
</Typography>
</Typography>
<Stack className="config-box">
<ConfigBox>
<Box>
<Typography component="h2">General settings</Typography>
<Typography component="p" mt={theme.gap.xs}>
<Typography component="p">
Here you can select the URL of the host, together with the type of
monitor.
</Typography>
</Box>
<Stack gap={theme.gap.xl}>
<Stack gap={theme.spacing(15)}>
<Field
type={monitor.type === "http" ? "url" : "text"}
id="monitor-url"
@@ -202,16 +210,16 @@ const CreateMonitor = () => {
error={errors["name"]}
/>
</Stack>
</Stack>
<Stack className="config-box">
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Checks to perform</Typography>
<Typography component="p" mt={theme.gap.xs}>
<Typography component="p">
You can always add or remove checks after adding your site.
</Typography>
</Box>
<Stack gap={theme.gap.large}>
<Stack gap={theme.gap.medium}>
<Stack gap={theme.spacing(12)}>
<Stack gap={theme.spacing(6)}>
<Radio
id="monitor-checks-http"
title="Website monitoring"
@@ -228,8 +236,7 @@ const CreateMonitor = () => {
label="HTTPS"
onClick={() => setHttps(true)}
sx={{
backgroundColor:
https && theme.palette.otherColors.fillGray,
backgroundColor: https && theme.palette.background.fill,
}}
/>
<Button
@@ -237,8 +244,7 @@ const CreateMonitor = () => {
label="HTTP"
onClick={() => setHttps(false)}
sx={{
backgroundColor:
!https && theme.palette.otherColors.fillGray,
backgroundColor: !https && theme.palette.background.fill,
}}
/>
</ButtonGroup>
@@ -257,7 +263,11 @@ const CreateMonitor = () => {
/>
{errors["type"] ? (
<Box className="error-container">
<Typography component="p" className="input-error">
<Typography
component="p"
className="input-error"
color={theme.palette.error.text}
>
{errors["type"]}
</Typography>
</Box>
@@ -265,15 +275,15 @@ const CreateMonitor = () => {
""
)}
</Stack>
</Stack>
<Stack className="config-box">
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Incident notifications</Typography>
<Typography component="p" mt={theme.gap.xs}>
<Typography component="p">
When there is an incident, notify users.
</Typography>
</Box>
<Stack gap={theme.gap.medium}>
<Stack gap={theme.spacing(6)}>
<Typography component="p">When there is a new incident,</Typography>
<Checkbox
id="notify-sms"
@@ -303,7 +313,7 @@ const CreateMonitor = () => {
{monitor.notifications.some(
(notification) => notification.type === "emails"
) ? (
<Box mx={`calc(${theme.gap.ml} * 2)`}>
<Box mx={theme.spacing(16)}>
<Field
id="notify-email-list"
type="text"
@@ -311,7 +321,7 @@ const CreateMonitor = () => {
value=""
onChange={() => logger.warn("disabled")}
/>
<Typography mt={theme.gap.small}>
<Typography mt={theme.spacing(4)}>
You can separate multiple emails with a comma
</Typography>
</Box>
@@ -319,12 +329,12 @@ const CreateMonitor = () => {
""
)}
</Stack>
</Stack>
<Stack className="config-box">
</ConfigBox>
<ConfigBox>
<Box>
<Typography component="h2">Advanced settings</Typography>
</Box>
<Stack gap={theme.gap.large}>
<Stack gap={theme.spacing(12)}>
<Select
id="monitor-interval"
label="Check frequency"
@@ -332,73 +342,8 @@ const CreateMonitor = () => {
onChange={(event) => handleChange(event, "interval")}
items={frequencies}
/>
{/* TODO */}
{/* <FlexibileTextField
id="monitor-settings-retries"
title="Maximum retries before the service is marked as down"
type="number"
value={advancedSettings.retries}
onChange={(event) =>
handleChange(event, "retries", setAdvancedSettings)
}
/>
<FlexibileTextField
id="monitor-settings-codes"
title="Accepted status codes"
type="number"
value={advancedSettings.codes}
onChange={(event) =>
handleChange(event, "codes", setAdvancedSettings)
}
/>
<FlexibileTextField
id="monitor-settings-redirects"
title="Maximum redirects"
type="number"
value={advancedSettings.redirects}
onChange={(event) =>
handleChange(event, "redirects", setAdvancedSettings)
}
/> */}
</Stack>
</Stack>
{/* TODO */}
{/*
<ConfigBox
leftLayout={
<div className="config-box-desc">
<div className="config-box-desc-title">Proxy settings</div>
</div>
}
rightLayout={
<div className="proxy-setting-config">
<CustomizableCheckBox
id="monitor-proxy-enable"
title="Enable proxy"
isChecked={proxy.enabled}
handleChange={() => handleCheck("enabled", setProxy)}
/>
<FlexibileTextField
id="monitor-proxy-protocol"
title="Proxy protocol"
value={proxy.protocol}
onChange={(event) => handleChange(event, "protocol", setProxy)}
/>
<FlexibileTextField
id="monitor-proxy-address"
title="Proxy address"
value={proxy.address}
onChange={(event) => handleChange(event, "address", setProxy)}
/>
<FlexibileTextField
id="monitor-proxy-port"
title="Proxy port"
value={proxy.proxy_port}
onChange={(event) => handleChange(event, "proxy_port", setProxy)}
/>
</div>
}
/> */}
</ConfigBox>
<Stack direction="row" justifyContent="flex-end">
<Button
id="create-monitor-btn"
+1 -38
View File
@@ -1,25 +1,13 @@
.monitor-details h1.MuiTypography-root {
font-size: var(--env-var-font-size-large-plus);
color: var(--primary-color);
font-weight: 600;
}
.monitor-details h2.MuiTypography-root {
font-size: var(--env-var-font-size-large);
}
.monitor-details h2.MuiTypography-root{
.monitor-details h2.MuiTypography-root {
font-weight: 600;
}
.monitor-details h2.MuiTypography-root,
.monitor-details h4.MuiTypography-root {
color: var(--secondary-color);
}
.monitor-details h6.MuiTypography-root {
color: var(--theme-main);
}
.monitor-details button.MuiButtonBase-root,
.monitor-details h4.MuiTypography-root {
font-size: var(--env-var-font-size-medium);
}
.monitor-details button.MuiButtonBase-root {
height: var(--env-var-height-2);
line-height: 1;
@@ -28,28 +16,3 @@
.monitor-details p.MuiTypography-root span.MuiTypography-root {
font-size: var(--env-var-font-size-small-plus);
}
.monitor-details p.MuiTypography-root {
color: var(--secondary-color-light);
}
.monitor-details .stat-box {
flex: 1 20%;
min-width: 100px;
border: solid 1px;
border-radius: var(--env-var-radius-1);
padding: var(--env-var-spacing-1) 16px;
background-color: var(--primary-bg);
}
.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(--secondary-color);
opacity: 0.7;
}
.monitor-details button.MuiButtonBase-root,
.monitor-details .stat-box {
border-color: var(--border-color);
}
+85 -40
View File
@@ -1,5 +1,5 @@
import { useEffect, useState, useCallback } from "react";
import PropTypes from "prop-types";
import { useEffect, useState, useCallback } from "react";
import { Box, Skeleton, Stack, Typography, useTheme } from "@mui/material";
import { useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
@@ -19,12 +19,41 @@ import PulseDot from "../../../Components/Animated/PulseDot";
import "./index.css";
const StatBox = ({ title, value }) => {
const theme = useTheme();
return (
<Box className="stat-box">
<Typography variant="h6" mb={1} fontWeight={500}>
<Box
className="stat-box"
flex="20%"
minWidth="100px"
px={theme.spacing(8)}
py={theme.spacing(4)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
>
<Typography
variant="h6"
mb={theme.spacing(2)}
fontSize={14}
fontWeight={500}
color={theme.palette.common.main}
sx={{
"& span": {
color: theme.palette.text.accent,
fontSize: 13,
fontStyle: "italic",
},
}}
>
{title}
</Typography>
<Typography variant="h4" fontWeight={500}>
<Typography
variant="h4"
fontWeight={500}
fontSize={13}
color={theme.palette.text.secondary}
>
{value}
</Typography>
</Box>
@@ -47,8 +76,8 @@ const SkeletonLayout = () => {
return (
<>
<Skeleton variant="rounded" width="20%" height={34} />
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
<Stack gap={theme.spacing(20)} mt={theme.spacing(6)}>
<Stack direction="row" gap={theme.spacing(4)} mt={theme.spacing(4)}>
<Skeleton
variant="circular"
style={{ minWidth: 24, minHeight: 24 }}
@@ -59,7 +88,7 @@ const SkeletonLayout = () => {
variant="rounded"
width="50%"
height={18}
sx={{ mt: theme.gap.small }}
sx={{ mt: theme.spacing(4) }}
/>
</Box>
<Skeleton
@@ -72,7 +101,7 @@ const SkeletonLayout = () => {
<Stack
direction="row"
justifyContent="space-between"
gap={theme.gap.large}
gap={theme.spacing(12)}
>
<Skeleton variant="rounded" width="100%" height={80} />
<Skeleton variant="rounded" width="100%" height={80} />
@@ -82,7 +111,7 @@ const SkeletonLayout = () => {
<Stack
direction="row"
justifyContent="space-between"
mb={theme.gap.ml}
mb={theme.spacing(8)}
>
<Skeleton
variant="rounded"
@@ -96,7 +125,7 @@ const SkeletonLayout = () => {
<Skeleton variant="rounded" width="100%" height="100%" />
</Box>
</Box>
<Stack gap={theme.gap.ml}>
<Stack gap={theme.spacing(8)}>
<Skeleton variant="rounded" width="20%" height={24} />
<Skeleton variant="rounded" width="100%" height={200} />
<Skeleton variant="rounded" width="100%" height={50} />
@@ -169,26 +198,33 @@ const DetailsPage = ({ isAdmin }) => {
{ name: "details", path: `/monitors/${monitorId}` },
]}
/>
<Stack gap={theme.gap.large} mt={theme.gap.large}>
<Stack direction="row" gap={theme.gap.xs}>
<Stack gap={theme.spacing(12)} mt={theme.spacing(12)}>
<Stack direction="row" gap={theme.spacing(2)}>
<PulseDot
color={
monitor?.status
? theme.label.up.dotColor
: theme.label.down.dotColor
? theme.palette.success.main
: theme.palette.error.main
}
/>
<Box>
<Typography component="h1" sx={{ lineHeight: 1 }}>
<Typography
component="h1"
color={theme.palette.text.primary}
lineHeight={1}
>
{monitor.url?.replace(/^https?:\/\//, "") || "..."}
</Typography>
<Typography mt={theme.gap.small}>
<Typography
mt={theme.spacing(4)}
color={theme.palette.text.tertiary}
>
<Typography
component="span"
sx={{
color: monitor?.status
? "var(--env-var-color-17)"
: "var(--env-var-color-24)",
? theme.palette.success.main
: theme.palette.success.text,
}}
>
Your site is {monitor?.status ? "up" : "down"}.
@@ -204,8 +240,8 @@ const DetailsPage = ({ isAdmin }) => {
img={
<SettingsIcon
style={{
minWidth: theme.gap.mlplus,
minHeight: theme.gap.mlplus,
minWidth: theme.spacing(10),
minHeight: theme.spacing(10),
}}
/>
}
@@ -213,10 +249,10 @@ const DetailsPage = ({ isAdmin }) => {
sx={{
ml: "auto",
alignSelf: "flex-end",
backgroundColor: "#f4f4f4",
px: theme.gap.medium,
backgroundColor: theme.palette.background.fill,
px: theme.spacing(6),
"& svg": {
mr: "6px",
mr: theme.spacing(3),
},
}}
/>
@@ -225,7 +261,7 @@ const DetailsPage = ({ isAdmin }) => {
<Stack
direction="row"
justifyContent="space-between"
gap={theme.gap.large}
gap={theme.spacing(12)}
flexWrap="wrap"
>
<StatBox
@@ -278,20 +314,29 @@ const DetailsPage = ({ isAdmin }) => {
<Stack
direction="row"
justifyContent="space-between"
mb={theme.gap.ml}
mb={theme.spacing(8)}
>
<Typography component="h2" alignSelf="flex-end">
<Typography
component="h2"
alignSelf="flex-end"
color={theme.palette.text.secondary}
>
Response Times
</Typography>
<ButtonGroup>
<ButtonGroup
sx={{
"& .MuiButtonBase-root": {
borderColor: theme.palette.border.light,
},
}}
>
<Button
level="secondary"
label="Day"
onClick={() => setDateRange("day")}
sx={{
backgroundColor:
dateRange === "day" &&
theme.palette.otherColors.fillGray,
dateRange === "day" && theme.palette.background.fill,
}}
/>
<Button
@@ -300,8 +345,7 @@ const DetailsPage = ({ isAdmin }) => {
onClick={() => setDateRange("week")}
sx={{
backgroundColor:
dateRange === "week" &&
theme.palette.otherColors.fillGray,
dateRange === "week" && theme.palette.background.fill,
}}
/>
<Button
@@ -310,19 +354,18 @@ const DetailsPage = ({ isAdmin }) => {
onClick={() => setDateRange("month")}
sx={{
backgroundColor:
dateRange === "month" &&
theme.palette.otherColors.fillGray,
dateRange === "month" && theme.palette.background.fill,
}}
/>
</ButtonGroup>
</Stack>
<Box
p={theme.gap.mlplus}
pb={theme.gap.xs}
backgroundColor={theme.palette.otherColors.white}
p={theme.spacing(10)}
pb={theme.spacing(2)}
backgroundColor={theme.palette.background.main}
border={1}
borderColor={theme.palette.otherColors.graishWhite}
borderRadius={`${theme.shape.borderRadius}px`}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
sx={{ height: "250px" }}
>
<MonitorDetailsAreaChart
@@ -330,8 +373,10 @@ const DetailsPage = ({ isAdmin }) => {
/>
</Box>
</Box>
<Stack gap={theme.gap.ml}>
<Typography component="h2">History</Typography>
<Stack gap={theme.spacing(8)}>
<Typography component="h2" color={theme.palette.text.secondary}>
History
</Typography>
<PaginationTable monitorId={monitorId} dateRange={dateRange} />
</Stack>
</Stack>
+11 -11
View File
@@ -13,21 +13,21 @@ const StatusBox = ({ title, value }) => {
let color;
let icon;
if (title === "up") {
color = theme.pie.green.stroke;
color = theme.palette.success.main;
icon = (
<Box sx={{ ...sharedStyles, top: 8 }}>
<Arrow />
</Box>
);
} else if (title === "down") {
color = theme.pie.red.stroke;
color = theme.palette.error.text;
icon = (
<Box sx={{ ...sharedStyles, transform: "rotate(180deg)", top: 5 }}>
<Arrow />
</Box>
);
} else if (title === "paused") {
color = theme.pie.yellow.stroke;
color = theme.palette.warning.main;
icon = (
<Box sx={{ ...sharedStyles, top: 12, right: 12 }}>
<ClockSnooze />
@@ -40,11 +40,11 @@ const StatusBox = ({ title, value }) => {
position="relative"
flex={1}
border={1}
borderColor={theme.palette.otherColors.graishWhite}
borderRadius={`${theme.shape.borderRadius}px`}
backgroundColor={theme.palette.otherColors.white}
px={theme.gap.large}
py={theme.gap.ml}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
px={theme.spacing(12)}
py={theme.spacing(8)}
overflow="hidden"
sx={{
"&:hover": {
@@ -67,8 +67,8 @@ const StatusBox = ({ title, value }) => {
textTransform="uppercase"
fontSize={15}
letterSpacing={0.5}
color={theme.palette.otherColors.bluishGray}
mb={theme.gap.ml}
color={theme.palette.text.secondary}
mb={theme.spacing(8)}
sx={{ opacity: 0.6 }}
>
{title}
@@ -87,7 +87,7 @@ const StatusBox = ({ title, value }) => {
component="span"
fontSize={20}
fontWeight={300}
color={theme.palette.otherColors.bluishGray}
color={theme.palette.text.secondary}
sx={{ opacity: 0.3 }}
>
#
+47 -13
View File
@@ -1,5 +1,7 @@
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
import { createToast } from "../../../Utils/toastUtils";
import {
IconButton,
@@ -14,10 +16,8 @@ import {
getUptimeMonitorsByTeamId,
} from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
import Settings from "../../../assets/icons/settings-bold.svg?react";
import { useTheme } from "@emotion/react";
import Button from "../../../Components/Button";
import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom";
const ActionsMenu = ({ monitor, isAdmin }) => {
const [anchorEl, setAnchorEl] = useState(null);
@@ -87,6 +87,30 @@ const ActionsMenu = ({ monitor, isAdmin }) => {
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={(e) => closeMenu(e)}
slotProps={{
paper: {
sx: {
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
boxShadow: theme.shape.boxShadow,
"& ul": {
p: theme.spacing(2.5),
minWidth: "100px",
},
"& li": {
color: theme.palette.text.secondary,
fontSize: 13,
px: theme.spacing(4),
py: theme.spacing(2.5),
borderRadius: theme.shape.borderRadius,
},
"& li:last-of-type": {
color: theme.palette.error.text,
},
},
},
}}
>
{actions.url !== null ? (
<MenuItem
@@ -137,31 +161,35 @@ const ActionsMenu = ({ monitor, isAdmin }) => {
aria-labelledby="modal-delete-monitor"
aria-describedby="delete-monitor-confirmation"
open={isOpen}
onClose={() => setIsOpen(false)}
disablePortal
onClose={(e) => {
e.stopPropagation();
setIsOpen(false);
}}
>
<Stack
gap={theme.gap.xs}
gap={theme.spacing(2)}
color={theme.palette.text.secondary}
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "white",
border: "solid 1px #f2f2f2",
borderRadius: `${theme.shape.borderRadius}px`,
bgcolor: theme.palette.background.main,
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
boxShadow: 24,
p: "30px",
p: theme.spacing(15),
"&:focus": {
outline: "none",
},
}}
>
<Typography id="modal-delete-monitor" component="h2">
<Typography id="modal-delete-monitor" component="h2" fontWeight={600}>
Do you really want to delete this monitor?
</Typography>
<Typography id="delete-monitor-confirmation">
<Typography id="delete-monitor-confirmation" fontSize={13}>
Once deleted, this monitor cannot be retrieved.
</Typography>
<Stack
@@ -173,12 +201,18 @@ const ActionsMenu = ({ monitor, isAdmin }) => {
<Button
level="tertiary"
label="Cancel"
onClick={() => setIsOpen(false)}
onClick={(e) => {
e.stopPropagation();
setIsOpen(false);
}}
/>
<Button
level="error"
label="Delete"
onClick={(e) => handleRemove(e)}
onClick={(e) => {
e.stopPropagation(e);
handleRemove(e);
}}
/>
</Stack>
</Stack>
+7 -6
View File
@@ -11,12 +11,13 @@ const Fallback = ({ isAdmin }) => {
return (
<Stack
alignItems="center"
backgroundColor={theme.palette.otherColors.white}
p={theme.gap.xxl}
gap={theme.gap.xs}
backgroundColor={theme.palette.background.main}
p={theme.spacing(30)}
gap={theme.spacing(2)}
border={1}
borderRadius={`${theme.shape.borderRadius}px`}
borderColor={theme.palette.otherColors.graishWhite}
borderRadius={theme.shape.borderRadius}
borderColor={theme.palette.border.light}
color={theme.palette.text.secondary}
>
<Typography component="h2">No monitors found</Typography>
<Typography>
@@ -29,7 +30,7 @@ const Fallback = ({ isAdmin }) => {
onClick={() => {
navigate("/monitors/create");
}}
sx={{ mt: theme.gap.large }}
sx={{ mt: theme.spacing(12) }}
/>
)}
</Stack>
+1 -1
View File
@@ -1,4 +1,4 @@
import { Box, Stack, Typography } from "@mui/material";
import { Box, Typography } from "@mui/material";
import PropTypes from "prop-types";
/**
* Host component.
-30
View File
@@ -1,16 +1,13 @@
.monitors h1.MuiTypography-root {
font-size: var(--env-var-font-size-large-plus);
color: var(--primary-color);
font-weight: 500;
}
.monitors h2.MuiTypography-root {
font-size: var(--env-var-font-size-large);
color: var(--secondary-color);
font-weight: 500;
}
.monitors p.MuiTypography-root {
font-size: var(--env-var-font-size-medium);
color: var(--secondary-color);
}
.monitors h1.MuiTypography-root + p.MuiTypography-root {
font-size: var(--env-var-font-size-medium-plus);
@@ -28,36 +25,9 @@
padding: 5px;
min-width: 25px;
min-height: 25px;
background-color: var(--unresolved-bg);
border: 1px solid var(--border-color);
border-radius: 50%;
font-size: var(--env-var-font-size-medium);
font-weight: 500;
color: var(--primary-color);
margin-left: 10px;
line-height: 0.8;
}
body:has(.monitors) .actions-menu .MuiPaper-root {
box-shadow: var(--env-var-shadow-1);
border: solid 1px var(--border-color);
border-radius: var(--env-var-radius-1);
gap: 1px;
}
body:has(.monitors) .actions-menu .MuiList-root {
padding: 6px 8px;
min-width: 100px;
}
body:has(.monitors) .actions-menu li.MuiButtonBase-root {
font-size: var(--env-var-font-size-medium);
color: var(--secondary-color);
padding: 5px 8px;
border-radius: var(--env-var-radius-1);
}
body:has(.monitors) .actions-menu li.MuiButtonBase-root:last-of-type {
color: var(--error-color);
}
body:has(.monitors) .actions-menu .MuiModal-root p.MuiTypography-root {
font-size: var(--env-var-font-size-medium);
color: var(--secondary-color-light);
}
+31 -13
View File
@@ -51,7 +51,7 @@ const Monitors = ({ isAdmin }) => {
}
return (
<Stack className="monitors" gap={theme.gap.large}>
<Stack className="monitors" gap={theme.spacing(12)}>
{loading ? (
<SkeletonLayout />
) : (
@@ -65,11 +65,15 @@ const Monitors = ({ isAdmin }) => {
mt={theme.spacing(5)}
>
<Box>
<Typography component="h1" lineHeight={1}>
<Typography
component="h1"
lineHeight={1}
color={theme.palette.text.primary}
>
<Typography
component="span"
fontSize="inherit"
color={theme.palette.otherColors.bluishGray}
color={theme.palette.text.secondary}
>
Good {greeting},{" "}
</Typography>
@@ -85,6 +89,7 @@ const Monitors = ({ isAdmin }) => {
sx={{ opacity: 0.8 }}
lineHeight={1}
fontWeight={300}
color={theme.palette.text.secondary}
>
Here’s an overview of your uptime monitors.
</Typography>
@@ -108,7 +113,7 @@ const Monitors = ({ isAdmin }) => {
{monitorState.monitors?.length !== 0 && (
<>
<Stack
gap={theme.gap.large}
gap={theme.spacing(12)}
direction="row"
justifyContent="space-between"
>
@@ -118,17 +123,30 @@ const Monitors = ({ isAdmin }) => {
</Stack>
<Box
flex={1}
p={theme.gap.lgplus}
p={theme.spacing(16)}
border={1}
borderColor={theme.palette.otherColors.graishWhite}
backgroundColor={theme.palette.otherColors.white}
sx={{
borderRadius: `${theme.shape.borderRadius}px`,
}}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
>
<Stack direction="row" alignItems="center" mb={theme.gap.large}>
<Typography component="h2">Current monitors</Typography>
<Box className="current-monitors-counter">
<Stack
direction="row"
alignItems="center"
mb={theme.spacing(12)}
>
<Typography
component="h2"
color={theme.palette.text.secondary}
>
Current monitors
</Typography>
<Box
className="current-monitors-counter"
color={theme.palette.text.primary}
border={1}
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.unresolved.bg}
>
{monitorState.monitors.length}
</Box>
{/* TODO - add search bar */}
+6 -2
View File
@@ -16,7 +16,7 @@ const SkeletonLayout = () => {
<Skeleton variant="rounded" width="15%" height={36} />
</Stack>
<Stack
gap={theme.gap.large}
gap={theme.spacing(12)}
direction="row"
justifyContent="space-between"
>
@@ -24,7 +24,11 @@ const SkeletonLayout = () => {
<Skeleton variant="rounded" width="100%" height={100} />
<Skeleton variant="rounded" width="100%" height={100} />
</Stack>
<Stack gap={theme.gap.large} p={theme.gap.xl} backgroundColor="#f9fafb">
<Stack
gap={theme.spacing(12)}
p={theme.spacing(20)}
backgroundColor="#f9fafb"
>
<Skeleton variant="rounded" width="50%" height={25} />
<Skeleton variant="rounded" width="100%" height={300} />
<Skeleton variant="rounded" width="100%" height={100} />
+35
View File
@@ -0,0 +1,35 @@
import { Stack, styled } from "@mui/material";
export const ConfigBox = styled(Stack)(({ theme }) => ({
flexDirection: "row",
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
borderRadius: theme.spacing(2),
backgroundColor: theme.palette.background.main,
"& > *": {
paddingTop: theme.spacing(12),
paddingBottom: theme.spacing(18),
},
"& > div:first-of-type": {
flex: 0.7,
borderRight: 1,
borderRightStyle: "solid",
borderRightColor: theme.palette.border.light,
paddingRight: theme.spacing(15),
paddingLeft: theme.spacing(15),
},
"& > div:last-of-type": {
flex: 1,
paddingRight: theme.spacing(20),
paddingLeft: theme.spacing(18),
},
"& h2": {
color: theme.palette.text.secondary,
fontSize: 15,
fontWeight: 600,
},
"& h3, & p": {
color: theme.palette.text.tertiary,
},
}));
+1 -23
View File
@@ -1,23 +1,9 @@
.configure-pagespeed form > .MuiStack-root:nth-child(2) {
background-color: var(--primary-bg);
border: solid 1px var(--border-color);
border-radius: var(--env-var-radius-1);
padding: var(--env-var-font-size-large-plus) var(--env-var-font-size-xlarge);
}
.configure-pagespeed h1.MuiTypography-root {
font-size: var(--env-var-font-size-large-plus);
}
.configure-pagespeed h1.MuiTypography-root,
.configure-pagespeed h2.MuiTypography-root {
color: var(--primary-color);
}
.configure-pagespeed span.MuiTypography-root {
font-size: var(--env-var-font-size-small-plus);
}
.configure-pagespeed p.MuiTypography-root,
.configure-pagespeed h3.MuiTypography-root {
color: var(--secondary-color);
}
.configure-pagespeed h1.MuiTypography-root,
.configure-pagespeed h3.MuiTypography-root,
.configure-pagespeed h2.MuiTypography-root {
@@ -38,13 +24,10 @@
.configure-pagespeed .checkbox-wrapper {
margin-bottom: 1px;
}
.configure-pagespeed .MuiInputBase-root:has(> .Mui-disabled) {
background-color: var(--primary-bg-accent);
}
/* to be removed */
.configure-pagespeed .section-disabled {
opacity: 0.4;
background-color: #f1f1f2;
padding: 10px;
border-radius: 8px;
user-select: none;
@@ -55,11 +38,6 @@
height: var(--env-var-height-2);
}
body:has(.configure-pagespeed) .select-dropdown .MuiMenuItem-root,
.configure-pagespeed .select-wrapper .select-component > .MuiSelect-select {
text-transform: lowercase;
}
.configure-pagespeed h3.MuiTypography-root {
flex: 0.7;
}
+66 -34
View File
@@ -32,8 +32,8 @@ const SkeletonLayout = () => {
return (
<>
<Skeleton variant="rounded" width="15%" height={34} />
<Stack gap={theme.gap.xl} mt={theme.gap.medium} maxWidth="1000px">
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
<Stack gap={theme.spacing(20)} mt={theme.spacing(6)} maxWidth="1000px">
<Stack direction="row" gap={theme.spacing(4)} mt={theme.spacing(4)}>
<Skeleton
variant="circular"
style={{ minWidth: 24, minHeight: 24 }}
@@ -43,13 +43,13 @@ const SkeletonLayout = () => {
variant="rounded"
width="50%"
height={24}
sx={{ mb: theme.gap.small }}
sx={{ mb: theme.spacing(4) }}
/>
<Skeleton variant="rounded" width="50%" height={18} />
</Box>
<Stack
direction="row"
gap={theme.gap.medium}
gap={theme.spacing(6)}
sx={{
ml: "auto",
alignSelf: "flex-end",
@@ -147,7 +147,7 @@ const PageSpeedConfigure = () => {
let loading = Object.keys(monitor).length === 0;
return (
<Stack className="configure-pagespeed" gap={theme.gap.large}>
<Stack className="configure-pagespeed" gap={theme.spacing(12)}>
{loading ? (
<SkeletonLayout />
) : (
@@ -165,21 +165,22 @@ const PageSpeedConfigure = () => {
spellCheck="false"
onSubmit={handleSave}
flex={1}
gap={theme.gap.large}
gap={theme.spacing(12)}
>
<Stack direction="row" gap={theme.gap.xs}>
<Stack direction="row" gap={theme.spacing(2)}>
<PulseDot
color={
monitor?.status
? theme.label.up.dotColor
: theme.label.down.dotColor
? theme.palette.success.main
: theme.palette.error.main
}
/>
<Box>
<Typography
component="h1"
mb={theme.gap.xs}
mb={theme.spacing(2)}
sx={{ lineHeight: 1 }}
color={theme.palette.text.primary}
>
{monitor?.url}
</Typography>
@@ -187,8 +188,8 @@ const PageSpeedConfigure = () => {
component="span"
sx={{
color: monitor?.status
? "var(--success-color)"
: "var(--error-color)",
? theme.palette.success.main
: theme.palette.error.text,
}}
>
Your pagespeed monitor is {monitor?.status ? "live" : "down"}.
@@ -201,11 +202,11 @@ const PageSpeedConfigure = () => {
animate="rotate180"
img={<PauseCircleOutlineIcon />}
sx={{
backgroundColor: theme.palette.otherColors.fillGray,
pl: theme.gap.small,
pr: theme.gap.medium,
backgroundColor: theme.palette.background.fill,
pl: theme.spacing(4),
pr: theme.spacing(6),
"& svg": {
mr: theme.gap.xs,
mr: theme.spacing(2),
},
}}
/>
@@ -214,14 +215,27 @@ const PageSpeedConfigure = () => {
label="Remove"
sx={{
boxShadow: "none",
px: theme.gap.ml,
ml: theme.gap.medium,
px: theme.spacing(8),
ml: theme.spacing(6),
}}
onClick={() => setIsOpen(true)}
/>
</Box>
</Stack>
<Stack gap={theme.gap.xl}>
<Stack
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
p={theme.spacing(20)}
pl={theme.spacing(15)}
gap={theme.spacing(20)}
sx={{
"& h3, & p": {
color: theme.palette.text.secondary,
},
}}
>
<Stack direction="row">
<Typography component="h3">Monitor display name</Typography>
<Field
@@ -233,7 +247,14 @@ const PageSpeedConfigure = () => {
error={errors.name}
/>
</Stack>
<Stack direction="row">
<Stack
direction="row"
sx={{
".MuiInputBase-root:has(> .Mui-disabled)": {
backgroundColor: theme.palette.background.accent,
},
}}
>
<Typography component="h3">URL</Typography>
<Field
type="url"
@@ -259,8 +280,11 @@ const PageSpeedConfigure = () => {
Incidents notifications{" "}
<Typography component="span">(coming soon)</Typography>
</Typography>
<Stack className="section-disabled">
<Typography mb={theme.gap.small}>
<Stack
className="section-disabled"
backgroundColor={theme.palette.background.fill}
>
<Typography mb={theme.spacing(4)}>
When there is a new incident,
</Typography>
<Checkbox
@@ -279,7 +303,7 @@ const PageSpeedConfigure = () => {
label="Notify via email to following emails"
isChecked={false}
/>
<Box mx={`calc(${theme.gap.ml} * 2)`}>
<Box mx={theme.spacing(16)}>
<Field
id="notify-emails-list"
placeholder="notifications@gmail.com"
@@ -287,7 +311,7 @@ const PageSpeedConfigure = () => {
onChange={() => logger.warn("disabled")}
error=""
/>
<Typography mt={theme.gap.small}>
<Typography mt={theme.spacing(4)}>
You can separate multiple emails with a comma
</Typography>
</Box>
@@ -300,7 +324,7 @@ const PageSpeedConfigure = () => {
level="primary"
label="Save"
onClick={handleSave}
sx={{ px: theme.gap.large, mt: theme.gap.large }}
sx={{ px: theme.spacing(12), mt: theme.spacing(12) }}
/>
</Stack>
</Stack>
@@ -314,33 +338,41 @@ const PageSpeedConfigure = () => {
disablePortal
>
<Stack
gap={theme.gap.xs}
gap={theme.spacing(2)}
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "white",
border: "solid 1px #f2f2f2",
borderRadius: `${theme.shape.borderRadius}px`,
bgcolor: theme.palette.background.main,
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
boxShadow: 24,
p: "30px",
p: theme.spacing(15),
"&:focus": {
outline: "none",
},
}}
>
<Typography id="modal-delete-pagespeed-monitor" component="h2">
<Typography
id="modal-delete-pagespeed-monitor"
component="h2"
color={theme.palette.text.secondary}
>
Do you really want to delete this monitor?
</Typography>
<Typography id="delete-pagespeed-monitor-confirmation">
<Typography
id="delete-pagespeed-monitor-confirmation"
color={theme.palette.text.tertiary}
>
Once deleted, this monitor cannot be retrieved.
</Typography>
<Stack
direction="row"
gap={theme.gap.small}
mt={theme.gap.large}
gap={theme.spacing(4)}
mt={theme.spacing(12)}
justifyContent="flex-end"
>
<Button
@@ -1,17 +1,3 @@
.create-page-speed form > .MuiStack-root:not(:last-of-type) {
background-color: var(--primary-bg);
border: solid 1px var(--border-color);
border-radius: var(--env-var-radius-1);
padding: var(--env-var-font-size-large-plus) var(--env-var-font-size-xlarge);
}
.create-page-speed h1.MuiTypography-root {
font-size: 22px;
color: var(--primary-bg);
}
.create-page-speed p.MuiTypography-root,
.create-page-speed h3.MuiTypography-root {
color: var(--secondary-color);
}
.create-page-speed h1.MuiTypography-root,
.create-page-speed h3.MuiTypography-root {
font-weight: 600;
@@ -31,10 +17,10 @@
.create-page-speed .checkbox-wrapper {
margin-bottom: 1px;
}
/* to be removed */
.create-page-speed .section-disabled {
opacity: 0.4;
background-color: #f1f1f2;
padding: 10px;
border-radius: 8px;
user-select: none;
@@ -45,11 +31,6 @@
height: var(--env-var-height-2);
}
body:has(.create-page-speed) .select-dropdown .MuiMenuItem-root,
.create-page-speed .select-wrapper .select-component > .MuiSelect-select {
text-transform: lowercase;
}
.create-page-speed h3.MuiTypography-root {
flex: 0.7;
}
@@ -99,7 +99,7 @@ const CreatePageSpeed = () => {
};
return (
<Stack className="create-page-speed" gap={theme.gap.mlplus}>
<Stack className="create-page-speed" gap={theme.spacing(6)}>
<Breadcrumbs
list={[
{ name: "pagespeed", path: "/pagespeed" },
@@ -111,11 +111,47 @@ const CreatePageSpeed = () => {
noValidate
spellCheck="false"
onSubmit={handleCreate}
gap={theme.gap.large}
gap={theme.spacing(12)}
flex={1}
>
<Typography component="h1">Create pagespeed monitor</Typography>
<Stack gap={theme.gap.xl}>
<Typography
component="h1"
lineHeight={1}
fontSize={21}
color={theme.palette.text.primary}
>
<Typography
component="span"
fontSize="inherit"
color={theme.palette.text.secondary}
>
Create your{" "}
</Typography>
<Typography component="span" fontSize="inherit" fontWeight="inherit">
pagespeed{" "}
</Typography>
<Typography
component="span"
fontSize="inherit"
color={theme.palette.text.secondary}
>
monitor
</Typography>
</Typography>
<Stack
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
p={theme.spacing(20)}
pl={theme.spacing(15)}
gap={theme.spacing(20)}
sx={{
"& h3, & p": {
color: theme.palette.text.secondary,
},
}}
>
<Stack direction="row">
<Typography component="h3">Monitor display name</Typography>
<Field
@@ -152,8 +188,11 @@ const CreatePageSpeed = () => {
Incidents notifications{" "}
<Typography component="span">(coming soon)</Typography>
</Typography>
<Stack className="section-disabled">
<Typography mb={theme.gap.small}>
<Stack
className="section-disabled"
backgroundColor={theme.palette.background.fill}
>
<Typography mb={theme.spacing(4)}>
When there is a new incident,
</Typography>
<Checkbox
@@ -180,7 +219,7 @@ const CreatePageSpeed = () => {
onChange={() => logger.warn("disabled")}
error=""
/>
<Typography mt={theme.gap.small}>
<Typography mt={theme.spacing(4)}>
You can separate multiple emails with a comma
</Typography>
</Box>
@@ -193,7 +232,7 @@ const CreatePageSpeed = () => {
level="primary"
label="Create"
onClick={handleCreate}
sx={{ px: theme.gap.large, mt: theme.gap.large }}
sx={{ px: theme.spacing(12), mt: theme.spacing(12) }}
/>
</Stack>
</Stack>
@@ -1,6 +1,5 @@
.page-speed-details h1 {
font-size: var(--env-var-font-size-large-plus);
color: var(--primary-color);
}
.page-speed-details h2,
.page-speed-details h6 {
@@ -15,13 +14,7 @@
.page-speed-details h4 > span {
font-size: var(--env-var-font-size-small-plus);
}
.page-speed-details h2,
.page-speed-details h4,
.page-speed-details p {
color: var(--secondary-color);
}
.page-speed-details h6 {
color: var(--theme-main);
line-height: 22px;
}
.page-speed-details h1,
@@ -33,14 +26,6 @@
height: 34px;
}
.page-speed-details .stat-box,
.page-speed-details > .MuiStack-root:last-child,
.page-speed-details > .MuiBox-root:nth-last-child(3) {
border: solid 1px var(--border-color);
border-radius: var(--env-var-radius-1);
background-color: var(--primary-bg);
min-width: 200px;
}
.page-speed-details .stat-box {
flex: 1;
}
+131 -52
View File
@@ -29,17 +29,28 @@ const StatBox = ({ icon, title, value }) => {
<Stack
className="stat-box"
direction="row"
gap={theme.gap.small}
pt={theme.gap.ml}
px={theme.gap.ml}
pb={theme.gap.mlplus}
gap={theme.spacing(4)}
pt={theme.spacing(8)}
px={theme.spacing(8)}
pb={theme.spacing(10)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
minWidth="200px"
>
{icon}
<Box>
<Typography variant="h6" mb={theme.gap.medium}>
<Typography
variant="h6"
color={theme.palette.common.main}
mb={theme.spacing(6)}
>
{title}
</Typography>
<Typography variant="h4">{value}</Typography>
<Typography variant="h4" color={theme.palette.text.secondary}>
{value}
</Typography>
</Box>
</Stack>
);
@@ -151,7 +162,7 @@ const SkeletonLayout = () => {
return (
<>
<Skeleton variant="rounded" width="15%" height={34} />
<Stack direction="row" gap={theme.gap.small}>
<Stack direction="row" gap={theme.spacing(4)}>
<Skeleton variant="circular" style={{ minWidth: 24, minHeight: 24 }} />
<Box width="85%">
<Skeleton variant="rounded" width="50%" height={24} />
@@ -159,7 +170,7 @@ const SkeletonLayout = () => {
variant="rounded"
width="50%"
height={18}
sx={{ mt: theme.gap.small }}
sx={{ mt: theme.spacing(4) }}
/>
</Box>
<Skeleton
@@ -172,7 +183,7 @@ const SkeletonLayout = () => {
<Stack
direction="row"
justifyContent="space-between"
gap={theme.gap.xl}
gap={theme.spacing(20)}
flexWrap="wrap"
>
<Skeleton variant="rounded" width="30%" height={90} sx={{ flex: 1 }} />
@@ -237,10 +248,37 @@ const PageSpeedDetails = () => {
* @returns {{stroke: string, text: string, bg: string}} The color properties for the given performance value.
*/
const getColors = (value) => {
if (value >= 90 && value <= 100) return theme.pie.green;
else if (value >= 50 && value < 90) return theme.pie.yellow;
else if (value >= 0 && value < 50) return theme.pie.red;
return theme.pie.default;
if (value >= 90 && value <= 100)
return {
stroke: theme.palette.success.main,
strokeBg: theme.palette.success.light,
text: theme.palette.success.text,
bg: theme.palette.success.bg,
shape: "circle",
};
else if (value >= 50 && value < 90)
return {
stroke: theme.palette.warning.main,
strokeBg: theme.palette.warning.bg,
text: theme.palette.warning.text,
bg: theme.palette.warning.light,
shape: "square",
};
else if (value >= 0 && value < 50)
return {
stroke: theme.palette.error.text,
strokeBg: theme.palette.error.light,
text: theme.palette.error.text,
bg: theme.palette.error.bg,
shape: "circle",
};
return {
stroke: theme.palette.unresolved.main,
strokeBg: theme.palette.unresolved.light,
text: theme.palette.unresolved.main,
bg: theme.palette.unresolved.bg,
shape: "",
};
};
/**
@@ -312,8 +350,15 @@ const PageSpeedDetails = () => {
let loading = Object.keys(monitor).length === 0;
const data = monitor?.checks ? [...monitor.checks].reverse() : [];
let sharedStyles = {
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.main,
};
return (
<Stack className="page-speed-details" gap={theme.gap.large}>
<Stack className="page-speed-details" gap={theme.spacing(12)}>
{loading ? (
<SkeletonLayout />
) : (
@@ -324,25 +369,30 @@ const PageSpeedDetails = () => {
{ name: "details", path: `/pagespeed/${monitorId}` },
]}
/>
<Stack direction="row" gap={theme.gap.xs}>
<Stack direction="row" gap={theme.spacing(2)}>
<PulseDot
color={
monitor?.status
? theme.label.up.dotColor
: theme.label.down.dotColor
? theme.palette.success.main
: theme.palette.error.main
}
/>
<Box>
<Typography
component="h1"
mb={theme.gap.xs}
mb={theme.spacing(2)}
color={theme.palette.text.primary}
sx={{ lineHeight: 1 }}
>
{monitor?.url}
</Typography>
<Typography
component="span"
sx={{ color: "var(--success-color)" }}
color={
monitor?.status
? theme.palette.success.main
: theme.palette.error.text
}
>
Your pagespeed monitor is live.
</Typography>
@@ -353,15 +403,18 @@ const PageSpeedDetails = () => {
animate="rotate90"
img={
<SettingsIcon
style={{ width: theme.gap.mlplus, height: theme.gap.mlplus }}
style={{
width: theme.spacing(10),
height: theme.spacing(10),
}}
/>
}
onClick={() => navigate(`/pagespeed/configure/${monitorId}`)}
sx={{
ml: "auto",
alignSelf: "flex-end",
backgroundColor: theme.palette.otherColors.fillGray,
px: theme.gap.medium,
backgroundColor: theme.palette.background.fill,
px: theme.spacing(6),
"& svg": {
mr: "6px",
},
@@ -371,7 +424,7 @@ const PageSpeedDetails = () => {
<Stack
direction="row"
justifyContent="space-between"
gap={theme.gap.large}
gap={theme.spacing(12)}
flexWrap="wrap"
>
<StatBox
@@ -412,19 +465,39 @@ const PageSpeedDetails = () => {
value={formatDurationRounded(monitor?.interval)}
></StatBox>
</Stack>
<Typography component="h2">Score history</Typography>
<Box height="300px">
<Typography component="h2" color={theme.palette.text.secondary}>
Score history
</Typography>
<Box
height="300px"
sx={{
...sharedStyles,
}}
>
<PageSpeedLineChart pageSpeedChecks={data} />
</Box>
<Typography component="h2">Performance report</Typography>
<Stack direction="row" alignItems="center" overflow="hidden" flex={1}>
<Typography component="h2" color={theme.palette.text.secondary}>
Performance report
</Typography>
<Stack
direction="row"
alignItems="center"
overflow="hidden"
flex={1}
sx={{
"& p": {
color: theme.palette.text.secondary,
},
...sharedStyles,
}}
>
<Stack
alignItems="center"
textAlign="center"
minWidth="300px"
flex={1}
px={theme.gap.xl}
py={theme.gap.ml}
px={theme.spacing(20)}
py={theme.spacing(8)}
>
<Box onMouseLeave={() => setExpand(false)}>
{expand ? (
@@ -514,12 +587,12 @@ const PageSpeedDetails = () => {
</PieChart>
)}
</Box>
<Typography mt={theme.gap.medium}>
<Typography mt={theme.spacing(6)}>
Values are estimated and may vary.{" "}
<Typography
component="span"
sx={{
color: theme.palette.primary.main,
color: theme.palette.common.main,
fontWeight: 500,
textDecoration: "underline",
cursor: "pointer",
@@ -530,21 +603,23 @@ const PageSpeedDetails = () => {
</Typography>
</Stack>
<Box
px={theme.gap.xl}
py={theme.gap.ml}
px={theme.spacing(20)}
py={theme.spacing(8)}
height="100%"
flex={1}
sx={{
borderLeft: `solid 1px ${theme.palette.otherColors.graishWhite}`,
borderLeft: 1,
borderLeftColor: theme.palette.border.light,
}}
>
<Typography
mb={theme.gap.medium}
pb={theme.gap.ml}
color={theme.palette.secondary.main}
mb={theme.spacing(6)}
pb={theme.spacing(8)}
color={theme.palette.text.secondary}
textAlign="center"
sx={{
borderBottom: `solid 1px ${theme.palette.otherColors.graishWhite}`,
borderBottom: 1,
borderBottomColor: theme.palette.border.light,
borderBottomStyle: "dashed",
}}
>
@@ -552,7 +627,7 @@ const PageSpeedDetails = () => {
<Typography
component="span"
sx={{
color: theme.palette.primary.main,
color: theme.palette.common.main,
fontWeight: 500,
textDecoration: "underline",
cursor: "pointer",
@@ -569,8 +644,8 @@ const PageSpeedDetails = () => {
<Stack
direction="row"
flexWrap="wrap"
pt={theme.gap.ml}
gap={theme.gap.ml}
pt={theme.spacing(8)}
gap={theme.spacing(8)}
>
{Object.keys(audits).map((key) => {
if (key === "_id") return;
@@ -581,8 +656,8 @@ const PageSpeedDetails = () => {
let shape = (
<Box
sx={{
width: theme.gap.medium,
height: theme.gap.medium,
width: theme.spacing(6),
height: theme.spacing(6),
borderRadius: "50%",
backgroundColor: metricParams.stroke,
}}
@@ -592,8 +667,8 @@ const PageSpeedDetails = () => {
shape = (
<Box
sx={{
width: theme.gap.medium,
height: theme.gap.medium,
width: theme.spacing(6),
height: theme.spacing(6),
backgroundColor: metricParams.stroke,
}}
></Box>
@@ -604,10 +679,14 @@ const PageSpeedDetails = () => {
sx={{
width: 0,
height: 0,
ml: `calc((${theme.gap.medium} - ${theme.gap.small}) / -2)`,
borderLeft: `${theme.gap.small} solid transparent`,
borderRight: `${theme.gap.small} solid transparent`,
borderBottom: `${theme.gap.medium} solid ${metricParams.stroke}`,
ml: `calc((${theme.spacing(6)} - ${theme.spacing(
4
)}) / -2)`,
borderLeft: `${theme.spacing(4)} solid transparent`,
borderRight: `${theme.spacing(4)} solid transparent`,
borderBottom: `${theme.spacing(6)} solid ${
metricParams.stroke
}`,
}}
></Box>
);
@@ -630,7 +709,7 @@ const PageSpeedDetails = () => {
className="metric"
key={`${key}-box`}
direction="row"
gap={theme.gap.small}
gap={theme.spacing(4)}
>
{shape}
<Box>
@@ -650,8 +729,8 @@ const PageSpeedDetails = () => {
component="span"
ml="2px"
sx={{
color: theme.palette.secondary.main,
fontSize: "13px",
color: theme.palette.text.secondary,
fontSize: 13,
}}
>
{unit}
-11
View File
@@ -1,10 +1,4 @@
.page-speed h1.MuiTypography-root,
.page-speed span.MuiTypography-root,
.page-speed p.MuiTypography-root {
color: var(--secondary-color);
}
.page-speed h2.MuiTypography-root {
color: var(--theme-main);
line-height: 1.1;
}
.page-speed h1.MuiTypography-root,
@@ -19,11 +13,6 @@
.page-speed p.MuiTypography-root > span.MuiTypography-root {
font-size: var(--env-var-font-size-small-plus);
}
.page-speed .MuiGrid-item > .MuiStack-root {
border: solid 1px var(--border-color);
border-radius: var(--env-var-radius-1);
background-color: var(--primary-bg);
}
.page-speed .label {
padding: 7px;
height: 22px;
+30 -13
View File
@@ -30,15 +30,25 @@ const Card = ({ data }) => {
>
<Stack
direction="row"
gap={theme.gap.medium}
p={theme.gap.ml}
gap={theme.spacing(6)}
p={theme.spacing(8)}
onClick={() => navigate(`/pagespeed/${data._id}`)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
sx={{ cursor: "pointer" }}
>
<PageSpeedIcon style={{ width: theme.gap.ml, height: theme.gap.ml }} />
<PageSpeedIcon
style={{ width: theme.spacing(8), height: theme.spacing(8) }}
/>
<Box flex={1}>
<Stack direction="row" justifyContent="space-between">
<Typography component="h2" mb={theme.gap.xs}>
<Typography
component="h2"
mb={theme.spacing(2)}
color={theme.palette.common.main}
>
{data.name}
</Typography>
<StatusLabel
@@ -47,7 +57,7 @@ const Card = ({ data }) => {
/>
</Stack>
<Typography>{data.url.replace(/^https?:\/\//, "")}</Typography>
<Typography mt={theme.gap.large}>
<Typography mt={theme.spacing(12)}>
<Typography component="span" fontWeight={600}>
Last checked:{" "}
</Typography>
@@ -75,11 +85,11 @@ const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack gap={theme.gap.xs}>
<Stack gap={theme.spacing(2)}>
<Stack
direction="row"
justifyContent="space-between"
mb={theme.gap.large}
mb={theme.spacing(12)}
>
<Box width="80%">
<Skeleton variant="rounded" width="25%" height={24} />
@@ -87,7 +97,7 @@ const SkeletonLayout = () => {
variant="rounded"
width="50%"
height={19.5}
sx={{ mt: theme.gap.xs }}
sx={{ mt: theme.spacing(2) }}
/>
</Box>
<Skeleton
@@ -97,7 +107,7 @@ const SkeletonLayout = () => {
sx={{ alignSelf: "flex-end" }}
/>
</Stack>
<Stack direction="row" flexWrap="wrap" gap={theme.gap.large}>
<Stack direction="row" flexWrap="wrap" gap={theme.spacing(12)}>
<Skeleton
variant="rounded"
width="100%"
@@ -163,15 +173,22 @@ const PageSpeed = ({ isAdmin }) => {
{isActuallyLoading ? (
<SkeletonLayout />
) : monitors?.length !== 0 ? (
<Stack gap={theme.gap.xs}>
<Stack
gap={theme.spacing(2)}
sx={{
"& h1, & span.MuiTypography-root, & p": {
color: theme.palette.text.secondary,
},
}}
>
<Stack
direction="row"
justifyContent="space-between"
mb={theme.gap.large}
mb={theme.spacing(12)}
>
<Box>
<Typography component="h1">All page speed monitors</Typography>
<Typography mt={theme.gap.xs}>
<Typography mt={theme.spacing(2)}>
Click on one of the monitors to get more site speed information.
</Typography>
</Box>
@@ -181,7 +198,7 @@ const PageSpeed = ({ isAdmin }) => {
onClick={() => navigate("/pagespeed/create")}
/>
</Stack>
<Grid container spacing={theme.gap.large}>
<Grid container spacing={theme.spacing(12)}>
{monitors?.map((monitor) => (
<Card data={monitor} key={`monitor-${monitor._id}`} />
))}
+6 -1
View File
@@ -53,7 +53,12 @@ const theme = createTheme({
light: "#ffffff",
border: "#D0D5DD",
},
success: { main: "#17b26a", light: "#d4f4e1", bg: "#ecfdf3" },
success: {
text: "#079455",
main: "#17b26a",
light: "#d4f4e1",
bg: "#ecfdf3",
},
error: {
text: "#f04438",
main: "#d32f2f",