'use client' import { useMemo, useState } from 'react' import { ChipTag } from '@sim/emcn' import { ArrowRight, Plus } from 'lucide-react' import { useParams } from 'next/navigation' import { SettingsEmptyState } from '@/app/workspace/[workspaceId]/settings/components/settings-empty-state' import { SettingsPanel } from '@/app/workspace/[workspaceId]/settings/components/settings-panel' import { SettingsResourceRow } from '@/app/workspace/[workspaceId]/settings/components/settings-resource-row/settings-resource-row' import { SettingsSection } from '@/app/workspace/[workspaceId]/settings/components/settings-section/settings-section' import { getCustomBlockIcon } from '@/blocks/custom/custom-block-icon' import { CustomBlockDetail } from '@/ee/custom-blocks/components/custom-block-detail' import { useWhitelabelSettings } from '@/ee/whitelabeling/hooks/whitelabel' import { useCanPublishCustomBlock, useCustomBlocks } from '@/hooks/queries/custom-blocks' import { useWorkspacesQuery } from '@/hooks/queries/workspace' export function CustomBlocks() { const params = useParams() const workspaceId = typeof params?.workspaceId === 'string' ? params.workspaceId : undefined const { data: canManage = false, isLoading } = useCanPublishCustomBlock(workspaceId) const { data: blocks = [] } = useCustomBlocks(workspaceId) const { data: workspaces = [] } = useWorkspacesQuery() // Any org member can view the org's blocks, but publishing requires admin on a // source workspace — the publish route enforces admin on the picked workspace. const currentOrgId = useMemo( () => workspaces.find((w) => w.id === workspaceId)?.organizationId ?? null, [workspaces, workspaceId] ) const canCreate = useMemo( () => !!currentOrgId && workspaces.some((w) => w.organizationId === currentOrgId && w.permissions === 'admin'), [workspaces, currentOrgId] ) const { data: whitelabel } = useWhitelabelSettings(blocks[0]?.organizationId) const fallbackIconUrl = whitelabel?.logoUrl ?? null const [searchTerm, setSearchTerm] = useState('') const [selected, setSelected] = useState(null) const filtered = useMemo(() => { if (!searchTerm.trim()) return blocks const q = searchTerm.toLowerCase() return blocks.filter((b) => b.name.toLowerCase().includes(q)) }, [blocks, searchTerm]) if (isLoading) return null if (!canManage) { return ( Custom blocks require an Enterprise plan. Contact your admin to enable them. ) } if (selected !== null && workspaceId) { return ( setSelected(null)} /> ) } return ( setSelected('new'), }, ] : [] } > {blocks.length === 0 ? ( {canCreate ? 'No custom blocks yet. Click "Create block" to publish a workflow as a block.' : 'No custom blocks yet.'} ) : filtered.length === 0 ? ( No blocks found matching "{searchTerm}" ) : (
{filtered.map((cb) => { const Icon = getCustomBlockIcon(cb.iconUrl, fallbackIconUrl) return ( ) })}
)}
) }