fix: ui fixes
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* /u/[handle]/collections/[id] — single public-collection view for another
|
||||
* user's profile. Mirrors the auth user's /u/me/collections/[id] exactly —
|
||||
* the CollectionScrollCard carousel (cover + posts) — but read-only: no Edit
|
||||
* affordance, since the viewer doesn't own it. Private collections (or a bad
|
||||
* id) 403/404 from the BFF, which we treat as "not found".
|
||||
*/
|
||||
|
||||
import { use, useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import {
|
||||
collections,
|
||||
SocialError,
|
||||
type Collection,
|
||||
type Post,
|
||||
} from "@/lib/social";
|
||||
import { CollectionScrollCard } from "@/components/social/collection/collection-scroll-card";
|
||||
|
||||
export default function PublicCollectionDetailPage(props: {
|
||||
params: Promise<{ handle: string; id: string }>;
|
||||
}) {
|
||||
const { handle, id } = use(props.params);
|
||||
|
||||
const [c, setC] = useState<Collection | null>(null);
|
||||
const [posts, setPosts] = useState<Post[]>([]);
|
||||
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 (cancelled) return;
|
||||
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) return <p className="text-sm text-muted-foreground">Loading…</p>;
|
||||
if (!c) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<Link
|
||||
href={`/u/${handle}/collections`}
|
||||
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<ArrowLeft className="size-4" /> All collections
|
||||
</Link>
|
||||
|
||||
<CollectionScrollCard
|
||||
collection={c}
|
||||
href={`/u/${handle}/collections/${c.id}`}
|
||||
initialPosts={posts}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,9 @@
|
||||
* The list comes from the layout's profile fetch (`public_collections`),
|
||||
* so this page only has to decide between the empty state and the grid.
|
||||
* Layout owns the ProfileHeader + tabs + container.
|
||||
*
|
||||
* Cards link into /u/[handle]/collections/[id] — the same grid → carousel
|
||||
* detail structure the auth user gets at /u/me/collections.
|
||||
*/
|
||||
|
||||
import { CollectionViews } from "@/components/social/collection/collection-views";
|
||||
@@ -23,5 +26,10 @@ export default function PublicProfileCollectionsPage() {
|
||||
);
|
||||
}
|
||||
|
||||
return <CollectionViews collections={list} hrefFor={(c) => `/c/${c.id}`} />;
|
||||
return (
|
||||
<CollectionViews
|
||||
collections={list}
|
||||
hrefFor={(c) => `/u/${data.handle}/collections/${c.id}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user