'use client'; import { Loader2 } from 'lucide-react'; import type { AggregatedGroup } from '@/hooks/use-aggregated-listing'; interface AggregatedSectionProps { title: string; icon?: React.ReactNode; groups: AggregatedGroup[]; renderRow: (item: T, group: AggregatedGroup) => React.ReactNode; emptyMessage?: string; loading?: boolean; onShowAll?: (group: AggregatedGroup) => void; } /** * Renders a Signing or Files section with one labelled subsection per * owner-source group. Each group shows up to 20 rows; a `Show all (N)` * link drills into the source-scoped flat list. Hidden when groups is * empty. */ export function AggregatedSection({ title, icon, groups, renderRow, emptyMessage = 'Nothing here yet.', loading, onShowAll, }: AggregatedSectionProps) { const total = groups.reduce((sum, g) => sum + g.total, 0); if (loading) { return (

{icon} {title}

); } if (groups.length === 0) { return (

{icon} {title} · 0

{emptyMessage}

); } return (

{icon} {title} · {total}

{groups.map((g) => ( ))}
); } function GroupBlock({ group, renderRow, onShowAll, }: { group: AggregatedGroup; renderRow: (item: T, group: AggregatedGroup) => React.ReactNode; onShowAll?: (group: AggregatedGroup) => void; }) { const items = (group.files ?? group.workflows ?? []) as T[]; return (
{group.label} · {group.total}
    {items.map((item) => (
  • {renderRow(item, group)}
  • ))}
{group.total > items.length ? ( ) : null}
); }