Files
reui-blocks/blocks/settings-integrations4.tsx
T

219 lines
7.4 KiB
TypeScript

"use client";
import { useState } from "react";
import { ScrollableTabsList } from "@/components/shadcnblocks/scrollable-tabslist";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { cn } from "@/lib/utils";
interface IntegrationItem {
image: string;
title: string;
description: string;
isConnected?: boolean;
category: string;
className?: string;
}
interface IntegrationCardProps {
integration: IntegrationItem;
onToggle?: (title: string) => void;
}
const IntegrationCard = ({ integration, onToggle }: IntegrationCardProps) => {
return (
<div className="flex items-start gap-4 rounded-lg border p-4 text-start">
<img
src={integration.image}
alt={`آیکون ${integration.title}`}
className={cn("size-10 shrink-0", integration.className)}
/>
<div className="min-w-0 flex-1 space-y-1">
<p className="font-medium">{integration.title}</p>
<p className="text-sm text-muted-foreground">
{integration.description}
</p>
</div>
<div className="flex shrink-0 flex-col items-end gap-2 sm:flex-row sm:items-center">
{integration.isConnected && (
<Badge variant="secondary" className="bg-green-100 text-green-800">
متصل
</Badge>
)}
<Button
variant={integration.isConnected ? "outline" : "default"}
size="sm"
onClick={() => onToggle?.(integration.title)}
>
{integration.isConnected ? "قطع اتصال" : "اتصال"}
</Button>
</div>
</div>
);
};
interface SettingsIntegrations4Props {
className?: string;
heading?: string;
subHeading?: string;
integrations?: IntegrationItem[];
}
const SettingsIntegrations4 = ({
className,
heading = "یکپارچه‌سازی‌ها",
subHeading = "کانال‌های فروش، فایل‌ها و پرداخت را به فضای کاری سامانه مدیریت ارتباط با مشتری وصل کنید.",
integrations: initialIntegrations = [
{
image:
"/block-media/shadcnblocks/block/logos/slack-icon.svg",
title: "Slack",
description: "هشدار لید و تیکت را لحظه‌ای به کانال تیم بفرستید.",
isConnected: true,
category: "communication",
},
{
image:
"/block-media/shadcnblocks/block/logos/discord-icon.svg",
title: "Discord",
description: "هشدارهای پایپ‌لاین را به سرور تیم بفرستید.",
category: "communication",
},
{
image:
"/block-media/shadcnblocks/block/logos/microsoft-teams-icon.svg",
title: "Microsoft Teams",
description: "گفتگوهای فروش را در Teams ادامه دهید.",
category: "communication",
},
{
image:
"/block-media/shadcnblocks/block/logos/google-icon.svg",
title: "Google Drive",
description: "اسناد معامله را با رکوردهای سامانه مدیریت ارتباط با مشتری همگام کنید.",
isConnected: true,
category: "storage",
},
{
image:
"/block-media/shadcnblocks/block/logos/dropbox-icon.svg",
title: "Dropbox",
description: "اسناد قرارداد را امن ذخیره و اشتراک بگذارید.",
category: "storage",
},
{
image:
"/block-media/shadcnblocks/block/logos/microsoft-onedrive-icon.svg",
title: "OneDrive",
description: "فایل‌های مشتری را از OneDrive به سامانه مدیریت ارتباط با مشتری بیاورید.",
category: "storage",
},
{
image:
"/block-media/shadcnblocks/block/logos/github-icon.svg",
title: "GitHub",
description: "وب‌هوک مخزن را به گردش‌کار محصول وصل کنید.",
isConnected: true,
category: "development",
className: "dark:invert",
},
{
image:
"/block-media/shadcnblocks/block/logos/gitlab-icon.svg",
title: "GitLab",
description: "خط لوله استقرار را با رویدادهای محصول همگام کنید.",
category: "development",
},
{
image:
"/block-media/shadcnblocks/block/logos/vercel-icon.svg",
title: "Vercel",
description: "لندینگ و پورتال مشتری را مستقر و پیش‌نمایش کنید.",
category: "development",
className: "dark:invert",
},
{
image:
"/block-media/shadcnblocks/block/logos/stripe-icon.svg",
title: "Stripe",
description: "پرداخت و اشتراک مشتری را از سامانه مدیریت ارتباط با مشتری پیگیری کنید.",
isConnected: true,
category: "payments",
},
{
image:
"/block-media/shadcnblocks/block/logos/paypal-icon.svg",
title: "PayPal",
description: "پرداخت آنلاین مشتریان را بپذیرید و ثبت کنید.",
category: "payments",
},
],
}: SettingsIntegrations4Props) => {
const [integrations, setIntegrations] = useState(initialIntegrations);
const categories = [...new Set(integrations.map((i) => i.category))];
const handleToggle = (title: string) => {
setIntegrations((prev) =>
prev.map((i) =>
i.title === title ? { ...i, isConnected: !i.isConnected } : i,
),
);
};
const getCategoryLabel = (category: string) => {
const labels: Record<string, string> = {
communication: "ارتباطات تیمی",
storage: "فایل و اسناد",
development: "مهندسی",
payments: "پرداخت و صورتحساب",
};
return labels[category] ?? category;
};
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container max-w-4xl">
<div className="space-y-2 border-b pb-6 text-start">
<h2 className="text-xl font-semibold tracking-tight">{heading}</h2>
<p className="text-sm text-muted-foreground">{subHeading}</p>
</div>
<Tabs defaultValue={categories[0]} className="mt-6">
<div className="flex w-full justify-start">
<ScrollableTabsList className="rounded-none [&_[data-slot=scroll-area-viewport]]:dir-rtl">
<TabsList className="justify-start overflow-y-hidden">
{categories.map((category) => (
<TabsTrigger key={category} value={category}>
{getCategoryLabel(category)}
</TabsTrigger>
))}
</TabsList>
</ScrollableTabsList>
</div>
{categories.map((category) => (
<TabsContent key={category} value={category} className="mt-6 text-start">
<div className="space-y-4">
{integrations
.filter((i) => i.category === category)
.map((integration) => (
<IntegrationCard
key={integration.title}
integration={integration}
onToggle={handleToggle}
/>
))}
</div>
</TabsContent>
))}
</Tabs>
</div>
</section>
);
};
export { SettingsIntegrations4 };