mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-02 06:30:08 -05:00
Refactored components styling 2/2
This commit is contained in:
@@ -2,7 +2,7 @@ import "./check.css";
|
||||
import PropTypes from "prop-types";
|
||||
import CheckGrey from "../../assets/icons/check.svg?react";
|
||||
import CheckOutlined from "../../assets/icons/check-outlined.svg?react";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
/**
|
||||
@@ -22,25 +22,41 @@ import { useTheme } from "@emotion/react";
|
||||
*/
|
||||
const Check = ({ text, variant = "info", outlined = false }) => {
|
||||
const theme = useTheme();
|
||||
const colors = {
|
||||
success: theme.palette.success.main,
|
||||
error: theme.palette.error.text,
|
||||
info: theme.palette.info.border,
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={outlined ? theme.gap.medium : theme.gap.small}
|
||||
className={`check${
|
||||
variant === "error"
|
||||
? " check-error"
|
||||
: variant === "success"
|
||||
? " check-success"
|
||||
: " check-info"
|
||||
}`}
|
||||
className="check"
|
||||
gap={outlined ? theme.spacing(6) : theme.spacing(4)}
|
||||
alignItems="center"
|
||||
>
|
||||
{outlined ? (
|
||||
<CheckOutlined alt="check" />
|
||||
) : (
|
||||
<CheckGrey alt="form checks" />
|
||||
<Box
|
||||
lineHeight={0}
|
||||
sx={{
|
||||
"& svg > path": { fill: colors[variant] },
|
||||
}}
|
||||
>
|
||||
<CheckGrey alt="form checks" />
|
||||
</Box>
|
||||
)}
|
||||
<Typography component="span">{text}</Typography>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{
|
||||
color:
|
||||
variant === "info" ? theme.palette.text.tertiary : colors[variant],
|
||||
opacity: 0.8,
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Typography>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,17 +1 @@
|
||||
.check > span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-small-plus);
|
||||
color: var(--secondary-color-light);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.check-error span.MuiTypography-root {
|
||||
color: var(--error-color);
|
||||
}
|
||||
.check-error svg > path {
|
||||
fill: var(--error-color);
|
||||
}
|
||||
.check-success span.MuiTypography-root {
|
||||
color: var(--success-color);
|
||||
}
|
||||
.check-success svg > path {
|
||||
fill: var(--success-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 600;
|
||||
}
|
||||
[class*="fallback__"] .check span.MuiTypography-root,
|
||||
[class*="fallback__"] h1.MuiTypography-root {
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
[class*="fallback__"] button.MuiButtonBase-root,
|
||||
[class*="fallback__"] .check {
|
||||
width: max-content;
|
||||
|
||||
@@ -27,15 +27,19 @@ const Fallback = ({ title, checks, link = "/" }) => {
|
||||
<Stack
|
||||
className={`fallback__${title.trim().split(" ")[0]}`}
|
||||
alignItems="center"
|
||||
gap={theme.gap.xl}
|
||||
gap={theme.spacing(20)}
|
||||
>
|
||||
<Skeleton style={{ zIndex: 1 }} />
|
||||
<Box
|
||||
className="background-pattern-svg"
|
||||
sx={{ backgroundImage: `url(${background})` }}
|
||||
/>
|
||||
<Stack gap={theme.gap.small} maxWidth={"275px"} zIndex={1}>
|
||||
<Typography component="h1" marginY={theme.gap.medium}>
|
||||
<Stack gap={theme.spacing(4)} maxWidth={"275px"} zIndex={1}>
|
||||
<Typography
|
||||
component="h1"
|
||||
marginY={theme.spacing(6)}
|
||||
color={theme.palette.text.secondary}
|
||||
>
|
||||
A {title} is used to:
|
||||
</Typography>
|
||||
{checks.map((check, index) => (
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
.checkbox-wrapper {
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.checkbox-wrapper:not(:has(.Mui-disabled)):hover {
|
||||
background-color: var(--unresolved-bg);
|
||||
}
|
||||
.checkbox-wrapper span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--secondary-color-light);
|
||||
}
|
||||
.checkbox-wrapper .MuiButtonBase-root {
|
||||
margin-right: var(--env-var-spacing-1);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { FormControlLabel, Checkbox as MuiCheckbox } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import CheckboxOutline from "../../../assets/icons/checkbox-outline.svg?react";
|
||||
import CheckboxFilled from "../../../assets/icons/checkbox-filled.svg?react";
|
||||
|
||||
@@ -16,7 +17,7 @@ import "./index.css";
|
||||
* @param {boolean} [props.isDisabled] - Whether the checkbox is disabled or not.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* <Checkbox
|
||||
* id="checkbox-id"
|
||||
@@ -37,6 +38,7 @@ const Checkbox = ({
|
||||
isDisabled,
|
||||
}) => {
|
||||
const sizes = { small: "14px", medium: "16px", large: "18px" };
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<FormControlLabel
|
||||
@@ -61,10 +63,20 @@ const Checkbox = ({
|
||||
label={label}
|
||||
disabled={isDisabled}
|
||||
sx={{
|
||||
p: "5px",
|
||||
m: "-5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
p: theme.spacing(2.5),
|
||||
m: theme.spacing(-2.5),
|
||||
"& .MuiButtonBase-root": {
|
||||
width: "20px",
|
||||
width: theme.spacing(10),
|
||||
p: 0,
|
||||
mr: theme.spacing(6),
|
||||
},
|
||||
"&:not(:has(.Mui-disabled)):hover": {
|
||||
backgroundColor: theme.palette.unresolved.bg,
|
||||
},
|
||||
"& span.MuiTypography-root": {
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.tertiary,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -8,24 +8,6 @@
|
||||
.field .input-error {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.field h3.MuiTypography-root,
|
||||
.field h5.MuiTypography-root,
|
||||
.field input,
|
||||
.field textarea {
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
.field h3.MuiTypography-root {
|
||||
font-weight: 500;
|
||||
}
|
||||
.field h3.MuiTypography-root span.field-required {
|
||||
color: var(--error-color);
|
||||
margin-left: 2px;
|
||||
}
|
||||
.field h3.MuiTypography-root span.field-optional {
|
||||
opacity: 0.6;
|
||||
margin-left: 4px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.field h5.MuiTypography-root {
|
||||
position: relative;
|
||||
opacity: 0.8;
|
||||
@@ -37,24 +19,7 @@
|
||||
.field .MuiInputBase-root:has(.MuiInputAdornment-root) {
|
||||
padding-right: var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field
|
||||
.MuiInputBase-root:has(.copy.MuiInputAdornment-root > .MuiButtonBase-root) {
|
||||
padding-right: 0;
|
||||
}
|
||||
.field .MuiInputBase-root .copy.MuiInputAdornment-root .MuiButtonBase-root {
|
||||
padding: 0 var(--env-var-spacing-1-minus);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
border-radius: 0;
|
||||
height: 34px;
|
||||
}
|
||||
.field .MuiInputBase-root .copy.MuiInputAdornment-root .MuiButtonBase-root svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.field .MuiInputBase-root .MuiInputAdornment-root .MuiButtonBase-root:hover {
|
||||
border-color: var(--border-color-dark);
|
||||
}
|
||||
|
||||
.field input {
|
||||
height: 100%;
|
||||
padding: 0 var(--env-var-spacing-1-minus);
|
||||
@@ -62,22 +27,6 @@
|
||||
.field .MuiInputBase-root:has(textarea) {
|
||||
padding: var(--env-var-spacing-1-minus);
|
||||
}
|
||||
.field .MuiOutlinedInput-root fieldset {
|
||||
border-color: var(--border-color-dark);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.field:not(:has(.Mui-disabled)):not(:has(.input-error))
|
||||
.MuiOutlinedInput-root:hover:not(:has(input:focus)):not(:has(textarea:focus))
|
||||
fieldset {
|
||||
border-color: var(--border-color-dark);
|
||||
}
|
||||
.field .input-error {
|
||||
color: var(--error-color);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.field:has(.input-error) .MuiOutlinedInput-root fieldset {
|
||||
border-color: var(--error-color);
|
||||
}
|
||||
|
||||
.register-page .field .MuiOutlinedInput-root fieldset,
|
||||
.register-page .field input,
|
||||
|
||||
@@ -23,7 +23,6 @@ import { forwardRef, useState } from "react";
|
||||
* @param {boolean} [props.isRequired] - Indicates if the field is required, will display a red asterisk.
|
||||
* @param {boolean} [props.isOptional] - Indicates if the field is optional, will display optional text.
|
||||
* @param {string} [props.optionalLabel] - Optional label for the input field.
|
||||
* @param {boolean} [props.hasCopy] - Indicates if the field supports copying.
|
||||
* @param {string} [props.autoComplete] - Autocomplete value for the input field.
|
||||
* @param {string} [props.placeholder] - Placeholder text for the input field.
|
||||
* @param {string} props.value - Value of the input field.
|
||||
@@ -43,7 +42,6 @@ const Field = forwardRef(
|
||||
isRequired,
|
||||
isOptional,
|
||||
optionalLabel,
|
||||
hasCopy,
|
||||
autoComplete,
|
||||
placeholder,
|
||||
value,
|
||||
@@ -56,25 +54,54 @@ const Field = forwardRef(
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
|
||||
// TODO - are we using this feature anywhere ?
|
||||
const [copy, setCopy] = useState(false);
|
||||
const handleCopy = () => {
|
||||
setCopy(true);
|
||||
setTimeout(() => setCopy(false), 1000);
|
||||
};
|
||||
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<Stack gap={theme.gap.xs} className={`field field-${type}`}>
|
||||
<Stack
|
||||
gap={theme.gap.xs}
|
||||
className={`field field-${type}`}
|
||||
sx={{
|
||||
"& fieldset": {
|
||||
borderColor: theme.palette.border.dark,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
"&:not(:has(.Mui-disabled)):not(:has(.input-error)) .MuiOutlinedInput-root:hover:not(:has(input:focus)):not(:has(textarea:focus)) fieldset":
|
||||
{
|
||||
borderColor: theme.palette.border.dark,
|
||||
},
|
||||
"&:has(.input-error) .MuiOutlinedInput-root fieldset": {
|
||||
borderColor: theme.palette.error.text,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{label && (
|
||||
<Typography component="h3">
|
||||
<Typography
|
||||
component="h3"
|
||||
color={theme.palette.text.secondary}
|
||||
fontWeight={500}
|
||||
>
|
||||
{label}
|
||||
{isRequired ? <span className="field-required">*</span> : ""}
|
||||
{isRequired ? (
|
||||
<Typography
|
||||
component="span"
|
||||
ml={theme.spacing(1)}
|
||||
color={theme.palette.error.text}
|
||||
>
|
||||
*
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{isOptional ? (
|
||||
<span className="field-optional">
|
||||
<Typography
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
fontWeight={400}
|
||||
ml={theme.spacing(2)}
|
||||
sx={{ opacity: 0.6 }}
|
||||
>
|
||||
{optionalLabel || "(optional)"}
|
||||
</span>
|
||||
</Typography>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
@@ -115,60 +142,48 @@ const Field = forwardRef(
|
||||
pl: theme.gap.medium,
|
||||
}}
|
||||
>
|
||||
<Typography component="h5" sx={{ lineHeight: 1 }}>
|
||||
<Typography
|
||||
component="h5"
|
||||
color={theme.palette.text.secondary}
|
||||
sx={{ lineHeight: 1 }}
|
||||
>
|
||||
{https ? "https" : "http"}://
|
||||
</Typography>
|
||||
</Stack>
|
||||
),
|
||||
endAdornment:
|
||||
type === "password" ? (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={() => setVisible((show) => !show)}
|
||||
tabIndex={-1}
|
||||
sx={{
|
||||
color: theme.palette.section.borderColor,
|
||||
padding: `calc(${theme.gap.xs} / 2)`,
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
"& .MuiTouchRipple-root": {
|
||||
pointerEvents: "none",
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{!isVisible ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
) : (
|
||||
hasCopy && (
|
||||
<InputAdornment className="copy" position="end">
|
||||
<Button
|
||||
level="tertiary"
|
||||
label={copy ? "Copied" : "Copy"}
|
||||
img={<ContentCopyIcon />}
|
||||
onClick={handleCopy}
|
||||
sx={{
|
||||
borderLeft: `solid 1px ${theme.palette.section.borderColor}`,
|
||||
lineHeight: 0,
|
||||
"& .MuiTouchRipple-root": {
|
||||
pointerEvents: "none",
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</InputAdornment>
|
||||
)
|
||||
),
|
||||
endAdornment: type === "password" && (
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={() => setVisible((show) => !show)}
|
||||
tabIndex={-1}
|
||||
sx={{
|
||||
color: theme.palette.section.borderColor,
|
||||
padding: `calc(${theme.gap.xs} / 2)`,
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
"& .MuiTouchRipple-root": {
|
||||
pointerEvents: "none",
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{!isVisible ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{error && (
|
||||
<Typography
|
||||
component="span"
|
||||
className="input-error"
|
||||
color={theme.palette.error.text}
|
||||
mt={theme.gap.xs}
|
||||
sx={{
|
||||
opacity: 0.8,
|
||||
}}
|
||||
>
|
||||
{error}
|
||||
</Typography>
|
||||
@@ -188,7 +203,6 @@ Field.propTypes = {
|
||||
isRequired: PropTypes.bool,
|
||||
isOptional: PropTypes.bool,
|
||||
optionalLabel: PropTypes.string,
|
||||
hasCopy: PropTypes.bool,
|
||||
autoComplete: PropTypes.string,
|
||||
placeholder: PropTypes.string,
|
||||
value: PropTypes.string.isRequired,
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
.image-field-wrapper h2.MuiTypography-root,
|
||||
.image-field-wrapper p.MuiTypography-root,
|
||||
.image-field-wrapper + p.MuiTypography-root,
|
||||
.MuiStack-root:has(#modal-update-picture) h1.MuiTypography-root {
|
||||
color: var(--secondary-color-light);
|
||||
}
|
||||
.MuiStack-root:has(#modal-update-picture) h1.MuiTypography-root {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -20,10 +14,5 @@
|
||||
}
|
||||
.image-field-wrapper + p.MuiTypography-root,
|
||||
.image-field-wrapper p.MuiTypography-root {
|
||||
opacity: 0.6;
|
||||
font-size: var(--env-var-font-size-small-plus);
|
||||
}
|
||||
.image-field-wrapper h2.MuiTypography-root span {
|
||||
color: var(--theme-main);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -31,19 +31,19 @@ const ImageField = ({ id, src, loading, onChange }) => {
|
||||
<>
|
||||
<Box
|
||||
className="image-field-wrapper"
|
||||
mt="20px"
|
||||
mt={theme.spacing(8)}
|
||||
sx={{
|
||||
position: "relative",
|
||||
height: "fit-content",
|
||||
border: "dashed",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
borderColor: isDragging
|
||||
? theme.palette.primary.main
|
||||
: theme.palette.otherColors.graishWhite,
|
||||
? theme.palette.common.main
|
||||
: theme.palette.border.light,
|
||||
borderWidth: "2px",
|
||||
transition: "0.2s",
|
||||
"&:hover": {
|
||||
borderColor: theme.palette.primary.main,
|
||||
borderColor: theme.palette.common.main,
|
||||
backgroundColor: "hsl(215, 87%, 51%, 0.05)",
|
||||
},
|
||||
}}
|
||||
@@ -85,20 +85,40 @@ const ImageField = ({ id, src, loading, onChange }) => {
|
||||
<IconButton
|
||||
sx={{
|
||||
pointerEvents: "none",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
border: `solid ${theme.shape.borderThick}px ${theme.palette.otherColors.graishWhite}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
border: `solid ${theme.shape.borderThick}px ${theme.palette.border.light}`,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
}}
|
||||
>
|
||||
<CloudUploadIcon />
|
||||
</IconButton>
|
||||
<Typography component="h2">
|
||||
<span>Click to upload</span> or drag and drop
|
||||
<Typography component="h2" color={theme.palette.text.tertiary}>
|
||||
<Typography
|
||||
component="span"
|
||||
fontSize="inherit"
|
||||
color={theme.palette.common.main}
|
||||
fontWeight={500}
|
||||
>
|
||||
Click to upload
|
||||
</Typography>{" "}
|
||||
or drag and drop
|
||||
</Typography>
|
||||
<Typography
|
||||
component="p"
|
||||
color={theme.palette.text.tertiary}
|
||||
sx={{ opacity: 0.6 }}
|
||||
>
|
||||
(maximum size: 3MB)
|
||||
</Typography>
|
||||
<Typography component="p">(maximum size: 3MB)</Typography>
|
||||
</Stack>
|
||||
</Box>
|
||||
<Typography component="p">Supported formats: JPG, PNG</Typography>
|
||||
<Typography
|
||||
component="p"
|
||||
color={theme.palette.text.tertiary}
|
||||
sx={{ opacity: 0.6 }}
|
||||
>
|
||||
Supported formats: JPG, PNG
|
||||
</Typography>
|
||||
</>
|
||||
) : (
|
||||
<Stack direction="row" justifyContent="center">
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
+37
-16
@@ -1,10 +1,16 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { FormControlLabel, Radio as MUIRadio, Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import RadioChecked from "../../../assets/icons/radio-checked.svg?react";
|
||||
import "./index.css";
|
||||
|
||||
/**
|
||||
* RadioButton component.
|
||||
* Radio component.
|
||||
*
|
||||
* @component
|
||||
* @example
|
||||
* // Usage:
|
||||
* <RadioButton
|
||||
* <Radio
|
||||
* title="Radio Button Title"
|
||||
* desc="Radio Button Description"
|
||||
* size="small"
|
||||
@@ -15,47 +21,62 @@
|
||||
* @param {string} props.title - The title of the radio button.
|
||||
* @param {string} [props.desc] - The description of the radio button.
|
||||
* @param {string} [props.size="small"] - The size of the radio button.
|
||||
* @returns {JSX.Element} - The rendered RadioButton component.
|
||||
* @returns {JSX.Element} - The rendered Radio component.
|
||||
*/
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { FormControlLabel, Radio, Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import "./index.css";
|
||||
|
||||
function RadioButton(props) {
|
||||
const Radio = (props) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<FormControlLabel
|
||||
className="custom-radio-button"
|
||||
checked={props.checked}
|
||||
value={props.value}
|
||||
control={
|
||||
<Radio
|
||||
<MUIRadio
|
||||
id={props.id}
|
||||
size={props.size}
|
||||
sx={{ color: theme.palette.secondary.main }}
|
||||
checkedIcon={<RadioChecked />}
|
||||
sx={{
|
||||
color: "transparent",
|
||||
width: 16,
|
||||
height: 16,
|
||||
boxShadow: "inset 0 0 0 1px rgb(16 22 26 / 40%)",
|
||||
mt: theme.spacing(0.5),
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onChange={props.onChange}
|
||||
label={
|
||||
<>
|
||||
<Typography component="p">{props.title}</Typography>
|
||||
<Typography component="h6" mt="2px">
|
||||
<Typography component="h6" mt={theme.spacing(1)}>
|
||||
{props.desc}
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
labelPlacement="end"
|
||||
sx={{ margin: 0, alignItems: "flex-start" }}
|
||||
sx={{
|
||||
alignItems: "flex-start",
|
||||
p: theme.spacing(2.5),
|
||||
m: theme.spacing(-2.5),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.unresolved.bg,
|
||||
},
|
||||
"& .MuiButtonBase-root": {
|
||||
p: 0,
|
||||
mr: theme.spacing(6),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
RadioButton.propTypes = {
|
||||
Radio.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
desc: PropTypes.string,
|
||||
size: PropTypes.string,
|
||||
};
|
||||
|
||||
export default RadioButton;
|
||||
export default Radio;
|
||||
@@ -1,46 +1,12 @@
|
||||
.select-wrapper .select-component > .MuiSelect-select {
|
||||
padding: 0 10px;
|
||||
height: 34px !important;
|
||||
display: flex !important;
|
||||
height: 34px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: capitalize;
|
||||
line-height: 1;
|
||||
}
|
||||
.select-wrapper .MuiInputBase-root:has(> .MuiSelect-select) {
|
||||
min-width: 150px;
|
||||
}
|
||||
.select-wrapper .MuiInputBase-root:has(> .MuiSelect-select),
|
||||
.MuiMenu-List .MuiMenuItem-root,
|
||||
.select-wrapper h3.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
.select-wrapper h3.MuiTypography-root {
|
||||
font-weight: 500;
|
||||
}
|
||||
.MuiInputBase-root:has(> .MuiSelect-select) fieldset {
|
||||
border-color: var(--border-color-dark);
|
||||
}
|
||||
.MuiInputBase-root:not(.Mui-focused):has(> .MuiSelect-select):hover fieldset {
|
||||
border-color: var(--border-color-dark);
|
||||
}
|
||||
|
||||
.select-dropdown.MuiPaper-root {
|
||||
box-shadow: var(--env-var-shadow-1);
|
||||
border: solid 1px var(--border-color);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.select-dropdown .MuiList-root {
|
||||
min-width: 100px;
|
||||
}
|
||||
.select-dropdown li {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--secondary-color);
|
||||
padding: 5px 8px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.select-dropdown li.Mui-selected,
|
||||
.select-dropdown li.Mui-selected.Mui-focusVisible,
|
||||
.select-dropdown li.Mui-selected:hover {
|
||||
background-color: var(--primary-bg-fill);
|
||||
}
|
||||
|
||||
@@ -55,15 +55,22 @@ const Select = ({
|
||||
const theme = useTheme();
|
||||
const itemStyles = {
|
||||
fontSize: "var(--env-var-font-size-medium)",
|
||||
color: theme.palette.otherColors.bluishGray,
|
||||
textTransform: "capitalize",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
margin: theme.gap.xs,
|
||||
color: theme.palette.text.tertiary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
margin: theme.spacing(2),
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap={theme.gap.xs} className="select-wrapper">
|
||||
{label && <Typography component="h3">{label}</Typography>}
|
||||
<Stack gap={theme.spacing(2)} className="select-wrapper">
|
||||
{label && (
|
||||
<Typography
|
||||
component="h3"
|
||||
color={theme.palette.text.secondary}
|
||||
fontWeight={500}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
)}
|
||||
<MuiSelect
|
||||
className="select-component"
|
||||
value={value}
|
||||
@@ -72,17 +79,43 @@ const Select = ({
|
||||
inputProps={{ id: id }}
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
className: "select-dropdown",
|
||||
style: {
|
||||
marginTop: theme.gap.xs,
|
||||
sx: {
|
||||
marginTop: theme.spacing(2),
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
},
|
||||
},
|
||||
MenuListProps: {
|
||||
style: { padding: 0 },
|
||||
sx: {
|
||||
p: 0,
|
||||
"& li": {
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 13,
|
||||
px: theme.spacing(4),
|
||||
py: theme.spacing(2.5),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
"& li.Mui-selected, & li.Mui-selected.Mui-focusVisible, & li.Mui-selected:hover":
|
||||
{
|
||||
backgroundColor: theme.palette.background.fill,
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
IconComponent={KeyboardArrowDownIcon}
|
||||
sx={{ ...sx }}
|
||||
sx={{
|
||||
minWidth: "125px",
|
||||
"& fieldset": {
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
borderColor: theme.palette.border.dark,
|
||||
},
|
||||
"&:not(.Mui-focused):hover fieldset": {
|
||||
borderColor: theme.palette.border.dark,
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
{placeholder && (
|
||||
<MenuItem
|
||||
|
||||
@@ -30,9 +30,9 @@ const BaseLabel = ({ label, styles, children }) => {
|
||||
<Box
|
||||
className="label"
|
||||
sx={{
|
||||
borderRadius: `${borderRadius}px`,
|
||||
borderColor: theme.palette.tertiary.main,
|
||||
color: theme.palette.tertiary.main,
|
||||
borderRadius: borderRadius,
|
||||
borderColor: theme.palette.text.tertiary,
|
||||
color: theme.palette.text.tertiary,
|
||||
padding: padding,
|
||||
...styles,
|
||||
}}
|
||||
@@ -90,7 +90,7 @@ const ColoredLabel = ({ label, color }) => {
|
||||
typeof color !== "string" ||
|
||||
!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(color)
|
||||
) {
|
||||
color = theme.palette.labelGray.color;
|
||||
color = theme.palette.border.light;
|
||||
}
|
||||
|
||||
// Calculate lighter shades for border and bg
|
||||
@@ -127,8 +127,26 @@ ColoredLabel.propTypes = {
|
||||
|
||||
const StatusLabel = ({ status, text, customStyles }) => {
|
||||
const theme = useTheme();
|
||||
const colors = {
|
||||
up: {
|
||||
dotColor: theme.palette.success.main,
|
||||
bgColor: theme.palette.success.bg,
|
||||
borderColor: theme.palette.success.light,
|
||||
},
|
||||
down: {
|
||||
dotColor: theme.palette.error.text,
|
||||
bgColor: theme.palette.error.bg,
|
||||
borderColor: theme.palette.error.light,
|
||||
},
|
||||
"cannot resolve": {
|
||||
dotColor: theme.palette.unresolved.main,
|
||||
bgColor: theme.palette.unresolved.bg,
|
||||
borderColor: theme.palette.unresolved.light,
|
||||
},
|
||||
};
|
||||
|
||||
// Look up the color for the status
|
||||
const { borderColor, bgColor, dotColor } = theme.label[status];
|
||||
const { borderColor, bgColor, dotColor } = colors[status];
|
||||
|
||||
return (
|
||||
<BaseLabel
|
||||
|
||||
@@ -16,24 +16,24 @@ const Link = ({ level, label, url }) => {
|
||||
const levelConfig = {
|
||||
primary: {},
|
||||
secondary: {
|
||||
color: theme.palette.otherColors.bluishGray,
|
||||
color: theme.palette.text.secondary,
|
||||
sx: {
|
||||
":hover": {
|
||||
color: theme.palette.otherColors.bluishGray,
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
},
|
||||
},
|
||||
tertiary: {
|
||||
color: theme.palette.tertiary.main,
|
||||
color: theme.palette.text.tertiary,
|
||||
sx: {
|
||||
textDecoration: "underline",
|
||||
textDecorationStyle: "dashed",
|
||||
textDecorationColor: theme.palette.primary.main,
|
||||
textDecorationColor: theme.palette.common.main,
|
||||
textUnderlineOffset: "1px",
|
||||
":hover": {
|
||||
color: theme.palette.tertiary.main,
|
||||
textDecorationColor: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.tertiary.linkHover,
|
||||
color: theme.palette.text.tertiary,
|
||||
textDecorationColor: theme.palette.common.main,
|
||||
backgroundColor: theme.palette.background.fill,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,32 +1,10 @@
|
||||
.progress-bar-container {
|
||||
background-color: #fafafa;
|
||||
padding: var(--env-var-spacing-1-plus);
|
||||
}
|
||||
.progress-bar-container h2.MuiTypography-root,
|
||||
.progress-bar-container p.MuiTypography-root {
|
||||
color: var(--secondary-color-light);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.progress-bar-container p.MuiTypography-root {
|
||||
opacity: 0.6;
|
||||
}
|
||||
.progress-bar-container p.MuiTypography-root:has(span) {
|
||||
font-size: 12px;
|
||||
}
|
||||
.progress-bar-container p.MuiTypography-root span {
|
||||
padding-left: 2px;
|
||||
}
|
||||
.progress-bar-container:has(p.input-error){
|
||||
border-color: var(--error-color);
|
||||
background-color: var(--error-bg);
|
||||
padding: 8px var(--env-var-spacing-1-plus);
|
||||
}
|
||||
.progress-bar-container p.input-error{
|
||||
color: var(--error-color);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.progress-bar-container:has(p.input-error)>.MuiStack-root>svg{
|
||||
fill: var(--error-color);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@@ -32,21 +32,36 @@ const ProgressUpload = ({
|
||||
error,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="progress-bar-container"
|
||||
mt="20px"
|
||||
mt={theme.spacing(10)}
|
||||
p={theme.spacing(8)}
|
||||
sx={{
|
||||
minWidth: "200px",
|
||||
height: "fit-content",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
border: `solid 1px ${theme.palette.otherColors.graishWhite}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
backgroundColor: "#fafafa",
|
||||
"&:has(.input-error)": {
|
||||
borderColor: theme.palette.error.main,
|
||||
backgroundColor: theme.palette.error.bg,
|
||||
py: theme.spacing(4),
|
||||
px: theme.spacing(8),
|
||||
"& > .MuiStack-root > svg": {
|
||||
fill: theme.palette.error.text,
|
||||
width: "20px",
|
||||
height: "20px",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
mb={error ? "0" : "10px"}
|
||||
gap="10px"
|
||||
mb={error ? 0 : theme.spacing(5)}
|
||||
gap={theme.spacing(5)}
|
||||
alignItems={error ? "center" : "flex-end"}
|
||||
>
|
||||
{error ? (
|
||||
@@ -54,10 +69,11 @@ const ProgressUpload = ({
|
||||
) : icon ? (
|
||||
<IconButton
|
||||
sx={{
|
||||
backgroundColor: theme.palette.otherColors.white,
|
||||
backgroundColor: theme.palette.background.main,
|
||||
pointerEvents: "none",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
border: `solid ${theme.shape.borderThick}px ${theme.palette.otherColors.graishWhite}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
border: 2,
|
||||
borderColor: theme.palette.border.light,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
}}
|
||||
>
|
||||
@@ -67,15 +83,21 @@ const ProgressUpload = ({
|
||||
""
|
||||
)}
|
||||
{error ? (
|
||||
<Typography component="p" className="input-error">
|
||||
<Typography
|
||||
component="p"
|
||||
className="input-error"
|
||||
color={theme.palette.error.text}
|
||||
>
|
||||
{error}
|
||||
</Typography>
|
||||
) : (
|
||||
<Box>
|
||||
<Typography component="h2" mb="5px">
|
||||
<Box color={theme.palette.text.tertiary}>
|
||||
<Typography component="h2" mb={theme.spacing(1.5)}>
|
||||
{error ? error : label}
|
||||
</Typography>
|
||||
<Typography component="p">{!error && size}</Typography>
|
||||
<Typography component="p" sx={{ opacity: 0.6 }}>
|
||||
{!error && size}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<IconButton
|
||||
@@ -85,9 +107,9 @@ const ProgressUpload = ({
|
||||
? {
|
||||
alignSelf: "flex-start",
|
||||
ml: "auto",
|
||||
mr: "-5px",
|
||||
mt: "-5px",
|
||||
padding: "5px",
|
||||
mr: theme.spacing(-2.5),
|
||||
mt: theme.spacing(-2.5),
|
||||
padding: theme.spacing(2.5),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
@@ -109,20 +131,23 @@ const ProgressUpload = ({
|
||||
</Stack>
|
||||
{!error ? (
|
||||
<Stack direction="row" alignItems="center">
|
||||
<Box sx={{ width: "100%", mr: "10px" }}>
|
||||
<Box sx={{ width: "100%", mr: theme.spacing(5) }}>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={progress}
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "10px",
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
maxWidth: "500px",
|
||||
backgroundColor: theme.palette.otherColors.graishWhite,
|
||||
backgroundColor: theme.palette.border.light,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<Typography component="p" sx={{ minWidth: "max-content" }}>
|
||||
<Typography
|
||||
component="p"
|
||||
sx={{ minWidth: "max-content", opacity: 0.6 }}
|
||||
>
|
||||
{progress}
|
||||
<span>%</span>
|
||||
</Typography>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
.create-monitor-form .custom-radio-button.MuiFormControlLabel-root,
|
||||
.configure-monitor .custom-radio-button.MuiFormControlLabel-root {
|
||||
padding: 5px;
|
||||
margin: -5px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
.create-monitor-form .custom-radio-button.MuiFormControlLabel-root:hover,
|
||||
.configure-monitor .custom-radio-button.MuiFormControlLabel-root:hover {
|
||||
background-color: var(--unresolved-bg);
|
||||
}
|
||||
|
||||
.custom-radio-button.MuiFormControlLabel-root .MuiButtonBase-root {
|
||||
margin-right: var(--env-var-spacing-1);
|
||||
padding: 0;
|
||||
}
|
||||
@@ -1,16 +1,8 @@
|
||||
aside .selected-path,
|
||||
.sidebar-popup .selected-path,
|
||||
aside .MuiListItemButton-root:hover {
|
||||
background-color: var(--primary-bg-accent);
|
||||
}
|
||||
aside .MuiList-root svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
aside .MuiList-root svg path {
|
||||
stroke: var(--secondary-color-light);
|
||||
}
|
||||
aside span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
line-height: 1;
|
||||
@@ -26,11 +18,6 @@ aside .MuiListSubheader-root {
|
||||
margin-bottom: 2px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
aside span.MuiTypography-root,
|
||||
aside p.MuiTypography-root,
|
||||
aside .MuiListSubheader-root {
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
aside p.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-small);
|
||||
opacity: 0.8;
|
||||
@@ -47,82 +34,15 @@ aside .selected-path span.MuiTypography-root {
|
||||
aside .MuiCollapse-wrapperInner .MuiList-root > .MuiListItemButton-root {
|
||||
position: relative;
|
||||
}
|
||||
aside .MuiDivider-root {
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
aside
|
||||
.MuiCollapse-wrapperInner
|
||||
.MuiList-root
|
||||
> .MuiListItemButton-root::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -7px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-left: solid 1px var(--secondary-color);
|
||||
opacity: 0.2;
|
||||
}
|
||||
aside
|
||||
.MuiCollapse-wrapperInner
|
||||
.MuiList-root
|
||||
> .MuiListItemButton-root:last-child::before {
|
||||
height: 50%;
|
||||
}
|
||||
aside .MuiCollapse-wrapperInner .MuiList-root svg,
|
||||
aside .MuiList-root .MuiListItemText-root + svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
aside .MuiCollapse-wrapperInner .MuiList-root > .MuiListItemButton-root::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 45%;
|
||||
height: 3px;
|
||||
width: 3px;
|
||||
border-radius: 50%;
|
||||
background-color: #d6d9dd;
|
||||
}
|
||||
|
||||
aside
|
||||
.MuiCollapse-wrapperInner
|
||||
.MuiList-root
|
||||
> .selected-path.MuiListItemButton-root::after {
|
||||
background-color: var(--secondary-color-light);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.sidebar-popup .MuiPaper-root {
|
||||
box-shadow: var(--env-var-shadow-1);
|
||||
border: solid 1px var(--border-color);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
gap: 1px;
|
||||
}
|
||||
.sidebar-popup .MuiList-root {
|
||||
padding: 3px;
|
||||
min-width: 100px;
|
||||
}
|
||||
.sidebar-popup 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);
|
||||
}
|
||||
.sidebar-popup li.MuiButtonBase-root:hover {
|
||||
background-color: var(--primary-bg-accent);
|
||||
}
|
||||
.sidebar-popup li.MuiButtonBase-root:has(.MuiBox-root):hover {
|
||||
background-color: white;
|
||||
}
|
||||
.sidebar-popup li.MuiButtonBase-root:has(.MuiBox-root) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.sidebar-popup .MuiModal-root p.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--secondary-color-light);
|
||||
}
|
||||
.sidebar-popup svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
@@ -124,21 +124,33 @@ function Sidebar() {
|
||||
<Stack
|
||||
component="aside"
|
||||
className={collapsed ? "collapsed" : "expanded"}
|
||||
gap={theme.gap.medium}
|
||||
gap={theme.spacing(6)}
|
||||
sx={{
|
||||
"& .selected-path, & .MuiListItemButton-root:hover": {
|
||||
backgroundColor: theme.palette.background.accent,
|
||||
},
|
||||
"& .MuiList-root svg path": {
|
||||
stroke: theme.palette.text.tertiary,
|
||||
},
|
||||
"& p, & span, & .MuiListSubheader-root": {
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Stack pt={theme.gap.medium} pb={theme.gap.large} pl={theme.gap.ml}>
|
||||
<Stack direction="row" alignItems="center" gap={theme.gap.small}>
|
||||
<Stack pt={theme.spacing(6)} pb={theme.spacing(12)} pl={theme.spacing(8)}>
|
||||
<Stack direction="row" alignItems="center" gap={theme.spacing(4)}>
|
||||
<Stack
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
minWidth={theme.gap.lgplus}
|
||||
minHeight={theme.gap.lgplus}
|
||||
fontSize="18px"
|
||||
minWidth={theme.spacing(16)}
|
||||
minHeight={theme.spacing(16)}
|
||||
pl="1px"
|
||||
fontSize={18}
|
||||
color="white"
|
||||
sx={{
|
||||
position: "relative",
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: "4px",
|
||||
backgroundColor: theme.palette.common.main,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
@@ -146,7 +158,7 @@ function Sidebar() {
|
||||
</Stack>
|
||||
<Typography
|
||||
component="span"
|
||||
mt={theme.gap.xs}
|
||||
mt={theme.spacing(2)}
|
||||
sx={{ opacity: 0.8, fontWeight: 500 }}
|
||||
>
|
||||
BlueWave Uptime
|
||||
@@ -158,20 +170,21 @@ function Sidebar() {
|
||||
top: 60,
|
||||
right: 0,
|
||||
transform: `translate(50%, 0)`,
|
||||
backgroundColor: theme.palette.otherColors.fillGray,
|
||||
border: `solid 1px ${theme.palette.otherColors.graishWhite}`,
|
||||
p: "5px",
|
||||
backgroundColor: theme.palette.background.fill,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
p: theme.spacing(2.5),
|
||||
"& svg": {
|
||||
width: theme.gap.ml,
|
||||
height: theme.gap.ml,
|
||||
width: theme.spacing(8),
|
||||
height: theme.spacing(8),
|
||||
"& path": {
|
||||
stroke: theme.palette.otherColors.bluishGray,
|
||||
stroke: theme.palette.text.secondary,
|
||||
},
|
||||
},
|
||||
"&:focus": { outline: "none" },
|
||||
"&:hover": {
|
||||
backgroundColor: "#e3e3e3",
|
||||
borderColor: theme.palette.otherColors.graishWhite,
|
||||
backgroundColor: theme.palette.border.light,
|
||||
borderColor: theme.palette.border.light,
|
||||
},
|
||||
}}
|
||||
onClick={() => {
|
||||
@@ -192,15 +205,15 @@ function Sidebar() {
|
||||
component="div"
|
||||
id="nested-menu-subheader"
|
||||
sx={{
|
||||
pt: theme.gap.small,
|
||||
px: collapsed ? theme.gap.xs : theme.gap.small,
|
||||
backgroundColor: "transparent"
|
||||
pt: theme.spacing(4),
|
||||
px: collapsed ? theme.spacing(2) : theme.spacing(4),
|
||||
backgroundColor: "transparent",
|
||||
}}
|
||||
>
|
||||
Menu
|
||||
</ListSubheader>
|
||||
}
|
||||
sx={{ px: theme.gap.medium }}
|
||||
sx={{ px: theme.spacing(6) }}
|
||||
>
|
||||
{menu.map((item) =>
|
||||
item.path ? (
|
||||
@@ -229,9 +242,9 @@ function Sidebar() {
|
||||
onClick={() => navigate(`/${item.path}`)}
|
||||
sx={{
|
||||
height: "37px",
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
px: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
px: theme.spacing(4),
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
|
||||
@@ -266,9 +279,9 @@ function Sidebar() {
|
||||
onClick={(event) => openPopup(event, item.name)}
|
||||
sx={{
|
||||
position: "relative",
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
px: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
px: theme.spacing(4),
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
|
||||
@@ -284,7 +297,38 @@ function Sidebar() {
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
sx={{ ml: theme.gap.ml }}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
},
|
||||
},
|
||||
}}
|
||||
MenuListProps={{
|
||||
sx: {
|
||||
p: 3,
|
||||
minWidth: "100px",
|
||||
"& li": {
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 13,
|
||||
px: theme.spacing(4),
|
||||
py: theme.spacing(2.5),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
"& li:hover": {
|
||||
backgroundColor: theme.palette.background.accent,
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{
|
||||
ml: theme.spacing(8),
|
||||
"& .selected-path": {
|
||||
backgroundColor: theme.palette.background.accent,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{item.nested.map((child) => {
|
||||
if (
|
||||
@@ -308,9 +352,9 @@ function Sidebar() {
|
||||
closePopup();
|
||||
}}
|
||||
sx={{
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
pl: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
pl: theme.spacing(4),
|
||||
mb: "1px",
|
||||
}}
|
||||
>
|
||||
@@ -331,9 +375,9 @@ function Sidebar() {
|
||||
}))
|
||||
}
|
||||
sx={{
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
px: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
px: theme.spacing(4),
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
|
||||
@@ -344,7 +388,7 @@ function Sidebar() {
|
||||
<List
|
||||
component="div"
|
||||
disablePadding
|
||||
sx={{ pl: theme.gap.large }}
|
||||
sx={{ pl: theme.spacing(12) }}
|
||||
>
|
||||
{item.nested.map((child) => {
|
||||
if (
|
||||
@@ -365,9 +409,35 @@ function Sidebar() {
|
||||
key={child.path}
|
||||
onClick={() => navigate(`/${child.path}`)}
|
||||
sx={{
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
pl: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
pl: theme.spacing(4),
|
||||
"&::before": {
|
||||
content: `""`,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: "-7px",
|
||||
height: "100%",
|
||||
borderLeft: 1,
|
||||
borderLeftColor: "#d6d9dd",
|
||||
},
|
||||
"&:last-child::before": {
|
||||
height: "50%",
|
||||
},
|
||||
"&::after": {
|
||||
content: `""`,
|
||||
position: "absolute",
|
||||
top: "45%",
|
||||
left: "-8px",
|
||||
height: "3px",
|
||||
width: "3px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#d6d9dd",
|
||||
},
|
||||
"&.selected-path::after": {
|
||||
backgroundColor: theme.palette.text.tertiary,
|
||||
transform: "scale(1.2)",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 0 }}>
|
||||
@@ -383,7 +453,9 @@ function Sidebar() {
|
||||
)
|
||||
)}
|
||||
</List>
|
||||
<Divider sx={{ my: theme.gap.small }} />
|
||||
<Divider
|
||||
sx={{ my: theme.spacing(4), borderColor: theme.palette.border.light }}
|
||||
/>
|
||||
{/* other */}
|
||||
<List
|
||||
component="nav"
|
||||
@@ -393,15 +465,15 @@ function Sidebar() {
|
||||
component="div"
|
||||
id="nested-other-subheader"
|
||||
sx={{
|
||||
pt: theme.gap.small,
|
||||
px: collapsed ? 0 : theme.gap.small,
|
||||
backgroundColor: "transparent"
|
||||
pt: theme.spacing(4),
|
||||
px: collapsed ? 0 : theme.spacing(4),
|
||||
backgroundColor: "transparent",
|
||||
}}
|
||||
>
|
||||
Other
|
||||
</ListSubheader>
|
||||
}
|
||||
sx={{ px: theme.gap.medium }}
|
||||
sx={{ px: theme.spacing(6) }}
|
||||
>
|
||||
{other.map((item) => (
|
||||
<Tooltip
|
||||
@@ -436,9 +508,9 @@ function Sidebar() {
|
||||
: navigate(`/${item.path}`)
|
||||
}
|
||||
sx={{
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
px: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
px: theme.spacing(4),
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
|
||||
@@ -447,16 +519,16 @@ function Sidebar() {
|
||||
</Tooltip>
|
||||
))}
|
||||
</List>
|
||||
<Divider sx={{ mt: "auto" }} />
|
||||
<Divider sx={{ mt: "auto", borderColor: theme.palette.border.light }} />
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
height="50px"
|
||||
alignItems="center"
|
||||
py={theme.gap.small}
|
||||
px={theme.gap.ml}
|
||||
gap={theme.gap.xs}
|
||||
borderRadius={`${theme.shape.borderRadius}px`}
|
||||
py={theme.spacing(4)}
|
||||
px={theme.spacing(8)}
|
||||
gap={theme.spacing(2)}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
>
|
||||
{collapsed ? (
|
||||
<>
|
||||
@@ -492,27 +564,56 @@ function Sidebar() {
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
sx={{ ml: theme.gap.ml }}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
},
|
||||
},
|
||||
}}
|
||||
MenuListProps={{
|
||||
sx: {
|
||||
p: 3,
|
||||
minWidth: "100px",
|
||||
"& li": {
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 13,
|
||||
px: theme.spacing(4),
|
||||
py: theme.spacing(2.5),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
"& li:hover": {
|
||||
backgroundColor: theme.palette.background.accent,
|
||||
},
|
||||
"& li:has(.MuiBox-root):hover": {
|
||||
backgroundColor: theme.palette.background.main,
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{ ml: theme.spacing(8) }}
|
||||
>
|
||||
<MenuItem sx={{ cursor: "default", minWidth: "150px" }}>
|
||||
<Box>
|
||||
<Typography component="span" fontWeight={500} fontSize="13px">
|
||||
<Typography component="span" fontWeight={500} fontSize={13}>
|
||||
{authState.user?.firstName} {authState.user?.lastName}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{ textTransform: "capitalize", fontSize: "12px" }}
|
||||
sx={{ textTransform: "capitalize", fontSize: 12 }}
|
||||
>
|
||||
{authState.user?.role}
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
<Divider sx={{ borderColor: theme.palette.border.light }} />
|
||||
<MenuItem
|
||||
onClick={logout}
|
||||
sx={{
|
||||
gap: theme.gap.small,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
pl: theme.gap.small,
|
||||
gap: theme.spacing(4),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
pl: theme.spacing(4),
|
||||
}}
|
||||
>
|
||||
<LogoutSvg />
|
||||
@@ -523,7 +624,7 @@ function Sidebar() {
|
||||
) : (
|
||||
<>
|
||||
<Avatar small={true} />
|
||||
<Box ml={theme.gap.xs}>
|
||||
<Box ml={theme.spacing(2)}>
|
||||
<Typography component="span" fontWeight={500}>
|
||||
{authState.user?.firstName} {authState.user?.lastName}
|
||||
</Typography>
|
||||
@@ -531,7 +632,7 @@ function Sidebar() {
|
||||
{authState.user?.role}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Tooltip title="Log Out">
|
||||
<Tooltip title="Log Out" disableInteractive>
|
||||
<IconButton
|
||||
sx={{ ml: "auto", "&:focus": { outline: "none" } }}
|
||||
onClick={logout}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "./index.css";
|
||||
import { useState } from "react";
|
||||
import RadioButton from "../../../Components/RadioButton";
|
||||
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";
|
||||
@@ -211,7 +211,7 @@ const CreateMonitor = () => {
|
||||
</Box>
|
||||
<Stack gap={theme.gap.large}>
|
||||
<Stack gap={theme.gap.medium}>
|
||||
<RadioButton
|
||||
<Radio
|
||||
id="monitor-checks-http"
|
||||
title="Website monitoring"
|
||||
desc="Use HTTP(s) to monitor your website or API endpoint."
|
||||
@@ -245,7 +245,7 @@ const CreateMonitor = () => {
|
||||
""
|
||||
)}
|
||||
</Stack>
|
||||
<RadioButton
|
||||
<Radio
|
||||
id="monitor-checks-ping"
|
||||
title="Ping monitoring"
|
||||
desc="Check whether your server is available or not."
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8Z" fill="#1570EF"/>
|
||||
<path d="M5 8C5 6.34315 6.34315 5 8 5C9.65685 5 11 6.34315 11 8C11 9.65685 9.65685 11 8 11C6.34315 11 5 9.65685 5 8Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 371 B |
Reference in New Issue
Block a user