159 lines
5.9 KiB
TypeScript
159 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
BarChart,
|
|
Database,
|
|
Layers,
|
|
PieChart,
|
|
SquareKanban,
|
|
} from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
import { BorderBeam } from "@/components/magicui/border-beam";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export interface Tab {
|
|
title: string;
|
|
icon: React.ReactNode;
|
|
image: string;
|
|
}
|
|
|
|
export interface Hero195Props {
|
|
title: string;
|
|
description: string;
|
|
primaryButtonText: string;
|
|
secondaryButtonText?: string;
|
|
primaryButtonUrl: string;
|
|
secondaryButtonUrl?: string;
|
|
tabs?: Tab[];
|
|
className?: string;
|
|
}
|
|
|
|
const defaultTabs: Tab[] = [
|
|
{
|
|
title: "بینشها",
|
|
icon: <SquareKanban />,
|
|
image:
|
|
"/block-media/shadcnblocks/block/dashboard/admin-dashboard-1.png",
|
|
},
|
|
{
|
|
title: "معیارها",
|
|
icon: <BarChart />,
|
|
image:
|
|
"/block-media/shadcnblocks/block/dashboard/admin-dashboard-2.png",
|
|
},
|
|
{
|
|
title: "روندها",
|
|
icon: <PieChart />,
|
|
image:
|
|
"/block-media/shadcnblocks/block/dashboard/admin-dashboard-3.png",
|
|
},
|
|
{
|
|
title: "منابع",
|
|
icon: <Database />,
|
|
image:
|
|
"/block-media/shadcnblocks/block/dashboard/admin-users.png",
|
|
},
|
|
{
|
|
title: "مدلها",
|
|
icon: <Layers />,
|
|
image:
|
|
"/block-media/shadcnblocks/block/dashboard/admin-developer.png",
|
|
},
|
|
];
|
|
|
|
const Hero195 = ({
|
|
title = "مجموعه بلاکهای آماده رابط کاربری",
|
|
description = "صدها بلاک و کامپوننت آماده مبتنی بر رابط کاربری، استایلدهی مدرن و ری یو آی که مستقیماً در پروژههای شما قابل استفاده هستند.",
|
|
primaryButtonText = "دریافت کامپوننتها",
|
|
primaryButtonUrl = "https://ShadcnBlocks",
|
|
secondaryButtonUrl,
|
|
secondaryButtonText,
|
|
tabs = defaultTabs,
|
|
className,
|
|
}: Hero195Props) => {
|
|
const [activeTab, setActiveTab] = useState(tabs[0]?.title || "");
|
|
|
|
return (
|
|
<section className={cn("overflow-hidden", className)}>
|
|
<div className="container">
|
|
<div className="border-x border-border py-20">
|
|
<div className="relative mx-auto max-w-2xl p-2">
|
|
<h1 className="mx-1 mt-6 text-center text-2xll font-bold tracking-tighter md:text-2xll">
|
|
{title}
|
|
</h1>
|
|
<p className="mx-2 mt-6 max-w-xl text-center text-lg font-medium text-muted-foreground md:text-xl">
|
|
{description}
|
|
</p>
|
|
<div className="mx-2 mt-6 flex justify-center gap-2">
|
|
<Button asChild>
|
|
<a href={primaryButtonUrl}>{primaryButtonText}</a>
|
|
</Button>
|
|
{secondaryButtonText && (
|
|
<Button variant="outline" asChild>
|
|
<a href={secondaryButtonUrl}>{secondaryButtonText}</a>
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="mt-16 md:mt-20">
|
|
<Tabs defaultValue={tabs[0]?.title} onValueChange={setActiveTab}>
|
|
<div className="px-2">
|
|
<TabsList className="mx-auto mb-6 flex !h-auto w-fit max-w-xs flex-wrap justify-center gap-2 md:max-w-none">
|
|
{tabs.map((tab) => (
|
|
<TabsTrigger
|
|
key={tab.title}
|
|
value={tab.title}
|
|
className="font-normal text-muted-foreground"
|
|
>
|
|
{tab.icon}
|
|
{tab.title}
|
|
</TabsTrigger>
|
|
))}
|
|
</TabsList>
|
|
</div>
|
|
<div className="relative isolate">
|
|
<div className="relative z-10">
|
|
{tabs.map((tab) => (
|
|
<TabsContent
|
|
key={tab.title}
|
|
value={tab.title}
|
|
className={cn(
|
|
"-mx-px bg-background transition-opacity duration-500",
|
|
{
|
|
"animate-in opacity-100 fade-in":
|
|
activeTab === tab.title,
|
|
"opacity-0": activeTab !== tab.title,
|
|
},
|
|
)}
|
|
>
|
|
<img
|
|
src={tab.image}
|
|
alt={tab.title}
|
|
className="aspect-[16/10] w-full border border-border object-top shadow-[0_6px_20px_rgb(0,0,0,0.12)]"
|
|
/>
|
|
<BorderBeam duration={8} size={100} />
|
|
</TabsContent>
|
|
))}
|
|
</div>
|
|
<span className="absolute -inset-x-1/5 top-0 -z-10 h-px bg-border [mask-image:linear-gradient(to_right,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
<span className="absolute -inset-x-1/5 bottom-0 -z-10 h-px bg-border [mask-image:linear-gradient(to_right,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
|
|
<span className="absolute -inset-x-1/5 top-12 h-px border-t border-dashed border-border [mask-image:linear-gradient(to_right,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
<span className="absolute -inset-x-1/5 bottom-12 h-px border-t border-dashed border-border [mask-image:linear-gradient(to_right,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
|
|
<span className="absolute -inset-y-1/5 left-1/6 w-px border-r border-dashed border-border [mask-image:linear-gradient(to_bottom,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
<span className="absolute -inset-y-1/5 right-1/6 w-px border-r border-dashed border-border [mask-image:linear-gradient(to_bottom,transparent_1%,black_10%,black_90%,transparent_99%)]"></span>
|
|
</div>
|
|
</Tabs>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { Hero195 };
|