refactor: split feature UI into .server/.client component pairs
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.
This commit is contained in:
34
packages/blog/src/ui/components/article-detail.client.tsx
Normal file
34
packages/blog/src/ui/components/article-detail.client.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user