"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 (
{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)} />
);
}