270 lines
9.5 KiB
TypeScript
270 lines
9.5 KiB
TypeScript
"use client";
|
|
|
|
import { ChevronRight, Circle, Search } from "lucide-react";
|
|
import { useMemo, useState } from "react";
|
|
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Input } from "@/components/ui/input";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface IntegrationItem {
|
|
image: string;
|
|
title: string;
|
|
description: string;
|
|
isConnected?: boolean;
|
|
category: string;
|
|
className?: string;
|
|
}
|
|
|
|
interface SettingsIntegrations8Props {
|
|
className?: string;
|
|
heading?: string;
|
|
subHeading?: string;
|
|
integrations?: IntegrationItem[];
|
|
}
|
|
|
|
const SettingsIntegrations8 = ({
|
|
className,
|
|
heading = "یکپارچهسازیها",
|
|
subHeading = "ابزارهای موردنیاز تیم فروش را پیدا و به سامانه مدیریت ارتباط با مشتری متصل کنید.",
|
|
integrations = [
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/slack-icon.svg",
|
|
title: "Slack",
|
|
description: "هشدار لید و تیکت را به کانال تیم بفرستید",
|
|
isConnected: true,
|
|
category: "ارتباطات تیمی",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/discord-icon.svg",
|
|
title: "Discord",
|
|
description: "بهروزرسانی پایپلاین را در سرور تیم منتشر کنید",
|
|
category: "ارتباطات تیمی",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/microsoft-teams-icon.svg",
|
|
title: "Microsoft Teams",
|
|
description: "گفتگو و هماهنگی فروش در Teams",
|
|
isConnected: true,
|
|
category: "ارتباطات تیمی",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/google-icon.svg",
|
|
title: "Google Drive",
|
|
description: "اسناد معامله را همگام کنید",
|
|
isConnected: true,
|
|
category: "فایل و اسناد",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/dropbox-icon.svg",
|
|
title: "Dropbox",
|
|
description: "فضای فایل امن برای اسناد مشتری",
|
|
category: "فایل و اسناد",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/microsoft-onedrive-icon.svg",
|
|
title: "OneDrive",
|
|
description: "همگامسازی فایلهای OneDrive",
|
|
category: "فایل و اسناد",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/github-icon.svg",
|
|
title: "GitHub",
|
|
description: "مخزن کد و همکاری مهندسی",
|
|
isConnected: true,
|
|
category: "مهندسی",
|
|
className: "dark:invert",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/gitlab-icon.svg",
|
|
title: "GitLab",
|
|
description: "CI/CD و تحویل محصول",
|
|
category: "مهندسی",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/vercel-icon.svg",
|
|
title: "Vercel",
|
|
description: "استقرار لندینگ و پورتال",
|
|
category: "مهندسی",
|
|
className: "dark:invert",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/figma-icon.svg",
|
|
title: "Figma",
|
|
description: "داراییهای بصری کمپین",
|
|
isConnected: true,
|
|
category: "طراحی محصول",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/notion-icon.svg",
|
|
title: "Notion",
|
|
description: "دانش و پلیبوک فروش",
|
|
category: "عملیات فروش",
|
|
className: "dark:invert",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/linear-icon.svg",
|
|
title: "Linear",
|
|
description: "پیگیری کارهای محصول",
|
|
isConnected: true,
|
|
category: "عملیات فروش",
|
|
className: "dark:invert",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/jira-icon.svg",
|
|
title: "Jira",
|
|
description: "هماهنگی تحویل پروژه",
|
|
category: "عملیات فروش",
|
|
},
|
|
{
|
|
image:
|
|
"/block-media/shadcnblocks/block/logos/stripe-icon.svg",
|
|
title: "Stripe",
|
|
description: "پرداخت و صورتحساب",
|
|
isConnected: true,
|
|
category: "پرداخت و صورتحساب",
|
|
},
|
|
],
|
|
}: SettingsIntegrations8Props) => {
|
|
const [searchValue, setSearchValue] = useState("");
|
|
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
|
|
|
const categories = useMemo(() => {
|
|
return [...new Set(integrations.map((i) => i.category))];
|
|
}, [integrations]);
|
|
|
|
const filteredIntegrations = useMemo(() => {
|
|
return integrations.filter((integration) => {
|
|
const matchesSearch =
|
|
!searchValue ||
|
|
integration.title.toLowerCase().includes(searchValue.toLowerCase()) ||
|
|
integration.description
|
|
.toLowerCase()
|
|
.includes(searchValue.toLowerCase());
|
|
const matchesCategory =
|
|
!selectedCategory || integration.category === selectedCategory;
|
|
return matchesSearch && matchesCategory;
|
|
});
|
|
}, [integrations, searchValue, selectedCategory]);
|
|
|
|
const getCategoryCount = (category: string) => {
|
|
return integrations.filter((i) => i.category === category).length;
|
|
};
|
|
|
|
return (
|
|
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
|
|
<div className="container max-w-6xl">
|
|
<div className="mb-8 space-y-2 text-start">
|
|
<h1 className="text-3xl font-bold tracking-tight">{heading}</h1>
|
|
<p className="text-muted-foreground">{subHeading}</p>
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-6 lg:flex-row">
|
|
{/* Sidebar */}
|
|
<div className="w-full shrink-0 lg:w-56">
|
|
<div className="sticky top-8 space-y-4">
|
|
<div className="relative">
|
|
<Search className="absolute top-1/2 start-3 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
<Input
|
|
placeholder="جستجوی سرویس…"
|
|
className="ps-9"
|
|
value={searchValue}
|
|
onChange={(e) => setSearchValue(e.target.value)}
|
|
/>
|
|
</div>
|
|
<div className="space-y-1">
|
|
<button
|
|
onClick={() => setSelectedCategory(null)}
|
|
className={cn(
|
|
"flex w-full items-center justify-between rounded-md px-3 py-2 text-start text-sm transition-colors hover:bg-muted",
|
|
!selectedCategory && "bg-muted font-medium",
|
|
)}
|
|
>
|
|
<span>همه سرویسها</span>
|
|
<span className="text-muted-foreground">
|
|
{integrations.length.toLocaleString("fa-IR")}
|
|
</span>
|
|
</button>
|
|
{categories.map((category) => (
|
|
<button
|
|
key={category}
|
|
onClick={() => setSelectedCategory(category)}
|
|
className={cn(
|
|
"flex w-full items-center justify-between rounded-md px-3 py-2 text-start text-sm transition-colors hover:bg-muted",
|
|
selectedCategory === category && "bg-muted font-medium",
|
|
)}
|
|
>
|
|
<span>{category}</span>
|
|
<span className="text-muted-foreground">
|
|
{getCategoryCount(category).toLocaleString("fa-IR")}
|
|
</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Main content */}
|
|
<div className="flex-1">
|
|
<ScrollArea className="h-[600px] pe-4">
|
|
<div className="space-y-2">
|
|
{filteredIntegrations.map((integration) => (
|
|
<a
|
|
key={integration.title}
|
|
href="#"
|
|
className="group flex items-center gap-4 rounded-lg border p-4 text-start transition-colors hover:bg-muted/50"
|
|
>
|
|
<div className="flex size-12 shrink-0 items-center justify-center rounded-lg border bg-background">
|
|
<img
|
|
src={integration.image}
|
|
alt={`آیکون ${integration.title}`}
|
|
className={cn("size-7", integration.className)}
|
|
/>
|
|
</div>
|
|
<div className="min-w-0 flex-1 space-y-1 text-start">
|
|
<div className="flex flex-wrap items-center gap-2">
|
|
<span className="font-medium">{integration.title}</span>
|
|
{integration.isConnected && (
|
|
<Badge
|
|
variant="secondary"
|
|
className="bg-green-100 text-green-800"
|
|
>
|
|
<Circle className="me-1 size-2 fill-current" />
|
|
متصل
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">
|
|
{integration.description}
|
|
</p>
|
|
</div>
|
|
<ChevronRight
|
|
className="size-5 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 rtl:rotate-180"
|
|
/>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { SettingsIntegrations8 };
|