This commit is contained in:
@@ -1,46 +1,63 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import BottomNavLink from './BottomNavLink'
|
||||
import BottomNavHighlightLink from './BottomNavLinkBig'
|
||||
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]/(Dialogs)/cart/hook/useCart';
|
||||
import { Building, Receipt21 } from 'iconsax-react';
|
||||
import clsx from 'clsx';
|
||||
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, Building, Heart, Home2, Receipt21 } from 'iconsax-react';
|
||||
import Link from 'next/link';
|
||||
import { useParams, usePathname, useRouter } from 'next/navigation';
|
||||
import { useMemo } from 'react';
|
||||
import { toast } from '../Toast';
|
||||
|
||||
function BottomNavBar() {
|
||||
type NavItemProps = {
|
||||
href?: string;
|
||||
isActive: boolean;
|
||||
onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
|
||||
Icon: Icon;
|
||||
badge?: number;
|
||||
};
|
||||
|
||||
function NavItem({ href, isActive, onClick, Icon, badge }: NavItemProps) {
|
||||
const className = clsx('flex-1 flex items-center justify-center h-full rounded-full', isActive && 'bg-primary/12');
|
||||
|
||||
const icon = (
|
||||
<span className="relative">
|
||||
<Icon size={20} color="currentColor" variant={isActive ? 'Bold' : 'Linear'} className={isActive ? 'text-primary' : 'text-icon-deactive'} />
|
||||
{badge != null && badge > 0 && (
|
||||
<span className="absolute -right-1.5 -top-1 flex min-w-3.5 h-3.5 items-center justify-center rounded-full bg-primary px-0.5 text-[8px] font-medium text-container dark:bg-white dark:text-black">
|
||||
{badge > 99 ? '99+' : badge}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<Link href={href ?? '#'} onClick={onClick} className={className}>
|
||||
{icon}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function BottomNavBar() {
|
||||
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 isOrderRoute = pathname.includes('order');
|
||||
const buildingVariant = React.useMemo(() => {
|
||||
return (isAboutRoute ? 'Bold' : 'Outline') as 'Bold' | 'Outline';
|
||||
}, [isAboutRoute]);
|
||||
const orderVariant = React.useMemo(() => {
|
||||
return (isOrderRoute ? 'Bold' : 'Outline') as 'Bold' | 'Outline';
|
||||
}, [isOrderRoute]);
|
||||
const { isSuccess } = useGetProfile()
|
||||
const router = useRouter()
|
||||
const { t } = useTranslation('common', {
|
||||
keyPrefix: 'BottomNavbar'
|
||||
});
|
||||
const router = useRouter();
|
||||
const { isSuccess } = useGetProfile();
|
||||
const { items } = useCart();
|
||||
|
||||
const cartItemsCount = React.useMemo(() => {
|
||||
return Object.values(items).reduce((total, item) => {
|
||||
return total + (item?.quantity || 0);
|
||||
}, 0);
|
||||
}, [items]);
|
||||
const cartItemCount = useMemo(
|
||||
() => Object.values(items).reduce((sum, item) => sum + (item?.quantity ?? 0), 0),
|
||||
[items],
|
||||
);
|
||||
|
||||
const isCartActive = pathname.startsWith(`/${name}/cart`);
|
||||
const isOrderActive = pathname.includes('/order');
|
||||
const isHomeActive = pathname === `/${name}`;
|
||||
const isAboutActive = pathname.startsWith(`/${name}/about`);
|
||||
const isFavoriteActive = pathname.startsWith(`/${name}/favorite`);
|
||||
|
||||
const handleFavoritesClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
e.preventDefault();
|
||||
@@ -51,156 +68,17 @@ function BottomNavBar() {
|
||||
toast('ابتدا لاگین کنید', 'error');
|
||||
router.replace(`/${name}/auth`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-0 left-0 w-full bg-transparent pointer-events-none">
|
||||
<div className="max-w-md mx-auto w-full aspect-436/104 relative z-30">
|
||||
<svg
|
||||
viewBox="0 0 436 104"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-full h-full block"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
<g filter="url(#filter0_d_9095_18036)" className='fill-container'>
|
||||
<path
|
||||
className='pointer-events-auto'
|
||||
d="M218 16C229.034 16 238.711 22.0313 244.148 31.0943C245.844 33.9222 248.724 36 252.022 36H406C414.837 36 422 43.1634 422 52V80C422 88.8366 414.837 96 406 96H30C21.1634 96 14 88.8366 14 80V52C14 43.1634 21.1634 36 30 36H183.979C187.277 36 190.157 33.9222 191.853 31.0943C197.29 22.0315 206.966 16.0001 218 16Z"
|
||||
/>
|
||||
</g>
|
||||
|
||||
{/* 🔽 Your HTML content inside SVG */}
|
||||
<foreignObject x="0" y="10" width="100%" height="80">
|
||||
<nav
|
||||
className="h-full px-4 grid grid-cols-5 gap-x-1 text-[10px] items-end"
|
||||
>
|
||||
<BottomNavLink
|
||||
href={`/${name}/cart`}
|
||||
icon={<BagIcon width={20} height={20} />}
|
||||
value={t('Cart')}
|
||||
/>
|
||||
|
||||
<Link
|
||||
href={`/${name}/order/history`}
|
||||
className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white'
|
||||
)}
|
||||
>
|
||||
<div className="shrink-0 text-primary dark:text-white">
|
||||
<Receipt21
|
||||
key={`receipt-${orderVariant}-${isOrderRoute}`}
|
||||
size={20}
|
||||
variant={orderVariant}
|
||||
color="currentColor"
|
||||
className='stroke-0'
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs2 text-center truncate w-full dark:text-white">
|
||||
{t('Orders')}
|
||||
</span>
|
||||
</Link>
|
||||
{/* <BottomNavLink href={`/${name}/order/history`} icon={<ReceiptIcon width={20} height={20} />} value={t('Orders')} /> */}
|
||||
<BottomNavHighlightLink
|
||||
href={`/${name}`}
|
||||
icon={
|
||||
<HomeIcon
|
||||
className={clsx(
|
||||
'transition-all duration-200 stroke-primary dark:stroke-black! dark:text-white'
|
||||
)}
|
||||
fill="white"
|
||||
stroke="currentColor"
|
||||
variant={isHomeRoute ? 'Bold' : 'Outline'}
|
||||
width={20}
|
||||
height={20} />}
|
||||
value={t('Menu')} />
|
||||
<Link
|
||||
href={`/${name}/about`}
|
||||
className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white'
|
||||
)}
|
||||
>
|
||||
<div className="shrink-0 text-primary dark:text-white">
|
||||
<Building
|
||||
key={`building-${buildingVariant}-${isAboutRoute}`}
|
||||
size={20}
|
||||
variant={buildingVariant as 'Bold' | 'Outline'}
|
||||
color="currentColor"
|
||||
className='stroke-0'
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs2 text-center truncate w-full dark:text-white">
|
||||
{t('about')}
|
||||
</span>
|
||||
</Link>
|
||||
<BottomNavLink href={`/${name}/favorite`} onClick={handleFavoritesClick} icon={<HeartIcon width={20} height={20} />} value={t('Favorites')} />
|
||||
</nav>
|
||||
</foreignObject>
|
||||
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_9095_18036"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
filterUnits="userSpaceOnUse"
|
||||
colorInterpolationFilters="sRGB"
|
||||
>
|
||||
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="-2" />
|
||||
<feGaussianBlur stdDeviation="7" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_9095_18036"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_9095_18036"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
{/* Badge Layer - خارج از SVG - دقیقاً مثل foreignObject */}
|
||||
{cartItemsCount > 0 && (
|
||||
<div
|
||||
className="absolute left-0 right-0 pointer-events-none"
|
||||
style={{
|
||||
top: 'calc(10 / 104 * 100%)',
|
||||
height: 'calc(80 / 104 * 100%)'
|
||||
}}
|
||||
>
|
||||
<div className="h-full px-4 grid grid-cols-5 gap-x-1 items-end">
|
||||
<div className="flex flex-col items-center gap-[5px]">
|
||||
<div className="relative shrink-0">
|
||||
<div className="w-5 h-5 opacity-0"></div>
|
||||
<span className="absolute sm:-top-1 sm:-right-1 top-0 -right-1 flex items-center justify-center min-w-[14px] min-h-[14px] px-1 text-[8px] font-medium text-white dark:bg-white dark:text-black bg-primary rounded-full z-50">
|
||||
{cartItemsCount > 99 ? '99+' : cartItemsCount}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-xs2 opacity-0">{t('Cart')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={glassSurfaceNav('mx-auto w-full rounded-full flex items-center h-14 max-w-md gap-2.5')}>
|
||||
<NavItem href={`/${name}/cart`} isActive={isCartActive} Icon={Bag2} badge={cartItemCount} />
|
||||
<NavItem href={`/${name}/order/history`} isActive={isOrderActive} Icon={Receipt21} />
|
||||
<NavItem href={`/${name}`} isActive={isHomeActive} Icon={Home2} />
|
||||
<NavItem href={`/${name}/about`} isActive={isAboutActive} Icon={Building} />
|
||||
<NavItem href={`/${name}/favorite`} isActive={isFavoriteActive} onClick={handleFavoritesClick} Icon={Heart} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default BottomNavBar
|
||||
export default BottomNavBar;
|
||||
|
||||
Reference in New Issue
Block a user