/** * KnowledgeTab — Qdrant-backed knowledge entry list with pagination and preview. * * Works with KnowledgeEntry domain entities via application mapper layer. * Components never access raw Qdrant payloads. * * (c) 2026 TWWIM UG. All rights reserved. (www.twwim.com) */ import { useState } from 'react'; import { FileText, Trash2, Plus, Search, X, Upload, AlertCircle, Database, ShieldAlert, ChevronLeft, ChevronRight, Eye, } from 'lucide-react'; import { useKnowledgeEntries, useCreateKnowledgeEntry, useDeleteKnowledgeEntry } from '../hooks'; import { useTranslation } from '@/i18n/TranslationProvider'; import { EntryPreviewModal } from './EntryPreviewModal'; import { KnowledgeDocumentsTab } from './KnowledgeDocumentsTab'; import { KnowledgeEntry, KnowledgeEntryType, KnowledgeSource } from '@/domain/entities/KnowledgeEntry'; import type { CreateEntryInput } from '@/infrastructure/http/api/knowledge'; const TYPE_COLORS: Record = { [KnowledgeEntryType.PRODUCT]: { bg: 'bg-blue-100', text: 'text-blue-800' }, [KnowledgeEntryType.PAGE]: { bg: 'bg-green-100', text: 'text-green-800' }, [KnowledgeEntryType.DOCUMENT]: { bg: 'bg-purple-100', text: 'text-purple-800' }, [KnowledgeEntryType.FAQ]: { bg: 'bg-amber-100', text: 'text-amber-800' }, [KnowledgeEntryType.CUSTOM]: { bg: 'bg-gray-100', text: 'text-gray-800' }, }; const SOURCE_COLORS: Record = { [KnowledgeSource.WORDPRESS]: { bg: 'bg-indigo-100', text: 'text-indigo-800' }, [KnowledgeSource.SHOPIFY]: { bg: 'bg-green-100', text: 'text-green-800' }, [KnowledgeSource.MANUAL]: { bg: 'bg-gray-100', text: 'text-gray-700' }, }; function TypeBadge({ type }: { type: string }) { const colors = TYPE_COLORS[type] || TYPE_COLORS[KnowledgeEntryType.CUSTOM]; return ( {type} ); } function SourceBadge({ source }: { source: string }) { const colors = SOURCE_COLORS[source] || SOURCE_COLORS[KnowledgeSource.MANUAL]; return ( {source} ); } function AddEntryForm({ tenantId, defaultType, onClose, }: { tenantId: string; defaultType: CreateEntryInput['type']; onClose: () => void; }) { const { t } = useTranslation(); const createMutation = useCreateKnowledgeEntry(tenantId); const [title, setTitle] = useState(''); const [content, setContent] = useState(''); const [url, setUrl] = useState(''); const [category, setCategory] = useState(''); const isFaq = defaultType === KnowledgeEntryType.FAQ; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!title.trim() || !content.trim()) return; createMutation.mutate( { type: defaultType, title: title.trim(), content: content.trim(), ...(!isFaq && url.trim() ? { url: url.trim() } : {}), ...(!isFaq && category.trim() ? { category: category.trim() } : {}), }, { onSuccess: () => onClose() }, ); }; return (

{t('knowledge.addEntry')}

{!isFaq && (
setCategory(e.target.value)} placeholder={t('common.optional')} className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none" />
)}
setTitle(e.target.value)} placeholder={isFaq ? t('knowledge.questionPlaceholder') : t('knowledge.titlePlaceholder')} className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none" required />