2025-07-03 15:19:48 +05:30
|
|
|
'use client';
|
|
|
|
|
|
2025-07-10 16:26:37 +05:30
|
|
|
import { useCallback } from 'react';
|
2025-07-03 15:19:48 +05:30
|
|
|
import { PictureImg } from '@/components/ui/picture-img';
|
|
|
|
|
import clsx from 'clsx';
|
|
|
|
|
import { z } from 'zod';
|
|
|
|
|
import { ZToolkit } from '@/app/lib/composio/composio';
|
2025-07-10 16:26:37 +05:30
|
|
|
import { Chip } from '@heroui/react';
|
|
|
|
|
import { LinkIcon } from 'lucide-react';
|
2025-07-23 15:37:49 +05:30
|
|
|
import { Workflow } from '@/app/lib/types/workflow_types';
|
2025-07-03 15:19:48 +05:30
|
|
|
|
|
|
|
|
type ToolkitType = z.infer<typeof ZToolkit>;
|
|
|
|
|
|
|
|
|
|
const toolkitCardStyles = {
|
|
|
|
|
base: clsx(
|
2025-07-10 16:26:37 +05:30
|
|
|
"group p-6 rounded-xl transition-all duration-200 cursor-pointer",
|
|
|
|
|
"bg-white dark:bg-gray-900",
|
|
|
|
|
"border border-gray-200 dark:border-gray-700",
|
|
|
|
|
"shadow-md dark:shadow-gray-900/20",
|
|
|
|
|
"hover:shadow-lg dark:hover:shadow-gray-900/30",
|
|
|
|
|
"hover:border-blue-300 dark:hover:border-blue-600",
|
|
|
|
|
"hover:bg-gray-50/50 dark:hover:bg-gray-800/50",
|
|
|
|
|
"hover:-translate-y-1",
|
|
|
|
|
"min-h-[200px] flex flex-col"
|
2025-07-03 15:19:48 +05:30
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface ToolkitCardProps {
|
|
|
|
|
toolkit: ToolkitType;
|
|
|
|
|
isConnected: boolean;
|
2025-07-23 15:37:49 +05:30
|
|
|
onSelectToolkit: () => void;
|
|
|
|
|
workflowTools: z.infer<typeof Workflow.shape.tools>;
|
2025-08-15 12:22:54 +08:00
|
|
|
showTriggerCounts?: boolean; // New prop to show trigger counts instead of tool counts
|
2025-07-03 15:19:48 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ToolkitCard({
|
|
|
|
|
toolkit,
|
|
|
|
|
isConnected,
|
2025-07-23 15:37:49 +05:30
|
|
|
onSelectToolkit,
|
|
|
|
|
workflowTools,
|
2025-08-15 12:22:54 +08:00
|
|
|
showTriggerCounts = false,
|
2025-07-03 15:19:48 +05:30
|
|
|
}: ToolkitCardProps) {
|
2025-07-10 16:26:37 +05:30
|
|
|
const handleCardClick = useCallback(() => {
|
2025-07-23 15:37:49 +05:30
|
|
|
onSelectToolkit();
|
|
|
|
|
}, [onSelectToolkit]);
|
2025-07-03 15:19:48 +05:30
|
|
|
|
|
|
|
|
// Calculate selected tools count for this toolkit
|
2025-07-23 15:37:49 +05:30
|
|
|
const selectedToolsCount = workflowTools
|
|
|
|
|
.filter(tool => tool.isComposio && tool.composioData?.toolkitSlug === toolkit.slug)
|
|
|
|
|
.length;
|
2025-07-03 15:19:48 +05:30
|
|
|
|
|
|
|
|
return (
|
2025-07-10 16:26:37 +05:30
|
|
|
<div className={toolkitCardStyles.base} onClick={handleCardClick}>
|
2025-07-03 15:19:48 +05:30
|
|
|
<div className="flex flex-col h-full">
|
2025-07-10 16:26:37 +05:30
|
|
|
{/* Header */}
|
|
|
|
|
<div className="flex items-start gap-3 mb-4">
|
|
|
|
|
{toolkit.meta.logo && (
|
|
|
|
|
<PictureImg
|
|
|
|
|
src={toolkit.meta.logo}
|
|
|
|
|
alt={`${toolkit.name} logo`}
|
|
|
|
|
className="w-8 h-8 rounded-md object-cover flex-shrink-0"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
<div className="flex-1 min-w-0">
|
|
|
|
|
<h3 className="font-semibold text-lg text-gray-900 dark:text-gray-100 truncate">
|
|
|
|
|
{toolkit.name}
|
|
|
|
|
</h3>
|
|
|
|
|
<div className="flex items-center gap-2 mt-1 flex-wrap">
|
|
|
|
|
<Chip
|
|
|
|
|
color="secondary"
|
|
|
|
|
variant="faded"
|
|
|
|
|
size="sm"
|
|
|
|
|
>
|
2025-08-15 12:22:54 +08:00
|
|
|
{showTriggerCounts
|
|
|
|
|
? `${toolkit.meta.triggers_count} triggers`
|
|
|
|
|
: selectedToolsCount > 0
|
|
|
|
|
? `${toolkit.meta.tools_count} tools, ${selectedToolsCount} selected`
|
|
|
|
|
: `${toolkit.meta.tools_count} tools`
|
2025-07-10 16:26:37 +05:30
|
|
|
}
|
|
|
|
|
</Chip>
|
2025-07-03 15:19:48 +05:30
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-07-10 16:26:37 +05:30
|
|
|
{/* Description */}
|
2025-07-03 15:19:48 +05:30
|
|
|
<div className="flex-1">
|
2025-07-10 16:26:37 +05:30
|
|
|
<p className="text-sm text-gray-600 dark:text-gray-400 line-clamp-3">
|
2025-07-03 15:19:48 +05:30
|
|
|
{toolkit.meta.description}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-07-10 16:26:37 +05:30
|
|
|
{/* Footer */}
|
|
|
|
|
<div className="mt-4 pt-4 border-t border-gray-100 dark:border-gray-700">
|
2025-07-03 15:19:48 +05:30
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex items-center gap-2">
|
2025-07-10 16:26:37 +05:30
|
|
|
{isConnected && !toolkit.no_auth && (
|
|
|
|
|
<Chip
|
|
|
|
|
color='success'
|
|
|
|
|
variant='flat'
|
|
|
|
|
size="sm"
|
|
|
|
|
startContent={<LinkIcon className="w-3 h-3 mr-1" />}
|
|
|
|
|
>
|
|
|
|
|
Connected
|
|
|
|
|
</Chip>
|
2025-07-03 15:19:48 +05:30
|
|
|
)}
|
2025-07-10 16:26:37 +05:30
|
|
|
{toolkit.no_auth && (
|
|
|
|
|
<Chip
|
|
|
|
|
color='success'
|
|
|
|
|
variant='flat'
|
|
|
|
|
size="sm"
|
|
|
|
|
>
|
|
|
|
|
Ready
|
|
|
|
|
</Chip>
|
2025-07-03 15:19:48 +05:30
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2025-07-10 16:26:37 +05:30
|
|
|
}
|