-
{worldEntityRules(entity).map((rule, j) => (
- {rule} ))}
(无显式硬规则)
)}"use client"; import { useMemo, useState } from "react"; import dynamic from "next/dynamic"; import { Clock3, Globe2, Share2, Sparkles, UserRound } from "lucide-react"; import { AppShell } from "@/components/AppShell"; import { CharacterGenerator } from "@/components/generation/CharacterGenerator"; import { WorldGenerator } from "@/components/generation/WorldGenerator"; import { Badge } from "@/components/ui/Badge"; import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; import { EmptyState } from "@/components/ui/EmptyState"; import { PageHeader } from "@/components/ui/PageHeader"; import { SegmentedControl } from "@/components/ui/SegmentedControl"; import type { CharacterCardView, ProjectResponse, WorldEntityCardView, } from "@/lib/api/types"; import { mergeCharacterCards, worldEntityRules, } from "@/lib/generation/cards"; type CodexTab = "characters" | "world" | "timeline"; interface CodexPageProps { project: ProjectResponse; // 后端读端点(GET .../characters / .../world_entities)拉来的跨会话全量真源。 initialCharacters: CharacterCardView[]; initialWorldEntities: WorldEntityCardView[]; // 进页可经 ?gen=character|world 直接打开对应生成器(命令面板动作跳转)。 initialTab?: CodexTab; } const TABS: { key: CodexTab; label: string }[] = [ { key: "characters", label: "人物" }, { key: "world", label: "世界观" }, { key: "timeline", label: "时间线" }, ]; // 关系图谱(React Flow)只在客户端渲染:ssr:false 绕开 canvas/window 依赖, // 并把 React Flow 及其样式拆到独立 chunk,进人物 tab 才加载。 const RelationshipGraph = dynamic( () => import("@/components/characters/RelationshipGraph").then( (mod) => mod.RelationshipGraph, ), { ssr: false, loading: () => (
{c.name}
{c.role}
(无显式硬规则)
)}