303 lines
9.1 KiB
TypeScript
303 lines
9.1 KiB
TypeScript
"use client";
|
|
import { Book, Menu, Sunset, Trees, Zap } from "lucide-react";
|
|
|
|
import {
|
|
Accordion,
|
|
AccordionContent,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from "@/components/ui/accordion";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
NavigationMenu,
|
|
NavigationMenuContent,
|
|
NavigationMenuItem,
|
|
NavigationMenuLink,
|
|
NavigationMenuList,
|
|
NavigationMenuTrigger,
|
|
} from "@/components/ui/navigation-menu";
|
|
import {
|
|
Sheet,
|
|
SheetContent,
|
|
SheetHeader,
|
|
SheetTitle,
|
|
SheetTrigger,
|
|
} from "@/components/ui/sheet";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface MenuItem {
|
|
title: string;
|
|
url: string;
|
|
description?: string;
|
|
icon?: React.ReactNode;
|
|
items?: MenuItem[];
|
|
}
|
|
|
|
interface Navbar2Props {
|
|
logo?: {
|
|
url: string;
|
|
src: string;
|
|
alt: string;
|
|
title: string;
|
|
className?: string;
|
|
};
|
|
menu?: MenuItem[];
|
|
auth?: {
|
|
login: {
|
|
title: string;
|
|
url: string;
|
|
};
|
|
signup: {
|
|
title: string;
|
|
url: string;
|
|
};
|
|
};
|
|
className?: string;
|
|
}
|
|
|
|
const Navbar2 = ({
|
|
logo = {
|
|
url: "https://www.ShadcnBlocks",
|
|
src: "/block-media/shadcnblocks/block/logos/ShadcnBlockscom-icon.svg",
|
|
alt: "لوگو",
|
|
title: "وندوک",
|
|
},
|
|
menu = [
|
|
{ title: "خانه", url: "#" },
|
|
{
|
|
title: "محصولات",
|
|
url: "#",
|
|
items: [
|
|
{
|
|
title: "وبلاگ",
|
|
description: "بینش فروش، گزارش محصول و روندهای سامانه مدیریت ارتباط با مشتری",
|
|
icon: <Book className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "شرکت",
|
|
description: "مأموریت ما شفافسازی پایپلاین فروش B2B است",
|
|
icon: <Trees className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "فرصتهای شغلی",
|
|
description: "موقعیتهای باز در تیم محصول و درآمد",
|
|
icon: <Sunset className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "پشتیبانی",
|
|
description: "با تیم موفقیت مشتری صحبت کنید یا راهنما را ببینید",
|
|
icon: <Zap className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "منابع",
|
|
url: "#",
|
|
items: [
|
|
{
|
|
title: "مرکز راهنما",
|
|
description: "راهاندازی سامانه مدیریت ارتباط با مشتری، واردات داده و بهترین روشها",
|
|
icon: <Zap className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "تماس با ما",
|
|
description: "برای دمو، قیمتگذاری و مهاجرت سامانه مدیریت ارتباط با مشتری آمادهایم",
|
|
icon: <Sunset className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "وضعیت سرویس",
|
|
description: "وضعیت فعلی پلتفرم و یکپارچهسازیها",
|
|
icon: <Trees className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
{
|
|
title: "شرایط استفاده",
|
|
description: "قوانین استفاده از وندوک",
|
|
icon: <Book className="size-5 shrink-0" />,
|
|
url: "#",
|
|
},
|
|
],
|
|
},
|
|
{ title: "قیمتگذاری", url: "#" },
|
|
{ title: "وبلاگ", url: "#" },
|
|
],
|
|
auth = {
|
|
login: { title: "ورود", url: "#" },
|
|
signup: { title: "شروع رایگان", url: "#" },
|
|
},
|
|
className,
|
|
}: Navbar2Props) => {
|
|
return (
|
|
<section
|
|
lang="fa"
|
|
className={cn("overflow-visible py-4 text-start", className)}
|
|
>
|
|
<div className="container">
|
|
<nav className="relative z-10 hidden justify-between overflow-visible lg:flex">
|
|
<a href={logo.url} className="flex items-center gap-2">
|
|
<img src={logo.src} className="max-h-8" alt={logo.alt} />
|
|
<span className="text-lg font-semibold tracking-tighter">
|
|
{logo.title}
|
|
</span>
|
|
</a>
|
|
<div className="flex items-center gap-6">
|
|
<NavigationMenu
|
|
dir="rtl"
|
|
viewport={false}
|
|
className="relative z-50 max-w-none overflow-visible"
|
|
>
|
|
<NavigationMenuList>
|
|
{menu.map((item) => renderMenuItem(item))}
|
|
</NavigationMenuList>
|
|
</NavigationMenu>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<Button asChild variant="outline" size="sm">
|
|
<a href={auth.login.url}>{auth.login.title}</a>
|
|
</Button>
|
|
<Button asChild size="sm">
|
|
<a href={auth.signup.url}>{auth.signup.title}</a>
|
|
</Button>
|
|
</div>
|
|
</nav>
|
|
|
|
<div className="block lg:hidden">
|
|
<div className="flex items-center justify-between">
|
|
<a href={logo.url} className="flex items-center gap-2">
|
|
<img src={logo.src} className="max-h-8" alt={logo.alt} />
|
|
</a>
|
|
<Sheet>
|
|
<SheetTrigger asChild>
|
|
<Button
|
|
variant="outline"
|
|
size="icon"
|
|
aria-label="باز کردن منو"
|
|
>
|
|
<Menu className="size-4" />
|
|
</Button>
|
|
</SheetTrigger>
|
|
<SheetContent
|
|
dir="rtl"
|
|
className="overflow-y-auto text-start"
|
|
>
|
|
<SheetHeader>
|
|
<SheetTitle>
|
|
<a href={logo.url} className="flex items-center gap-2">
|
|
<img src={logo.src} className="max-h-8" alt={logo.alt} />
|
|
</a>
|
|
</SheetTitle>
|
|
</SheetHeader>
|
|
<div className="flex flex-col gap-6 p-4">
|
|
<Accordion
|
|
type="single"
|
|
collapsible
|
|
dir="rtl"
|
|
className="flex w-full flex-col gap-4 text-start"
|
|
>
|
|
{menu.map((item) => renderMobileMenuItem(item))}
|
|
</Accordion>
|
|
<div className="flex flex-col gap-3">
|
|
<Button asChild variant="outline">
|
|
<a href={auth.login.url}>{auth.login.title}</a>
|
|
</Button>
|
|
<Button asChild>
|
|
<a href={auth.signup.url}>{auth.signup.title}</a>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</SheetContent>
|
|
</Sheet>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
const renderMenuItem = (item: MenuItem) => {
|
|
if (item.items) {
|
|
return (
|
|
<NavigationMenuItem key={item.title} className="relative">
|
|
<NavigationMenuTrigger className="text-start [&_svg]:ms-1 [&_svg]:!me-0 [&_svg]:!ml-0">
|
|
{item.title}
|
|
</NavigationMenuTrigger>
|
|
<NavigationMenuContent
|
|
dir="rtl"
|
|
className="start-0 end-auto left-auto z-50 !w-80 max-w-[calc(100vw-2rem)] text-start"
|
|
>
|
|
{item.items.map((subItem) => (
|
|
<NavigationMenuLink asChild key={subItem.title}>
|
|
<SubMenuLink item={subItem} />
|
|
</NavigationMenuLink>
|
|
))}
|
|
</NavigationMenuContent>
|
|
</NavigationMenuItem>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<NavigationMenuItem key={item.title}>
|
|
<NavigationMenuLink
|
|
href={item.url}
|
|
className="group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-start text-sm font-medium transition-colors hover:bg-muted hover:text-accent-foreground"
|
|
>
|
|
{item.title}
|
|
</NavigationMenuLink>
|
|
</NavigationMenuItem>
|
|
);
|
|
};
|
|
|
|
const renderMobileMenuItem = (item: MenuItem) => {
|
|
if (item.items) {
|
|
return (
|
|
<AccordionItem key={item.title} value={item.title} className="border-b-0">
|
|
<AccordionTrigger className="justify-start py-0 text-start text-base font-semibold hover:no-underline [&>svg]:ms-auto [&>svg]:me-0">
|
|
{item.title}
|
|
</AccordionTrigger>
|
|
<AccordionContent className="mt-2 text-start">
|
|
{item.items.map((subItem) => (
|
|
<SubMenuLink key={subItem.title} item={subItem} />
|
|
))}
|
|
</AccordionContent>
|
|
</AccordionItem>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<a
|
|
key={item.title}
|
|
href={item.url}
|
|
className="block text-start text-base font-semibold"
|
|
>
|
|
{item.title}
|
|
</a>
|
|
);
|
|
};
|
|
|
|
const SubMenuLink = ({ item }: { item: MenuItem }) => {
|
|
return (
|
|
<a
|
|
className="flex w-full flex-row gap-4 rounded-md p-3 text-start leading-none no-underline transition-colors outline-none select-none hover:bg-muted hover:text-accent-foreground"
|
|
href={item.url}
|
|
>
|
|
<div className="shrink-0 text-muted-foreground">{item.icon}</div>
|
|
<div className="min-w-0">
|
|
<div className="text-sm font-semibold">{item.title}</div>
|
|
{item.description && (
|
|
<p className="text-sm leading-snug text-muted-foreground">
|
|
{item.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</a>
|
|
);
|
|
};
|
|
|
|
export { Navbar2 };
|