From bcfaceae94223cc3f1163655d535d93e343aa25b Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 27 Jun 2026 12:21:32 +0330 Subject: [PATCH] base bottom navbar --- src/components/navigation/BottomNavBar.tsx | 198 +++++++----------- .../wrapper/ClientMenuRouteWrapper.tsx | 26 ++- 2 files changed, 94 insertions(+), 130 deletions(-) diff --git a/src/components/navigation/BottomNavBar.tsx b/src/components/navigation/BottomNavBar.tsx index 60d322a..6a00a9a 100644 --- a/src/components/navigation/BottomNavBar.tsx +++ b/src/components/navigation/BottomNavBar.tsx @@ -1,50 +1,59 @@ -'use client'; +"use client"; -import React from 'react' -import Link from 'next/link' -import BottomNavLink from './BottomNavLink' -import BottomNavHighlightLink from './BottomNavLinkBig' -import PagerIcon from '../icons/PagerIcon' -import BagIcon from '../icons/BagIcon' -import HeartIcon from '../icons/HeartIcon' -import { useParams, usePathname, useRouter } from 'next/navigation' -import HomeIcon from '../icons/HomeIcon' -import { useTranslation } from 'react-i18next'; -import { useCart } from '@/app/[name]/(Main)/cart/hook/useCart'; -import { Building } from 'iconsax-react'; -import { glassSurfaceNav } from '@/lib/styles/glassSurface'; -import { getBottomNavMaskStyle } from './bottomNavShape'; -import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData'; -import { toastLoginRequired } from '../Toast'; +import { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData"; +import { glassSurfaceNav } from "@/lib/styles/glassSurface"; +import clsx from "clsx"; +import type { Icon } from "iconsax-react"; +import { Bag2, Heart, Home2, NotificationStatus, Reserve } from "iconsax-react"; +import Link from "next/link"; +import { useParams, usePathname, useRouter } from "next/navigation"; +import { toastLoginRequired } from "../Toast"; type BottomNavBarProps = { onPagerClick?: () => void; + compact?: boolean; }; -function BottomNavBar({ onPagerClick }: BottomNavBarProps) { +type NavItemProps = { + href?: string; + isActive: boolean; + onClick?: (e: React.MouseEvent) => void; + onButtonClick?: () => void; + Icon: Icon; +}; +function NavItem({ href, isActive, onClick, onButtonClick, Icon }: NavItemProps) { + const className = clsx("flex-1 flex items-center justify-center h-full rounded-full", isActive && "bg-primary/12"); + + const icon = ; + + if (onButtonClick) { + return ( + + ); + } + + return ( + + {icon} + + ); +} + +function BottomNavBar({ onPagerClick, compact = false }: BottomNavBarProps) { const params = useParams(); - const { name } = params; + const name = params.name as string; const pathname = usePathname(); - const isHomeRoute = pathname === `/${name}`; - const isAboutRoute = pathname.includes('about'); - const buildingVariant = React.useMemo(() => { - return (isAboutRoute ? 'Bold' : 'Outline') as 'Bold' | 'Outline'; - }, [isAboutRoute]); - const { isSuccess } = useGetProfile() - const router = useRouter() - const { t } = useTranslation('common', { - keyPrefix: 'BottomNavbar' - }); - const { items } = useCart(); + const router = useRouter(); + const { isSuccess } = useGetProfile(); - const navMaskStyle = React.useMemo(() => getBottomNavMaskStyle(), []); - - const cartItemsCount = React.useMemo(() => { - return Object.values(items).reduce((total, item) => { - return total + (item?.quantity || 0); - }, 0); - }, [items]); + const isHomeActive = pathname === `/${name}`; + const isFavoriteActive = pathname.startsWith(`/${name}/favorite`); + const isPagerActive = pathname.includes("/pager"); + const isNotificationsActive = pathname.startsWith(`/${name}/notifications`); + const isCartActive = pathname.startsWith(`/${name}/cart`); const handleFavoritesClick = (e: React.MouseEvent) => { e.preventDefault(); @@ -52,99 +61,34 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) { router.push(`/${name}/favorite`); } else { e.stopPropagation(); - toastLoginRequired(() => router.push(`/${name}/auth`), 'error'); + toastLoginRequired(() => router.push(`/${name}/auth`), "error"); } - } + }; + + const handleNotificationClick = (e: React.MouseEvent) => { + e.preventDefault(); + if (isSuccess) { + router.push(`/${name}/notifications`); + } else { + toastLoginRequired(() => router.push(`/${name}/auth`), "error"); + } + }; return ( -
-
-
- - - - {cartItemsCount > 0 && ( -
-
-
-
-
- - {cartItemsCount > 99 ? '99+' : cartItemsCount} - -
- {t('Cart')} -
-
-
- )} -
+
+ + + {onPagerClick ? : } + +
- ) + ); } -export default BottomNavBar +export default BottomNavBar; diff --git a/src/components/wrapper/ClientMenuRouteWrapper.tsx b/src/components/wrapper/ClientMenuRouteWrapper.tsx index 7ff3f96..f2232de 100644 --- a/src/components/wrapper/ClientMenuRouteWrapper.tsx +++ b/src/components/wrapper/ClientMenuRouteWrapper.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { useEffect } from 'react' +import React, { useEffect, useRef, useState } from 'react' import TopBar from '../topbar/TopBar' import SideMenu from '../menu/SideMenu' import BottomNavBar from '../navigation/BottomNavBar' @@ -44,6 +44,8 @@ function ClientMenuRouteWrapper({ children }: Props) { const location = usePathname(); const hideBottomNav = pathname.endsWith('/cart'); + const mainRef = useRef(null); + const [navCompact, setNavCompact] = useState(false); useEffect(() => { if (menuState) { @@ -52,6 +54,23 @@ function ClientMenuRouteWrapper({ children }: Props) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [location]) + useEffect(() => { + const scrollContainer = mainRef.current; + if (!scrollContainer || hideBottomNav) { + setNavCompact(false); + return; + } + + const handleScroll = () => { + setNavCompact(scrollContainer.scrollTop > 24); + }; + + scrollContainer.addEventListener('scroll', handleScroll, { passive: true }); + handleScroll(); + + return () => scrollContainer.removeEventListener('scroll', handleScroll); + }, [hideBottomNav, location]); + return (
@@ -70,8 +89,8 @@ function ClientMenuRouteWrapper({ children }: Props) { {!hideBottomNav && ( -
- +
+
)} @@ -85,6 +104,7 @@ function ClientMenuRouteWrapper({ children }: Props) {