Files
thoughts/thoughts-frontend/app/thoughts/[thoughtId]/page.tsx
Gabriel Kaszewski b95cebc799
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 9m41s
test / unit (pull_request) Successful in 16m33s
test / integration (pull_request) Failing after 17m3s
fix: await searchParams and params for Next.js 15 async API, compute totalPages in all-users page
2026-05-14 17:28:35 +02:00

70 lines
1.9 KiB
TypeScript

import { cookies } from "next/headers";
import {
getThoughtThread,
getUserProfile,
getMe,
Me,
User,
ThoughtThread as ThoughtThreadType,
} from "@/lib/api";
import { ThoughtThread } from "@/components/thought-thread";
import { notFound } from "next/navigation";
interface ThoughtPageProps {
params: Promise<{ thoughtId: string }>;
}
function collectAuthors(thread: ThoughtThreadType): string[] {
const authors = new Set<string>([thread.author.username]);
for (const reply of thread.replies) {
collectAuthors(reply).forEach((author) => authors.add(author));
}
return Array.from(authors);
}
export default async function ThoughtPage({ params }: ThoughtPageProps) {
const { thoughtId } = await params;
const token = (await cookies()).get("auth_token")?.value ?? null;
const [threadResult, meResult] = await Promise.allSettled([
getThoughtThread(thoughtId, token),
token ? getMe(token) : Promise.resolve(null),
]);
if (threadResult.status === "rejected") {
notFound();
}
const thread = threadResult.value;
const me = meResult.status === "fulfilled" ? (meResult.value as Me) : null;
// Fetch details for all authors in the thread efficiently
const authorUsernames = collectAuthors(thread);
const userProfiles = await Promise.all(
authorUsernames.map((username) =>
getUserProfile(username, token).catch(() => null)
)
);
const authorDetails = new Map<string, { avatarUrl?: string | null }>(
userProfiles
.filter((u): u is User => !!u)
.map((user) => [user.username, { avatarUrl: user.avatarUrl }])
);
return (
<div className="container mx-auto max-w-2xl p-4 sm:p-6">
<header className="my-6">
<h1 className="text-3xl font-bold">Thoughts</h1>
</header>
<main>
<ThoughtThread
thought={thread}
authorDetails={authorDetails}
currentUser={me}
/>
</main>
</div>
);
}