mosaicmap/app/blog/[slug]/page.tsx
2025-08-12 21:25:52 +08:00

61 lines
2.0 KiB
TypeScript

"use client"
import { gql, useQuery } from '@apollo/client'
import { use, useState } from 'react'
import BlogViewer from '@/components/blog-viewer'
import TableOfContents from '@/components/table-of-contents'
import { cn } from '@/lib/utils'
const BLOG = gql`
query Blog($slug: String!) {
blogBySlug(slug: $slug) {
id
title
content
}
}
`
export default function Page({ params }: { params: Promise<{ slug: string }> }) {
// 使用 React.use() 来解包 params Promise
const resolvedParams = use(params);
const { slug } = resolvedParams;
const [contentReady, setContentReady] = useState(false);
const { data, loading, error } = useQuery(BLOG, {
variables: { slug },
})
// 条件渲染处理
if (loading) return <div className="flex items-center justify-center min-h-[400px]">Loading...</div>;
if (error) return <div className="flex items-center justify-center min-h-[400px] text-red-500">Error: {error.message}</div>;
if (!data?.blogBySlug) return <div className="flex items-center justify-center min-h-[400px]">Blog not found</div>;
const content = data.blogBySlug.content;
console.log('Blog content:', content);
return (
<div className="relative">
{contentReady && (
<div className={cn(
"fixed left-4 top-1/2 -translate-y-1/2 z-40 hidden xl:block",
"animate-in slide-in-from-left-8 fade-in duration-500 ease-out"
)}>
<TableOfContents />
</div>
)}
{/* 主内容区域 */}
<div className="container mx-auto py-8 max-w-4xl">
<main>
<h1 className="text-5xl font-bold my-12">{data.blogBySlug.title}</h1>
<BlogViewer
content={content}
onContentReady={() => setContentReady(true)}
/>
</main>
</div>
</div>
);
}