done mobile navbar and users

This commit is contained in:
2026-03-16 16:29:16 +08:00
parent 62bb558706
commit 925804021a
11 changed files with 313 additions and 128 deletions

View File

@@ -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 */}
<div className={styles.organizationContainer}>
<div className={styles.orgContainer}>
<div
className={styles.orgContainer}
onClick={isMobile ? () => setOpen(!open) : null} //toggler entire header
>
{/* Logo */}
<div className={styles.orgLogo}></div>
<div className={styles.orgName}>
<p>Organization</p>
<p
className={`${styles.orgNameText} ${isMobile && open ? styles.orgNameActive : ""}`}
>
Organization
</p>
<div className={styles.dropdownContainer}>
{/* Dropdown Menu*/}
{open && <HeaderDropdown />}
{open && (
<HeaderDropdown
setOpen={setOpen}
sampleData={sampleData}
selectedOrg={selectedOrg}
setSelectedOrg={setSelectedOrg}
/>
)}
{/* Toggle Button */}
<div
className={styles.dropdownBtn}
onClick={() => setOpen(!open)}
onClick={() => {
if (!isMobile) setOpen(!open); //toggle only org
}}
>
<p>Project Moonshot Inc.</p>
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
>
<path
d="M1.03906 3.51953L6.00031 8.48083L10.9616 3.51953"
stroke="#969AF9"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<p
className={`${styles.projectName} ${isMobile && open ? styles.projectNameActive : ""}`}
>
{sampleData[selectedOrg].name}
</p>
<div
className={`${styles.arrowIcon} ${isMobile && open ? styles.arrowRotate : ""}`}
>
<ArrowDownIcon width={12} height={12} color="#969AF9" />
</div>
</div>
</div>

View File

@@ -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 = () => {
<p>Organization</p>
<div className={styles.createBtn}>
<p>Create</p>
<CreateIcon />
{isMobile ? <CreateIcon width="24" height="24" /> : <CreateIcon />}
</div>
</div>
{/* Search */}
@@ -73,12 +73,15 @@ const HeaderDropdown = () => {
{/* Select Options */}
<div className={styles.optionsContainer}>
{orgList.map((org, index) => {
{sampleData.map((org, index) => {
return (
<div
className={styles.orgList}
key={index}
onClick={() => handleOrgSelect(index)}
onClick={(e) => {
e.stopPropagation();
handleOrgSelect(index);
}}
>
<div
className={`${styles.iconTxt} ${index === selectedOrg ? styles.active : ""}`}

View File

@@ -9,6 +9,7 @@
align-items: center;
gap: 16px;
border-radius: 4px;
align-self: stretch;
}
.orgLogo {
@@ -30,9 +31,8 @@
align-items: flex-start;
gap: 4px;
}
.orgName > 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;
}
}