84 lines
2.8 KiB
TypeScript
84 lines
2.8 KiB
TypeScript
import Link from "next/link";
|
||
import { BookOpen, PenLine, Plus } from "lucide-react";
|
||
|
||
import { AppShell } from "@/components/AppShell";
|
||
import { BackendDownNotice } from "@/components/BackendDownNotice";
|
||
import { ProjectLibrary } from "@/components/projects/ProjectLibrary";
|
||
import { EmptyState } from "@/components/ui/EmptyState";
|
||
import { PageContainer } from "@/components/ui/PageContainer";
|
||
import { PageHeader } from "@/components/ui/PageHeader";
|
||
import { fetchProjects } from "@/lib/api/server";
|
||
import type { ProjectResponse } from "@/lib/api/types";
|
||
import { buttonClass } from "@/lib/ui/variants";
|
||
|
||
// 作品库(Dashboard 入口,UX §6.1)。Server Component 读取。
|
||
export default async function DashboardPage() {
|
||
let projects: ProjectResponse[] = [];
|
||
let loadError = false;
|
||
try {
|
||
const data = await fetchProjects();
|
||
projects = data.projects ?? [];
|
||
} catch {
|
||
loadError = true;
|
||
}
|
||
|
||
return (
|
||
<AppShell>
|
||
<PageContainer>
|
||
<PageHeader
|
||
title="我的作品"
|
||
description="从一个灵感进入正文、设定、审稿与验收闭环。"
|
||
actions={
|
||
<div className="flex flex-wrap items-center gap-2">
|
||
<Link
|
||
href="/write"
|
||
className={buttonClass({ variant: "primary" })}
|
||
>
|
||
<PenLine className="h-4 w-4" aria-hidden="true" />
|
||
直接开始写
|
||
</Link>
|
||
<Link
|
||
href="/projects/new"
|
||
className={buttonClass({ variant: "secondary" })}
|
||
>
|
||
<Plus className="h-4 w-4" aria-hidden="true" />
|
||
先立项
|
||
</Link>
|
||
</div>
|
||
}
|
||
/>
|
||
|
||
{loadError ? (
|
||
<BackendDownNotice />
|
||
) : projects.length === 0 ? (
|
||
<EmptyState
|
||
icon={BookOpen}
|
||
title="还没有作品"
|
||
description="直接开始写,落笔即成书;或先立项,从一句灵感搭好设定、大纲再动笔。"
|
||
action={
|
||
<div className="flex flex-wrap items-center justify-center gap-2">
|
||
<Link
|
||
href="/write"
|
||
className={buttonClass({ variant: "primary" })}
|
||
>
|
||
<PenLine className="h-4 w-4" aria-hidden="true" />
|
||
直接开始写
|
||
</Link>
|
||
<Link
|
||
href="/projects/new"
|
||
className={buttonClass({ variant: "secondary" })}
|
||
>
|
||
<Plus className="h-4 w-4" aria-hidden="true" />
|
||
先立项
|
||
</Link>
|
||
</div>
|
||
}
|
||
/>
|
||
) : (
|
||
<ProjectLibrary projects={projects} />
|
||
)}
|
||
</PageContainer>
|
||
</AppShell>
|
||
);
|
||
}
|