219 lines
7.4 KiB
TypeScript
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 };
|