"use client"; import { useSetAtom } from "jotai"; import { Boxes, RefreshCw, TriangleAlert } from "lucide-react"; import { useMemo, useState } from "react"; import { openReportPanelAtom } from "@/atoms/chat/report-panel.atom"; import { MobileReportPanel } from "@/components/report-panel/report-panel"; import { Button } from "@/components/ui/button"; import { useLibraryArtifacts } from "../hooks/use-library-artifacts"; import type { LibraryArtifact, LibraryArtifactKind } from "../model/artifact"; import { ArtifactCard } from "./artifact-card"; import { KIND_META, KIND_ORDER } from "./kind-meta"; import { MediaViewerDialog } from "./media-viewer-dialog"; const SKELETON_KEYS = ["s1", "s2", "s3", "s4", "s5", "s6"]; function LoadingState() { return (
{SKELETON_KEYS.map((key) => (
))}
); } function ErrorState({ onRetry }: { onRetry: () => void }) { return (

Couldn't load artifacts

Something went wrong fetching this search space's deliverables.

); } function EmptyState() { return (

No artifacts yet

Reports, resumes, podcasts, presentations, and images you generate appear here.

); } export function ArtifactsLibrary({ searchSpaceId }: { searchSpaceId: number }) { const { artifacts, loading, error, refresh } = useLibraryArtifacts(searchSpaceId); const openReportPanel = useSetAtom(openReportPanelAtom); const [selectedMedia, setSelectedMedia] = useState(null); const grouped = useMemo(() => { const map = new Map(); for (const artifact of artifacts) { const bucket = map.get(artifact.kind); if (bucket) bucket.push(artifact); else map.set(artifact.kind, [artifact]); } return map; }, [artifacts]); const handleOpen = (artifact: LibraryArtifact) => { // Reports/resumes reuse the shared report panel; the rest open in the dialog. if (artifact.kind === "report" || artifact.kind === "resume") { openReportPanel({ reportId: artifact.entityId, title: artifact.title, contentType: artifact.contentType, }); return; } setSelectedMedia(artifact); }; return (

Artifacts

Every deliverable created across this search space.

{!loading && artifacts.length > 0 ? ( {artifacts.length} total ) : null}
{loading ? ( ) : error ? ( refresh()} /> ) : artifacts.length === 0 ? ( ) : (
{KIND_ORDER.map((kind) => { const items = grouped.get(kind); if (!items || items.length === 0) return null; return (

{KIND_META[kind].group} {items.length}

{items.map((artifact) => ( ))}
); })}
)} setSelectedMedia(null)} />
); }