Server components (.server.tsx) resolve controllers from DI, prefetch data, and wrap client components in HydrationBoundary. Client components (.client.tsx) use hooks for hydration + background refetch. Barrel exports server components under clean names — consumers never see the server/client split.
35 lines
935 B
TypeScript
35 lines
935 B
TypeScript
"use client";
|
|
|
|
import { useArticleBySlug } from "../hooks/use-article-by-slug";
|
|
|
|
export type ArticleDetailProps = {
|
|
slug: string;
|
|
};
|
|
|
|
export function ArticleDetail({ slug }: ArticleDetailProps) {
|
|
const { data: article } = useArticleBySlug(slug);
|
|
|
|
if (!article) return null;
|
|
|
|
return (
|
|
<article className="mx-auto max-w-3xl">
|
|
<header className="mb-8">
|
|
<h1 className="text-3xl font-bold text-foreground">{article.title}</h1>
|
|
{article.createdAt ? (
|
|
<time
|
|
className="mt-2 block text-sm text-muted-foreground"
|
|
dateTime={article.createdAt.toISOString()}
|
|
>
|
|
{article.createdAt.toLocaleDateString()}
|
|
</time>
|
|
) : null}
|
|
</header>
|
|
<div className="prose text-foreground">
|
|
<pre className="whitespace-pre-wrap text-sm">
|
|
{JSON.stringify(article.content, null, 2)}
|
|
</pre>
|
|
</div>
|
|
</article>
|
|
);
|
|
}
|