diff --git a/app/components/home/menu/mobile.jsx b/app/components/home/menu/mobile.jsx index 612425a..9ace574 100644 --- a/app/components/home/menu/mobile.jsx +++ b/app/components/home/menu/mobile.jsx @@ -1,12 +1,14 @@ // import dependencies import PropTypes from 'prop-types'; +import { FaCog, FaPlus } from 'react-icons/fa'; import { observer } from 'mobx-react-lite'; // import local files -import useDropdown from '../../../hooks/useDropdown'; -import { FaEllipsisVertical } from '../../icons'; -import Dropdown from '../../ui/dropdown'; import useContextStore from '../../../context'; +import Modal from '../../ui/modal'; +import Button from '../../ui/button'; +import HomeMobileMenuStatus from './mobile/status'; +import HomeMobileMenuLayout from './mobile/layout'; import MonitorConfigureModal from '../../modal/monitor/configure'; const HomeMenuMobile = ({ handleReset }) => { @@ -15,40 +17,54 @@ const HomeMenuMobile = ({ handleReset }) => { globalStore: { addMonitor }, } = useContextStore(); - const { toggleDropdown, dropdownIsOpen } = useDropdown(true); return ( - - - - - - - openModal( - , - false - ) - } - > - Add Monitor - - { - handleReset(); - toggleDropdown(); - }} - > - Reset - - - + + + + Close + { + handleReset(); + closeModal(); + }} + > + Reset + + + , + false + ); + }} + /> ); }; diff --git a/app/components/home/menu/mobile/layout.jsx b/app/components/home/menu/mobile/layout.jsx new file mode 100644 index 0000000..7e00200 --- /dev/null +++ b/app/components/home/menu/mobile/layout.jsx @@ -0,0 +1,71 @@ +// import dependencies +import { observer } from 'mobx-react-lite'; + +// import local files +import useDropdown from '../../../../hooks/useDropdown'; +import Dropdown from '../../../ui/dropdown'; +import useLocalStorageContext from '../../../../hooks/useLocalstorage'; +import { FaBars, IoGrid } from '../../../icons'; + +const views = [ + { + text: 'Cards', + id: 'cards', + icon: , + }, + { + text: 'Compact', + id: 'compact', + icon: , + }, +]; + +const HomeMobileMenuLayout = () => { + const { toggleDropdown, dropdownIsOpen } = useDropdown(true); + + const { layout, setLayout } = useLocalStorageContext(); + + const dropdownItems = views.map((view) => ( + { + setLayout(view.id); + toggleDropdown(); + }} + showDot + isSelected={layout === view.id} + dotColor="primary" + > +
+ {view.icon} + {view.text} +
+
+ )); + + return ( + + + {layout.charAt(0).toUpperCase() + layout.slice(1)} + + + {dropdownItems} + + + ); +}; + +HomeMobileMenuLayout.displayName = 'HomeMobileMenuLayout'; + +HomeMobileMenuLayout.propTypes = {}; + +export default observer(HomeMobileMenuLayout); diff --git a/app/components/home/menu/mobile/status.jsx b/app/components/home/menu/mobile/status.jsx new file mode 100644 index 0000000..5b59113 --- /dev/null +++ b/app/components/home/menu/mobile/status.jsx @@ -0,0 +1,73 @@ +// import local files +import useDropdown from '../../../../hooks/useDropdown'; +import Dropdown from '../../../ui/dropdown'; +import useLocalStorageContext from '../../../../hooks/useLocalstorage'; + +import { HiStatusOffline, HiStatusOnline, FaBars } from '../../../icons'; + +const statusOptions = [ + { + text: 'All', + id: 'all', + icon: , + }, + { + text: 'Up', + id: 'up', + icon: , + }, + { + text: 'Down', + id: 'down', + icon: , + }, +]; + +const HomeMobileMenuStatus = () => { + const { toggleDropdown, dropdownIsOpen } = useDropdown(true); + + const { status, setStatus } = useLocalStorageContext(); + + const dropdownItems = statusOptions.map((view) => ( + { + setStatus(view.id); + toggleDropdown(); + }} + showDot + isSelected={status === view.id} + > +
+ {view.icon} + {view.text} +
+
+ )); + + return ( + + + {status.charAt(0).toUpperCase() + status.slice(1)} + + + {dropdownItems} + + + ); +}; + +HomeMobileMenuStatus.displayName = 'HomeMobileMenuStatus'; + +HomeMobileMenuStatus.propTypes = {}; + +export default HomeMobileMenuStatus; diff --git a/app/components/home/menu/styles.scss b/app/components/home/menu/styles.scss index cc932e4..76f5165 100644 --- a/app/components/home/menu/styles.scss +++ b/app/components/home/menu/styles.scss @@ -27,12 +27,6 @@ display: none; } -@include tablet { - #home-menu-status { - display: none; - } -} - @include mobile { .home-menu-buttons { display: none; diff --git a/app/components/home/monitor/layout/compact/index.jsx b/app/components/home/monitor/layout/compact/index.jsx new file mode 100644 index 0000000..b7869fd --- /dev/null +++ b/app/components/home/monitor/layout/compact/index.jsx @@ -0,0 +1,54 @@ +import './styles.scss'; + +// import dependencies +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import Monitor from '../../../../../pages/monitor'; + +const MonitorCompact = ({ children, monitor_id }) => { + return ( +
+
+
+
Name
+
Uptime
+
+ +
{children}
+
+
+ +
+
+ ); +}; + +MonitorCompact.displayName = 'MonitorCompact'; +MonitorCompact.propTypes = { + children: PropTypes.node, + monitor_id: PropTypes.string, +}; + +export default MonitorCompact; diff --git a/app/components/home/monitor/layout/compact.jsx b/app/components/home/monitor/layout/compact/monitor.jsx similarity index 51% rename from app/components/home/monitor/layout/compact.jsx rename to app/components/home/monitor/layout/compact/monitor.jsx index 878fcec..713be7a 100644 --- a/app/components/home/monitor/layout/compact.jsx +++ b/app/components/home/monitor/layout/compact/monitor.jsx @@ -1,16 +1,13 @@ -import './compact.scss'; - // import dependencies import { useNavigate } from 'react-router-dom'; // import local files -import { monitorPropType } from '../../../../../shared/utils/propTypes'; +import { monitorPropType } from '../../../../../../shared/utils/propTypes'; -const MonitorList = ({ monitor = {} }) => { +const MonitorCompactItem = ({ monitor = {} }) => { const navigate = useNavigate(); - const { name, uptimePercentage = '0', heartbeats = [] } = monitor; - const [heartbeat = {}] = heartbeats; + const { name, uptimePercentage = '0' } = monitor; return (
{ >
{name}
-
- {heartbeat.latency ? `${heartbeat.latency}ms` : '0ms'} -
-
{uptimePercentage}%
); }; -MonitorList.displayName = 'MonitorList'; +MonitorCompactItem.displayName = 'MonitorCompactItem'; -MonitorList.propTypes = { +MonitorCompactItem.propTypes = { monitor: monitorPropType.isRequired, }; -export default MonitorList; +export default MonitorCompactItem; diff --git a/app/components/home/monitor/layout/compact.scss b/app/components/home/monitor/layout/compact/styles.scss similarity index 93% rename from app/components/home/monitor/layout/compact.scss rename to app/components/home/monitor/layout/compact/styles.scss index d1e7de9..bbef5af 100644 --- a/app/components/home/monitor/layout/compact.scss +++ b/app/components/home/monitor/layout/compact/styles.scss @@ -1,4 +1,4 @@ -@use '../../../../styles/pxToRem.scss' as *; +@use '../../../../../styles/pxToRem.scss' as *; .home-monitor-container-compact { width: 100%; diff --git a/app/components/home/monitor/layout/table.jsx b/app/components/home/monitor/layout/table.jsx index b94f7b6..2cf929e 100644 --- a/app/components/home/monitor/layout/table.jsx +++ b/app/components/home/monitor/layout/table.jsx @@ -2,33 +2,11 @@ import './table.scss'; // import dependencies import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -const MonitorTable = ({ layout, children }) => { - const isCompact = layout === 'compact'; - - const classes = classNames({ - 'home-monitor-table-container-list': !isCompact, - 'home-monitor-table-container-compact': isCompact, - }); - - if (isCompact) { - return ( -
-
-
Name
-
Ping
-
Uptime
-
- -
{children}
-
- ); - } +const MonitorTable = ({ children }) => { return (
-
+
Name
Ping
Uptime
@@ -42,7 +20,6 @@ const MonitorTable = ({ layout, children }) => { MonitorTable.displayName = 'MonitorTable'; MonitorTable.propTypes = { - layout: PropTypes.oneOf(['compact', 'list']), children: PropTypes.node, }; diff --git a/app/components/icons/index.jsx b/app/components/icons/index.jsx index 93f27d9..68ddae7 100644 --- a/app/components/icons/index.jsx +++ b/app/components/icons/index.jsx @@ -22,6 +22,7 @@ import { FaCheck, FaBars, FaTrashCan, + FaFilter, } from 'react-icons/fa6'; import { IoArrowBack, IoColorPalette, IoGrid, IoReload } from 'react-icons/io5'; import { RiStackFill } from 'react-icons/ri'; @@ -38,6 +39,7 @@ export { FaCircleCheck, FaCog, FaEllipsisVertical, + FaFilter, FaHome, FaPlus, FaSignOutAlt, diff --git a/app/components/navigation/left.scss b/app/components/navigation/left.scss index 281a32f..282b02c 100644 --- a/app/components/navigation/left.scss +++ b/app/components/navigation/left.scss @@ -72,17 +72,10 @@ } .left-actions-bottom { - display: flex; - justify-content: center; - align-items: flex-end; - gap: 20px; + display: none; } .navigation-left-top-action { flex: 1; } - - .navigation-left-signout-button { - display: none; - } } diff --git a/app/components/notifications/menu/styles.scss b/app/components/notifications/menu/styles.scss index cc932e4..76f5165 100644 --- a/app/components/notifications/menu/styles.scss +++ b/app/components/notifications/menu/styles.scss @@ -27,12 +27,6 @@ display: none; } -@include tablet { - #home-menu-status { - display: none; - } -} - @include mobile { .home-menu-buttons { display: none; diff --git a/app/main.jsx b/app/main.jsx index da9e8cc..8137b2b 100644 --- a/app/main.jsx +++ b/app/main.jsx @@ -68,6 +68,7 @@ ReactDOM.createRoot(document.getElementById('root')).render( } /> } /> } /> + } /> diff --git a/app/pages/home.jsx b/app/pages/home.jsx index 3dae015..3b940e6 100644 --- a/app/pages/home.jsx +++ b/app/pages/home.jsx @@ -15,6 +15,7 @@ import useContextStore from '../context'; import HomeMenu from '../components/home/menu'; import MonitorTable from '../components/home/monitor/layout/table'; import useLocalStorageContext from '../hooks/useLocalstorage'; +import MonitorCompactItem from '../components/home/monitor/layout/compact/monitor'; const Home = () => { const { @@ -63,7 +64,10 @@ const Home = () => { if (layout === 'compact') { return ( - + ); } @@ -84,6 +88,20 @@ const Home = () => { ); } + if (layout === 'compact') { + return ( +
+ setSearch(e.target.value)} + /> + + {monitorsList} +
+ ); + } + return (
{ setSearch={(e) => setSearch(e.target.value)} /> - {monitorsList} + {monitorsList}
); }; diff --git a/app/pages/monitor.jsx b/app/pages/monitor.jsx index c712021..d5891b2 100644 --- a/app/pages/monitor.jsx +++ b/app/pages/monitor.jsx @@ -12,13 +12,13 @@ import useContextStore from '../context'; import MonitorMenu from '../components/monitor/menu'; import { useParams } from 'react-router-dom'; -const Monitor = () => { +const Monitor = ({ monitor_id }) => { const { globalStore: { getMonitor }, } = useContextStore(); const query = useParams(); - const monitorId = query['monitor_id']; + const monitorId = query['monitor_id'] || monitor_id; const monitor = getMonitor(monitorId); diff --git a/server/utils/config.js b/server/utils/config.js index aa0f132..330e44c 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -30,7 +30,7 @@ class Config { message: 'Configuration file not found. Please run "npm run setup" (or "yarn setup" or "pnpm setup") to create it.', }); - process.exit(1); + return; } const fileData = fs.readFileSync(this.configPath);