Merge remote-tracking branch 'upstream/master' into feat/incidents-page

This commit is contained in:
M M committed 2024-06-28 16:35:02 -07:00
commit 02339e9cde
10 files changed
+315 -291

No files matched your search

+13
View File
@@ -6,6 +6,7 @@ import Register from "./Pages/Register";
import HomeLayout from "./Layouts/HomeLayout";
import Demo from "./Pages/Demo/Demo";
import PlayGround from "./Pages/PlayGround/PlayGround";
import Account from "./Pages/Account";
import Monitors from "./Pages/Monitors";
import CreateNewMonitor from "./Pages/CreateNewMonitor";
import Incidents from "./Pages/Incidents";
@@ -53,6 +54,18 @@ function App() {
path="settings"
element={<ProtectedRoute Component={Settings} />}
/>
<Route
path="account/profile"
element={<ProtectedRoute Component={Account} open="profile" />}
/>
<Route
path="account/password"
element={<ProtectedRoute Component={Account} open="password" />}
/>
<Route
path="account/team"
element={<ProtectedRoute Component={Account} open="team" />}
/>
</Route>
<Route exact path="/login" element={<Login />} />
+2 -2
View File
@@ -66,10 +66,10 @@ function NavBar() {
setAnchorElUser(null);
switch (setting) {
case "Profile":
console.log("Profile");
navigate("/account/profile");
break;
case "Team":
console.log("Team");
navigate("/account/team");
break;
case "Invite Colleagues":
console.log("Invite Colleagues");
@@ -87,7 +87,7 @@ const PasswordPanel = () => {
};
return (
<TabPanel value="1">
<TabPanel value="password">
<form
onSubmit={handleSubmit}
className="edit-password-form"
@@ -148,7 +148,7 @@ const ProfilePanel = () => {
};
return (
<TabPanel value="0">
<TabPanel value="profile">
<form className="edit-profile-form" noValidate spellCheck="false">
<div className="edit-profile-form__wrapper">
<Stack>
@@ -184,7 +184,7 @@ const TeamPanel = () => {
return count;
};
return (
<TabPanel value="2">
<TabPanel value="team">
<form className="edit-organization-form">
<div
className="edit-organization-form__wrapper"
+200
View File
@@ -0,0 +1,200 @@
.account h1.MuiTypography-root,
.account p.MuiTypography-root,
.account input,
.account button,
.account td,
.account .MuiSelect-select {
font-size: var(--env-var-font-size-medium);
}
.account h1.MuiTypography-root,
.account p.MuiTypography-root,
.account input,
.account .MuiSelect-select {
color: var(--env-var-color-2);
}
.account h1.MuiTypography-root {
font-weight: 600;
}
.account .MuiStack-root:not(.table-stack) {
flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
}
.account .MuiTabPanel-root {
padding: 0;
margin-top: 50px;
}
.account .MuiDivider-root:not(.short-divider) {
margin: 50px 0;
}
.account .MuiDivider-root,
.account .MuiOutlinedInput-root fieldset,
.account .announcement-tile {
border-color: var(--env-var-color-29);
}
.account [class$="-form"] {
width: inherit;
}
.account [class$="__wrapper"],
.account [class$="__wrapper compact"] {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
}
.edit-profile-form__wrapper .MuiStack-root:not(.row-stack),
.edit-password-form__wrapper .MuiStack-root:not(.row-stack),
.edit-organization-form__wrapper .MuiStack-root:not(.row-stack) {
flex-direction: column;
gap: 8px;
margin-right: 10px;
}
.edit-profile-form__wrapper p.MuiTypography-root,
.delete-profile-form__wrapper p.MuiTypography-root {
opacity: 0.6;
}
#modal-delete-account,
#modal-edit-org-name,
#modal-invite-member {
font-size: var(--env-var-font-size-large);
}
.edit-profile-form__wrapper:not(:first-of-type),
.edit-password-form__wrapper:not(:first-of-type),
.edit-team-form__wrapper:not(:first-of-type) {
margin-top: var(--env-var-spacing-4);
}
.edit-team-form__wrapper.compact {
margin-top: var(--env-var-spacing-3);
justify-content: flex-start;
align-items: center;
}
.edit-profile-form__wrapper input,
.edit-password-form__wrapper input,
#edit-organization-name,
#input-team-member {
padding: 10px;
}
.edit-password-form__wrapper > .announcement-tile {
width: 100%;
}
.edit-password-form__wrapper
> .announcement-tile
.announcement-content-subject {
margin-bottom: 2px;
}
#edit-new-password + div > button > svg,
#edit-confirm-password + div > button > svg,
#edit-current-password + div > button > svg {
color: var(--env-var-color-29);
}
.edit-password-form__wrapper .announcement-tile {
margin: 0;
}
.edit-password-form__wrapper .announcement-tile .announcement-close {
margin-left: auto;
}
.MuiBox-root > .announcement-tile {
border-color: var(--env-var-color-27);
background-color: var(--lighter-env-var-color-27);
}
.MuiBox-root > .announcement-tile .announcement-content-body {
color: var(--env-var-color-28);
}
.MuiBox-root > .announcement-tile .announcement-close svg,
.edit-password-form__wrapper > .announcement-tile .announcement-close svg {
display: none;
}
#org-name-flex-container .Mui-disabled {
color: var(--env-var-color-2) !important;
}
.edit-team-form__wrapper td {
padding: 10px 0;
padding-top: 20px;
vertical-align: text-top;
}
.edit-team-form__wrapper th {
padding: var(--env-var-spacing-1) 0;
}
.edit-team-form__wrapper th:first-of-type {
padding-left: 20px;
}
.edit-team-form__wrapper td {
color: var(--env-var-color-25);
}
#select-actions,
#select-role {
padding: 5px 0;
padding-left: 15px;
padding-right: 50px;
line-height: 1.75;
}
.MuiInputBase-root:has(#select-actions) fieldset,
.MuiInputBase-root:has(#select-role) fieldset {
border-color: #a1a7b1;
margin: -1px;
border-width: 1px;
}
.MuiInputBase-root:has(#select-actions):hover fieldset,
.MuiInputBase-root:has(#select-role):hover fieldset {
border-color: var(--env-var-color-2);
}
.MuiStack-root:has(.MuiBox-root > .members-query) .MuiBox-root {
cursor: pointer;
}
.members-query {
display: inline-flex;
justify-content: center;
align-items: center;
margin-left: 6px;
padding: 2px;
font-size: 12px;
font-weight: 500;
color: var(--env-var-color-3);
background-color: #e0e9fd;
min-width: 22px;
min-height: 22px;
border-radius: 50%;
}
/* for testing, will remove later */
@media only screen and (max-width: 1600px) {
.edit-profile-form__wrapper .MuiStack-root:not(.row-stack),
.edit-password-form__wrapper .MuiStack-root:not(.row-stack),
.edit-organization-form__wrapper .MuiStack-root:not(.row-stack) {
margin-right: 30px;
}
}
.account .MuiStack-root:has(p.MuiTypography-root.input-error) {
position: relative;
}
.account .text-field-icon {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 18px !important;
height: 18px !important;
opacity: 0.8;
}
.account p.MuiTypography-root.input-error {
color: var(--env-var-color-24);
opacity: 0.8;
position: absolute;
top: calc(100% + 5px);
}
.account .email-text-field,
.account .password-text-field {
margin: 0;
}
.edit-profile-form__wrapper .MuiFormControl-root,
.edit-password-form__wrapper .MuiFormControl-root {
width: 100%;
}
.edit-profile-form__wrapper .MuiStack-root:has(.MuiFormControl-root),
.edit-password-form__wrapper .MuiStack-root:has(.MuiFormControl-root) {
margin: 0;
}
+84
View File
@@ -0,0 +1,84 @@
import PropTypes from "prop-types";
import { useState } from "react";
import { Box, Tab, useTheme } from "@mui/material";
import TabContext from "@mui/lab/TabContext";
import TabList from "@mui/lab/TabList";
import "./index.css";
import ProfilePanel from "../../Components/TabPanels/Account/ProfilePanel";
import PasswordPanel from "../../Components/TabPanels/Account/PasswordPanel";
import TeamPanel from "../../Components/TabPanels/Account/TeamPanel";
import { useNavigate } from "react-router";
/**
* Account component renders a settings page with tabs for Profile, Password, and Team settings.
* @param {string} [props.open] - Specifies the initially open tab: 'profile', 'password', or 'team'.
* @returns {JSX.Element}
*/
const tabList = ["Profile", "Password", "Team"];
const Account = ({ open = "profile" }) => {
const theme = useTheme();
const navigate = useNavigate();
const tab = open;
const handleTabChange = (event, newTab) => {
navigate(`/account/${newTab}`);
};
return (
<Box
//TODO - breakpoints for responsive design
minWidth={theme.spacing(55)}
maxWidth="1200px"
py={theme.spacing(5)}
px={theme.spacing(10)}
className="account"
>
<TabContext value={tab}>
<Box
sx={{
borderBottom: 1,
borderColor: theme.palette.section.borderColor,
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
}}
>
<TabList onChange={handleTabChange} aria-label="account tabs">
{tabList.map((label, index) => (
<Tab
label={label}
key={index}
value={label.toLowerCase()}
sx={{
fontSize: "13px",
color: theme.palette.secondary.main,
textTransform: "none",
minWidth: "fit-content",
minHeight: 0,
paddingLeft: "0",
paddingY: "10px",
marginRight: "20px",
"&:focus": {
outline: "none",
},
"& .MuiTouchRipple-root": {
pointerEvents: "none",
display: "none",
},
}}
/>
))}
</TabList>
</Box>
<ProfilePanel />
<PasswordPanel />
<TeamPanel />
</TabContext>
</Box>
);
};
Account.propTypes = {
open: PropTypes.oneOf(["profile", "password", "team"]),
};
export default Account;
+11 -2
View File
@@ -9,11 +9,13 @@ import { MenuItem, Select, Typography } from "@mui/material";
import { useSelector, useDispatch } from "react-redux";
import { createMonitorValidation } from "../../Validation/validation";
import { createMonitor } from "../../Features/Monitors/monitorsSlice";
import { useNavigate } from "react-router-dom";
const CreateNewMonitor = () => {
const MS_PER_MINUTE = 60000;
const { user, authToken } = useSelector((state) => state.auth);
const dispatch = useDispatch();
const navigate = useNavigate();
const [errors, setErrors] = useState({});
@@ -76,7 +78,7 @@ const CreateNewMonitor = () => {
// }));
// };
const handleCreateNewMonitor = (event) => {
const handleCreateNewMonitor = async (event) => {
event.preventDefault();
//obj to submit
let monitor = {
@@ -102,7 +104,14 @@ const CreateNewMonitor = () => {
// ...advancedSettings, // TODO frequency should be interval, then we can use spread
interval: advancedSettings.frequency * MS_PER_MINUTE,
};
dispatch(createMonitor({ authToken, monitor }));
try {
const action = await dispatch(createMonitor({ authToken, monitor }));
if (action.meta.requestStatus === "fulfilled") {
navigate("/monitors");
}
} catch (error) {
alert(error);
}
}
};
-203
View File
@@ -1,203 +0,0 @@
.settings h1.MuiTypography-root,
.settings p.MuiTypography-root,
.settings input,
.settings button,
.settings td,
.settings .MuiSelect-select {
font-size: var(--env-var-font-size-medium);
}
.settings h1.MuiTypography-root,
.settings p.MuiTypography-root,
.settings input,
.settings .MuiSelect-select {
color: var(--env-var-color-2);
}
.settings h1.MuiTypography-root {
font-weight: 600;
}
.settings .MuiStack-root:not(.table-stack) {
flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
}
.settings .MuiTabPanel-root {
padding: 0;
margin-top: 50px;
}
.settings .MuiDivider-root:not(.short-divider) {
margin: 50px 0;
}
.settings .MuiDivider-root,
.settings .MuiOutlinedInput-root fieldset,
.announcement-tile {
border-color: var(--env-var-color-29);
}
.settings [class$="-form"] {
width: inherit;
}
.settings [class$="__wrapper"],
.settings [class$="__wrapper compact"] {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
}
.edit-profile-form__wrapper .MuiStack-root:not(.row-stack),
.edit-password-form__wrapper .MuiStack-root:not(.row-stack),
.edit-organization-form__wrapper .MuiStack-root:not(.row-stack) {
flex-direction: column;
gap: 8px;
margin-right: 10px;
}
.edit-profile-form__wrapper p.MuiTypography-root,
.delete-profile-form__wrapper p.MuiTypography-root {
opacity: 0.6;
}
#modal-delete-account,
#modal-edit-org-name,
#modal-invite-member {
font-size: var(--env-var-font-size-large);
}
.edit-profile-form__wrapper:not(:first-of-type),
.edit-password-form__wrapper:not(:first-of-type),
.edit-team-form__wrapper:not(:first-of-type) {
margin-top: var(--env-var-spacing-4);
}
.edit-team-form__wrapper.compact {
margin-top: var(--env-var-spacing-3);
justify-content: flex-start;
align-items: center;
}
.edit-profile-form__wrapper input,
.edit-password-form__wrapper input,
#edit-organization-name,
#input-team-member {
padding: 10px;
}
.edit-password-form__wrapper > .announcement-tile {
width: 100%;
}
.edit-password-form__wrapper
> .announcement-tile
.announcement-content-subject {
margin-bottom: 2px;
}
#edit-new-password + div > button > svg,
#edit-confirm-password + div > button > svg,
#edit-current-password + div > button > svg {
color: var(--env-var-color-29);
}
.edit-password-form__wrapper .announcement-tile {
margin: 0;
}
.edit-password-form__wrapper .announcement-tile .announcement-close {
margin-left: auto;
}
.MuiBox-root > .announcement-tile {
border-color: var(--env-var-color-27);
background-color: var(--lighter-env-var-color-27);
}
.MuiBox-root > .announcement-tile .announcement-content-body {
color: var(--env-var-color-28);
}
.MuiBox-root > .announcement-tile .announcement-close svg,
.edit-password-form__wrapper > .announcement-tile .announcement-close svg {
display: none;
}
#org-name-flex-container .Mui-disabled {
color: var(--env-var-color-2) !important;
}
.edit-team-form__wrapper td {
padding: 10px 0;
padding-top: 20px;
vertical-align: text-top;
}
.edit-team-form__wrapper th {
padding: var(--env-var-spacing-1) 0;
}
.edit-team-form__wrapper th:first-of-type {
padding-left: 20px;
}
.edit-team-form__wrapper td {
color: var(--env-var-color-25);
}
#select-actions,
#select-role {
padding: 5px 0;
padding-left: 15px;
padding-right: 50px;
line-height: 1.75;
}
.MuiInputBase-root:has(#select-actions) fieldset,
.MuiInputBase-root:has(#select-role) fieldset {
border-color: #a1a7b1;
margin: -1px;
border-width: 1px;
}
.MuiInputBase-root:has(#select-actions):hover fieldset,
.MuiInputBase-root:has(#select-role):hover fieldset {
border-color: var(--env-var-color-2);
}
.MuiStack-root:has(.MuiBox-root > .members-query) .MuiBox-root {
cursor: pointer;
}
.members-query {
display: inline-flex;
justify-content: center;
align-items: center;
margin-left: 6px;
padding: 2px;
font-size: 12px;
font-weight: 500;
color: var(--env-var-color-3);
background-color: #e0e9fd;
min-width: 22px;
min-height: 22px;
border-radius: 50%;
}
/* for testing, will remove later */
@media only screen and (max-width: 1600px) {
.settings {
max-width: calc(90vw - 250px) !important;
}
.edit-profile-form__wrapper .MuiStack-root:not(.row-stack),
.edit-password-form__wrapper .MuiStack-root:not(.row-stack),
.edit-organization-form__wrapper .MuiStack-root:not(.row-stack) {
margin-right: 30px;
}
}
.settings .MuiStack-root:has(p.MuiTypography-root.input-error) {
position: relative;
}
.settings .text-field-icon {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 18px !important;
height: 18px !important;
opacity: 0.8;
}
.settings p.MuiTypography-root.input-error {
color: var(--env-var-color-24);
opacity: 0.8;
position: absolute;
top: calc(100% + 5px);
}
.settings .email-text-field,
.settings .password-text-field {
margin: 0;
}
.edit-profile-form__wrapper .MuiFormControl-root,
.edit-password-form__wrapper .MuiFormControl-root {
width: 100%;
}
.edit-profile-form__wrapper .MuiStack-root:has(.MuiFormControl-root),
.edit-password-form__wrapper .MuiStack-root:has(.MuiFormControl-root) {
margin: 0;
}
+2 -81
View File
@@ -1,86 +1,7 @@
import PropTypes from "prop-types";
import { useState } from "react";
import { Box, Tab, useTheme } from "@mui/material";
import TabContext from "@mui/lab/TabContext";
import TabList from "@mui/lab/TabList";
import "./index.css";
import ProfilePanel from "../../Components/TabPanels/ProfileSettings/ProfilePanel";
import PasswordPanel from "../../Components/TabPanels/ProfileSettings/PasswordPanel";
import TeamPanel from "../../Components/TabPanels/ProfileSettings/TeamPanel";
/**
* Settings component renders a settings page with tabs for Profile, Password, and Team settings.
*
* @returns {JSX.Element}
*/
const tabList = ["Profile", "Password", "Team"];
import React from "react";
const Settings = () => {
const theme = useTheme();
//(tab) 0 - Profile
//(tab) 1 - Password
//(tab) 2 - Team
const [tab, setTab] = useState("0");
const handleTabChange = (event, newTab) => {
setTab(newTab);
};
return (
<Box
//TODO - breakpoints for responsive design
minWidth={theme.spacing(55)}
width="100vw"
maxWidth="calc(100vw - 800px)"
py={theme.spacing(5)}
px={theme.spacing(10)}
className="settings"
>
<TabContext value={tab}>
<Box
sx={{
borderBottom: 1,
borderColor: theme.palette.section.borderColor,
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
}}
>
<TabList onChange={handleTabChange} aria-label="settings tabs">
{tabList.map((label, index) => (
<Tab
label={label}
key={index}
value={index.toString()}
sx={{
fontSize: "13px",
color: theme.palette.secondary.main,
textTransform: "none",
minWidth: "fit-content",
minHeight: 0,
paddingLeft: "0",
paddingY: "10px",
marginRight: "20px",
"&:focus": {
outline: "none",
},
"& .MuiTouchRipple-root": {
pointerEvents: "none",
display: "none",
},
}}
/>
))}
</TabList>
</Box>
<ProfilePanel />
<PasswordPanel />
<TeamPanel />
</TabContext>
</Box>
);
};
Settings.propTypes = {
// No props are being passed to this component, hence no specific PropTypes are defined.
return <div>Settings</div>;
};
export default Settings;