diff --git a/Client/src/Components/BasicTable/index.css b/Client/src/Components/BasicTable/index.css index 821726cf4..604dc412e 100644 --- a/Client/src/Components/BasicTable/index.css +++ b/Client/src/Components/BasicTable/index.css @@ -148,7 +148,7 @@ height: 22px; } .MuiTablePagination-root svg path { - stroke: var(--env-var-color-5); + stroke: var(--env-var-color-2); stroke-width: 1.3; } .MuiTablePagination-root .MuiSelect-icon { @@ -175,7 +175,8 @@ padding: 4px; min-width: 100px; } -.pagination-dropdown li { +.pagination-dropdown li, +body:has(.pagination-dropdown) p:has(+ .MuiTablePagination-root) { font-size: var(--env-var-font-size-medium); color: var(--env-var-color-2); padding: 4px; @@ -185,3 +186,6 @@ .pagination-dropdown li.Mui-selected:hover { background-color: #f4f4f4; } +body:has(.pagination-dropdown) p:has(+ .MuiTablePagination-root) { + font-size: var(--env-var-font-size-small-plus); +} diff --git a/Client/src/Components/BasicTable/index.jsx b/Client/src/Components/BasicTable/index.jsx index b9bbb795e..8b6cafd91 100644 --- a/Client/src/Components/BasicTable/index.jsx +++ b/Client/src/Components/BasicTable/index.jsx @@ -14,6 +14,9 @@ import { Typography, Stack, } from "@mui/material"; +import { useDispatch, useSelector } from "react-redux"; +import { useLocation, useParams } from "react-router-dom"; +import { setRowsPerPage } from "../../Features/UI/uiSlice"; import LeftArrowDouble from "../../assets/icons/left-arrow-double.svg?react"; import RightArrowDouble from "../../assets/icons/right-arrow-double.svg?react"; import LeftArrow from "../../assets/icons/left-arrow.svg?react"; @@ -140,10 +143,14 @@ const TablePaginationActions = (props) => { * */ -const BasicTable = ({ data, paginated, reversed, rows = 5 }) => { +const BasicTable = ({ data, paginated, reversed }) => { const theme = useTheme(); + const location = useLocation(); + const dispatch = useDispatch(); + const uiState = useSelector((state) => state.ui); + let table = location.pathname.split("/").pop(); + let rowsPerPage = uiState[table].rowsPerPage; const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(rows); useEffect(() => { setPage(0); @@ -154,7 +161,12 @@ const BasicTable = ({ data, paginated, reversed, rows = 5 }) => { }; const handleChangeRowsPerPage = (event) => { - setRowsPerPage(parseInt(event.target.value, 10)); + dispatch( + setRowsPerPage({ + value: parseInt(event.target.value, 10), + table: table, + }) + ); setPage(0); }; @@ -211,50 +223,59 @@ const BasicTable = ({ data, paginated, reversed, rows = 5 }) => { - - - Showing {getRange()} of {data.rows.length} monitor(s) - - - `Page ${page + 1} of ${Math.max(0, Math.ceil(count / rowsPerPage))}` - } - slotProps={{ - select: { - MenuProps: { - keepMounted: true, - PaperProps: { - className: "pagination-dropdown", + {paginated && ( + + + Showing {getRange()} of {data.rows.length} monitor(s) + + + `Page ${page + 1} of ${Math.max( + 0, + Math.ceil(count / rowsPerPage) + )}` + } + slotProps={{ + select: { + MenuProps: { + keepMounted: true, + PaperProps: { + className: "pagination-dropdown", + }, + transformOrigin: { vertical: "bottom", horizontal: "left" }, + anchorOrigin: { vertical: "top", horizontal: "left" }, + sx: { mt: "-4px" }, }, - transformOrigin: { vertical: "bottom", horizontal: "left" }, - anchorOrigin: { vertical: "top", horizontal: "left" }, - sx: { mt: "-4px" }, - }, - inputProps: { id: "pagination-dropdown" }, - IconComponent: SelectorVertical, - sx: { - ml: theme.gap.small, - mr: theme.gap.large, - minWidth: theme.gap.xl, - textAlign: "left", - "&.Mui-focused > div": { - backgroundColor: theme.palette.otherColors.white, + inputProps: { id: "pagination-dropdown" }, + IconComponent: SelectorVertical, + sx: { + ml: theme.gap.small, + mr: theme.gap.large, + minWidth: theme.gap.xl, + textAlign: "left", + "&.Mui-focused > div": { + backgroundColor: theme.palette.otherColors.white, + }, }, }, - }, - }} - sx={{ mt: theme.gap.medium }} - /> - + }} + sx={{ mt: theme.gap.medium }} + /> + + )} > ); }; diff --git a/Client/src/Components/Sidebar/index.css b/Client/src/Components/Sidebar/index.css index 59924b1a1..10cdfc77d 100644 --- a/Client/src/Components/Sidebar/index.css +++ b/Client/src/Components/Sidebar/index.css @@ -58,7 +58,7 @@ aside height: 100%; width: 100%; border-left: solid 1px var(--env-var-color-5); - opacity: 0.3; + opacity: 0.2; } aside .MuiCollapse-wrapperInner @@ -75,13 +75,13 @@ aside .MuiList-root .MuiListItemText-root + svg { aside .MuiCollapse-wrapperInner .MuiList-root > .MuiListItemButton-root::after { content: ""; position: absolute; - left: -7px; + left: -8px; top: 50%; - height: 1px; - width: 6px; + transform: translateY(-50%); + height: 3px; + width: 3px; border-radius: 50%; - background-color: var(--env-var-color-5); - opacity: 0.3; + background-color: #d6d9dd; } aside { diff --git a/Client/src/Components/Sidebar/index.jsx b/Client/src/Components/Sidebar/index.jsx index 38baa33ec..69b44c125 100644 --- a/Client/src/Components/Sidebar/index.jsx +++ b/Client/src/Components/Sidebar/index.jsx @@ -19,6 +19,7 @@ import { useLocation, useNavigate } from "react-router"; import { useTheme } from "@emotion/react"; import { useDispatch, useSelector } from "react-redux"; import { clearAuthState } from "../../Features/Auth/authSlice"; +import { toggleSidebar } from "../../Features/UI/uiSlice"; import { clearUptimeMonitorState } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; import Avatar from "../Avatar"; import LockSvg from "../../assets/icons/lock.svg?react"; @@ -86,8 +87,9 @@ function Sidebar() { const location = useLocation(); const dispatch = useDispatch(); const authState = useSelector((state) => state.auth); + const { sidebar } = useSelector((state) => state.ui); + let collapsed = sidebar.collapsed; const [open, setOpen] = useState({ Dashboard: false, Account: false }); - const [collapsed, setCollapsed] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const [popup, setPopup] = useState(); @@ -157,7 +159,7 @@ function Sidebar() { borderColor: theme.palette.otherColors.graishWhite, }, }} - onClick={() => setCollapsed(!collapsed)} + onClick={() => dispatch(toggleSidebar())} > {collapsed ? : } @@ -200,6 +202,7 @@ function Sidebar() { ], }, }} + disableInteractive > openPopup(event, "logout")} diff --git a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx index 398c10c54..e42d9f20f 100644 --- a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx +++ b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx @@ -322,13 +322,13 @@ const ProfilePanel = () => { - + Delete account Note that deleting your account will remove all data from our system. This is permanent and non-recoverable. - + { top: "50%", left: "50%", transform: "translate(-50%, -50%)", - width: 400, + width: 450, bgcolor: "white", border: "solid 1px #f2f2f2", borderRadius: `${theme.shape.borderRadius}px`, diff --git a/Client/src/Features/UI/uiSlice.js b/Client/src/Features/UI/uiSlice.js new file mode 100644 index 000000000..ebea20bf1 --- /dev/null +++ b/Client/src/Features/UI/uiSlice.js @@ -0,0 +1,31 @@ +import { createSlice } from "@reduxjs/toolkit"; + +// Initial state for UI settings. +// Add more settings as needed (e.g., theme preferences, user settings) +const initialState = { + monitors: { + rowsPerPage: 5, + }, + team: { + rowsPerPage: 5, + }, + sidebar: { + collapsed: false, + }, +}; + +const uiSlice = createSlice({ + name: "ui", + initialState, + reducers: { + setRowsPerPage: (state, action) => { + state[action.payload.table].rowsPerPage = action.payload.value; + }, + toggleSidebar: (state) => { + state.sidebar.collapsed = !state.sidebar.collapsed; + }, + }, +}); + +export default uiSlice.reducer; +export const { setRowsPerPage, toggleSidebar } = uiSlice.actions; diff --git a/Client/src/Pages/Account/index.jsx b/Client/src/Pages/Account/index.jsx index 700e8c6e8..2fed926b8 100644 --- a/Client/src/Pages/Account/index.jsx +++ b/Client/src/Pages/Account/index.jsx @@ -1,14 +1,13 @@ import PropTypes from "prop-types"; -import { useState } from "react"; +import { useNavigate } from "react-router"; +import { useSelector } from "react-redux"; 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"; -import { useSelector } from "react-redux"; +import "./index.css"; /** * Account component renders a settings page with tabs for Profile, Password, and Team settings. diff --git a/Client/src/Pages/Monitors/index.css b/Client/src/Pages/Monitors/index.css index 7b40f7464..1f46b3517 100644 --- a/Client/src/Pages/Monitors/index.css +++ b/Client/src/Pages/Monitors/index.css @@ -11,8 +11,6 @@ } .monitors p.MuiTypography-root { font-size: var(--env-var-font-size-medium); -} -.monitors p.MuiTypography-root { color: var(--env-var-color-5); } .monitors .MuiStack-root > button:not(.MuiIconButton-root) { diff --git a/Client/src/Pages/Monitors/index.jsx b/Client/src/Pages/Monitors/index.jsx index 0aae47984..7857aaefa 100644 --- a/Client/src/Pages/Monitors/index.jsx +++ b/Client/src/Pages/Monitors/index.jsx @@ -376,7 +376,7 @@ const Monitors = () => { let loading = monitorState.isLoading && monitorState.monitors.length === 0; return ( - + {loading ? ( ) : ( @@ -395,10 +395,11 @@ const Monitors = () => { {monitorState.monitors?.length !== 0 && ( { navigate("/monitors/create"); }} + sx={{ fontWeight: 500 }} /> )} diff --git a/Client/src/store.js b/Client/src/store.js index 27141202d..0c9a18b54 100644 --- a/Client/src/store.js +++ b/Client/src/store.js @@ -3,6 +3,7 @@ import { configureStore, combineReducers } from "@reduxjs/toolkit"; import uptimeMonitorsReducer from "./Features/UptimeMonitors/uptimeMonitorsSlice"; import pageSpeedMonitorReducer from "./Features/PageSpeedMonitor/pageSpeedMonitorSlice"; import authReducer from "./Features/Auth/authSlice"; +import uiReducer from "./Features/UI/uiSlice"; import storage from "redux-persist/lib/storage"; import { persistReducer, persistStore, createTransform } from "redux-persist"; @@ -20,7 +21,7 @@ const authTransform = createTransform( const persistConfig = { key: "root", storage, - whitielist: ["auth", "monitors", "pageSpeed"], + whitielist: ["auth", "monitors", "pageSpeed", "ui"], transforms: [authTransform], }; @@ -28,6 +29,7 @@ const rootReducer = combineReducers({ uptimeMonitors: uptimeMonitorsReducer, auth: authReducer, pageSpeedMonitors: pageSpeedMonitorReducer, + ui: uiReducer, }); const persistedReducer = persistReducer(persistConfig, rootReducer);