chore: restyle topbar and side menu based on dmail

This commit is contained in:
Mahyar Khanbolooki
2025-08-02 23:11:19 +03:30
parent 9a39c84116
commit 97307090ab
5 changed files with 104 additions and 81 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+87 -66
View File
@@ -114,11 +114,88 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
{ href: '?share', handler: toggleShareModalVisiblity }
];
const renderMenu = () => {
return (
<section className="flex-1 overflow-y-scroll noscrollbar pt-20 pb-10 flex flex-col justify-between">
<div>
<header className="px-12 pt-6 mt-3">
<h6 className="text-start font-bold text-sm text-menu-header mt-2 mb-[19px]">منو</h6>
</header>
<nav aria-label={tMenu('NavAriaLabel')}>
<ul>
{menuItems[0]
.filter(item => !item.auth || (item.auth && userIsAuthenticated))
.map((item, index) => {
const href = `/${name}/${item.href}`;
const isActive = pathname === href;
return (
<li key={index} className="mt-4 h-6">
<SideMenuItem
className={clsx(isActive && 'text-foreground! border-primary!', 'border-r-4!')}
href={href ?? ''}
title={tMenu(item.title)}
onClick={
typeof item.href === 'string'
? hrefOnClicks.find((i) => i.href === item.href)?.handler
: undefined
}
icon={
<span className={clsx(isActive ? 'text-foreground!' : 'text-icon-deactive')}>
{item.icon}
</span>
}
/>
</li>
);
})}
</ul>
</nav>
</div>
<section aria-label={tMenu('ControlsAriaLabel')}>
<ul className="flex flex-col pt-16">
{menuItems[2]
.filter(item => !item.auth || (item.auth && userIsAuthenticated))
.map((item, index) => {
const href = `/${name}/${item.href}`;
const isActive = pathname === href;
return (
<li key={index} className="mt-4 h-6 w-full">
<SideMenuItem
key={index}
href={item.href ?? ''}
className={clsx(isActive && 'text-foreground! border-primary!', 'border-r-4!')}
onClick={
typeof item.href === 'string'
? hrefOnClicks.find((i) => i.href === item.href)?.handler
: undefined
}
title={tMenu(item.title)}
icon={
<span className={clsx(isActive ? 'text-foreground!' : 'text-icon-deactive')}>
{item.icon}
</span>
} />
</li>
)
})}
<li className="mt-4 h-6">
<SideMenuItem href={''} title={''} icon={<></>}>
<NightModeSwitch checked={nightModeState} onClick={togglenightModeState} />
</SideMenuItem>
</li>
</ul>
</section>
</section>
)
}
return (
<>
<div className='w-full' ref={closeRef} onClick={toggleMenuState}>
<BlurredOverlayContainer bgOpacity={40} visible={menuStateMemo} outDelay={150} inDuration={200}>
<aside aria-label={tMenu('AriaLabel')}>
<aside aria-label={tMenu('AriaLabel')}>
<BlurredOverlayContainer className='md:hidden!' bgOpacity={40} visible={menuStateMemo} outDelay={150} inDuration={200}>
<motion.nav
drag='x'
dragConstraints={{ left: 0, right: 20 }}
@@ -134,74 +211,18 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
onClick={(e) => { e.stopPropagation(); }}
className="fixed top-0 bottom-0 right-0 bg-white w-[200px] h-dvh flex flex-col z-40 overflow-clip not-xl:!rounded-s-none"
>
<section className="flex-1 overflow-y-scroll noscrollbar pt-20 pb-10 flex flex-col justify-between">
<div>
<header className="px-12">
<h6 className="text-start text-sm text-menu-header mt-2 mb-[23px]">منو</h6>
</header>
<nav aria-label={tMenu('NavAriaLabel')}>
<ul>
{menuItems[0]
.filter(item => !item.auth || (item.auth && userIsAuthenticated))
.map((item, index) => {
const href = `/${name}/${item.href}`;
const isActive = pathname === href;
return (
<li key={index} className="mt-[18px]">
<SideMenuItem
className={clsx(isActive && 'text-foreground!')}
href={href ?? ''}
title={tMenu(item.title)}
onClick={
typeof item.href === 'string'
? hrefOnClicks.find((i) => i.href === item.href)?.handler
: undefined
}
icon={
<span className={clsx(isActive ? 'text-foreground!' : 'text-icon-deactive')}>
{item.icon}
</span>
}
/>
</li>
);
})}
</ul>
</nav>
</div>
<section aria-label={tMenu('ControlsAriaLabel')}>
<ul className="flex flex-col gap-6 pt-16">
{menuItems[2]
.filter(item => !item.auth || (item.auth && userIsAuthenticated))
.map((item, index) => (
<SideMenuItem
key={index}
href={item.href ?? ''}
onClick={
typeof item.href === 'string'
? hrefOnClicks.find((i) => i.href === item.href)?.handler
: undefined
}
title={tMenu(item.title)}
icon={<span className="text-icon-deactive">{item.icon}</span>}
/>
))}
<SideMenuItem href={''} title={''} icon={<></>}>
<NightModeSwitch checked={nightModeState} onClick={togglenightModeState} />
</SideMenuItem>
</ul>
</section>
</section>
{renderMenu()}
</motion.nav>
</aside>
</BlurredOverlayContainer>
</BlurredOverlayContainer>
<div className="hidden fixed top-4 bottom-4 right-4 bg-white xl:w-[250px] md:flex flex-col z-40 overflow-clip md:rounded-4xl">
{renderMenu()}
</div>
</aside>
</div>
{/* Logout Modal */}
<BlurredOverlayContainer visible={logoutModalVisible} onClick={toggleLogoutModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
<div className="absolute top-1/2 left-0 w-full px-6">
<div className="absolute top-1/2 left-6 right-6 px-6">
<motion.div
animate={{ y: logoutModalVisible ? [10, 0] : [0, 10] }}
transition={{ duration: 0.1, ease: 'easeInOut' }}
@@ -227,7 +248,7 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
{/* Share modal */}
<BlurredOverlayContainer visible={shareModalVisible} onClick={toggleShareModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
<div className="absolute top-1/2 left-0 w-full px-6">
<div className="absolute top-1/2 left-6 right-6 px-6">
<motion.div
animate={{ y: shareModalVisible ? [10, 0] : [0, 10] }}
transition={{ duration: 0.1, ease: 'easeInOut' }}
+2 -2
View File
@@ -12,8 +12,8 @@ export default function SideMenuItem({ href, title, icon, className, children, .
{...restProps}
href={href}
className={`
inline-flex gap-2 ps-8 items-center h-6 overflow-hidden text-nowrap
text-[0.7rem] font-light text-disabled-text border-transparent
inline-flex gap-3 ps-9 h-full w-full items-center overflow-hidden text-nowrap
text-xs font-light text-disabled-text border-transparent
data-[active]:border-s-6 data-[active]:border-black data-[active]:text-black
${className}
`}
+11 -9
View File
@@ -8,6 +8,7 @@ import NotificationBellIcon from '../icons/NotificationBellIcon'
import WalletIcon from '../icons/WalletIcon'
import GridIcon from '../icons/GridIcon'
import Image from 'next/image'
import { ArrowDown2 } from 'iconsax-react'
type Props = {
profileDropState: boolean,
@@ -22,10 +23,10 @@ type Props = {
function TopBar({ profileDropState, toggleProfileDropState, menuState, toggleMenuState, searchModalState, toggleSearchModalState, nightModeState, toggleNightModeState }: Props) {
return (
<div className="fixed top-0 left-0 w-full p-4 pb-0 z-40">
<div className='bg-white grid grid-cols-3 overflow-hidden rounded-2xl w-full h-12 lg:h-24 px-2 sm:px-6 xl:gap-8 items-center'>
<div className="w-full">
<div className='grid grid-cols-3 overflow-hidden rounded-2xl w-full h-12 lg:h-24 px-2 xl:gap-8 items-center'>
<div className='inline-flex justify-between items-center'>
<button className='inline-block' onClick={toggleMenuState}>
<button className='inline-block xl:hidden' onClick={toggleMenuState}>
<BurgerMenuIcon />
</button>
{/* <div onClick={toggleSearchModalState} className='xl:bg-[#EEF0F7] xl:hidden inline-flex rounded-xl px-4 h-12 xl:w-[370px] items-center content-center' >
@@ -53,18 +54,19 @@ function TopBar({ profileDropState, toggleProfileDropState, menuState, toggleMen
<div className='flex items-center justify-end gap-3'>
{/* <NightModeSwitch checked={nightMode} onClick={toggleNightMode} /> */}
{/* <img className='hidden sm:block' src={rectangles} /> */}
<GridIcon className='w-4 h-4 text-icon-active' />
<WalletIcon className='w-4 h-4 text-icon-active' />
<NotificationBellIcon className='w-4 h-4 text-icon-active' />
<GridIcon className='size-4.5 text-icon-active' />
<WalletIcon className='size-4.5 text-icon-active' />
<NotificationBellIcon className='size-4.5 text-icon-active' />
<button className='flex items-center justify-between' onClick={toggleProfileDropState}>
<Image
width={32}
height={32}
width={24}
height={24}
alt='Profile avatar'
className='rounded-full'
src={'/assets/images/user-avatar.png'} />
<div className='pe-6 hidden xl:inline-flex' >
<div className='pe-0 hidden xl:inline-flex items-end' >
<div className='ps-2 pe-1 text-xs text-nowrap'>مهرداد مظفری</div>
<ArrowDown2 className='stroke-disabled-text' size={14} />
{/* <img src={arrow} /> */}
</div>
</button>
@@ -36,9 +36,9 @@ function ClientMenuRouteWrapper({ children }: Props) {
// }, [location])
return (
<div className="h-svh overflow-hidden pt-16 flex flex-col pb-8 ">
<div className="h-svh overflow-hidden pt-10 flex flex-col pb-4 xl:pt-12">
<div className="fixed top-0 left-0 right-0 z-50 px-4">
<div className="z-50 fixed right-4 left-4 xl:right-[285px] top-4 xl:h-16 h-12 flex items-center px-4 bg-white justify-between rounded-[32px] xl:w-[calc(100%-305px)]">
<TopBar
profileDropState={profileDrop}
toggleProfileDropState={toggleProfileDrop}
@@ -66,7 +66,7 @@ function ClientMenuRouteWrapper({ children }: Props) {
<main
className="noscrollbar overflow-y-auto h-svh pt-0 pb-12 mx-2 px-2"
className="noscrollbar overflow-y-auto h-svh pt-6 xl:pt-8 pb-12 px-4 xl:pr-0 xl:pl-5 w-full xl:w-[calc(100%-285px)] xl:self-end"
>
{children}
</main>