2026-07-11 21:21:29 +03:30
|
|
|
|
"use client";
|
|
|
|
|
|
import clsx from "clsx";
|
|
|
|
|
|
import {
|
|
|
|
|
|
ChevronLeft,
|
|
|
|
|
|
ChevronRight,
|
|
|
|
|
|
CircleUserRound,
|
|
|
|
|
|
type LucideIcon,
|
|
|
|
|
|
Menu,
|
|
|
|
|
|
Phone,
|
|
|
|
|
|
Search,
|
|
|
|
|
|
Send,
|
|
|
|
|
|
ShoppingBag,
|
|
|
|
|
|
X,
|
|
|
|
|
|
} from "lucide-react";
|
|
|
|
|
|
import { type CSSProperties, Fragment, useState } from "react";
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
Logo,
|
|
|
|
|
|
LogoImage,
|
|
|
|
|
|
LogoTextDesktop,
|
|
|
|
|
|
} from "@/components/shadcnblocks/logo";
|
|
|
|
|
|
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
|
|
|
|
|
import { Badge } from "@/components/ui/badge";
|
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import {
|
|
|
|
|
|
NavigationMenu,
|
|
|
|
|
|
NavigationMenuContent,
|
|
|
|
|
|
NavigationMenuItem,
|
|
|
|
|
|
NavigationMenuLink,
|
|
|
|
|
|
NavigationMenuList,
|
|
|
|
|
|
NavigationMenuTrigger,
|
|
|
|
|
|
} from "@/components/ui/navigation-menu";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Select,
|
|
|
|
|
|
SelectContent,
|
|
|
|
|
|
SelectItem,
|
|
|
|
|
|
SelectTrigger,
|
|
|
|
|
|
SelectValue,
|
|
|
|
|
|
} from "@/components/ui/select";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Sheet,
|
|
|
|
|
|
SheetClose,
|
|
|
|
|
|
SheetContent,
|
|
|
|
|
|
SheetFooter,
|
|
|
|
|
|
SheetHeader,
|
|
|
|
|
|
SheetTitle,
|
|
|
|
|
|
} from "@/components/ui/sheet";
|
|
|
|
|
|
import { useIsMobile } from "@/hooks/use-mobile";
|
|
|
|
|
|
import usePreventScrollLock from "@/hooks/usePreventScrollLock";
|
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
|
|
|
|
|
|
|
type MegaMenuSectionType = {
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
imageSrc: string;
|
|
|
|
|
|
items: {
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
}[];
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type FeaturedItemType = {
|
|
|
|
|
|
imageSrc: string;
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type MenuItemType = {
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
href?: string;
|
|
|
|
|
|
accentColor?: string;
|
|
|
|
|
|
id?: string;
|
|
|
|
|
|
megaMenu?: {
|
|
|
|
|
|
sections?: MegaMenuSectionType[];
|
|
|
|
|
|
featuredItems?: FeaturedItemType[];
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type SocialIcon = {
|
|
|
|
|
|
title: string;
|
|
|
|
|
|
light: string;
|
|
|
|
|
|
dark: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type SocialLink = {
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
icon: SocialIcon;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type HelpfullLink = {
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type ContactInfoItem = {
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
icon: LucideIcon;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type HomeLink = {
|
|
|
|
|
|
href: string;
|
|
|
|
|
|
logo: {
|
|
|
|
|
|
src: string;
|
|
|
|
|
|
alt: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type MenuItemProps = MenuItemType;
|
|
|
|
|
|
|
|
|
|
|
|
interface EcommerceNavbar1Props {
|
|
|
|
|
|
menu: MenuItemType[];
|
|
|
|
|
|
socialLinks?: SocialLink[];
|
|
|
|
|
|
helpfulLinks?: HelpfullLink[];
|
|
|
|
|
|
contactInfo?: ContactInfoItem[];
|
|
|
|
|
|
home: HomeLink;
|
|
|
|
|
|
className?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface MenuLinksListProps {
|
|
|
|
|
|
lists?: MegaMenuSectionType[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface MenuFeaturedLinksProps {
|
|
|
|
|
|
lists?: FeaturedItemType[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface MenuLinksProps {
|
|
|
|
|
|
list: MegaMenuSectionType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface MobileNavProps {
|
|
|
|
|
|
menu: MenuItemType[];
|
|
|
|
|
|
socialLinks?: SocialLink[];
|
|
|
|
|
|
helpfulLinks?: HelpfullLink[];
|
|
|
|
|
|
contactInfo?: ContactInfoItem[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type MenuFeaturedLinkProps = FeaturedItemType;
|
|
|
|
|
|
|
|
|
|
|
|
interface MegaMenuMobileProps {
|
|
|
|
|
|
menuItem?: MenuItemType;
|
|
|
|
|
|
open: boolean;
|
|
|
|
|
|
onOpenChange: (open: boolean) => void;
|
|
|
|
|
|
openSubMenu: boolean;
|
|
|
|
|
|
handleOnSubMenuClick: (id?: string) => void;
|
|
|
|
|
|
linkStyle?: string;
|
|
|
|
|
|
closeAll: () => void;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface SubMenuMobileProps {
|
|
|
|
|
|
subMenu?: MegaMenuSectionType;
|
|
|
|
|
|
open: boolean;
|
|
|
|
|
|
onOpenChange: (open: boolean) => void;
|
|
|
|
|
|
linkStyle?: string;
|
|
|
|
|
|
closeAll: () => void;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface SocialMediaSectionProps {
|
|
|
|
|
|
links?: SocialLink[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface HelpfullLinksProps {
|
|
|
|
|
|
links?: HelpfullLink[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface ContactInfoListProps {
|
|
|
|
|
|
links?: ContactInfoItem[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const HELPFULL_LINKS = [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "مرجوعی و تعویض",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "ارسال و پیگیری",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "شرایط و ضوابط",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const CONTACT_INFO = [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "+1 855-987-4420",
|
|
|
|
|
|
href: "tel:+18559874420",
|
|
|
|
|
|
icon: Phone,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "support@fashion.co",
|
|
|
|
|
|
href: "mailto:support@fashion.co",
|
|
|
|
|
|
icon: Send,
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const SOCIAL_ICONS = {
|
|
|
|
|
|
facebook: {
|
|
|
|
|
|
title: "Facebook",
|
|
|
|
|
|
light:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/logos/facebook-icon.svg",
|
|
|
|
|
|
dark: "/block-media/shadcnblocks/block/logos/facebook-icon.svg",
|
|
|
|
|
|
},
|
|
|
|
|
|
x: {
|
|
|
|
|
|
title: "X",
|
|
|
|
|
|
light:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/logos/x.svg",
|
|
|
|
|
|
dark: "/block-media/shadcnblocks/block/logos/x.svg",
|
|
|
|
|
|
},
|
|
|
|
|
|
instagram: {
|
|
|
|
|
|
title: "Instagram",
|
|
|
|
|
|
light:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/logos/instagram-icon.svg",
|
|
|
|
|
|
dark: "/block-media/shadcnblocks/block/logos/instagram-icon.svg",
|
|
|
|
|
|
},
|
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
|
|
const SOCIAL_MEDIA_LINKS = [
|
|
|
|
|
|
{ icon: SOCIAL_ICONS.facebook, href: "#" },
|
|
|
|
|
|
{ icon: SOCIAL_ICONS.x, href: "#" },
|
|
|
|
|
|
{ icon: SOCIAL_ICONS.instagram, href: "#" },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const MENU = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: "store",
|
|
|
|
|
|
label: "فروشگاه",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
megaMenu: {
|
|
|
|
|
|
sections: [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "اکسسوری",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "accessories",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/accessories/Elegant-Watch-on-Womans-Wrist-2.png",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "کیف و کوله", href: "#" },
|
|
|
|
|
|
{ label: "کلاه", href: "#" },
|
|
|
|
|
|
{ label: "کمربند", href: "#" },
|
|
|
|
|
|
{ label: "جواهرات", href: "#" },
|
|
|
|
|
|
{ label: "عینک آفتابی", href: "#" },
|
|
|
|
|
|
{ label: "ساعت", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "مردانه",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "men",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/pexels-cottonbro-6764036-2.jpg",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "تازهها", href: "#" },
|
|
|
|
|
|
{ label: "تیشرت", href: "#" },
|
|
|
|
|
|
{ label: "پیراهن", href: "#" },
|
|
|
|
|
|
{ label: "کت و کاپشن", href: "#" },
|
|
|
|
|
|
{ label: "شلوار", href: "#" },
|
|
|
|
|
|
{ label: "کفش", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "زنانه",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "women",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/pexels-429124762-19881454-2.jpg",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "تازهها", href: "#" },
|
|
|
|
|
|
{ label: "لباس", href: "#" },
|
|
|
|
|
|
{ label: "تاپ و بلوز", href: "#" },
|
|
|
|
|
|
{ label: "پوشاک بیرونی", href: "#" },
|
|
|
|
|
|
{ label: "دامن", href: "#" },
|
|
|
|
|
|
{ label: "کفش", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
featuredItems: [
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Summer-Fashion-Duo-2.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "پیشنهاد تابستانه",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Contemplative-Casual-Chic-2.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "پرفروشترینها",
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: "collections",
|
|
|
|
|
|
label: "مجموعهها",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
megaMenu: {
|
|
|
|
|
|
sections: [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "بر اساس سبک",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "by-style",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Man-in-White-Hoodie-1.png",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "مینیمال", href: "#" },
|
|
|
|
|
|
{ label: "کلاسیک", href: "#" },
|
|
|
|
|
|
{ label: "مدرن", href: "#" },
|
|
|
|
|
|
{ label: "راحتی", href: "#" },
|
|
|
|
|
|
{ label: "رسمی", href: "#" },
|
|
|
|
|
|
{ label: "ورزشی", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "بر اساس مناسبت",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "by-occasion",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Chic-Fashion-Portrait-2.png",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "کار و اداری", href: "#" },
|
|
|
|
|
|
{ label: "آخر هفته", href: "#" },
|
|
|
|
|
|
{ label: "مهمانی", href: "#" },
|
|
|
|
|
|
{ label: "سفر", href: "#" },
|
|
|
|
|
|
{ label: "روزمره", href: "#" },
|
|
|
|
|
|
{ label: "فصل جدید", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "مجموعههای ویژه",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
id: "curated",
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Modern-Fashion-Portrait-2.png",
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ label: "محصولات ضروری", href: "#" },
|
|
|
|
|
|
{ label: "پرفروشترینها", href: "#" },
|
|
|
|
|
|
{ label: "نسخه محدود", href: "#" },
|
|
|
|
|
|
{ label: "ستهای آماده", href: "#" },
|
|
|
|
|
|
{ label: "هدایای منتخب", href: "#" },
|
|
|
|
|
|
{ label: "همکاریهای ویژه", href: "#" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
featuredItems: [
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Man-in-White-Hoodie-1.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "محصولات ضروری",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Man-in-White-Hoodie-1.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "کلاسیک مینیمال",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Man-in-White-Hoodie-1.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "لباس کار مدرن",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
imageSrc:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/Man-in-White-Hoodie-1.png",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
label: "لباس آخر هفته",
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "حراج",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
accentColor: "oklch(58.6% 0.253 17.585)",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: "وبلاگ",
|
|
|
|
|
|
href: "#",
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const HOME = {
|
|
|
|
|
|
href: "https://ShadcnBlocks",
|
|
|
|
|
|
logo: {
|
|
|
|
|
|
src: "/block-media/shadcnblocks/block/logos/ShadcnBlockscom-icon.svg",
|
|
|
|
|
|
alt: "لوگو",
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const EcommerceNavbar1 = ({
|
|
|
|
|
|
menu = MENU,
|
|
|
|
|
|
home = HOME,
|
|
|
|
|
|
helpfulLinks = HELPFULL_LINKS,
|
|
|
|
|
|
socialLinks = SOCIAL_MEDIA_LINKS,
|
|
|
|
|
|
contactInfo = CONTACT_INFO,
|
|
|
|
|
|
className,
|
|
|
|
|
|
}: EcommerceNavbar1Props) => {
|
|
|
|
|
|
const isMobile = useIsMobile();
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div dir="rtl" lang="fa" className={cn("relative w-full overflow-visible text-start", className)}>
|
|
|
|
|
|
{isMobile ? (
|
|
|
|
|
|
<div className="md:hidden">
|
|
|
|
|
|
<MobileNav
|
|
|
|
|
|
menu={menu}
|
|
|
|
|
|
helpfulLinks={helpfulLinks}
|
|
|
|
|
|
socialLinks={socialLinks}
|
|
|
|
|
|
contactInfo={contactInfo}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<NavigationMenu
|
|
|
|
|
|
dir="rtl"
|
|
|
|
|
|
viewport={false}
|
|
|
|
|
|
className="relative z-50 w-full max-w-full overflow-visible border-b max-md:hidden [&>div]:w-full"
|
|
|
|
|
|
>
|
|
|
|
|
|
<NavigationMenuList asChild className="h-fit min-h-17.5 px-7.5">
|
|
|
|
|
|
<div className="flex items-center gap-6 overflow-visible">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<Logo url={home.href}>
|
|
|
|
|
|
<LogoImage
|
|
|
|
|
|
src={home.logo.src}
|
|
|
|
|
|
alt={home.logo.alt}
|
|
|
|
|
|
className="size-8 dark:invert"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<LogoTextDesktop className="font-medium text-foreground">
|
|
|
|
|
|
ری یو آی
|
|
|
|
|
|
</LogoTextDesktop>
|
|
|
|
|
|
</Logo>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
|
{menu.map((item, index) => (
|
|
|
|
|
|
<NavigationMenuItem key={index} className="static">
|
|
|
|
|
|
<MenuItem {...item} />
|
|
|
|
|
|
</NavigationMenuItem>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="ms-auto flex items-center gap-4">
|
|
|
|
|
|
<CountrySelector />
|
|
|
|
|
|
<SecondaryNav />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</NavigationMenuList>
|
|
|
|
|
|
</NavigationMenu>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MenuItem = ({ label, href, megaMenu, accentColor }: MenuItemProps) => {
|
|
|
|
|
|
const menuLinkStyle = "text-xs font-semibold px-4";
|
|
|
|
|
|
if (!megaMenu) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<NavigationMenuLink
|
|
|
|
|
|
asChild
|
|
|
|
|
|
style={{
|
|
|
|
|
|
color: accentColor,
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={menuLinkStyle}
|
|
|
|
|
|
>
|
|
|
|
|
|
<a href={href}>{label}</a>
|
|
|
|
|
|
</NavigationMenuLink>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Fragment>
|
|
|
|
|
|
<NavigationMenuTrigger
|
|
|
|
|
|
style={{
|
|
|
|
|
|
color: accentColor,
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={menuLinkStyle}
|
|
|
|
|
|
>
|
|
|
|
|
|
{label}
|
|
|
|
|
|
</NavigationMenuTrigger>
|
|
|
|
|
|
<NavigationMenuContent
|
|
|
|
|
|
className={clsx(
|
|
|
|
|
|
"inset-x-0 start-0 end-0",
|
|
|
|
|
|
"z-50 mt-0! h-auto max-h-none min-h-0 rounded-none! p-0",
|
|
|
|
|
|
"!overflow-visible shadow-md",
|
|
|
|
|
|
"group-data-[viewport=false]/navigation-menu:!overflow-visible",
|
|
|
|
|
|
"group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-none! group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-none!",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="mx-auto w-full max-w-7xl px-7.5 py-10.5">
|
|
|
|
|
|
<div className="relative flex items-start justify-center gap-6 overflow-visible">
|
|
|
|
|
|
{megaMenu?.sections && (
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={clsx(
|
|
|
|
|
|
"relative z-10 min-w-0",
|
|
|
|
|
|
megaMenu?.featuredItems && "basis-[60%]",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<MenuLinksList lists={megaMenu?.sections} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{megaMenu?.featuredItems && (
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={clsx(
|
|
|
|
|
|
"relative z-0 shrink-0",
|
|
|
|
|
|
megaMenu?.sections ? "basis-[40%]" : "flex-1",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<MenuFeaturedLinks lists={megaMenu?.featuredItems} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</NavigationMenuContent>
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MenuLinksList = ({ lists }: MenuLinksListProps) => {
|
|
|
|
|
|
if (!lists) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<ul className="relative z-10 flex gap-7.5">
|
|
|
|
|
|
{lists.map((list, index) => (
|
|
|
|
|
|
<li key={index} className="basis-1/3">
|
|
|
|
|
|
<MenuLinks list={list} />
|
|
|
|
|
|
</li>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MenuLinks = ({ list }: MenuLinksProps) => {
|
|
|
|
|
|
const { label, href, items } = list;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="space-y-1.5">
|
|
|
|
|
|
<h2 className="px-1 text-xs leading-relaxed font-semibold">
|
|
|
|
|
|
<a href={href}>{label}</a>
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
{items.map((item, index) => (
|
|
|
|
|
|
<li key={index}>
|
|
|
|
|
|
<a
|
|
|
|
|
|
className="block w-full rounded-sm px-1 py-0.5 text-xs leading-normal text-muted-foreground hover:bg-muted"
|
|
|
|
|
|
href={item.href}
|
|
|
|
|
|
>
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MenuFeaturedLinks = ({ lists }: MenuFeaturedLinksProps) => {
|
|
|
|
|
|
if (!lists) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="relative z-0 flex gap-7.5">
|
|
|
|
|
|
{lists.map((item, index) => (
|
|
|
|
|
|
<div className="flex-1" key={index}>
|
|
|
|
|
|
<MenuFeaturedLink {...item} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MenuFeaturedLink = ({ href, imageSrc, label }: MenuFeaturedLinkProps) => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<a href={href} className="group/feat-link relative z-0 block space-y-3">
|
|
|
|
|
|
<AspectRatio className="relative overflow-hidden">
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={imageSrc}
|
|
|
|
|
|
alt={label}
|
|
|
|
|
|
className="block size-full object-cover object-center transition-all duration-500 group-hover/feat-link:scale-105 group-hover/feat-link:opacity-80"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</AspectRatio>
|
|
|
|
|
|
<div className="text-center text-xs leading-relaxed font-semibold">
|
|
|
|
|
|
{label}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const SecondaryNav = () => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
|
<Button variant="ghost" size="icon" aria-label="حساب کاربری">
|
|
|
|
|
|
<CircleUserRound />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<div className="relative">
|
|
|
|
|
|
<Button variant="ghost" size="icon" aria-label="سبد خرید">
|
|
|
|
|
|
<ShoppingBag />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<div className="absolute -top-4 start-1/2 -translate-x-1/2">
|
|
|
|
|
|
<Badge className="text-[0.5rem]">۰</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Button variant="ghost" size="icon" aria-label="جستجو">
|
|
|
|
|
|
<Search />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const CountrySelector = ({ className }: { className?: string }) => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Select defaultValue="IR">
|
|
|
|
|
|
<SelectTrigger
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"w-42 border-none text-xs leading-relaxed font-semibold text-muted-foreground shadow-none",
|
|
|
|
|
|
className,
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<SelectValue placeholder="انتخاب کشور" />
|
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
<SelectContent align="start">
|
|
|
|
|
|
<SelectItem value="IR">ایران (تومان)</SelectItem>
|
2026-07-21 19:25:31 +03:30
|
|
|
|
<SelectItem value="US">آمریکا (ریال)</SelectItem>
|
2026-07-11 21:21:29 +03:30
|
|
|
|
<SelectItem value="FR">فرانسه (یورو)</SelectItem>
|
2026-07-21 19:25:31 +03:30
|
|
|
|
<SelectItem value="AUS">استرالیا (ریال)</SelectItem>
|
2026-07-11 21:21:29 +03:30
|
|
|
|
</SelectContent>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MobileNav = ({
|
|
|
|
|
|
menu,
|
|
|
|
|
|
socialLinks,
|
|
|
|
|
|
helpfulLinks,
|
|
|
|
|
|
contactInfo,
|
|
|
|
|
|
}: MobileNavProps) => {
|
|
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
|
|
const [openMegaMenu, setOpenMegaMenu] = useState(false);
|
|
|
|
|
|
const [openSubMenu, setOpenSubMenu] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
const [menuItem, setMenuItem] = useState<MenuItemType>();
|
|
|
|
|
|
const [subMenu, setSubMenu] = useState<MegaMenuSectionType>();
|
|
|
|
|
|
|
|
|
|
|
|
usePreventScrollLock(open);
|
|
|
|
|
|
|
|
|
|
|
|
const closeAll = () => {
|
|
|
|
|
|
setOpen(false);
|
|
|
|
|
|
setOpenMegaMenu(false);
|
|
|
|
|
|
setOpenSubMenu(false);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleMegaMenu = (value: boolean) => {
|
|
|
|
|
|
setOpenMegaMenu(value);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleSheet = () => {
|
|
|
|
|
|
setOpen((state) => !state);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleOnMenuItemClick = (id?: string) => {
|
|
|
|
|
|
const foundMenu = menu.find((item) => item.id === id);
|
|
|
|
|
|
|
|
|
|
|
|
setMenuItem(foundMenu);
|
|
|
|
|
|
setOpenMegaMenu(true);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleSubMenu = (value: boolean) => {
|
|
|
|
|
|
setOpenSubMenu(value);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleOnSubMenuClick = (id?: string) => {
|
|
|
|
|
|
const foundMenu = menuItem?.megaMenu?.sections?.find(
|
|
|
|
|
|
(item) => item.id === id,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
setSubMenu(foundMenu);
|
|
|
|
|
|
setOpenSubMenu(true);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const linkStyle =
|
|
|
|
|
|
"flex w-full py-4 px-2 justify-between hover:bg-inherit rounded-none h-fit border-b font-semibold hover:no-underline text-sm leading-relaxed";
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Fragment>
|
|
|
|
|
|
<nav className="h-15 border-b bg-background">
|
|
|
|
|
|
<div className="flex h-full items-center gap-4 px-4">
|
|
|
|
|
|
<Logo url="https://ShadcnBlocks">
|
|
|
|
|
|
<LogoImage
|
|
|
|
|
|
src="/block-media/shadcnblocks/block/logos/ShadcnBlockscom-icon.svg"
|
|
|
|
|
|
alt="لوگو"
|
|
|
|
|
|
className="size-8 dark:invert"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Logo>
|
|
|
|
|
|
<div className="ms-auto flex items-center gap-2">
|
|
|
|
|
|
<SecondaryNav />
|
|
|
|
|
|
<Button onClick={handleSheet} size="icon" variant="ghost" aria-label="باز کردن منو">
|
|
|
|
|
|
<Menu />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
<Sheet open={open} onOpenChange={setOpen}>
|
|
|
|
|
|
<SheetContent
|
|
|
|
|
|
style={
|
|
|
|
|
|
{
|
|
|
|
|
|
"--padding-top": "1.25rem",
|
|
|
|
|
|
"--header-height": "2.25rem",
|
|
|
|
|
|
"--footer-height": "4rem",
|
|
|
|
|
|
"--sheet-width": "27.75rem",
|
|
|
|
|
|
} as CSSProperties
|
|
|
|
|
|
}
|
|
|
|
|
|
side="right"
|
|
|
|
|
|
className="w-full sm:max-w-[var(--sheet-width)] [&>button]:hidden"
|
|
|
|
|
|
aria-describedby={undefined}
|
|
|
|
|
|
onInteractOutside={(e: Event) => {
|
|
|
|
|
|
if (openMegaMenu) {
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="h-full pt-5">
|
|
|
|
|
|
<SheetHeader className="h-9 p-0 px-6">
|
|
|
|
|
|
<SheetTitle className="sr-only">منوی موبایل</SheetTitle>
|
|
|
|
|
|
<div className="flex items-center justify-between gap-5">
|
|
|
|
|
|
<SheetClose asChild>
|
|
|
|
|
|
<Button size="icon" variant="ghost" aria-label="بستن منو">
|
|
|
|
|
|
<X />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</SheetClose>
|
|
|
|
|
|
<Button variant="ghost">
|
|
|
|
|
|
<CircleUserRound />
|
|
|
|
|
|
ورود
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SheetHeader>
|
|
|
|
|
|
<div className="h-[calc(100dvh-var(--padding-top)-var(--header-height)-var(--footer-height))] overflow-auto">
|
|
|
|
|
|
<div className="px-6 py-5">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{menu.map(
|
|
|
|
|
|
({ megaMenu, id, label, accentColor, href }, index) =>
|
|
|
|
|
|
megaMenu ? (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className={linkStyle}
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
onClick={() => handleOnMenuItemClick(id)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{label}
|
|
|
|
|
|
<ChevronRight className="rtl:rotate-180" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<a
|
|
|
|
|
|
style={{
|
|
|
|
|
|
color: accentColor,
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={linkStyle}
|
|
|
|
|
|
href={href}
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
>
|
|
|
|
|
|
{label}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
),
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="mt-6 space-y-5">
|
|
|
|
|
|
<HelpfullLinks links={helpfulLinks} />
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<ContactInfoList links={contactInfo} />
|
|
|
|
|
|
<SocialMediaSection links={socialLinks} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<SheetFooter className="absolute inset-x-0 bottom-0 border-t bg-background px-6 py-4">
|
|
|
|
|
|
<CountrySelector className="w-full" />
|
|
|
|
|
|
</SheetFooter>
|
|
|
|
|
|
</SheetContent>
|
|
|
|
|
|
</Sheet>
|
|
|
|
|
|
<MegaMenuMobile
|
|
|
|
|
|
menuItem={menuItem}
|
|
|
|
|
|
open={openMegaMenu}
|
|
|
|
|
|
onOpenChange={handleMegaMenu}
|
|
|
|
|
|
openSubMenu={openSubMenu}
|
|
|
|
|
|
handleOnSubMenuClick={handleOnSubMenuClick}
|
|
|
|
|
|
linkStyle={linkStyle}
|
|
|
|
|
|
closeAll={closeAll}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<SubMenuMobile
|
|
|
|
|
|
subMenu={subMenu}
|
|
|
|
|
|
onOpenChange={handleSubMenu}
|
|
|
|
|
|
open={openSubMenu}
|
|
|
|
|
|
linkStyle={linkStyle}
|
|
|
|
|
|
closeAll={closeAll}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const MegaMenuMobile = ({
|
|
|
|
|
|
menuItem,
|
|
|
|
|
|
open,
|
|
|
|
|
|
onOpenChange,
|
|
|
|
|
|
openSubMenu,
|
|
|
|
|
|
handleOnSubMenuClick,
|
|
|
|
|
|
linkStyle,
|
|
|
|
|
|
closeAll,
|
|
|
|
|
|
}: MegaMenuMobileProps) => {
|
|
|
|
|
|
if (!menuItem) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Fragment>
|
|
|
|
|
|
<Sheet open={open} onOpenChange={onOpenChange} modal={false}>
|
|
|
|
|
|
<SheetContent
|
|
|
|
|
|
side="right"
|
|
|
|
|
|
aria-describedby={undefined}
|
|
|
|
|
|
className="w-full gap-0 overflow-auto px-6 pt-5 pb-10 sm:max-w-[27.75rem] [&>button]:hidden"
|
|
|
|
|
|
onInteractOutside={(e: Event) => {
|
|
|
|
|
|
if (openSubMenu) {
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<SheetHeader className="p-0">
|
|
|
|
|
|
<div className="flex items-center justify-between gap-5">
|
|
|
|
|
|
<Button onClick={closeAll} size="icon" variant="ghost" aria-label="بستن منو">
|
|
|
|
|
|
<X />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center py-4">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
onClick={(e: React.MouseEvent) => {
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
onOpenChange(false);
|
|
|
|
|
|
}}
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
aria-label="بازگشت"
|
|
|
|
|
|
>
|
|
|
|
|
|
<ChevronLeft className="rtl:rotate-180" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<SheetTitle className="flex-1 text-center text-sm">
|
|
|
|
|
|
{menuItem.label}
|
|
|
|
|
|
</SheetTitle>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SheetHeader>
|
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{menuItem?.megaMenu?.sections?.map(({ label, id }, index) => (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
handleOnSubMenuClick(id);
|
|
|
|
|
|
}}
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className={linkStyle}
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
>
|
|
|
|
|
|
{label}
|
|
|
|
|
|
<ChevronRight className="rtl:rotate-180" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="grid grid-cols-2 gap-4.5">
|
|
|
|
|
|
{menuItem?.megaMenu?.featuredItems?.map((item, index) => (
|
|
|
|
|
|
<MenuFeaturedLink key={index} {...item} />
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Button size="lg" className="w-full" variant="outline">
|
|
|
|
|
|
<a href={menuItem?.href}>مشاهده {menuItem?.label}</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SheetContent>
|
|
|
|
|
|
</Sheet>
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const SubMenuMobile = ({
|
|
|
|
|
|
subMenu,
|
|
|
|
|
|
open,
|
|
|
|
|
|
onOpenChange,
|
|
|
|
|
|
linkStyle,
|
|
|
|
|
|
closeAll,
|
|
|
|
|
|
}: SubMenuMobileProps) => {
|
|
|
|
|
|
if (!subMenu) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Sheet open={open} onOpenChange={onOpenChange} modal={false}>
|
|
|
|
|
|
<SheetContent
|
|
|
|
|
|
side="right"
|
|
|
|
|
|
aria-describedby={undefined}
|
|
|
|
|
|
className="w-full gap-0 overflow-auto sm:max-w-[27.75rem] [&>button]:hidden"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<AspectRatio ratio={1.77} className="overflow-hidden">
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={subMenu.imageSrc}
|
|
|
|
|
|
alt={subMenu.label}
|
|
|
|
|
|
className="block size-full object-cover object-center"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</AspectRatio>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="px-6 pt-5 pb-10">
|
|
|
|
|
|
<SheetHeader className="p-0">
|
|
|
|
|
|
<div className="flex items-center justify-between gap-5">
|
|
|
|
|
|
<Button onClick={closeAll} size="icon" variant="ghost" aria-label="بستن منو">
|
|
|
|
|
|
<X />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center py-4">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
onClick={(e: React.MouseEvent) => {
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
onOpenChange(false);
|
|
|
|
|
|
}}
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
aria-label="بازگشت"
|
|
|
|
|
|
>
|
|
|
|
|
|
<ChevronLeft className="rtl:rotate-180" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<SheetTitle className="flex-1 text-center text-sm">
|
|
|
|
|
|
{subMenu.label}
|
|
|
|
|
|
</SheetTitle>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SheetHeader>
|
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{subMenu?.items?.map(({ label, href }, index) => (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
asChild
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className={linkStyle}
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a href={href}>
|
|
|
|
|
|
{label}
|
|
|
|
|
|
<ChevronRight className="rtl:rotate-180" />
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Button size="lg" className="w-full" variant="outline">
|
|
|
|
|
|
<a href={subMenu?.href}>مشاهده {subMenu?.label}</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SheetContent>
|
|
|
|
|
|
</Sheet>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const SocialMediaSection = ({ links }: SocialMediaSectionProps) => {
|
|
|
|
|
|
if (!links) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<ul className="flex flex-wrap">
|
|
|
|
|
|
{links.map(({ icon, href }) => (
|
|
|
|
|
|
<li key={crypto.randomUUID()}>
|
|
|
|
|
|
<Button size="icon" variant="ghost" asChild className="rounded-full">
|
|
|
|
|
|
<a href={href}>
|
|
|
|
|
|
<img
|
|
|
|
|
|
className="hidden size-4 dark:block"
|
|
|
|
|
|
alt={icon.title}
|
|
|
|
|
|
src={icon.dark}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<img
|
|
|
|
|
|
className="size-4 dark:hidden"
|
|
|
|
|
|
alt={icon.title}
|
|
|
|
|
|
src={icon.light}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const HelpfullLinks = ({ links }: HelpfullLinksProps) => {
|
|
|
|
|
|
if (!links) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<ul className="flex flex-col">
|
|
|
|
|
|
{links.map(({ href, label }, index) => (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
asChild
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className="justify-start px-1 text-xs font-semibold text-muted-foreground"
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a href={href}>{label}</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const ContactInfoList = ({ links }: ContactInfoListProps) => {
|
|
|
|
|
|
if (!links) return;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<ul className="flex flex-col">
|
|
|
|
|
|
{links.map((item, index) => (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
asChild
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
className="justify-start px-1 text-xs font-semibold text-muted-foreground"
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a href={item.href}>
|
|
|
|
|
|
<item.icon />
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export { EcommerceNavbar1 };
|