feat(ui): 星盘/星历/报告中心并入 app 外壳,侧栏不再消失
三个页面此前各是脱离外壳的独立全屏路由,各写了一套一样的 *-shell / *-topbar(只有一个「返回对话」链接)/ *-hero 骨架, 侧栏在打开它们的瞬间整个消失。 新增 AppNavRail(只读:两个 GET,零写操作)与 SecondaryShell。 会话行走 sessionHref → /?c=<uuid>,跳转复用现有侧栏的 persistLoginSessionReturn + location.assign,行为完全一致。 刻意不带重命名/收藏/归档/删除与账户菜单:那套连着 Home() 的乐观更新与 回滚层,为四个路由把它整体上提远超需要,且会撞 useState 增长门禁。 四个路由渲染标记完全不变:/ ○、/chart ○、/ephemeris ○、/reports ƒ。 CSS gzip 39,825→39,727(−0.25%);per-route JS 体积构建不输出, 已作为口径缺口记录。 两处自身问题被测试抓到并修复:usePathname() 在 app-router 上下文外 返回 null(类型说是 string)、fetch 在 jsdom 里可能不存在。 另差点随 hero 一起丢掉 BUG-717 的 eyebrow 文案(成本与速度承诺, 会印在失败页上),已放回 tab 行下方。 /reports/[reportId] 留给 R6 与目录一起做;根边界页保留「返回对话」, 它们不得 import globals.css,挂不了外壳。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
This commit is contained in:
co-authored by
Claude Opus 5
parent
b3ea8c336e
commit
50ce02c837
@@ -1,10 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { ArrowLeft, Check, Clock3, FileText, RefreshCw, TriangleAlert } from "lucide-react";
|
||||
import { Check, Clock3, FileText, RefreshCw, TriangleAlert } from "lucide-react";
|
||||
import { InlineSpinner } from "@/components/inline-spinner";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { SecondaryShell } from "@/components/secondary-shell";
|
||||
import { GeneratePersonalReportButton } from "./generate-personal-report-button";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useVisibilityAwarePoll } from "@/hooks/use-visibility-aware-poll";
|
||||
@@ -166,30 +167,30 @@ export function PersonalReportCenter() {
|
||||
|
||||
if (state.phase === "unauthorized") {
|
||||
return (
|
||||
<main className="report-center-shell report-center-message">
|
||||
<FileText aria-hidden="true" className="size-8 text-primary" />
|
||||
<h1>请先登录</h1>
|
||||
<p>登录后即可生成和查看你的个人报告。</p>
|
||||
<Button render={<Link href="/login" />} nativeButton={false}>去登录</Button>
|
||||
</main>
|
||||
<SecondaryShell title="我的报告">
|
||||
<section className="report-center-message">
|
||||
<FileText aria-hidden="true" className="size-8 text-primary" />
|
||||
<h2>请先登录</h2>
|
||||
<p>登录后即可生成和查看你的个人报告。</p>
|
||||
<Button render={<Link href="/login" />} nativeButton={false}>去登录</Button>
|
||||
</section>
|
||||
</SecondaryShell>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="report-center-shell">
|
||||
<header className="report-center-topbar">
|
||||
<Link href="/" className="report-center-back"><ArrowLeft aria-hidden="true" />返回对话</Link>
|
||||
</header>
|
||||
|
||||
<SecondaryShell
|
||||
title="我的报告"
|
||||
actions={<GeneratePersonalReportButton onCreated={() => void load()} />}
|
||||
>
|
||||
<div className="report-center-body">
|
||||
<section className="report-center-hero">
|
||||
<div>
|
||||
<h1>个人报告</h1>
|
||||
<p>有填报到分钟的出生时间即可生成;未校正会标明为方向性参考。只有日期和时段时,完整本命报告需要具体分钟,生时校正可选。与某一次对话无关。创建后会在后台继续处理,你无需停留等待。</p>
|
||||
<p className="report-center-meta" aria-label="报告概览">
|
||||
共 {state.reports.length} 份 · 已完成 {state.reports.filter((report) => report.status === "ready").length} 份 · {hasGenerating ? "有报告生成中" : latestReady ? "最新报告可查看" : "尚待生成"}
|
||||
</p>
|
||||
</div>
|
||||
<GeneratePersonalReportButton onCreated={() => void load()} />
|
||||
</section>
|
||||
|
||||
<section className="report-center-section">
|
||||
@@ -261,6 +262,7 @@ export function PersonalReportCenter() {
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</SecondaryShell>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user