feat(foreshadow): 写作台本章伏笔主动提醒(前端)
- 新增 chapterForeshadow 纯分类:按当前章分 可回收/待回收/已逾期(启用闲置的 isWindowApproaching) - useChapterForeshadow hook(复用 GET /foreshadow,切章仅重分类不重拉) - 右栏「本章参考」+ ContextDrawer 伏笔页新增「本章伏笔」实时清单, 分色展示 + 跳看板链接 + 空态;标注『按已验收进度』
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
ArrowUpRight,
|
||||
Minus,
|
||||
Pin,
|
||||
PinOff,
|
||||
@@ -15,6 +17,9 @@ import {
|
||||
import { ThinkingIndicator } from "@/components/ThinkingIndicator";
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { StatusNote } from "@/components/ui/StatusNote";
|
||||
import { ChapterForeshadowList } from "@/components/workbench/ChapterForeshadowList";
|
||||
import { chapterForeshadowTotal } from "@/lib/foreshadow/chapterForeshadow";
|
||||
import { useChapterForeshadow } from "@/lib/foreshadow/useChapterForeshadow";
|
||||
import { buttonClass } from "@/lib/ui/variants";
|
||||
import {
|
||||
isPinned,
|
||||
@@ -183,6 +188,8 @@ export function AssistantContent({ projectId, chapterNo }: ChapterAssistantProps
|
||||
) : null}
|
||||
</section>
|
||||
|
||||
<ChapterForeshadowSection projectId={projectId} chapterNo={chapterNo} />
|
||||
|
||||
<section className="mt-6 border-t border-line-soft pt-5">
|
||||
<PanelLabel>写完后检查</PanelLabel>
|
||||
<p className="mt-1.5 text-caption leading-6 text-ink-soft">
|
||||
@@ -193,6 +200,55 @@ export function AssistantContent({ projectId, chapterNo }: ChapterAssistantProps
|
||||
);
|
||||
}
|
||||
|
||||
// 「本章伏笔」主动提醒:按当前章号把伏笔分可回收 / 待回收 / 已逾期三类,
|
||||
// 让作者在写这章时就想起该回收哪条、哪条已逾期。只读,编辑走「伏笔看板」。
|
||||
function ChapterForeshadowSection({ projectId, chapterNo }: ChapterAssistantProps) {
|
||||
const { groups, status, reload } = useChapterForeshadow(projectId, chapterNo);
|
||||
const boardHref = `/projects/${projectId}/foreshadow`;
|
||||
const isEmpty = chapterForeshadowTotal(groups) === 0;
|
||||
|
||||
return (
|
||||
<section className="mt-6 border-t border-line-soft pt-5">
|
||||
<PanelLabel
|
||||
action={<span className="text-2xs text-muted-soft">按已验收进度</span>}
|
||||
>
|
||||
本章伏笔
|
||||
</PanelLabel>
|
||||
|
||||
{status === "loading" ? (
|
||||
<p className="mt-2 text-caption text-ink-soft">加载伏笔…</p>
|
||||
) : status === "error" ? (
|
||||
<StatusNote variant="danger" className="mt-2 text-xs" title="伏笔暂不可用">
|
||||
<button
|
||||
type="button"
|
||||
onClick={reload}
|
||||
className={buttonClass({ variant: "outline", size: "sm", className: "mt-2" })}
|
||||
>
|
||||
<RotateCcw className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
重试
|
||||
</button>
|
||||
</StatusNote>
|
||||
) : isEmpty ? (
|
||||
<p className="mt-2 text-caption leading-6 text-ink-soft">
|
||||
这一章暂无待回收或已逾期的伏笔。
|
||||
</p>
|
||||
) : (
|
||||
<div className="mt-3">
|
||||
<ChapterForeshadowList groups={groups} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Link
|
||||
href={boardHref}
|
||||
className="mt-3 inline-flex items-center gap-1 text-caption text-cinnabar hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cinnabar/35"
|
||||
>
|
||||
去伏笔看板
|
||||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</Link>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
interface EntityRowProps {
|
||||
entity: InjectionEntity;
|
||||
pinned: boolean;
|
||||
|
||||
Reference in New Issue
Block a user