Merge branch 'master' into feat/server-db-images
This commit is contained in:
commit
b6da1ce7c1
69 files changed
+4439
-813
No files matched your search
Generated
+1494
-350
File diff suppressed because it is too large.
Load diff
@@ -18,9 +18,12 @@
|
||||
"@mui/x-charts": "^7.5.1",
|
||||
"@mui/x-data-grid": "7.3.2",
|
||||
"@mui/x-date-pickers": "7.3.2",
|
||||
"@reduxjs/toolkit": "2.2.5",
|
||||
"axios": "1.7.2",
|
||||
"dayjs": "1.11.11",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "9.1.2",
|
||||
"react-router": "^6.23.0",
|
||||
"react-router-dom": "^6.23.0"
|
||||
},
|
||||
|
||||
+13
-2
@@ -6,17 +6,21 @@ import Register from "./Pages/Register";
|
||||
import HomeLayout from "./Layouts/HomeLayout";
|
||||
import Demo from "./Pages/Demo/Demo";
|
||||
import PlayGround from "./Pages/PlayGround/PlayGround";
|
||||
import Monitors from "./Pages/Monitors"
|
||||
import Monitors from "./Pages/Monitors";
|
||||
import Incidents from "./Pages/Incidents";
|
||||
import Status from "./Pages/Status";
|
||||
import Integrations from "./Pages/Integrations";
|
||||
import Settings from "./Pages/Settings";
|
||||
import ForgotPassword from "./Pages/ForgotPassword";
|
||||
import CheckEmail from "./Pages/CheckEmail";
|
||||
import SetNewPassword from "./Pages/SetNewPassword";
|
||||
import NewPasswordConfirmed from "./Pages/NewPasswordConfirmed";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<Routes>
|
||||
<Route exact path="/" element={<HomeLayout />} >
|
||||
<Route exact path="/" element={<HomeLayout />}>
|
||||
<Route path="monitors" element={<Monitors />} />
|
||||
<Route path="incidents" element={<Incidents />} />
|
||||
<Route path="status" element={<Status />} />
|
||||
@@ -28,6 +32,13 @@ function App() {
|
||||
<Route exact path="/demo" element={<Demo />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
<Route path="/playground" element={<PlayGround />} />
|
||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||
<Route path="/check-email" element={<CheckEmail />} />
|
||||
<Route path="/set-new-password" element={<SetNewPassword />} />
|
||||
<Route
|
||||
path="/new-password-confirmed"
|
||||
element={<NewPasswordConfirmed />}
|
||||
/>
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
|
||||
+22
-39
@@ -1,22 +1,5 @@
|
||||
:root {
|
||||
--update-subscription-color-0: #101828;
|
||||
--update-subscription-color-1: #475467;
|
||||
--update-subscription-color-2: #fff;
|
||||
--update-subscription-color-3: #eaecf0;
|
||||
--update-subscription-color-4: #7f56d9;
|
||||
--update-subscription-color-5: #1570ef;
|
||||
--update-subscription-color-6: #344054;
|
||||
--update-subscription-color-7: #d0d5dd;
|
||||
--update-subscription-padding-0: 12px 16px;
|
||||
--update-subscription-margin-right: 12px;
|
||||
--update-subscription-font-size: 13px;
|
||||
--update-subscription-radius-0: 4px;
|
||||
--spacing-1: 16px;
|
||||
--spacing-2: 20px;
|
||||
}
|
||||
|
||||
.update-subscription {
|
||||
margin: var(--spacing-2);
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.update-subscription,
|
||||
@@ -33,7 +16,7 @@
|
||||
.subscription-dialog-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: var(--update-subscription-color-0);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.v-spacing-small {
|
||||
@@ -46,7 +29,7 @@
|
||||
|
||||
.subscription-dialog-text {
|
||||
font-size: 13px;
|
||||
color: var(--update-subscription-color-1);
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.subscription-dialog-controls {
|
||||
@@ -54,28 +37,28 @@
|
||||
}
|
||||
|
||||
.controls-negative {
|
||||
padding: var(--update-subscription-padding-0);
|
||||
margin-right: var(--update-subscription-margin-right);
|
||||
border-radius: var(--update-subscription-radius-0);
|
||||
border: 1px solid var(--update-subscription-color-3);
|
||||
background-color: var(--update-subscription-color-2);
|
||||
font-size: var(--update-subscription-font-size);
|
||||
padding: 12px 16px;
|
||||
margin-right: 12px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
border: 1px solid var(--env-var-color-6);
|
||||
background-color: var(--env-var-color-8);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.controls-positive,
|
||||
.subscribe-button {
|
||||
padding: var(--update-subscription-padding-0);
|
||||
margin-right: var(--update-subscription-margin-right);
|
||||
border-radius: var(--update-subscription-radius-0);
|
||||
border: 1px solid var(--update-subscription-color-4);
|
||||
background-color: var(--update-subscription-color-5);
|
||||
color: var(--update-subscription-color-2);
|
||||
font-size: var(--update-subscription-font-size);
|
||||
padding: 12px 16px;
|
||||
margin-right: 12px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
border: 1px solid var(--env-var-color-7);
|
||||
background-color: var(--env-var-color-3);
|
||||
color: var(--env-var-color-8);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.update-subscription-title {
|
||||
color: var(--update-subscription-color-6);
|
||||
padding: 0 var(--spacing-2);
|
||||
color: var(--env-var-color-5);
|
||||
padding: 0 20px;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
@@ -83,17 +66,17 @@
|
||||
|
||||
.subscription-email {
|
||||
display: flex;
|
||||
padding: 0 var(--spacing-2);
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.subscription-email-field {
|
||||
width: 290px;
|
||||
height: 24px;
|
||||
border-radius: var(--update-subscription-radius-0);
|
||||
border: 1px solid var(--update-subscription-color-7);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
box-shadow: 0px 1px 2px 0px rgba(101, 182, 28, 0.05);
|
||||
padding: 5px 15px;
|
||||
margin-right: var(--spacing-2);
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.subscribe-button {
|
||||
|
||||
+8
-21
@@ -1,24 +1,11 @@
|
||||
:root {
|
||||
--announcement-border-color: #d0d5dd;
|
||||
--announcement-border-radius: 4px;
|
||||
--announcement-border-radius-2: 8px;
|
||||
--announcement-font-size-0: 13px;
|
||||
--announcement-font-color-0: #344054;
|
||||
--announcement-font-color-1: #475467;
|
||||
--announcement-font-color-2: #1570ef;
|
||||
--announcement-padding: 16px;
|
||||
--info-icon-frame-color: #eaecf0;
|
||||
--margin: 20px;
|
||||
}
|
||||
|
||||
.announcement-without-tile {
|
||||
margin: var(--margin);
|
||||
margin: 20px;
|
||||
max-width: 343px;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
border: 1px solid var(--announcement-border-color);
|
||||
padding: var(--announcement-padding);
|
||||
border-radius: var(--announcement-border-radius);
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
padding: 16px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.h-spacing {
|
||||
@@ -26,13 +13,13 @@
|
||||
}
|
||||
|
||||
.announcement-without-content-subject {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
color: var(--announcement-font-color-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.announcement-without-content-body {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
color: var(--announcement-font-color-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
+19
-32
@@ -1,71 +1,58 @@
|
||||
:root {
|
||||
--announcement-border-color: #d0d5dd;
|
||||
--announcement-border-radius: 4px;
|
||||
--announcement-border-radius-2: 8px;
|
||||
--announcement-font-size-0: 13px;
|
||||
--announcement-font-color-0: #344054;
|
||||
--announcement-font-color-1: #475467;
|
||||
--announcement-font-color-2: #1570ef;
|
||||
--announcement-padding: 16px;
|
||||
--info-icon-frame-color: #eaecf0;
|
||||
--tile-margin: 20px;
|
||||
}
|
||||
|
||||
.announcement-tile {
|
||||
margin: var(--tile-margin);
|
||||
margin: 20px;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
border: 1px solid var(--announcement-border-color);
|
||||
padding: var(--announcement-padding);
|
||||
border-radius: var(--announcement-border-radius);
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
padding: 16px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.info-icon-frame {
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid var(--info-icon-frame-color);
|
||||
border-radius: var(--announcement-border-radius-2);
|
||||
width: var(--env-var-default-2);
|
||||
height: var(--env-var-default-2);
|
||||
border: 1px solid var(--env-var-color-6);
|
||||
border-radius: var(--env-var-radius-2);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.announcement-content {
|
||||
padding: 0 var(--announcement-padding);
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.announcement-content-subject {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
color: var(--announcement-font-color-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.announcement-content-body {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
color: var(--announcement-font-color-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.announcement-content-controllers {
|
||||
display: flex;
|
||||
font-size: var(--announcement-font-size-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.controllers-button-esc {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 600;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.controllers-button-primary {
|
||||
font-size: var(--announcement-font-size-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 600;
|
||||
color: var(--announcement-font-color-2);
|
||||
color: var(--env-var-color-3);
|
||||
}
|
||||
|
||||
.announcement-close {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: var(--env-var-default-1);
|
||||
height: var(--env-var-default-1);
|
||||
}
|
||||
+3
-9
@@ -1,13 +1,7 @@
|
||||
:root {
|
||||
--announcement-font-size-0: 13px;
|
||||
--announcement-padding: 16px;
|
||||
--margin: 20px;
|
||||
}
|
||||
|
||||
.announcement-messagebar-body {
|
||||
margin: var(--margin);
|
||||
font-size: var(--announcement-font-size-0);
|
||||
padding: 0 var(--announcement-padding) 0 0;
|
||||
margin: 20px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
padding: 0 16px 0 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: auto;
|
||||
|
||||
@@ -39,20 +39,22 @@ const levelConfig = {
|
||||
* @param {string} props.label - The label of the button
|
||||
* @param {React.ReactNode} props.img - Image for button
|
||||
* @param {boolean} [props.disabled] - Whether the button is disabled
|
||||
* @param {Object} prps.sx - Styles for the button
|
||||
* @param {function} props.onClick - Function to run when the button is clicked
|
||||
* @param {Object} props.sx - Styles for the button
|
||||
* @returns {JSX.Element}
|
||||
* @example
|
||||
* // Render an error button
|
||||
* <Button level="error" label="Error" disabled sx={{marginTop: "1rem"}}/>
|
||||
*/
|
||||
|
||||
const Button = ({ level, label, disabled, img, sx }) => {
|
||||
const Button = ({ level, label, disabled, img, onClick, sx }) => {
|
||||
const { variant, color } = levelConfig[level];
|
||||
return (
|
||||
<MuiButton
|
||||
variant={variant}
|
||||
color={color}
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
sx={{
|
||||
textTransform: "none",
|
||||
...sx,
|
||||
@@ -68,6 +70,7 @@ Button.propTypes = {
|
||||
level: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
img: PropTypes.node,
|
||||
onClick: PropTypes.func,
|
||||
sx: PropTypes.object,
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
}
|
||||
|
||||
.check-h-spacing {
|
||||
@@ -14,7 +14,7 @@
|
||||
}
|
||||
|
||||
.check-label {
|
||||
font-size: 11px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
font-weight: 600;
|
||||
color: #475467;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
.checkbox-holder {
|
||||
height: 20px;
|
||||
height: var(--env-var-img-width-1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
width: var(--env-var-font-size-medium);
|
||||
height: var(--env-var-font-size-medium);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
.checkbox-label {
|
||||
margin-left: 5px;
|
||||
font-size: 13px;
|
||||
color: #344054;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
.dashboard-menu-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dashboard-menu-text {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dashboard-menu-text {
|
||||
margin-left: 8px;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BarChart } from '@mui/x-charts/BarChart';
|
||||
import { BarChart } from "@mui/x-charts/BarChart";
|
||||
|
||||
const ChartsOverviewDemo = () => {
|
||||
return (
|
||||
@@ -10,7 +10,7 @@ const ChartsOverviewDemo = () => {
|
||||
{ data: [60, 50, 15, 25] },
|
||||
]}
|
||||
height={290}
|
||||
xAxis={[{ data: ['Q1', 'Q2', 'Q3', 'Q4'], scaleType: 'band' }]}
|
||||
xAxis={[{ data: ["Q1", "Q2", "Q3", "Q4"], scaleType: "band" }]}
|
||||
margin={{ top: 10, bottom: 30, left: 40, right: 10 }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
.dashboard-sidebar {
|
||||
height: 100vh;
|
||||
width: 250px;
|
||||
background-color: #f4f4f4;
|
||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.menu-container {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
.support-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.support-text {
|
||||
margin-left: 8px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import DashboardMenu from '../../Components/DashboardMenu';
|
||||
import SupportIcon from '@mui/icons-material/Support';
|
||||
import SvgIcon from '@mui/material/SvgIcon';
|
||||
import './index.css';
|
||||
|
||||
/**
|
||||
* @component
|
||||
* DashboardSidebar component serves as a sidebar containing the DashboardMenu and a Support icon at the bottom.
|
||||
*
|
||||
* @returns {JSX.Element} The JSX element representing the DashboardSidebar component.
|
||||
*/
|
||||
|
||||
function DashboardSidebar() {
|
||||
return (
|
||||
<div className="dashboard-sidebar">
|
||||
<div className="menu-container">
|
||||
<DashboardMenu />
|
||||
</div>
|
||||
<div className="support-container">
|
||||
<SvgIcon component={SupportIcon} />
|
||||
<span className="support-text">Support</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardSidebar;
|
||||
@@ -46,8 +46,8 @@ function NavBar() {
|
||||
};
|
||||
|
||||
return (
|
||||
<AppBar position="static">
|
||||
<Container maxWidth="xl">
|
||||
<AppBar position="fixed" sx={{ width: '100%' }}>
|
||||
<Container maxWidth="xxl" sx={{ width: '100%' }}>
|
||||
<Toolbar disableGutters>
|
||||
<Typography
|
||||
variant="h6"
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
:root {
|
||||
--popup-color-border-0: #f2f2f2;
|
||||
--popup-color-0: #101828;
|
||||
--popup-color-1: #475467;
|
||||
--color-0: #1570ef;
|
||||
--color-1: #175cd3;
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-holder {
|
||||
width: 380px;
|
||||
height: 130px;
|
||||
@@ -13,19 +5,19 @@
|
||||
padding: 30px;
|
||||
box-shadow: 0px 8px 8px -4px rgba(16, 24, 40, 0.03),
|
||||
0px 20px 24px -4px rgba(16, 24, 40, 0.08);
|
||||
border: 1px solid var(--popup-color-border-0);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--env-var-color-9);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-subject {
|
||||
color: var(--popup-color-0);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dual-button-popup-modal-description {
|
||||
color: var(--popup-color-1);
|
||||
font-size: 13px;
|
||||
color: var(--env-var-color-2);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -42,19 +34,19 @@
|
||||
width: 145px;
|
||||
height: 35px;
|
||||
padding: 5px 20px;
|
||||
background-color: var(--color-0);
|
||||
border: 1px solid var(--color-1);
|
||||
border-radius: 4px;
|
||||
background-color: var(--env-var-color-3);
|
||||
border: 1px solid var(--env-var-color-10);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
margin: 5px 0;
|
||||
margin-left: 20px;
|
||||
color: white;
|
||||
color: var(--env-var-color-8);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.transparent-discard-button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
margin: 5px 10px;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
+8
-14
@@ -1,16 +1,10 @@
|
||||
:root {
|
||||
--popup-color-with-input-border-0: #f2f2f2;
|
||||
--popup-color-with-input-border-1: #d0d5dd;
|
||||
--popup-modal-with-input-title-color: #344054;
|
||||
}
|
||||
|
||||
.popup-modal-holder {
|
||||
width: 480px;
|
||||
font-family: var(--popup-font-family-0);
|
||||
padding: 50px 40px;
|
||||
border-radius: 4px;
|
||||
border-radius: var(--env-var-radius-1);
|
||||
margin: 10px 20px;
|
||||
border: 1px solid var(--popup-color-with-input-border-0);
|
||||
border: 1px solid var(--env-var-color-9);
|
||||
box-shadow: 0px 8px 8px -4px rgba(16, 24, 40, 0.03),
|
||||
0px 20px 24px -4px rgba(16, 24, 40, 0.08);
|
||||
}
|
||||
@@ -31,14 +25,14 @@
|
||||
|
||||
.popup-modal-input-title {
|
||||
margin-bottom: 15px;
|
||||
color: var(--popup-modal-with-input-title-color);
|
||||
color: var(--env-var-color-5);
|
||||
}
|
||||
|
||||
.popup-modal-text-field {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
border: 1px solid var(--popup-color-with-input-border-1);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
}
|
||||
|
||||
.popup-modal-controllers {
|
||||
@@ -54,8 +48,8 @@
|
||||
width: 145px;
|
||||
height: 35px;
|
||||
padding: 5px 20px;
|
||||
border: 1px solid var(--popup-color-with-input-border-1);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--env-var-color-4);
|
||||
border-radius: var(--env-var-radius-1);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import AddIcon from "@mui/icons-material/Add";
|
||||
/**
|
||||
* @component
|
||||
* @param {Object} props
|
||||
* @param { Array} props.montitors - Array of monitors associated with the section
|
||||
* @param { Array} props.monitors - Array of monitors associated with the section
|
||||
* @returns {JSX.Element}
|
||||
* @example
|
||||
* // Renders a section component with a list of monitors
|
||||
@@ -29,7 +29,6 @@ const Section = ({ monitors }) => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Monitor states updated", monitorStates);
|
||||
// Update DB here
|
||||
}, [monitorStates]);
|
||||
|
||||
|
||||
@@ -1,32 +1,64 @@
|
||||
:root {
|
||||
--color-title-1: #344054;
|
||||
--text-field-margin-0: 10px 20px;
|
||||
--description-color-0: #344054;
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.description-field-holder {
|
||||
margin: var(--text-field-margin-0);
|
||||
margin: 10px 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.text-field-title {
|
||||
color: var(--color-title-1);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: 13px;
|
||||
color: var(--description-color-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.description-field-area {
|
||||
min-width: 320px;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.description-field-label {
|
||||
margin-top: 10px;
|
||||
font-size: 11px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.with-error {
|
||||
@@ -36,10 +68,10 @@
|
||||
#description-field-area-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: 11px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
#description-field-area {
|
||||
min-width: 320px;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
@@ -1,6 +1,39 @@
|
||||
:root {
|
||||
--textfield-color-0: #344054;
|
||||
--textfield-font-size: 13px;
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.email-text-field {
|
||||
@@ -11,24 +44,24 @@
|
||||
#outlined-basic {
|
||||
width: 320px;
|
||||
height: 14px;
|
||||
font-size: var(--textfield-font-size);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.email-text-field-title {
|
||||
font-size: var(--textfield-font-size);
|
||||
color: var(--textfield-color-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.email-text-field-input {
|
||||
font-size: var(--textfield-font-size);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
#outlined-basic-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: 11px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.text-field-icon {
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
:root {
|
||||
--textfield-color-0: #344054;
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.password-text-field {
|
||||
@@ -10,20 +44,20 @@
|
||||
#outlined-basic {
|
||||
width: 320px;
|
||||
height: 14px;
|
||||
font-size: 13px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.password-text-field-title {
|
||||
font-size: 13px;
|
||||
color: var(--textfield-color-0);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#outlined-basic-helper-text {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: 11px;
|
||||
font-size: var(--env-var-font-size-small);
|
||||
}
|
||||
|
||||
.text-field-icon {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
:root {
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
@@ -1,17 +1,46 @@
|
||||
:root {
|
||||
--website-color-0: #344054;
|
||||
--border-color: #d0d5dd;
|
||||
--label-font-color: #475467;
|
||||
--icon-color: #98a2b3;
|
||||
--text-field-margin-0: 10px 20px;
|
||||
--text-field-margin-1: 10px 20px 5px;
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.website-textfield-title {
|
||||
margin: 0 20px;
|
||||
margin-top: 30px;
|
||||
font-size: 13px;
|
||||
color: var(--website-color-0);
|
||||
color: var(--env-var-color-5);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -19,17 +48,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
margin: var(--text-field-margin-1);
|
||||
margin: 10px 20px 5px;
|
||||
}
|
||||
|
||||
.website-textfield-hint {
|
||||
margin: var(--text-field-margin-0);
|
||||
margin: 10px 20px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.website-label {
|
||||
padding: 6px 20px 6px 10px;
|
||||
border: solid 1px var(--border-color);
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-right: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
font-size: 13px;
|
||||
@@ -37,21 +66,21 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--label-font-color);
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.website-url {
|
||||
width: 248px;
|
||||
height: 31.5px;
|
||||
padding: 0px 15px;
|
||||
border: solid 1px var(--border-color);
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
}
|
||||
|
||||
.website-icon-holder {
|
||||
width: 40px;
|
||||
height: 33px;
|
||||
padding: 5px;
|
||||
border: solid 1px var(--border-color);
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-left: none;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
@@ -61,7 +90,7 @@
|
||||
|
||||
.copy-to-clipboard-button {
|
||||
padding: 5.5px 20px 6px 10px;
|
||||
border: solid 1px var(--border-color);
|
||||
border: solid 1px var(--env-var-color-4);
|
||||
border-left: none;
|
||||
border-radius: 0 8px 8px 0;
|
||||
font-size: 13px;
|
||||
@@ -69,7 +98,7 @@
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
color: var(--label-font-color);
|
||||
color: var(--env-var-color-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,49 @@
|
||||
:root {
|
||||
--tooltip-color-0: #d0d5dd;
|
||||
--tooltip-margin: 5px;
|
||||
--tooltip-font-size: 12px;
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
.tooltip-title {
|
||||
font-size: var(--tooltip-font-size);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: bold;
|
||||
margin: var(--tooltip-margin);
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.tooltip-description {
|
||||
font-size: var(--tooltip-font-size);
|
||||
color: var(--tooltip-color-0);
|
||||
margin: var(--tooltip-margin);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-4);
|
||||
margin: 5px;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import axios from "axios";
|
||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
isLoading: false,
|
||||
monitors: [],
|
||||
success: null,
|
||||
msg: null,
|
||||
};
|
||||
|
||||
export const getMonitors = createAsyncThunk(
|
||||
"monitors/getMonitors",
|
||||
async (token, thunkApi) => {
|
||||
try {
|
||||
const res = await axios.get(
|
||||
import.meta.env.VITE_APP_API_BASE_URL + "/monitors"
|
||||
);
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
return thunkApi.rejectWithValue(error.response.data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const monitorsSlice = createSlice({
|
||||
name: "monitors",
|
||||
initialState,
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(getMonitors.pending, (state, action) => {
|
||||
state.isLoading = true;
|
||||
})
|
||||
.addCase(getMonitors.fulfilled, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = action.payload.success;
|
||||
state.msg = action.payload.msg;
|
||||
console.log(action.payload);
|
||||
state.monitors = action.payload.data;
|
||||
})
|
||||
.addCase(getMonitors.rejected, (state, action) => {
|
||||
state.isLoading = false;
|
||||
state.success = action.payload.success;
|
||||
state.msg = action.payload.msg;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const { setMonitors } = monitorsSlice.actions;
|
||||
|
||||
export default monitorsSlice.reducer;
|
||||
@@ -1 +1,11 @@
|
||||
/*Homelayout styles*/
|
||||
.home-layout {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: 250px;
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import NavBar from '../../Components/NavBar'
|
||||
import { Outlet } from 'react-router'
|
||||
import Home from '../../Pages/Home'
|
||||
import './index.css'
|
||||
import ChartsOverviewDemo from '../../Components/DashboardProgressBars'
|
||||
import DashboardSettings from '../../Components/DashboardSettingsIcon'
|
||||
|
||||
import NavBar from '../../Components/NavBar';
|
||||
import { Outlet } from 'react-router';
|
||||
import DashboardSidebar from '../../Components/DashboardSidebar';
|
||||
import './index.css';
|
||||
|
||||
const HomeLayout = () => {
|
||||
return (
|
||||
<>
|
||||
<NavBar />
|
||||
<Home />
|
||||
<Outlet />
|
||||
<ChartsOverviewDemo />
|
||||
<DashboardSettings />
|
||||
</>
|
||||
)
|
||||
return (
|
||||
<div className="home-layout">
|
||||
<DashboardSidebar />
|
||||
<div className="main-content">
|
||||
<NavBar />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default HomeLayout
|
||||
export default HomeLayout;
|
||||
@@ -0,0 +1,83 @@
|
||||
.check-email-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.check-email-form {
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
.check-email-form-header {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.check-email-v-gap-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.check-email-v-gap-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.check-email-v-gap-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.check-email-form-heading {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.check-email-form-subheading {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.check-email-form-subheading span {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.check-email-body {
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
|
||||
.check-email-resend {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
color: var(--env-var-color-2);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.check-email-resend span {
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-3);
|
||||
}
|
||||
|
||||
.check-email-back-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-email-back-button-img {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-email-back-button-text {
|
||||
height: var(--env-var-img-width-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-2);
|
||||
align-items: center;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import EmailIcon from "../../assets/Images/email.png";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
|
||||
const CheckEmail = () => {
|
||||
return (
|
||||
<div className="check-email-page">
|
||||
<BackgroundPattern />
|
||||
<div className="check-email-form">
|
||||
<div className="check-email-form-header">
|
||||
<img
|
||||
className="check-email-form-header-logo"
|
||||
src={EmailIcon}
|
||||
alt="EmailIcon"
|
||||
/>
|
||||
<div className="check-email-v-gap-medium"></div>
|
||||
<div className="check-email-form-heading">Check your email</div>
|
||||
<div className="check-email-v-gap-small"></div>
|
||||
<div className="check-email-form-subheading">
|
||||
We sent a password reset link to <span>username@email.com</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-body">
|
||||
<Button
|
||||
level="primary"
|
||||
label="Open email app"
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: "13px",
|
||||
fontWeight: "200",
|
||||
height: "44px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-resend">
|
||||
Didn’t receive the email?
|
||||
<span> Click to resend</span>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-back-button">
|
||||
<img
|
||||
className="check-email-back-button-img"
|
||||
src={LeftArrow}
|
||||
alt="LeftArrow"
|
||||
/>
|
||||
<div className="check-email-back-button-text">Back to log in</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckEmail;
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from "react";
|
||||
import axios from "axios";
|
||||
import Button from "../../Components/Button/";
|
||||
import Link from "../../Components/Link";
|
||||
import {
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
RadioGroup,
|
||||
Tab,
|
||||
Tabs,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { ColoredLabel, StatusLabel } from "../../Components/Label/";
|
||||
import Avatar from "../../Components/Avatar/";
|
||||
@@ -25,6 +27,11 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import Divider from "@mui/material/Divider";
|
||||
|
||||
// Redux
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { getMonitors } from "../../Features/Monitors/monitorsSlice";
|
||||
|
||||
const cols = [
|
||||
{
|
||||
field: "name",
|
||||
@@ -84,13 +91,15 @@ const steps = [
|
||||
{ label: "Invite your team", content: "Start collaborating with your team" },
|
||||
];
|
||||
|
||||
const monitors = [
|
||||
const demoMonitors = [
|
||||
{ id: 0, name: "Google", isActive: true },
|
||||
{ id: 1, name: "Yahoo", isActive: false },
|
||||
{ id: 2, name: "Reddit", isActive: true },
|
||||
];
|
||||
|
||||
const Demo = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [radio, setRadio] = React.useState(1);
|
||||
const [tab, setTab] = React.useState("departments");
|
||||
const [date, setDate] = React.useState("Pick a date!");
|
||||
@@ -167,8 +176,47 @@ const Demo = () => {
|
||||
];
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
// *********************************
|
||||
// Redux Demo
|
||||
// *********************************
|
||||
const monitorState = useSelector((state) => state.monitors);
|
||||
const { monitors, msg } = monitorState;
|
||||
return (
|
||||
<div>
|
||||
<div style={{ padding: "4rem", border: "1px solid black" }}>
|
||||
<Typography variant="h4">Redux Demo</Typography>
|
||||
<Typography variant="h6">Monitors</Typography>
|
||||
<table
|
||||
style={{ border: "1px solid black", borderCollapse: "collapse" }}
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style={{ border: "1px solid black" }}>Name</th>
|
||||
<th style={{ border: "1px solid black" }}>URL</th>
|
||||
</tr>
|
||||
{monitors &&
|
||||
monitors.map((monitor) => {
|
||||
return (
|
||||
<tr key={monitor._id}>
|
||||
<td style={{ border: "1px solid black" }}>
|
||||
{monitor.name}
|
||||
</td>
|
||||
<td style={{ border: "1px solid black" }}>{monitor.url}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Message: {msg}</p>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Get Monitors"
|
||||
onClick={() => {
|
||||
dispatch(getMonitors());
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ul style={{ listStyle: "none" }}>
|
||||
{links.map((link) => (
|
||||
<li key={link.url}>
|
||||
@@ -304,7 +352,7 @@ const Demo = () => {
|
||||
</div>
|
||||
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
|
||||
<h4 id="section">Section</h4>
|
||||
<Section monitors={monitors} />
|
||||
<Section monitors={demoMonitors} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
.forgot-password-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.forgot-password-form {
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
.forgot-password-form-header {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.forgot-password-form-header-logo {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.forgot-password-v-gap-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.forgot-password-v-gap-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.forgot-password-v-gap-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.forgot-password-form-heading {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.forgot-password-form-subheading {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.forgot-password-body {
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
|
||||
#forgot-password-email-input {
|
||||
width: 308px;
|
||||
height: 11px;
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.forgot-password-back-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.forgot-password-back-button-img {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.forgot-password-back-button-text {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import Logomark from "../../assets/Images/key-password.png";
|
||||
import EmailTextField from "../../Components/TextFields/Email/EmailTextField";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
|
||||
const ForgotPassword = () => {
|
||||
return (
|
||||
<div className="forgot-password-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
<div className="forgot-password-form">
|
||||
<div className="forgot-password-form-header">
|
||||
<img
|
||||
className="forgot-password-form-header-logo"
|
||||
src={Logomark}
|
||||
alt="Logomark"
|
||||
/>
|
||||
<div className="forgot-password-v-gap-medium"></div>
|
||||
<div className="forgot-password-form-heading">Forgot password?</div>
|
||||
<div className="forgot-password-v-gap-small"></div>
|
||||
<div className="forgot-password-form-subheading">
|
||||
No worries, we’ll send you reset instructions.
|
||||
</div>
|
||||
</div>
|
||||
<div className="forgot-password-v-gap-large"></div>
|
||||
<div className="forgot-password-body">
|
||||
<EmailTextField
|
||||
error={false}
|
||||
placeholder="Enter your email"
|
||||
id="forgot-password-email-input"
|
||||
/>
|
||||
<div className="forgot-password-v-gap-medium"></div>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Reset password"
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: "13px",
|
||||
fontWeight: "200",
|
||||
height: "44px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="forgot-password-v-gap-large"></div>
|
||||
<div className="forgot-password-back-button">
|
||||
<img
|
||||
className="forgot-password-back-button-img"
|
||||
src={LeftArrow}
|
||||
alt="LeftArrow"
|
||||
/>
|
||||
<div className="forgot-password-back-button-text">Back to log in</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPassword;
|
||||
@@ -1,34 +1,13 @@
|
||||
:root {
|
||||
--spacing-1: 15px;
|
||||
--spacing-2: 20px;
|
||||
--spacing-3: 25px;
|
||||
--textfield-font-size: 13px;
|
||||
|
||||
--login-page-width-1: 100vw;
|
||||
--login-page-height-1: 100vh;
|
||||
|
||||
--login-form-width-1: 360px;
|
||||
--login-form-height-1: 526px;
|
||||
|
||||
--logo-width-1: 20px;
|
||||
--login-font-size-medium: 13px;
|
||||
|
||||
--login-color-1: #101828;
|
||||
--login-color-2: #1570ef;
|
||||
--login-color-3: #475467;
|
||||
}
|
||||
|
||||
.login-page {
|
||||
width: var(--login-page-width-1);
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: var(--login-page-height-1);
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: var(--login-form-width-1);
|
||||
height: var(--login-form-height-1);
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
@@ -43,27 +22,27 @@
|
||||
}
|
||||
|
||||
.login-form-v-spacing {
|
||||
height: var(--spacing-1);
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.login-form-v2-spacing {
|
||||
height: var(--spacing-2);
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.login-form-v3-spacing {
|
||||
height: var(--spacing-3);
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.login-form-heading {
|
||||
font-size: 30px;
|
||||
font-size: var(--env-var-font-size-xlarge);
|
||||
font-weight: 700;
|
||||
color: var(--login-color-1);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
#login-email-input {
|
||||
width: 308px;
|
||||
height: 11px;
|
||||
font-size: var(--textfield-font-size);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.login-form-password-options {
|
||||
@@ -73,15 +52,15 @@
|
||||
}
|
||||
|
||||
.login-form-forgot-password {
|
||||
color: var(--login-color-2);
|
||||
color: var(--env-var-color-3);
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-size: var(--login-font-size-medium);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
|
||||
.google-enter {
|
||||
width: var(--logo-width-1);
|
||||
height: var(--logo-width-1);
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@@ -89,14 +68,15 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--login-color-3);
|
||||
font-size: var(--login-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.new-account-option-span {
|
||||
margin-left: 5px;
|
||||
color: var(--login-color-2);
|
||||
font-size: 14px;
|
||||
color: var(--env-var-color-3);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
.password-confirmed-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.password-confirmed-form {
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
.password-confirmed-form-header {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.password-confirmed-v-gap-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.password-confirmed-v-gap-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.password-confirmed-v-gap-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.password-confirmed-form-heading {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.password-confirmed-form-subheading {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 600;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.password-confirmed-body {
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
|
||||
.password-confirmed-back-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.password-confirmed-back-button-img {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.password-confirmed-back-button-text {
|
||||
height: var(--env-var-img-width-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 600;
|
||||
color: var(--env-var-color-2);
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import SuccessIcon from "../../assets/Images/success-icon.png";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
|
||||
const NewPasswordConfirmed = () => {
|
||||
return (
|
||||
<div className="password-confirmed-page">
|
||||
<BackgroundPattern />
|
||||
<div className="password-confirmed-form">
|
||||
<div className="password-confirmed-form-header">
|
||||
<img
|
||||
className="password-confirmed-form-header-logo"
|
||||
src={SuccessIcon}
|
||||
alt="SuccessIcon"
|
||||
/>
|
||||
<div className="password-confirmed-v-gap-medium"></div>
|
||||
<div className="password-confirmed-form-heading">Password reset</div>
|
||||
<div className="password-confirmed-v-gap-small"></div>
|
||||
<div className="password-confirmed-form-subheading">
|
||||
Your password has been successfully reset. Click below to log in
|
||||
magically.
|
||||
</div>
|
||||
</div>
|
||||
<div className="password-confirmed-v-gap-large"></div>
|
||||
<div className="password-confirmed-body">
|
||||
<Button
|
||||
level="primary"
|
||||
label="Continue"
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: "13px",
|
||||
fontWeight: "200",
|
||||
height: "44px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="password-confirmed-v-gap-large"></div>
|
||||
<div className="password-confirmed-back-button">
|
||||
<img
|
||||
className="password-confirmed-back-button-img"
|
||||
src={LeftArrow}
|
||||
alt="LeftArrow"
|
||||
/>
|
||||
<div className="password-confirmed-back-button-text">
|
||||
Back to log in
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewPasswordConfirmed;
|
||||
@@ -1,29 +1,12 @@
|
||||
:root {
|
||||
--dimension-width-1: 100vw;
|
||||
--dimension-width-2: 360px;
|
||||
|
||||
--dimension-height-1: 100vh;
|
||||
|
||||
--spacing-small: 12px;
|
||||
--spacing-medium: 24px;
|
||||
--spacing-large: 40px;
|
||||
|
||||
--font-size-small: 13px;
|
||||
--font-size-medium: 16px;
|
||||
|
||||
--register-form-heading-color-1: #101828;
|
||||
--register-form-subheading-color-1: #475467;
|
||||
}
|
||||
|
||||
.register-page {
|
||||
width: var(--dimension-width-1);
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--dimension-height-1);
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.register-form {
|
||||
width: var(--dimension-width-2);
|
||||
width: var(--env-var-width-2);
|
||||
margin: 140px auto;
|
||||
}
|
||||
|
||||
@@ -37,27 +20,23 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.register-form-v-spacing-24px {
|
||||
height: var(--spacing-medium);
|
||||
.register-form-v-spacing-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.register-form-v-spacing-12px {
|
||||
height: var(--spacing-small);
|
||||
}
|
||||
|
||||
.register-form-v-spacing-40px {
|
||||
height: var(--spacing-large);
|
||||
.register-form-v-spacing-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.register-form-heading {
|
||||
font-size: var(--spacing-medium);
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 700;
|
||||
color: var(--register-form-heading-color-1);
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.register-form-subheading {
|
||||
font-size: var(--spacing-small);
|
||||
color: var(--register-form-subheading-color-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -65,7 +44,7 @@
|
||||
#register-lastname-input,
|
||||
#register-email-input,
|
||||
#register-password-input {
|
||||
font-size: var(--spacing-small);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
width: 294px;
|
||||
height: 11px;
|
||||
padding: 12px 14px;
|
||||
|
||||
@@ -20,12 +20,9 @@ const Register = () => {
|
||||
src={Logomark}
|
||||
alt="Logomark"
|
||||
/>
|
||||
<div className="register-form-v-spacing-24px" />
|
||||
<div className="register-form-v-spacing-large" />
|
||||
<div className="register-form-heading">Create an account</div>
|
||||
<div className="register-form-v-spacing-12px"></div>
|
||||
<div className="register-form-subheading">
|
||||
Start your 30-day free trial.
|
||||
</div>
|
||||
<div className="register-form-v-spacing-large"></div>
|
||||
</div>
|
||||
<div className="register-form-v-spacing-40px" />
|
||||
<div className="register-form-inputs">
|
||||
@@ -60,7 +57,7 @@ const Register = () => {
|
||||
<div className="login-form-v2-spacing" />
|
||||
<div className="register-form-checks">
|
||||
<Check text="Must be at least 8 characters" />
|
||||
<div className="register-form-v-spacing-12px"></div>
|
||||
<div className="register-form-v-spacing-small"></div>
|
||||
<Check text="Must contain one special character" />
|
||||
</div>
|
||||
<div className="login-form-v2-spacing" />
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
.set-new-password-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
}
|
||||
|
||||
.set-new-password-form {
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
.set-new-password-form-header {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.set-new-password-form-gap-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.set-new-password-form-gap-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.set-new-password-form-gap-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.set-new-password-form-heading {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.set-new-password-form-subheading {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.set-new-password-back-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.set-new-password-back-button-img {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.set-new-password-back-button-text {
|
||||
height: var(--env-var-img-width-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
color: var(--env-var-color-2);
|
||||
font-weight: 600;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import LockIcon from "../../assets/Images/lock-icon.png";
|
||||
import PasswordTextField from "../../Components/TextFields/Password/PasswordTextField";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
|
||||
const SetNewPassword = () => {
|
||||
return (
|
||||
<div className="set-new-password-page">
|
||||
<BackgroundPattern />
|
||||
<div className="set-new-password-form">
|
||||
<div className="set-new-password-form-header">
|
||||
<img
|
||||
className="set-new-password-form-header-logo"
|
||||
src={LockIcon}
|
||||
alt="LockIcon"
|
||||
/>
|
||||
<div className="set-new-password-form-gap-medium" />
|
||||
<div className="set-new-password-form-heading">Set new password</div>
|
||||
<div className="set-new-password-form-gap-small" />
|
||||
<div className="set-new-password-form-subheading">
|
||||
Your new password must be different to previously used passwords.
|
||||
</div>
|
||||
</div>
|
||||
<div className="set-new-password-form-gap-large"></div>
|
||||
<div className="set-new-password-form-content">
|
||||
<PasswordTextField
|
||||
label="Password"
|
||||
error={false}
|
||||
placeholder="••••••••"
|
||||
id="register-password-input"
|
||||
/>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<PasswordTextField
|
||||
label="Confirm password"
|
||||
error={false}
|
||||
placeholder="••••••••"
|
||||
id="register-password-input"
|
||||
/>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<div className="set-new-password-form-checks">
|
||||
<Check text="Must be at least 8 characters" />
|
||||
<div className="set-new-password-form-gap-small"></div>
|
||||
<Check text="Must contain one special character" />
|
||||
</div>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Reset passwprd"
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: "13px",
|
||||
fontWeight: "200",
|
||||
height: "35px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="set-new-password-form-gap-medium"></div>
|
||||
<div className="set-new-password-back-button">
|
||||
<img
|
||||
className="set-new-password-back-button-img"
|
||||
src={LeftArrow}
|
||||
alt="LeftArrow"
|
||||
/>
|
||||
<div className="set-new-password-back-button-text">
|
||||
Back to log in
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SetNewPassword;
|
||||
@@ -13,10 +13,20 @@ const labelPurple = "#6941C6";
|
||||
const labelGreen = "#067647";
|
||||
const labelRed = "#F04438";
|
||||
|
||||
//Section colros
|
||||
// Section colors
|
||||
const sectionBorder = "#D0D5DD";
|
||||
const sectionBg = "#F8F9F8";
|
||||
|
||||
// Other Colors
|
||||
const otherColorsBlackish = "#101828";
|
||||
const otherColorsBluishGray = "#344054";
|
||||
const otherColorsGraishWhite = "#eaecf0";
|
||||
const otherColorsPurple = "#7f56d9";
|
||||
const otherColorsWhite = "#fff";
|
||||
const otherColorsGraishWhiteLight = "#f2f2f2";
|
||||
const otherColorsStrongBlue = "#f2f2f2";
|
||||
|
||||
|
||||
// Global Font Family
|
||||
const fontFamilyDefault = '"Roboto", "Helvetica", "Arial", sans-serif';
|
||||
|
||||
@@ -51,6 +61,15 @@ const theme = createTheme({
|
||||
borderColor: sectionBorder,
|
||||
bgColor: sectionBg,
|
||||
},
|
||||
otherColors: {
|
||||
blackish: otherColorsBlackish,
|
||||
bluishGray: otherColorsBluishGray,
|
||||
graishWhite: otherColorsGraishWhite,
|
||||
purple: otherColorsPurple,
|
||||
white: otherColorsWhite,
|
||||
graishWhiteLight: otherColorsGraishWhiteLight,
|
||||
strongBlue: otherColorsStrongBlue,
|
||||
},
|
||||
},
|
||||
font :{
|
||||
default: {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 310 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -11,6 +11,44 @@
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Generalized Stylings */
|
||||
|
||||
--env-var-color-1: #101828;
|
||||
--env-var-color-2: #475467;
|
||||
--env-var-color-3: #1570ef;
|
||||
|
||||
--env-var-color-4: #d0d5dd;
|
||||
--env-var-color-5: #344054;
|
||||
--env-var-color-6: #eaecf0;
|
||||
--env-var-color-7: #7f56d9;
|
||||
--env-var-color-8: #fff;
|
||||
--env-var-color-9: #f2f2f2;
|
||||
--env-var-color-10: #175cd3;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
|
||||
--env-var-width-1: 100vw;
|
||||
--env-var-width-2: 360px;
|
||||
|
||||
--env-var-height-1: 100vh;
|
||||
|
||||
--env-var-spacing-1: 12px;
|
||||
--env-var-spacing-2: 24px;
|
||||
--env-var-spacing-3: 32px;
|
||||
--env-var-spacing-4: 40px;
|
||||
|
||||
--env-var-font-size-small: 11px;
|
||||
--env-var-font-size-medium: 13px;
|
||||
--env-var-font-size-medium-plus: 14px;
|
||||
--env-var-font-size-large: 16px;
|
||||
--env-var-font-size-xlarge: 30px;
|
||||
|
||||
--env-var-img-width-1: 20px;
|
||||
|
||||
--env-var-default-1: 24px;
|
||||
--env-var-default-2: 40px;
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
+10
-5
@@ -5,12 +5,17 @@ import "./index.css";
|
||||
import { BrowserRouter as Router, HashRouter } from "react-router-dom";
|
||||
import theme from "./Utils/Theme.js";
|
||||
import { ThemeProvider } from "@mui/material";
|
||||
import { Provider } from "react-redux";
|
||||
import store from "./store";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import monitorsReducer from "./Features/Monitors/monitorsSlice";
|
||||
|
||||
export default configureStore({
|
||||
reducer: { monitors: monitorsReducer },
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
Whitespace-only changes.
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
Whitespace-only changes.
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
@@ -1,10 +0,0 @@
|
||||
// vite.config.js
|
||||
import { defineConfig } from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/vite/dist/node/index.js";
|
||||
import react from "file:///c:/Users/cosmi/OneDrive/Desktop/BlueWave/Uptime-Monitor/bluewave-uptime/Client/node_modules/@vitejs/plugin-react/dist/index.mjs";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJjOlxcXFxVc2Vyc1xcXFxjb3NtaVxcXFxPbmVEcml2ZVxcXFxEZXNrdG9wXFxcXEJsdWVXYXZlXFxcXFVwdGltZS1Nb25pdG9yXFxcXGJsdWV3YXZlLXVwdGltZVxcXFxDbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcImM6XFxcXFVzZXJzXFxcXGNvc21pXFxcXE9uZURyaXZlXFxcXERlc2t0b3BcXFxcQmx1ZVdhdmVcXFxcVXB0aW1lLU1vbml0b3JcXFxcYmx1ZXdhdmUtdXB0aW1lXFxcXENsaWVudFxcXFx2aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vYzovVXNlcnMvY29zbWkvT25lRHJpdmUvRGVza3RvcC9CbHVlV2F2ZS9VcHRpbWUtTW9uaXRvci9ibHVld2F2ZS11cHRpbWUvQ2xpZW50L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKV0sXHJcbn0pXHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBOGEsU0FBUyxvQkFBb0I7QUFDM2MsT0FBTyxXQUFXO0FBR2xCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxNQUFNLENBQUM7QUFDbkIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
@@ -0,0 +1,185 @@
|
||||
const express = require("express");
|
||||
const logger = require("../utils/logger");
|
||||
require("dotenv").config();
|
||||
const {
|
||||
createAlertParamValidation,
|
||||
createAlertBodyValidation,
|
||||
getAlertsByUserIdParamValidation,
|
||||
getAlertsByMonitorIdParamValidation,
|
||||
getAlertByIdParamValidation,
|
||||
editAlertParamValidation,
|
||||
editAlertBodyValidation,
|
||||
deleteAlertParamValidation,
|
||||
} = require("../validation/joi");
|
||||
const { get } = require("mongoose");
|
||||
|
||||
const SERVICE_NAME = "alerts";
|
||||
|
||||
/**
|
||||
* Creates an alert for a monitor
|
||||
* @async
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Express.Response>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const createAlert = async (req, res, next) => {
|
||||
try {
|
||||
await createAlertParamValidation.validateAsync(req.params);
|
||||
await createAlertBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const alertData = { ...req.body };
|
||||
const alert = await req.db.createAlert(alertData);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Alert created", data: alert });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all alerts for a user
|
||||
* @async
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Express.Response>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const getAlertsByUserId = async (req, res, next) => {
|
||||
try {
|
||||
await getAlertsByUserIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const alerts = await req.db.getAlertsByUserId(req.params.userId);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Got alerts", data: alerts });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getAlertsByMonitorId = async (req, res, next) => {
|
||||
try {
|
||||
await getAlertsByMonitorIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const alerts = await req.db.getAlertsByMonitorId(req.params.monitorId);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Got alerts by Monitor",
|
||||
data: alerts,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getAlertById = async (req, res, next) => {
|
||||
try {
|
||||
await getAlertByIdParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const alert = await req.db.getAlertById(req.params.alertId);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Got Alert By alertID",
|
||||
data: alert,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
const editAlert = async (req, res, next) => {
|
||||
try {
|
||||
await editAlertParamValidation.validateAsync(req.params);
|
||||
await editAlertBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const alertData = { ...req.body };
|
||||
const alert = await req.db.editAlert(req.params.alertId, alertData);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Edited alert",
|
||||
data: alert,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
const deleteAlert = async (req, res, next) => {
|
||||
try {
|
||||
await deleteAlertParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message = error.details[0].message;
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const deleted = await req.db.deleteAlert(req.params.alertId);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Deleted alert",
|
||||
data: deleted,
|
||||
});
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createAlert,
|
||||
getAlertsByUserId,
|
||||
getAlertsByMonitorId,
|
||||
getAlertById,
|
||||
editAlert,
|
||||
deleteAlert,
|
||||
};
|
||||
@@ -17,7 +17,7 @@ const SERVICE_NAME = "auth";
|
||||
* @returns {String}
|
||||
*/
|
||||
const issueToken = (payload) => {
|
||||
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1h" });
|
||||
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "99d" });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,7 @@ const registerController = async (req, res, next) => {
|
||||
try {
|
||||
await registerValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 400;
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
next(error);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
const {
|
||||
createCheckParamValidation,
|
||||
createCheckBodyValidation,
|
||||
getChecksParamValidation,
|
||||
deleteChecksParamValidation,
|
||||
} = require("../validation/joi");
|
||||
const SERVICE_NAME = "check";
|
||||
|
||||
const createCheck = async (req, res, next) => {
|
||||
try {
|
||||
await createCheckParamValidation.validateAsync(req.params);
|
||||
await createCheckBodyValidation.validateAsync(req.body);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const checkData = { ...req.body };
|
||||
const check = await req.db.createCheck(checkData);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Check created", data: check });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getChecks = async (req, res, next) => {
|
||||
try {
|
||||
await getChecksParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const checks = await req.db.getChecks(req.params.monitorId);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Checks retrieved", data: checks });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteChecks = async (req, res, next) => {
|
||||
try {
|
||||
await deleteChecksParamValidation.validateAsync(req.params);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.service = SERVICE_NAME;
|
||||
error.message = error.details[0].message;
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const deletedCount = await req.db.deleteChecks(req.params.monitorId);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, msg: "Checks deleted", data: { deletedCount } });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createCheck,
|
||||
getChecks,
|
||||
deleteChecks,
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
const Monitor = require("../models/Monitor");
|
||||
const mongoose = require("mongoose");
|
||||
const UserModel = require("../models/user");
|
||||
const Check = require("../models/Check");
|
||||
const Alert = require("../models/Alert");
|
||||
|
||||
const verifyId = (userId, monitorId) => {
|
||||
return userId.toString() === monitorId.toString();
|
||||
@@ -16,6 +18,10 @@ const connect = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
//****************************************
|
||||
// Users
|
||||
//****************************************
|
||||
|
||||
/**
|
||||
* Insert a User
|
||||
* @async
|
||||
@@ -80,6 +86,10 @@ const updateUser = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
//****************************************
|
||||
// Monitors
|
||||
//****************************************
|
||||
|
||||
/**
|
||||
* Get all monitors
|
||||
* @async
|
||||
@@ -194,6 +204,190 @@ const editMonitor = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
//****************************************
|
||||
// Checks
|
||||
//****************************************
|
||||
|
||||
/**
|
||||
* Create a check for a monitor
|
||||
* @async
|
||||
* @param {Object} checkData
|
||||
* @param {string} checkData.monitorId
|
||||
* @param {boolean} checkData.status
|
||||
* @param {number} checkData.responseTime
|
||||
* @param {number} checkData.statusCode
|
||||
* @param {string} checkData.message
|
||||
* @returns {Promise<Check>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
|
||||
const createCheck = async (checkData) => {
|
||||
try {
|
||||
console.log(checkData);
|
||||
const check = await new Check({ ...checkData }).save();
|
||||
return check;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all checks for a monitor
|
||||
* @async
|
||||
* @param {string} monitorId
|
||||
* @returns {Promise<Array<Check>>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
|
||||
const getChecks = async (monitorId) => {
|
||||
try {
|
||||
const checks = await Check.find({ monitorId });
|
||||
return checks;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete all checks for a monitor
|
||||
* @async
|
||||
* @param {string} monitorId
|
||||
* @returns {number}
|
||||
* @throws {Error}
|
||||
*/
|
||||
|
||||
const deleteChecks = async (monitorId) => {
|
||||
try {
|
||||
const result = await Check.deleteMany({ monitorId });
|
||||
if (result.deletedCount > 0) {
|
||||
return result.deletedCount;
|
||||
} else {
|
||||
throw new Error(`No checks found for monitor with id ${monitorId}`);
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
//****************************************
|
||||
// Alerts
|
||||
//****************************************
|
||||
|
||||
/**
|
||||
* Creates an Alert associated with a Monitor and User
|
||||
* @async
|
||||
* @param {Object} alertData
|
||||
* @param {string} alertData.checkId
|
||||
* @param {string} alert.monitorId
|
||||
* @param {string} alert.userId
|
||||
* @param {boolean} alert.status
|
||||
* @param {string} alert.message
|
||||
* @param {boolean} alert.notifiedStatus
|
||||
* @param {boolean} alert.acknowledgeStatus
|
||||
* @returns {<Promise<Alert>>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const createAlert = async (alertData) => {
|
||||
try {
|
||||
const alert = await new Alert({ ...alertData }).save();
|
||||
return alert;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all alerts a User has set
|
||||
* @async
|
||||
* @param {string} userId
|
||||
* @returns {<Promise<Array<Alert>>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const getAlertsByUserId = async (userId) => {
|
||||
try {
|
||||
const alerts = await Alert.find({ userId });
|
||||
return alerts;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all alerts a for an associated Monitor
|
||||
* @async
|
||||
* @param {string} monitorId
|
||||
* @returns {<Promise<Array<Alert>>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const getAlertsByMonitorId = async (monitorId) => {
|
||||
try {
|
||||
const alerts = await Alert.find({ monitorId });
|
||||
return alerts;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an alert with specified ID
|
||||
* @async
|
||||
* @param {string} alertId
|
||||
* @returns {Promise<Alert>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const getAlertById = async (alertId) => {
|
||||
try {
|
||||
const alert = await Alert.findById(alertId);
|
||||
return alert;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an edited alert with the specified ID
|
||||
* @async
|
||||
* @param {string} alertId
|
||||
* @param {Object} alertData
|
||||
* @param {string} alertData.checkId
|
||||
* @param {string} alertData.monitorId
|
||||
* @param {string} alertData.userId
|
||||
* @param {boolean} alertData.status
|
||||
* @param {string} alertData.message
|
||||
* @param {boolean} alertData.notifiedStatus
|
||||
* @param {boolean} alertData.acknowledgeStatus
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Alert>>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const editAlert = async (alertId, alertData) => {
|
||||
try {
|
||||
const editedAlert = await Alert.findByIdAndUpdate(alertId, alertData, {
|
||||
new: true,
|
||||
});
|
||||
return editedAlert;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes an alert with the specified ID
|
||||
* @async
|
||||
* @param {string} alertId
|
||||
* @throws {Error}
|
||||
*/
|
||||
const deleteAlert = async (alertId) => {
|
||||
try {
|
||||
const result = await Alert.findByIdAndDelete(alertId);
|
||||
if (result) {
|
||||
return result;
|
||||
} else throw new Error(`Alert with id ${alertId} not found`);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
connect,
|
||||
insertUser,
|
||||
@@ -205,4 +399,13 @@ module.exports = {
|
||||
createMonitor,
|
||||
deleteMonitor,
|
||||
editMonitor,
|
||||
createCheck,
|
||||
getChecks,
|
||||
deleteChecks,
|
||||
createAlert,
|
||||
getAlertsByUserId,
|
||||
getAlertsByMonitorId,
|
||||
getAlertById,
|
||||
editAlert,
|
||||
deleteAlert,
|
||||
};
|
||||
+5
-13
@@ -3,14 +3,14 @@ const helmet = require("helmet");
|
||||
const cors = require("cors");
|
||||
const authRouter = require("./routes/authRoute");
|
||||
const monitorRouter = require("./routes/monitorRoute");
|
||||
const checkRouter = require("./routes/checkRoute");
|
||||
const alertRouter = require("./routes/alertRoute");
|
||||
const { connectDbAndRunServer } = require("./configs/db");
|
||||
require("dotenv").config();
|
||||
const logger = require("./utils/logger");
|
||||
const { verifyJWT } = require("./middleware/verifyJWT");
|
||||
const { handleErrors } = require("./middleware/handleErrors");
|
||||
|
||||
// const { sendEmail } = require('./utils/sendEmail')
|
||||
|
||||
// **************************
|
||||
// Here is where we can swap out DBs easily. Spin up a mongoDB instance and try it out.
|
||||
// Simply comment out the FakeDB and uncomment the MongoDB or vice versa.
|
||||
@@ -33,11 +33,6 @@ const db = DB_TYPE[process.env.DB_TYPE]
|
||||
? DB_TYPE[process.env.DB_TYPE]()
|
||||
: require("./db/FakeDb");
|
||||
|
||||
/**
|
||||
* NOTES
|
||||
* Email Service will be added
|
||||
* Logger Service will be added (Winston or similar)
|
||||
*/
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -61,13 +56,10 @@ app.use((req, res, next) => {
|
||||
|
||||
//routes
|
||||
app.use("/api/v1/auth", authRouter);
|
||||
app.use("/api/v1/monitors", verifyJWT, monitorRouter);
|
||||
app.use("/api/v1/monitors", monitorRouter);
|
||||
app.use("/api/v1/checks", verifyJWT, checkRouter);
|
||||
app.use("/api/v1/alerts", verifyJWT, alertRouter);
|
||||
|
||||
// Testing email service
|
||||
// app.use('/sendEmail', async (req, res) => {
|
||||
// const response = sendEmail(['veysel.boybay@bluewavelabs.ca'], 'Testing email service', '<h1>Testing Bluewavelabs</h1>');
|
||||
// console.log(response);
|
||||
// })
|
||||
|
||||
//health check
|
||||
app.use("/api/v1/healthy", (req, res) => {
|
||||
|
||||
@@ -7,6 +7,16 @@ const AlertSchema = mongoose.Schema(
|
||||
ref: 'Check',
|
||||
immutable: true,
|
||||
},
|
||||
monitorId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'Monitor',
|
||||
immutable: true,
|
||||
},
|
||||
userId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'User',
|
||||
immutable: true,
|
||||
},
|
||||
status: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
Generated
+115
@@ -9,6 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@sendgrid/mail": "^8.1.3",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
@@ -96,6 +97,41 @@
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@sendgrid/client": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.3.tgz",
|
||||
"integrity": "sha512-mRwTticRZIdUTsnyzvlK6dMu3jni9ci9J+dW/6fMMFpGRAJdCJlivFVYQvqk8kRS3RnFzS7sf6BSmhLl1ldDhA==",
|
||||
"dependencies": {
|
||||
"@sendgrid/helpers": "^8.0.0",
|
||||
"axios": "^1.6.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.*"
|
||||
}
|
||||
},
|
||||
"node_modules/@sendgrid/helpers": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz",
|
||||
"integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==",
|
||||
"dependencies": {
|
||||
"deepmerge": "^4.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sendgrid/mail": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.3.tgz",
|
||||
"integrity": "sha512-Wg5iKSUOER83/cfY6rbPa+o3ChnYzWwv1OcsR8gCV8SKi+sUPIMroildimlnb72DBkQxcbylxng1W7f0RIX7MQ==",
|
||||
"dependencies": {
|
||||
"@sendgrid/client": "^8.1.3",
|
||||
"@sendgrid/helpers": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.*"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
||||
@@ -229,6 +265,21 @@
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
|
||||
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -422,6 +473,17 @@
|
||||
"text-hex": "1.0.x"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -484,6 +546,14 @@
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
@@ -500,6 +570,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
@@ -689,6 +767,38 @@
|
||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@@ -1703,6 +1813,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/pstree.remy": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@sendgrid/mail": "^8.1.3",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
const router = require("express").Router();
|
||||
const alertController = require("../controllers/alertController");
|
||||
const { verifyOwnership } = require("../middleware/verifyOwnership");
|
||||
const Alert = require("../models/Alert");
|
||||
|
||||
// Create alert
|
||||
router.post("/:monitorId", alertController.createAlert);
|
||||
// Get all alerts for a user
|
||||
router.get("/user/:userId", alertController.getAlertsByUserId);
|
||||
// Get all alerts for a monitor
|
||||
router.get("/monitor/:monitorId", alertController.getAlertsByMonitorId);
|
||||
// Get a single alert
|
||||
router.get("/:alertId", alertController.getAlertById);
|
||||
// Edit
|
||||
router.post(
|
||||
"/edit/:alertId",
|
||||
verifyOwnership(Alert, "alertId"),
|
||||
alertController.editAlert
|
||||
);
|
||||
//Delete
|
||||
router.post(
|
||||
"/delete/:alertId",
|
||||
verifyOwnership(Alert, "alertId"),
|
||||
alertController.deleteAlert
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,24 @@
|
||||
const router = require("express").Router();
|
||||
const checkController = require("../controllers/checkController");
|
||||
const { verifyOwnership } = require("../middleware/verifyOwnership");
|
||||
const Monitor = require("../models/Monitor");
|
||||
|
||||
router.post(
|
||||
"/:monitorId",
|
||||
verifyOwnership(Monitor, "monitorId"),
|
||||
checkController.createCheck
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:monitorId",
|
||||
verifyOwnership(Monitor, "monitorId"),
|
||||
checkController.getChecks
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/delete/:monitorId",
|
||||
verifyOwnership(Monitor, "monitorId"),
|
||||
checkController.deleteChecks
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
+27
-34
@@ -1,43 +1,36 @@
|
||||
const { MailerSend, EmailParams, Sender, Recipient } = require('mailersend')
|
||||
const logger = require('../utils/logger')
|
||||
|
||||
|
||||
const mailersend = new MailerSend({
|
||||
apiKey: process.env.MAILERSEND_API_KEY,
|
||||
})
|
||||
const sgMail = require('@sendgrid/mail')
|
||||
const logger = require('./logger')
|
||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
|
||||
const SERVICE_NAME = 'Email_Service';
|
||||
/**
|
||||
* @async
|
||||
* @function
|
||||
* @param {[string]} receivers - takes an array of strings
|
||||
* @param {string} subject - takes a single string
|
||||
* @param {string} contentHTML - takes a single string that contains HTML
|
||||
* @returns {JSON}
|
||||
* @example
|
||||
* sendEmail(['veysel@bluewavelabs.ca','alex@bluewavelabs.ca','monzer@bluewavelabs.ca'],'Testing Email Servide','<h1>BlueWaveLabs</h1>')
|
||||
* @param {[String]} receivers - takes an array of strings
|
||||
* @param {String} subject - takes a single string
|
||||
* @param {String} contentHTML - takes a single string that contains HTML
|
||||
* @param {String} contentText - takes a string to be used if contentHTML is not compatible
|
||||
* @example
|
||||
* await sendEmail(['veysel@bluewavelabs.ca','alex@bluewavelabs.ca'],'Testing Email Service','<h1>BlueWaveLabs</h1>','Testing Email Service')
|
||||
*/
|
||||
// TODO: from email should be in .env file
|
||||
const sendEmail = async (receivers,subject,contentHTML) => {
|
||||
// Sender
|
||||
const from = process.env.SYSTEM_EMAIL_ADDRESS;
|
||||
const sender = new Sender(from);
|
||||
// receivers
|
||||
let recipients = []
|
||||
receivers.map(email => recipients.push(new Recipient(email)));
|
||||
// Set params
|
||||
const emailParams = new EmailParams()
|
||||
.setFrom(sender)
|
||||
.setTo(recipients)
|
||||
.setSubject(subject)
|
||||
.setHtml(contentHTML);
|
||||
|
||||
const sendEmail = async (receivers,subject, contentHTML, contentText = null ) => {
|
||||
const msg = {
|
||||
to: receivers,
|
||||
from: {
|
||||
name: 'Uptime System',
|
||||
email: process.env.SYSTEM_EMAIL_ADDRESS // must be verified email by sendgrid
|
||||
},
|
||||
subject: subject,
|
||||
text: contentText || contentHTML,
|
||||
html: contentHTML,
|
||||
}
|
||||
try {
|
||||
const response = await mailersend.email.send(emailParams);
|
||||
logger.info("Email sent to receivers!",{"service":"Email"})
|
||||
return response;
|
||||
|
||||
await sgMail.send(msg);
|
||||
logger.info(`Emails sent to receivers:${receivers} with the subject:${subject}`,{service:SERVICE_NAME})
|
||||
} catch (error) {
|
||||
logger.error(error.body,{"service":"email"})
|
||||
console.log(error.body)
|
||||
logger.error(`Sending Email action failed, ERROR:${error}`, { service: SERVICE_NAME });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {sendEmail}
|
||||
@@ -1,5 +1,9 @@
|
||||
const joi = require("joi");
|
||||
|
||||
//****************************************
|
||||
// Auth
|
||||
//****************************************
|
||||
|
||||
const loginValidation = joi.object({
|
||||
email: joi.string().email().required(),
|
||||
password: joi.string().min(8).required(),
|
||||
@@ -11,6 +15,20 @@ const registerValidation = joi.object({
|
||||
password: joi.string().min(8).required(),
|
||||
});
|
||||
|
||||
const editUserParamValidation = joi.object({
|
||||
userId: joi.string().required(),
|
||||
});
|
||||
|
||||
const editUserBodyValidation = joi.object({
|
||||
firstname: joi.string(),
|
||||
lastname: joi.string(),
|
||||
profilePicUrl: joi.string(),
|
||||
});
|
||||
|
||||
//****************************************
|
||||
// Monitors
|
||||
//****************************************
|
||||
|
||||
const getMonitorByIdValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
@@ -29,14 +47,73 @@ const monitorValidation = joi.object({
|
||||
interval: joi.number(),
|
||||
});
|
||||
|
||||
const editUserParamValidation = joi.object({
|
||||
//****************************************
|
||||
// Alerts
|
||||
//****************************************
|
||||
|
||||
const createAlertParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
const createAlertBodyValidation = joi.object({
|
||||
checkId: joi.string().required(),
|
||||
monitorId: joi.string().required(),
|
||||
userId: joi.string().required(),
|
||||
status: joi.boolean(),
|
||||
message: joi.string(),
|
||||
notifiedStatus: joi.boolean(),
|
||||
acknowledgeStatus: joi.boolean(),
|
||||
});
|
||||
|
||||
const getAlertsByUserIdParamValidation = joi.object({
|
||||
userId: joi.string().required(),
|
||||
});
|
||||
|
||||
const editUserBodyValidation = joi.object({
|
||||
firstname: joi.string(),
|
||||
lastname: joi.string(),
|
||||
profilePicUrl: joi.string(),
|
||||
const getAlertsByMonitorIdParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
const getAlertByIdParamValidation = joi.object({
|
||||
alertId: joi.string().required(),
|
||||
});
|
||||
|
||||
const editAlertParamValidation = joi.object({
|
||||
alertId: joi.string().required(),
|
||||
});
|
||||
|
||||
const editAlertBodyValidation = joi.object({
|
||||
status: joi.boolean(),
|
||||
message: joi.string(),
|
||||
notifiedStatus: joi.boolean(),
|
||||
acknowledgeStatus: joi.boolean(),
|
||||
});
|
||||
|
||||
const deleteAlertParamValidation = joi.object({
|
||||
alertId: joi.string().required(),
|
||||
});
|
||||
|
||||
//****************************************
|
||||
// Checks
|
||||
//****************************************
|
||||
|
||||
const createCheckParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
const createCheckBodyValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
status: joi.boolean().required(),
|
||||
responseTime: joi.number().required(),
|
||||
statusCode: joi.number().required(),
|
||||
message: joi.string().required(),
|
||||
});
|
||||
|
||||
const getChecksParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
const deleteChecksParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
@@ -47,4 +124,16 @@ module.exports = {
|
||||
monitorValidation,
|
||||
editUserParamValidation,
|
||||
editUserBodyValidation,
|
||||
createAlertParamValidation,
|
||||
createAlertBodyValidation,
|
||||
getAlertsByUserIdParamValidation,
|
||||
getAlertsByMonitorIdParamValidation,
|
||||
getAlertByIdParamValidation,
|
||||
editAlertParamValidation,
|
||||
editAlertBodyValidation,
|
||||
deleteAlertParamValidation,
|
||||
createCheckParamValidation,
|
||||
createCheckBodyValidation,
|
||||
getChecksParamValidation,
|
||||
deleteChecksParamValidation,
|
||||
};
|
||||
Reference in new issue
Block a user