import { ExternalLink, BookmarkPlus, BookmarkCheck, Copy } from 'lucide-react'; import { clsx } from 'clsx'; import toast from 'react-hot-toast'; import { useBibliographyStore } from '../store/bibliography'; import type { SearchSource } from '../types'; interface SourceCardProps { source: SearchSource; } const SOURCE_DB_LABELS: Record = { openalex: 'OpenAlex', cyberleninka: 'КиберЛенинка', arxiv: 'arXiv', wikipedia_ru: 'Wikipedia RU', wikipedia_en: 'Wikipedia EN', }; function getRelevanceColor(score: number): string { if (score >= 0.7) return 'text-green-700 bg-green-50 border-green-200'; if (score >= 0.4) return 'text-yellow-700 bg-yellow-50 border-yellow-200'; return 'text-gray-600 bg-gray-50 border-gray-200'; } export function SourceCard({ source }: SourceCardProps) { const { addSource, removeSource, hasSource } = useBibliographyStore(); const inBibliography = hasSource(source.id); const handleToggleBibliography = () => { if (inBibliography) { removeSource(source.id); toast.success('Удалено из библиографии'); } else { addSource(source); toast.success('Добавлено в библиографию'); } }; const handleCopyCitation = () => { navigator.clipboard.writeText(source.gost_citation).then(() => { toast.success('ГОСТ-цитата скопирована'); }); }; const authorsStr = source.authors .slice(0, 3) .map((a) => `${a.last_name} ${a.initials || ''}`.trim()) .join(', '); return (
{/* Заголовок и значки */}

{source.title}

{authorsStr && ( {authorsStr} )} {source.year && ( {source.year} )} {source.journal && ( {source.journal} )}
{/* Бейдж релевантности */}
{(source.relevance_score * 100).toFixed(0)}%
{/* Аннотация */} {source.abstract && (

{source.abstract}

)} {/* ГОСТ-цитата */}

ГОСТ-цитата:

{source.gost_citation}

{/* Действия */}
{/* Источник */} {SOURCE_DB_LABELS[source.source_db] || source.source_db}
{/* Открыть источник */} {source.url && ( Открыть )} {/* Копировать цитату */} {/* В библиографию */}
); }