SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
2.6 KB · 57 lines tsx
Raw Blame History
1import Link from 'next/link';2import type { ReactNode } from 'react';3import { Badge, ClaimBadge } from '@/components/ui/badge';4import { SourceBadge, TableProvenance, type ProvenanceInfo } from '@/components/ui/source-badge';5import type { PublicationListRow } from '@/lib/queries/publications';6import { fmtDate, fmtInt } from '@/lib/format';78const PUBMED: ProvenanceInfo = { sourceSlug: 'pubmed', sourceName: 'PubMed (NLM)', dataset: 'PubMed E-utilities', layer: 'normalized' };910/**11 * Publication list. Bibliographic rows all come from PubMed, so one provenance popover sits in the12 * caption and each row carries a compact badge. Link method / validation status stay per row.13 * Layout classes live in globals.css (.ci-pub) — the list is repeated 25× per page.14 */15export function PublicationList({ rows, summary }: { rows: PublicationListRow[]; summary?: ReactNode }) {16  const latest = rows.reduce<Date | string | null>((m, p) => (m == null || String(p.updated_at) > String(m) ? p.updated_at : m), null);17  return (18    <div>19      <TableProvenance p={{ ...PUBMED, retrievedAt: latest }} claim={<ClaimBadge kind="published" />}>20        {summary ?? `${fmtInt(rows.length)} publication${rows.length === 1 ? '' : 's'}`} · bibliographic data as recorded by PubMed; abstracts are not reproduced.21      </TableProvenance>22      <ol className="ci-pubs">23        {rows.map((p) => (24          <li key={p.id} className="ci-pub">25            <div>26              {p.pmid ? (27                <Link href={`/publication/${p.pmid}`} className="ci-link font-medium">28                  {p.title}29                </Link>30              ) : (31                <span className="font-medium">{p.title}</span>32              )}33              {p.retracted ? <Badge tone="danger">Retracted</Badge> : null}34              {p.is_preprint ? <Badge tone="warn">Preprint</Badge> : null}35            </div>36            <p>37              {p.authors.map((a) => a.name).join(', ')}38              {p.author_count > 3 ? ' et al.' : ''}39              {p.journal_iso || p.journal ? ` · ${p.journal_iso ?? p.journal}` : ''}40              {p.pub_date ? ` · ${fmtDate(p.pub_date)}` : p.pub_year ? ` · ${p.pub_year}` : ''}41              {p.pmid ? ` · PMID ${p.pmid}` : ''}42              {p.edge_status ? (43                <>44                  {' · '}45                  <Badge tone={p.edge_status === 'validated' ? 'ok' : 'warn'}>{p.edge_status}</Badge>46                  {p.method ? <span className="ci-mono"> {p.method}</span> : null}47                </>48              ) : null}{' '}49              <SourceBadge compact title={null} p={PUBMED} />50            </p>51          </li>52        ))}53      </ol>54    </div>55  );56}57