"use client"; /** * Public collection at /c/[id]. Anyone can view if `is_public=true`. * Private collections return 403 from the BFF, which we treat as "not * found" to avoid leaking existence. */ import { use, useEffect, useState } from "react"; import { notFound } from "next/navigation"; import { Globe, Lock, FolderPlus } from "lucide-react"; import { collections, SocialError, type Collection, type Post, } from "@/lib/social"; import { PostViews } from "@/components/social/post/post-views"; export default function PublicCollectionPage(props: { params: Promise<{ id: string }>; }) { const { id } = use(props.params); const [c, setC] = useState(null); const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [missing, setMissing] = useState(false); useEffect(() => { let cancelled = false; collections .get(id) .then(({ collection, posts }) => { if (cancelled) return; setC(collection); setPosts(posts ?? []); }) .catch((err) => { if ( err instanceof SocialError && (err.status === 404 || err.status === 403) ) { setMissing(true); } }) .finally(() => !cancelled && setLoading(false)); return () => { cancelled = true; }; }, [id]); if (missing) notFound(); if (loading || !c) return (

Loading…

); return (
{c.is_public ? : } {c.is_public ? "Public collection" : "Private collection"}

{c.title}

{c.description ? (

{c.description}

) : null}

{c.item_count} post{c.item_count === 1 ? "" : "s"}

{posts.length === 0 ? (

This collection has no items yet.

) : ( )}
); }