mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-25 11:19:16 -06:00
Merge remote-tracking branch 'upstream/develop' into feat/fe/monitor-refactor
This commit is contained in:
2
Client/package-lock.json
generated
2
Client/package-lock.json
generated
@@ -18,7 +18,7 @@
|
||||
"@mui/x-data-grid": "7.3.2",
|
||||
"@mui/x-date-pickers": "7.3.2",
|
||||
"@reduxjs/toolkit": "2.2.5",
|
||||
"axios": "1.7.4",
|
||||
"axios": "^1.7.4",
|
||||
"chart.js": "^4.4.3",
|
||||
"dayjs": "1.11.11",
|
||||
"joi": "17.13.1",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@mui/x-data-grid": "7.3.2",
|
||||
"@mui/x-date-pickers": "7.3.2",
|
||||
"@reduxjs/toolkit": "2.2.5",
|
||||
"axios": "1.7.4",
|
||||
"axios": "^1.7.4",
|
||||
"chart.js": "^4.4.3",
|
||||
"dayjs": "1.11.11",
|
||||
"joi": "17.13.1",
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
.MuiTable-root .host span {
|
||||
font-size: var(--env-var-font-size-small);
|
||||
margin-left: 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.MuiTable-root .label {
|
||||
@@ -180,3 +179,16 @@ body:has(.pagination-dropdown) p:has(+ .MuiTablePagination-root) {
|
||||
body:has(.pagination-dropdown) p:has(+ .MuiTablePagination-root) {
|
||||
font-size: var(--env-var-font-size-small-plus);
|
||||
}
|
||||
|
||||
.monitors .MuiTable-root .MuiTableHead-root .MuiTableCell-root {
|
||||
text-transform: uppercase;
|
||||
color: var(--env-var-color-5);
|
||||
opacity: 0.8;
|
||||
font-size: var(--env-var-font-size-small-plus);
|
||||
font-weight: 400;
|
||||
}
|
||||
.monitors .MuiTableCell-root:not(:first-of-type):not(:last-of-type),
|
||||
.monitors .MuiTableCell-root:not(:first-of-type):not(:last-of-type) {
|
||||
padding-left: var(--env-var-spacing-1);
|
||||
padding-right: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
@@ -233,6 +233,7 @@ const BasicTable = ({ data, paginated, reversed, table }) => {
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
px={theme.gap.small}
|
||||
>
|
||||
<Typography sx={{ opacity: 0.7 }}>
|
||||
Showing {getRange()} of {data.rows.length} monitor(s)
|
||||
@@ -277,7 +278,10 @@ const BasicTable = ({ data, paginated, reversed, table }) => {
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{ mt: theme.gap.medium }}
|
||||
sx={{
|
||||
mt: theme.gap.medium,
|
||||
color: theme.palette.otherColors.bluishGray,
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import React from "react";
|
||||
import "./serverStatus.css";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param {string} props.title - The title text for the server status (required)
|
||||
* @param {number} props.value - The value text to be displayed (required)
|
||||
* @param {string} props.state - The state of the server (e.g., "online", "offline", "warning") (required)
|
||||
* @returns {JSX.Element} - Renders the server status component
|
||||
*/
|
||||
const ServerStatus = ({ title, value, state }) => {
|
||||
return (
|
||||
<div className="server-status-tile">
|
||||
<div className="server-status-tile-title">{title}</div>
|
||||
<div className={`server-status-tile-value ` + " " + state}>{value}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ServerStatus.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
state: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default ServerStatus;
|
||||
@@ -1,46 +0,0 @@
|
||||
:root {
|
||||
--spacing-general-0: 12px 18px;
|
||||
--spacing-general-1: 20px;
|
||||
--color-border-0: #eaecf0;
|
||||
--border-radius-0: 4px;
|
||||
--font-size-0: 1rem;
|
||||
--font-size-2: 36px;
|
||||
|
||||
--color-up: #17b26a;
|
||||
--color-down: #f04438;
|
||||
--color-pause: #fdb022;
|
||||
}
|
||||
|
||||
.server-status-tile {
|
||||
min-width: 100px;
|
||||
width: calc(100% - 310px);
|
||||
padding: var(--spacing-general-0);
|
||||
border: 1px solid var(--color-border-0);
|
||||
border-radius: var(--border-radius-0);
|
||||
background-color: var(--env-var-color-8);
|
||||
}
|
||||
|
||||
.server-status-tile-title {
|
||||
font-size: var(--font-size-0);
|
||||
font-weight: 500;
|
||||
margin-bottom: calc(var(--spacing-general-1) / 2);
|
||||
color: var(--env-var-color-5);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.server-status-tile-value {
|
||||
font-size: var(--font-size-2);
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.up {
|
||||
color: var(--color-up);
|
||||
}
|
||||
|
||||
.down {
|
||||
color: var(--color-down);
|
||||
}
|
||||
|
||||
.pause {
|
||||
color: var(--color-pause);
|
||||
}
|
||||
@@ -181,7 +181,14 @@ const Field = forwardRef(
|
||||
Field.displayName = "Field";
|
||||
|
||||
Field.propTypes = {
|
||||
type: PropTypes.oneOf(["text", "password", "url", "email", "description"]),
|
||||
type: PropTypes.oneOf([
|
||||
"text",
|
||||
"password",
|
||||
"url",
|
||||
"email",
|
||||
"description",
|
||||
"number",
|
||||
]),
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
https: PropTypes.bool,
|
||||
|
||||
@@ -15,6 +15,9 @@ aside span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
line-height: 1;
|
||||
}
|
||||
aside .MuiStack-root + span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium-plus);
|
||||
}
|
||||
aside .MuiListSubheader-root {
|
||||
font-size: var(--env-var-font-size-small);
|
||||
font-weight: 500;
|
||||
|
||||
@@ -194,6 +194,7 @@ function Sidebar() {
|
||||
sx={{
|
||||
pt: theme.gap.small,
|
||||
px: collapsed ? theme.gap.xs : theme.gap.small,
|
||||
backgroundColor: "transparent"
|
||||
}}
|
||||
>
|
||||
Menu
|
||||
@@ -289,7 +290,7 @@ function Sidebar() {
|
||||
if (
|
||||
child.name === "Team" &&
|
||||
authState.user?.role &&
|
||||
!authState.user.role.includes("admin")
|
||||
!authState.user.role.includes("superadmin")
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@@ -349,7 +350,7 @@ function Sidebar() {
|
||||
if (
|
||||
child.name === "Team" &&
|
||||
authState.user?.role &&
|
||||
!authState.user.role.includes("admin")
|
||||
!authState.user.role.includes("superadmin")
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@@ -394,6 +395,7 @@ function Sidebar() {
|
||||
sx={{
|
||||
pt: theme.gap.small,
|
||||
px: collapsed ? 0 : theme.gap.small,
|
||||
backgroundColor: "transparent"
|
||||
}}
|
||||
>
|
||||
Other
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
height: calc(100vh - var(--env-var-spacing-2) * 2);
|
||||
max-width: var(--env-var-side-bar-width);
|
||||
|
||||
border: 1px solid var(--color-border-0);
|
||||
border: 1px solid var(--env-var-color-6);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
background-color: var(--env-var-color-8);
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ const Incidents = () => {
|
||||
null,
|
||||
null
|
||||
);
|
||||
console.log(res);
|
||||
// Reduce to a lookup object for 0(1) lookup
|
||||
if (res.data && res.data.data.length > 0) {
|
||||
const monitorLookup = res.data.data.reduce((acc, monitor) => {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
.duration-config .field-text .MuiTextField-root,
|
||||
.duration-config .field {
|
||||
.maintenance-options .duration-config .field {
|
||||
width: 70px;
|
||||
min-width: 70px;
|
||||
max-width: 70px;
|
||||
|
||||
@@ -10,6 +10,9 @@ import dayjs from "dayjs";
|
||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||
import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker";
|
||||
import Field from "../../../Components/Inputs/Field";
|
||||
import { maintenanceWindowValidation } from "../../../Validation/validation";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
|
||||
const directory = {
|
||||
title: "Create a maintenance window",
|
||||
@@ -59,9 +62,10 @@ const CreateNewMaintenanceWindow = () => {
|
||||
startTime: dayjs(),
|
||||
duration: "60",
|
||||
unit: "minutes",
|
||||
friendlyName: "",
|
||||
displayName: "",
|
||||
AddMonitors: "",
|
||||
});
|
||||
const [errors, setErrors] = useState({});
|
||||
|
||||
const handleChange = (event, name) => {
|
||||
const { value } = event.target;
|
||||
@@ -71,6 +75,41 @@ const CreateNewMaintenanceWindow = () => {
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const data = {
|
||||
repeat: values.repeat,
|
||||
date: values.date.format("YYYY-MM-DD"),
|
||||
startTime: values.startTime.format("HH:mm"),
|
||||
duration: values.duration,
|
||||
unit: values.unit,
|
||||
displayName: values.displayName,
|
||||
addMonitors: values.AddMonitors,
|
||||
};
|
||||
|
||||
const { error } = maintenanceWindowValidation.validate(data, {
|
||||
abortEarly: false,
|
||||
});
|
||||
logger.log("error: ", error);
|
||||
if (!error || error.details.length === 0) {
|
||||
setErrors({});
|
||||
} else {
|
||||
const newErrors = {};
|
||||
error.details.forEach((err) => {
|
||||
newErrors[err.path[0]] = err.message;
|
||||
});
|
||||
setErrors(newErrors);
|
||||
createToast({
|
||||
body:
|
||||
error.details && error.details.length > 0
|
||||
? error.details[0].message
|
||||
: "Error validating data",
|
||||
});
|
||||
logger.error("Validation errors:", error.details);
|
||||
}
|
||||
|
||||
logger.log("Submitting data: ", data);
|
||||
};
|
||||
|
||||
const configOptions = [
|
||||
{
|
||||
title: "Repeat",
|
||||
@@ -126,6 +165,8 @@ const CreateNewMaintenanceWindow = () => {
|
||||
placeholder="60"
|
||||
onChange={(e) => handleChange(e, "duration")}
|
||||
value={values.duration}
|
||||
error={errors.duration}
|
||||
type="number"
|
||||
/>
|
||||
<Select
|
||||
onChange={(e) => handleChange(e, "unit")}
|
||||
@@ -137,13 +178,14 @@ const CreateNewMaintenanceWindow = () => {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Friendly name",
|
||||
title: "Display name",
|
||||
component: (
|
||||
<Field
|
||||
id="friendly-name"
|
||||
id="display-name"
|
||||
placeholder="Maintanence at __ : __ for ___ minutes"
|
||||
value={values.friendlyName}
|
||||
onChange={(e) => handleChange(e, "friendlyName")}
|
||||
value={values.displayName}
|
||||
onChange={(e) => handleChange(e, "displayName")}
|
||||
error={errors.displayName}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -160,6 +202,7 @@ const CreateNewMaintenanceWindow = () => {
|
||||
placeholder="Start typing to search for current monitors"
|
||||
value={values.AddMonitors}
|
||||
onChange={(e) => handleChange(e, "AddMonitors")}
|
||||
error={errors.addMonitors}
|
||||
/>
|
||||
<Typography
|
||||
sx={{
|
||||
@@ -246,6 +289,7 @@ const CreateNewMaintenanceWindow = () => {
|
||||
}}
|
||||
level="primary"
|
||||
label="Create"
|
||||
onClick={handleSubmit}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
@@ -314,7 +314,7 @@ const Configure = () => {
|
||||
<Field
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Friendly name"
|
||||
label="Display name"
|
||||
isOptional={true}
|
||||
placeholder="Google"
|
||||
value={monitor?.name || ""}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
.create-monitor h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large-plus);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
.create-monitor h1.MuiTypography-root,
|
||||
.create-monitor h2.MuiTypography-root {
|
||||
font-weight: 600;
|
||||
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 {
|
||||
|
||||
@@ -122,7 +122,6 @@ const CreateMonitor = () => {
|
||||
userId: user._id,
|
||||
notifications: monitor.notifications,
|
||||
};
|
||||
console.log(form);
|
||||
const action = await dispatch(
|
||||
createUptimeMonitor({ authToken, monitor: form })
|
||||
);
|
||||
@@ -159,9 +158,20 @@ const CreateMonitor = () => {
|
||||
noValidate
|
||||
spellCheck="false"
|
||||
gap={theme.gap.large}
|
||||
mt={theme.gap.mlplus}
|
||||
mt={theme.gap.medium}
|
||||
>
|
||||
<Typography component="h1">Create new monitor</Typography>
|
||||
<Typography component="h1">
|
||||
<Typography
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
color={theme.palette.otherColors.bluishGray}
|
||||
>
|
||||
Create your{" "}
|
||||
</Typography>
|
||||
<Typography component="span" fontSize="inherit" fontWeight="inherit">
|
||||
monitor
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Stack className="config-box">
|
||||
<Box>
|
||||
<Typography component="h2">General settings</Typography>
|
||||
@@ -184,7 +194,7 @@ const CreateMonitor = () => {
|
||||
<Field
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
label="Friendly name"
|
||||
label="Display name"
|
||||
isOptional={true}
|
||||
placeholder="Google"
|
||||
value={monitor.name}
|
||||
@@ -391,9 +401,9 @@ const CreateMonitor = () => {
|
||||
/> */}
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
<Button
|
||||
id="create-new-monitor-btn"
|
||||
id="create-monitor-btn"
|
||||
level="primary"
|
||||
label="Create new monitor"
|
||||
label="Create monitor"
|
||||
onClick={handleCreateMonitor}
|
||||
disabled={Object.keys(errors).length !== 0 && true}
|
||||
/>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
.monitors h1.MuiTypography-root,
|
||||
.monitors h2.MuiTypography-root {
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.monitors h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large-plus);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 500;
|
||||
}
|
||||
.monitors h2.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: 500;
|
||||
}
|
||||
.monitors p.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
.monitors h1.MuiTypography-root + p.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium-plus);
|
||||
}
|
||||
.monitors .MuiStack-root > button:not(.MuiIconButton-root) {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
height: var(--env-var-height-2);
|
||||
@@ -31,7 +33,7 @@
|
||||
border-radius: 50%;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-5);
|
||||
color: var(--env-var-color-1);
|
||||
margin-left: 10px;
|
||||
line-height: 0.8;
|
||||
}
|
||||
|
||||
0
Client/src/Pages/Monitors/index.jsx
Normal file
0
Client/src/Pages/Monitors/index.jsx
Normal file
@@ -223,7 +223,7 @@ const PageSpeedConfigure = () => {
|
||||
</Stack>
|
||||
<Stack gap={theme.gap.xl}>
|
||||
<Stack direction="row">
|
||||
<Typography component="h3">Monitor friendly name</Typography>
|
||||
<Typography component="h3">Monitor display name</Typography>
|
||||
<Field
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
|
||||
@@ -116,7 +116,7 @@ const CreatePageSpeed = () => {
|
||||
<Typography component="h1">Create pagespeed monitor</Typography>
|
||||
<Stack gap={theme.gap.xl}>
|
||||
<Stack direction="row">
|
||||
<Typography component="h3">Monitor friendly name</Typography>
|
||||
<Typography component="h3">Monitor display name</Typography>
|
||||
<Field
|
||||
type="text"
|
||||
id="monitor-name"
|
||||
|
||||
@@ -112,4 +112,43 @@ const imageValidation = joi.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export { credentials, imageValidation, monitorValidation };
|
||||
const maintenanceWindowValidation = joi.object({
|
||||
repeat: joi.number().valid(1, 2, 3).required().messages({
|
||||
"number.base": "Repeat must be a number.",
|
||||
"any.only": "Repeat must be one of [1, 2, 3].",
|
||||
"any.required": "Repeat is required.",
|
||||
}),
|
||||
date: joi.date().required().messages({
|
||||
"date.base": "Date must be a valid date.",
|
||||
"any.required": "Date is required.",
|
||||
}),
|
||||
startTime: joi.string().required().messages({
|
||||
"string.base": "Start time must be a valid time.",
|
||||
"any.required": "Start time is required.",
|
||||
}),
|
||||
duration: joi.number().required().messages({
|
||||
"number.empty": "duration is required.",
|
||||
"number.base": "Duration must be a number.",
|
||||
"any.required": "Duration is required.",
|
||||
}),
|
||||
unit: joi.string().valid("minutes", "hours", "days").required().messages({
|
||||
"string.base": "Unit must be a string.",
|
||||
"any.only": "Unit must be one of ['minutes', 'hours', 'days'].",
|
||||
"any.required": "Unit is required.",
|
||||
}),
|
||||
displayName: joi.string().max(50).required().messages({
|
||||
"string.empty": "Display name is required.",
|
||||
"string.max": "Display name must be less than 50 characters long",
|
||||
}),
|
||||
addMonitors: joi.string().max(50).required().messages({
|
||||
"string.empty": "Add monitors is required.",
|
||||
"string.max": "Add monitors must be less than 50 characters long",
|
||||
}),
|
||||
});
|
||||
|
||||
export {
|
||||
credentials,
|
||||
imageValidation,
|
||||
monitorValidation,
|
||||
maintenanceWindowValidation,
|
||||
};
|
||||
|
||||
67
Client/src/assets/Images/background-grid.svg
Normal file
67
Client/src/assets/Images/background-grid.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<svg width="768" height="768" viewBox="0 0 768 768" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_14_2)">
|
||||
<mask id="mask0_14_2" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="768" height="768">
|
||||
<path d="M768 0H0V768H768V0Z" fill="url(#paint0_radial_14_2)"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_14_2)">
|
||||
<mask id="mask1_14_2" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="768" height="768">
|
||||
<path d="M768 0H0V768H768V0Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask1_14_2)">
|
||||
<mask id="mask2_14_2" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="768" height="768">
|
||||
<path d="M768 0H0V768H768V0Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask2_14_2)">
|
||||
<path d="M0.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M48.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M96.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M144.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M192.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M240.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M288.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M336.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M384.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M432.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M480.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M528.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M576.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M624.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M672.5 0V768" stroke="#b8b9bd"/>
|
||||
<path d="M720.5 0V768" stroke="#b8b9bd"/>
|
||||
</g>
|
||||
<path d="M767.5 0.5H0.5V767.5H767.5V0.5Z" stroke="#b8b9bd"/>
|
||||
<mask id="mask3_14_2" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="768" height="768">
|
||||
<path d="M768 0H0V768H768V0Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask3_14_2)">
|
||||
<path d="M0 47.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 95.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 143.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 191.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 239.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 287.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 335.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 383.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 431.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 479.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 527.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 575.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 623.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 671.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 719.5H768" stroke="#b8b9bd"/>
|
||||
<path d="M0 767.5H768" stroke="#b8b9bd"/>
|
||||
</g>
|
||||
<path d="M767.5 0.5H0.5V767.5H767.5V0.5Z" stroke="#b8b9bd"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_14_2" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(384 384) rotate(90) scale(384)">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_14_2">
|
||||
<rect width="768" height="768" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
3
Client/src/assets/icons/clock-snooze.svg
Normal file
3
Client/src/assets/icons/clock-snooze.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.5 17H21.5L16.5 22H21.5M21.9506 13C21.9833 12.6711 22 12.3375 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C12.1677 22 12.3344 21.9959 12.5 21.9877C12.6678 21.9795 12.8345 21.9671 13 21.9506M12 6V12L15.7384 13.8692" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 454 B |
3
Client/src/assets/icons/top-right-arrow.svg
Normal file
3
Client/src/assets/icons/top-right-arrow.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7 17L17 7M17 7H7M17 7V17" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 224 B |
@@ -85,7 +85,7 @@
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-large-plus: 24px;
|
||||
--env-var-font-size-large-plus: 22px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
Reference in New Issue
Block a user