import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { getCollection, getCollectionItems, deleteCollection, removeCollectionItem, resolveHandle, } from "../../api/client"; import { Loader2, ArrowLeft, Trash2, Plus, ExternalLink } from "lucide-react"; import CollectionIcon from "../../components/common/CollectionIcon"; import ShareMenu from "../../components/modals/ShareMenu"; import Card from "../../components/common/Card"; import { useStore } from "@nanostores/react"; import { $user } from "../../store/auth"; import type { Collection, AnnotationItem } from "../../types"; import EditCollectionModal from "../../components/modals/EditCollectionModal"; import { Edit3 } from "lucide-react"; interface CollectionDetailProps { handle?: string; rkey?: string; uri?: string; } export default function CollectionDetail({ handle, rkey, uri, }: CollectionDetailProps) { const user = useStore($user); const [collection, setCollection] = useState(null); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isEditModalOpen, setIsEditModalOpen] = useState(false); useEffect(() => { const loadData = async () => { setLoading(true); try { let targetUri = uri; if (!targetUri && handle && rkey) { if (handle.startsWith("did:")) { targetUri = `at://${handle}/at.margin.collection/${rkey}`; } else { const did = await resolveHandle(handle); if (did) { targetUri = `at://${did}/at.margin.collection/${rkey}`; } else { setError("Collection not found"); setLoading(false); return; } } } if (targetUri) { const col = await getCollection(targetUri); if (col) { setCollection(col); const colItems = await getCollectionItems(col.uri); setItems(colItems.filter((i) => i && i.uri)); } else { setError("Collection not found"); } } } catch { setError("Failed to load collection"); } finally { setLoading(false); } }; loadData(); }, [handle, rkey, uri]); const handleDelete = async () => { if (!collection) return; if (window.confirm("Delete this collection?")) { await deleteCollection(collection.id); window.location.href = "/collections"; } }; const handleRemoveItem = async (item: AnnotationItem) => { if (!item.collectionItemUri) return; if (!window.confirm("Remove from collection?")) return; const success = await removeCollectionItem(item.collectionItemUri); if (success) { setItems((prev) => prev.filter((i) => i.collectionItemUri !== item.collectionItemUri), ); } }; if (loading) { return (
); } if (error || !collection) { return (
{error || "Collection not found"}
); } const isOwner = user?.did === collection.creator?.did; const isSemble = collection.uri?.includes("network.cosmik"); const sembleUrl = (() => { if (!isSemble) return ""; const parts = collection.uri.split("/"); const rk = parts[parts.length - 1]; const h = collection.creator?.handle || ""; return `https://semble.so/profile/${h}/collections/${rk}`; })(); return (
Collections

{collection.name}

{collection.description && (

{collection.description}

)}
{items.length} items by{" "} {collection.creator?.displayName || collection.creator?.handle}
{isOwner && !isSemble && ( <> )} {isSemble && ( View in Semble )}
setIsEditModalOpen(false)} collection={collection} onUpdate={(updated) => setCollection({ ...updated, creator: updated.creator || collection.creator, }) } />
{items.length === 0 ? (

Collection is empty

) : ( items.map((item) => (
{isOwner && !isSemble && item.collectionItemUri && ( )}
)) )}
); }