From 925804021a1c2e75f0424fe607f733352d11b2ac Mon Sep 17 00:00:00 2001 From: benzbarquilla Date: Mon, 16 Mar 2026 16:29:16 +0800 Subject: [PATCH] done mobile navbar and users --- frontend/src/app/components/icons/create.jsx | 6 +- frontend/src/app/components/icons/logout.jsx | 23 +++++ .../src/app/components/icons/settings.jsx | 30 +++++++ frontend/src/app/components/navbar/Navbar.jsx | 5 +- .../app/components/navbar/navleft/Header.jsx | 61 +++++++++----- .../navbar/navleft/HeaderDropdown.jsx | 27 +++--- .../navbar/navleft/styles.module.css | 82 ++++++++++++++---- .../components/navbar/navright/Profile.jsx | 49 ++++++++--- .../navbar/navright/ProfileDropdown.jsx | 64 ++++++-------- .../navbar/navright/styles.module.css | 84 ++++++++++++++++--- .../app/components/navbar/styles.module.css | 10 --- 11 files changed, 313 insertions(+), 128 deletions(-) create mode 100644 frontend/src/app/components/icons/logout.jsx create mode 100644 frontend/src/app/components/icons/settings.jsx diff --git a/frontend/src/app/components/icons/create.jsx b/frontend/src/app/components/icons/create.jsx index 1d3d56d..9f54424 100644 --- a/frontend/src/app/components/icons/create.jsx +++ b/frontend/src/app/components/icons/create.jsx @@ -1,11 +1,11 @@ import React from "react"; -const create = () => { +const create = ({ width = "16", height = "16" }) => { return ( diff --git a/frontend/src/app/components/icons/logout.jsx b/frontend/src/app/components/icons/logout.jsx new file mode 100644 index 0000000..0a123e9 --- /dev/null +++ b/frontend/src/app/components/icons/logout.jsx @@ -0,0 +1,23 @@ +import React from "react"; + +const logout = () => { + return ( + + + + ); +}; + +export default logout; diff --git a/frontend/src/app/components/icons/settings.jsx b/frontend/src/app/components/icons/settings.jsx new file mode 100644 index 0000000..23413b9 --- /dev/null +++ b/frontend/src/app/components/icons/settings.jsx @@ -0,0 +1,30 @@ +import React from "react"; + +const settings = () => { + return ( + + + + + ); +}; + +export default settings; diff --git a/frontend/src/app/components/navbar/Navbar.jsx b/frontend/src/app/components/navbar/Navbar.jsx index 822dfbb..9008eb9 100644 --- a/frontend/src/app/components/navbar/Navbar.jsx +++ b/frontend/src/app/components/navbar/Navbar.jsx @@ -5,7 +5,6 @@ import styles from "./styles.module.css"; import NavLeft from "./navleft/Header"; import NavRight from "./navright/Profile"; import HamburgerIcon from "../../components/icons/hamburger"; -import VerticalEllipsis from "../icons/verticalEllipsis"; import useIsMobile from "@/app/hooks/useIsMobile"; const Navbar = () => { @@ -18,9 +17,7 @@ const Navbar = () => { {/* Mobile Menu Button */} -
- {isMobile ? : } -
+ ); }; diff --git a/frontend/src/app/components/navbar/navleft/Header.jsx b/frontend/src/app/components/navbar/navleft/Header.jsx index 0277f22..0446e48 100644 --- a/frontend/src/app/components/navbar/navleft/Header.jsx +++ b/frontend/src/app/components/navbar/navleft/Header.jsx @@ -1,43 +1,62 @@ import React, { useState } from "react"; import HeaderDropdown from "./HeaderDropdown"; import styles from "./styles.module.css"; +import ArrowDownIcon from "../../icons/arrowDown"; +import useIsMobile from "@/app/hooks/useIsMobile"; const Header = () => { const [open, setOpen] = useState(false); + const [selectedOrg, setSelectedOrg] = useState(0); + const sampleData = [ + { name: "Project Moonshot Inc." }, + { name: "Organization X" }, + { name: "Organization Y" }, + { name: "Organization Z" }, + ]; + + const isMobile = useIsMobile(); return ( <> {/* Organization Header */}
-
+
setOpen(!open) : null} //toggler entire header + > {/* Logo */}
-

Organization

+

+ Organization +

{/* Dropdown Menu*/} - {open && } - + {open && ( + + )} {/* Toggle Button */}
setOpen(!open)} + onClick={() => { + if (!isMobile) setOpen(!open); //toggle only org + }} > -

Project Moonshot Inc.

-
- - - +

+ {sampleData[selectedOrg].name} +

+
+
diff --git a/frontend/src/app/components/navbar/navleft/HeaderDropdown.jsx b/frontend/src/app/components/navbar/navleft/HeaderDropdown.jsx index ae2c1a9..96ff68c 100644 --- a/frontend/src/app/components/navbar/navleft/HeaderDropdown.jsx +++ b/frontend/src/app/components/navbar/navleft/HeaderDropdown.jsx @@ -1,19 +1,19 @@ import React, { useState } from "react"; import CreateIcon from "../../icons/create"; import styles from "./styles.module.css"; +import useIsMobile from "@/app/hooks/useIsMobile"; -const HeaderDropdown = () => { - const orgList = [ - { name: "Project Moonshot Inc." }, - { name: "Organization X" }, - { name: "Organization Y" }, - { name: "Organization Z" }, - ]; - - const [selectedOrg, setSelectedOrg] = useState(null); +const HeaderDropdown = ({ + setOpen, + sampleData, + selectedOrg, + setSelectedOrg, +}) => { + const isMobile = useIsMobile(); const handleOrgSelect = (index) => { setSelectedOrg(index); + setOpen(false); }; return ( @@ -25,7 +25,7 @@ const HeaderDropdown = () => {

Organization

Create

- + {isMobile ? : }
{/* Search */} @@ -73,12 +73,15 @@ const HeaderDropdown = () => { {/* Select Options */}
- {orgList.map((org, index) => { + {sampleData.map((org, index) => { return (
handleOrgSelect(index)} + onClick={(e) => { + e.stopPropagation(); + handleOrgSelect(index); + }} >
p { +.orgNameText { color: #eeeffd; - color: color(display-p3 0.9333 0.9373 0.9882); font-family: Inter; font-size: 14px; font-style: normal; @@ -52,16 +52,15 @@ align-items: center; gap: 16px; } -.dropdownBtn > p { +.projectName { color: #85869b; - color: color(display-p3 0.5216 0.5255 0.6); font-family: Inter; font-size: 15px; font-style: normal; font-weight: 500; line-height: normal; } -.dropdownBtn > div { +.arrowIcon { display: inline-flex; padding: 8px; justify-content: center; @@ -69,8 +68,12 @@ gap: 10px; border-radius: 100px; border: 1px solid #b8badc00; + transition: transform 0.3s ease; } -.dropdownBtn > div:hover { +.arrowRotate { + transform: rotate(180deg); +} +.arrowIcon:hover { border: 1px solid #b8badc; background: linear-gradient( 180deg, @@ -86,9 +89,7 @@ gap: 12px; border-radius: 6px; background: #2d3143; - background: color(display-p3 0.1804 0.1922 0.2588); box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 2px 15px 0 color(display-p3 0 0 0 / 0.25); position: absolute; z-index: 1; top: 100%; @@ -110,7 +111,8 @@ .orgSearchContainer { display: flex; - width: 318px; + width: 100%; + min-width: 318px; flex-direction: column; align-items: flex-start; gap: 16px; @@ -182,7 +184,6 @@ flex: 1 0 0; border-radius: 4px; background: #282c3c; - background: color(display-p3 0.1593 0.1702 0.2316); } .placeholderTxt { @@ -195,7 +196,6 @@ } .placeholderTxt::placeholder { color: #85869b; - color: color(display-p3 0.5216 0.5255 0.6); font-family: Inter; font-size: 16px; font-style: normal; @@ -206,18 +206,15 @@ .optionsContainer { display: flex; - width: 318px; flex-direction: column; align-items: flex-start; + width: 100%; } - .orgList:hover { border-radius: 4px; background: #3c4159; color: #acb0ff; - background: color(display-p3 0.2398 0.2548 0.3399); } - .orgList { display: flex; padding: 6px; @@ -244,7 +241,6 @@ .iconTxt > p { color: #d2d3e1; - color: color(display-p3 0.8235 0.8275 0.8784); font-family: Inter; font-size: 14px; font-style: normal; @@ -254,4 +250,58 @@ /* Mobile */ @media (max-width: 768px) { + .dropdown { + display: flex; + background: linear-gradient(0deg, #2d3143 0%, #191a24 100%); + border-radius: 0; + position: fixed; + top: 90px; + left: 0; + width: 100%; + margin-top: 0; + box-shadow: none; + } + .orgSearchContainer { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; + align-self: stretch; + } + .createBtnContainer { + padding: 8px 0; + } + .createBtnContainer > p { + font-size: 16px; + } + .createBtn { + gap: 8px; + } + .createBtn > p { + font-size: 16px; + } + .srchInputGroup { + display: flex; + width: 358px; + height: 38px; + padding: 10px 12px; + border-radius: 6px; + } + .optionsContainer { + align-self: stretch; + } + .iconTxt > p { + font-size: 16px; + font-weight: 400; + } + + .orgNameText { + color: #85869b; + } + .orgNameActive { + color: #eeeffd; + } + .projectNameActive { + color: #959aff; + } } diff --git a/frontend/src/app/components/navbar/navright/Profile.jsx b/frontend/src/app/components/navbar/navright/Profile.jsx index 1155ec4..2fecacd 100644 --- a/frontend/src/app/components/navbar/navright/Profile.jsx +++ b/frontend/src/app/components/navbar/navright/Profile.jsx @@ -2,30 +2,53 @@ import React, { useState } from "react"; import EllipsisIcon from "../../icons/ellipsis"; import ProfileDropdown from "./ProfileDropdown"; import styles from "./styles.module.css"; +import VerticalEllipsis from "../../icons/verticalEllipsis"; +import useIsMobile from "@/app/hooks/useIsMobile"; const Profile = () => { + const isMobile = useIsMobile(); const [open, setOpen] = useState(false); + const [user, setUser] = useState(""); + const sampleData = [ + { + name: "JM Grills", + role: "Super Admin", + }, + ]; return ( <> {/* Profile Section */} -
setOpen(!open)}> +
{/* Profile */} -
- {/* Username and Role*/} -
-

JM Grills

-

Super Admin

-
+ {!isMobile && ( +
setOpen(!open)}> + {/* Username and Role*/} + {sampleData.map((data, index) => { + return ( +
+

{data.name}

+

{data.role}

+
+ ); + })} - {/* User profile*/} -
-
- + {/* User profile*/} +
+
+ +
-
+ )} + + {/* Mobile Ellipsis */} + {isMobile && ( +
setOpen(!open)}> + +
+ )} {/* Dropdown */} - {open && } + {open && }
); diff --git a/frontend/src/app/components/navbar/navright/ProfileDropdown.jsx b/frontend/src/app/components/navbar/navright/ProfileDropdown.jsx index f5de146..e802002 100644 --- a/frontend/src/app/components/navbar/navright/ProfileDropdown.jsx +++ b/frontend/src/app/components/navbar/navright/ProfileDropdown.jsx @@ -1,35 +1,37 @@ import React from "react"; import styles from "./styles.module.css"; +import SettingsIcon from "../../icons/settings"; +import LogoutIcon from "../../icons/logout"; -const ProfileDropdown = () => { +const ProfileDropdown = ({ isMobile, user }) => { return (
{/* Settings */} + + {/* Mobile View */} + {isMobile && ( + <> + {" "} +
+ {/* User profile*/} +
+
+
+ + {/* Username and Role*/} +
+

{user.name}

+

{user.role}

+
+
+
+ + )} +
{/* Icon */}
- - - - +

Settings

@@ -37,21 +39,7 @@ const ProfileDropdown = () => {
{/* Icon */}
- - - +

Logout

diff --git a/frontend/src/app/components/navbar/navright/styles.module.css b/frontend/src/app/components/navbar/navright/styles.module.css index 5d2f4d4..4717a5e 100644 --- a/frontend/src/app/components/navbar/navright/styles.module.css +++ b/frontend/src/app/components/navbar/navright/styles.module.css @@ -30,7 +30,6 @@ .userName { align-self: stretch; color: #d2d3e1; - color: color(display-p3 0.8235 0.8275 0.8784); text-align: right; leading-trim: both; text-edge: cap; @@ -45,7 +44,6 @@ .userRole { align-self: stretch; color: #85869b; - color: color(display-p3 0.5216 0.5255 0.6); text-align: right; leading-trim: both; text-edge: cap; @@ -112,13 +110,14 @@ color: #acb0ff; border-radius: 4px; } -.settingsBtn:hover, + +.settingsBtn:hover { + background: #3c4159; + color: #d2d3e1; +} .logoutBtn:hover { background: #3c4159; - background: color(display-p3 0.2392 0.2549 0.3412); - color: #d2d3e1; - color: color(display-p3 0.8235 0.8275 0.8784); } .btn { display: flex; @@ -127,19 +126,82 @@ gap: 12px; } -.settingsBtn, -.logoutBtn > p { - color: #acb0ff; - color: color(display-p3 0.678 0.6895 1); +.settingsBtn > p { + color: inherit; font-family: Inter; font-size: 16px; font-style: normal; font-weight: 400; line-height: normal; } + +.logoutBtn > p { + color: inherit; + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + /* Mobile */ @media (max-width: 768px) { + .dropdownContainer { + display: flex; + width: 390px; + padding: 16px; + border-radius: 0; + flex-direction: column; + align-items: flex-start; + gap: 16px; + background: linear-gradient(0deg, #2d3143 0%, #191a24 100%); + position: fixed; + top: 90px; + left: 0; + width: 100%; + margin-top: 0; + box-shadow: none; + } + .mobileEllipsis { + display: flex; + height: 61px; + align-items: center; + gap: 10px; + padding-right: 10px; + } .profileBadge { - display: none; + display: flex; + padding: 12px 16px; + align-items: center; + gap: 24px; + } + .userImgContainer { + width: 50px; + height: 50px; + aspect-ratio: 1/1; + } + .userPic { + width: 100%; + height: 100%; + border-radius: 50%; + } + + .nameRole { + align-items: flex-start; + gap: 10px; + } + + .userName { + text-align: start; + font-size: 18px; + letter-spacing: -0.18px; + } + .userRole { + font-size: 14px; + } + .divider { + height: 1px; + align-self: stretch; + background: #393d53; } } diff --git a/frontend/src/app/components/navbar/styles.module.css b/frontend/src/app/components/navbar/styles.module.css index 968af4b..a834977 100644 --- a/frontend/src/app/components/navbar/styles.module.css +++ b/frontend/src/app/components/navbar/styles.module.css @@ -19,16 +19,6 @@ flex-shrink: 0; } - .mobileEllipsis { - display: flex; - height: 61px; - align-items: center; - gap: 10px; - padding-right: 10px; - flex-shrink: 0; - align-self: stretch; - } - .mainContainer { display: flex; padding: 12px 0px;