diff --git a/package.json b/package.json index b2f517f..d6faee0 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "deploy": "scp -Cvpr -i build/* ubuntu@ec2-13-59-140-102.us-east-2.compute.amazonaws.com:/home/ubuntu/web-wms/" }, "eslintConfig": { "extends": [ diff --git a/src/assets/icons/Hamburger-icon.js b/src/assets/icons/Hamburger-icon.js new file mode 100644 index 0000000..b1b0523 --- /dev/null +++ b/src/assets/icons/Hamburger-icon.js @@ -0,0 +1,19 @@ +const HamburgerIcon = ({ width = 24, height = 24, color, ...props }) => ( + + + + + +); + +export default HamburgerIcon; diff --git a/src/assets/icons/Home-icon.js b/src/assets/icons/Home-icon.js new file mode 100644 index 0000000..2c7cb15 --- /dev/null +++ b/src/assets/icons/Home-icon.js @@ -0,0 +1,14 @@ +const HomeIcon = ({ width = 24, height = 24, color = 'white', ...props }) => ( + + + + +); + +export default HomeIcon; diff --git a/src/assets/icons/SidebarDown-icon.js b/src/assets/icons/SidebarDown-icon.js new file mode 100644 index 0000000..ae6969a --- /dev/null +++ b/src/assets/icons/SidebarDown-icon.js @@ -0,0 +1,10 @@ +const SidebarDownIcon = ({ width = 14, height = 8, color = 'white', ...props }) => ( + + + +); + +export default SidebarDownIcon; diff --git a/src/assets/icons/X-close-icon.js b/src/assets/icons/X-close-icon.js new file mode 100644 index 0000000..820160e --- /dev/null +++ b/src/assets/icons/X-close-icon.js @@ -0,0 +1,19 @@ +const XIcon = ({ width = 18, height = 18, color = '#ffffff', ...props }) => ( + + + + +); + +export default XIcon; diff --git a/src/components/Sidebar/index.js b/src/components/Sidebar/index.js index 436cb8f..9fd3811 100644 --- a/src/components/Sidebar/index.js +++ b/src/components/Sidebar/index.js @@ -1,9 +1,81 @@ +import { NavLink } from 'react-router-dom'; +import SidebarDownIcon from '../../assets/icons/SidebarDown-icon'; +import HomeIcon from '../../assets/icons/Home-icon'; +import XIcon from '../../assets/icons/X-close-icon'; +import combineClasses from '../../utils/combineCssClasses'; import styles from './sidebar.module.css'; -export default function Sidebar() { +const items = { + title: { + icon: '', + text: 'Main link', + link: '/', + }, + subs: [ + { + text: 'Sub links', + link: '/login', + }, + { + text: 'Sub links', + link: '/login', + }, + { + text: 'Sub links', + link: '/login', + }, + { + text: 'Sub links', + link: '/', + }, + { + text: 'Sub links', + link: '/login', + }, + ], +}; + +const NavGroupItems = ({ list }) => { return ( -
-
Plaidware
+
+
+ + +
{list.title.text}
+
+ +
+ {list.subs.map((subLink, idx) => ( + + {({ isActive }) => ( +
{subLink.text}
+ )} +
+ ))}
); +}; + +export default function Sidebar({ isMobileScreen, isOpen, setOpen }) { + if (!isMobileScreen && isOpen) { + return ( +
+
+
Plaidware
+
{ + setOpen(false); + }} + > + +
+
+
+ + +
+
+ ); + } + return null; } diff --git a/src/components/Sidebar/sidebar.module.css b/src/components/Sidebar/sidebar.module.css index 92a4f36..8c31091 100644 --- a/src/components/Sidebar/sidebar.module.css +++ b/src/components/Sidebar/sidebar.module.css @@ -2,7 +2,18 @@ grid-column: 1; background: #2d373c; min-height: 100vh; - padding: 40px; + min-width: 350px; +} + +/* @media only screen and (max-width: 800px) { + +} */ + +.sidebarBrandingHeader { + display: grid; + padding: 40px 0px 30px 40px; + grid-template-columns: auto 40px; + align-items: center; } .sidebarBranding { @@ -12,4 +23,60 @@ line-height: 44px; color: #ffffff; -} \ No newline at end of file +} + +.sidebarList { + width: 100%; +} + +.sidebarGroup { +} + +.sidebarMainItem { + width: 100%; + display: grid; + align-items: center; + grid-template-columns: auto 55px; + height: 48px; + + /* background: #007aff; */ +} + +.mainItemContent { + display: grid; + align-items: center; + grid-template-columns: 80px auto; + height: 100%; + + color: white; +} + +.mainItemIcon { + padding-left: 40px; + width: auto; +} + +.dropdownIcon { + padding-left: 20px; + width: auto; +} + +.sidebarSubItem { + width: 100%; + height: 46px; + display: grid; + align-items: center; + padding-left: 80px; + + color: white; +} + +.alink:visited, +.alink:link { + text-decoration: none; +} + +.subActive { + background: #1f282d; + color: #007aff !important; +} diff --git a/src/components/topbar/index.js b/src/components/topbar/index.js index 81478ac..571f32c 100644 --- a/src/components/topbar/index.js +++ b/src/components/topbar/index.js @@ -1,8 +1,18 @@ -import React from 'react' -import styles from './topbar.module.css' +import React from 'react'; +import HamburgerIcon from '../../assets/icons/Hamburger-icon'; +import styles from './topbar.module.css'; -export default function TopBar() { +export default function TopBar({ isMobileScreen, isSidebarOpen, setSidebarOpen }) { return ( -
search comes here
- ) +
+
{ + setSidebarOpen(true); + }} + > + {isSidebarOpen ? null : } +
+
Right side icons here
+
+ ); } diff --git a/src/components/topbar/topbar.module.css b/src/components/topbar/topbar.module.css index 0592525..ffb2a48 100644 --- a/src/components/topbar/topbar.module.css +++ b/src/components/topbar/topbar.module.css @@ -1,5 +1,10 @@ .topBar { grid-row: 1; + padding: 24px 48px; box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.08); -} \ No newline at end of file + + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/src/hooks/placeholder b/src/hooks/placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/src/hooks/useWindowDimensions.js b/src/hooks/useWindowDimensions.js new file mode 100644 index 0000000..6e2273a --- /dev/null +++ b/src/hooks/useWindowDimensions.js @@ -0,0 +1,25 @@ +import { useState, useEffect } from 'react'; + +function getWindowDimensions() { + const { innerWidth: width, innerHeight: height } = window; + return { + width, + height, + isMobileScreen: width <= 800, + }; +} + +export default function useWindowDimensions() { + const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); + + useEffect(() => { + function handleResize() { + setWindowDimensions(getWindowDimensions()); + } + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + return windowDimensions; +} diff --git a/src/index.css b/src/index.css index e4baebe..5faa02f 100644 --- a/src/index.css +++ b/src/index.css @@ -1,11 +1,13 @@ +html, body { margin: 0; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } * { font-family: Averta; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + box-sizing: border-box; } code { diff --git a/src/layouts/dashboard/dashboard.module.css b/src/layouts/dashboard/dashboard.module.css index 21897ac..c771b02 100644 --- a/src/layouts/dashboard/dashboard.module.css +++ b/src/layouts/dashboard/dashboard.module.css @@ -1,7 +1,7 @@ .dashboardGrid { width: 100vw; display: grid; - grid-template-columns: 300px auto; + grid-template-columns: max-content auto; } .mainContent { @@ -10,7 +10,19 @@ grid-template-rows: 108px 72px auto; } +@media only screen and (max-width: 800px) { + .dashboardGrid { + grid-template-columns: auto; + } + + .mainContent { + grid-column: 1; + grid-template-rows: 50px 50px auto; + } +} + .content { grid-row: 3; padding: 24px 48px; + min-height: 100%; } diff --git a/src/layouts/dashboard/index.js b/src/layouts/dashboard/index.js index e3f196b..e244d1d 100644 --- a/src/layouts/dashboard/index.js +++ b/src/layouts/dashboard/index.js @@ -1,15 +1,21 @@ +import { useState } from 'react'; import { Outlet } from 'react-router-dom'; + import Breadcrumbs from '../../components/breadcrumbs'; import Sidebar from '../../components/Sidebar'; import TopBar from '../../components/topbar'; +import useWindowDimensions from '../../hooks/useWindowDimensions'; import styles from './dashboard.module.css'; export default function Dashboard() { + const [sidebarOpen, setSidebarOpen] = useState(true); + const { isMobileScreen } = useWindowDimensions(); + return (
- +
- +
diff --git a/src/utils/combineCssClasses.js b/src/utils/combineCssClasses.js new file mode 100644 index 0000000..d36bc34 --- /dev/null +++ b/src/utils/combineCssClasses.js @@ -0,0 +1,15 @@ +export const combineClasses = (...classes) => { + return classes.reduce((classNames, currentClassName) => { + if (Array.isArray(currentClassName)) { + return currentClassName[0] ? classNames + ' ' + currentClassName[1] : classNames; + } else if (currentClassName) { + return classNames + ' ' + currentClassName; + } else { + return classNames; + } + }, ''); +}; + +export default combineClasses; + +// Ref: https://www.npmjs.com/package/combine-classes