feat: show parameter freeze panel

This commit is contained in:
732642856
2026-07-21 15:17:22 +08:00
parent 19b8491b18
commit d6726e849d
4 changed files with 60 additions and 0 deletions
+7
View File
@@ -481,6 +481,13 @@ button:disabled { cursor: default; opacity: .45; }
.product-entrypoint-action .starter-arrow { width: 15px; height: 15px; color: currentColor; }
.starter-loading { color: var(--color-ink-secondary); margin-left: 0; padding: var(--space-5); border-radius: var(--radius-lg); background: var(--color-canvas-muted); font-size: 14px; }
.starter-note { margin: 10px 0 0; color: var(--color-ink-secondary); line-height: 1.5; grid-column: 1 / -1; font-size: 13px; }
.parameter-freeze-panel { display: grid; grid-column: 1 / -1; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); }
.parameter-freeze-panel > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); color: var(--color-ink-secondary); font-size: var(--type-caption); }
.parameter-freeze-panel b { color: var(--color-ink); font-size: var(--type-title-sm); }
.parameter-freeze-panel dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: var(--space-2); margin: 0; }
.parameter-freeze-panel dl > div { min-width: 0; padding: var(--space-2); border-radius: var(--radius-md); background: var(--color-canvas-soft); }
.parameter-freeze-panel dt { color: var(--color-ink-tertiary); font-size: 11px; }
.parameter-freeze-panel dd { overflow: hidden; margin: 2px 0 0; color: var(--color-ink); text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.message-list { margin: 0 auto; width: min(900px, 100%); padding: var(--space-8) var(--space-8) var(--space-16); }
.message { display: flex; animation: message-enter 160ms var(--ease-out) both; padding: var(--space-2) 0; }
+12
View File
@@ -14,6 +14,7 @@ import { BirthTimeIntakeFields } from "@/components/birth-time-intake";
import { ChatMessageContent } from "@/components/chat-message-content";
import { AgentAvatar, ChatMessageRow } from "@/components/chat-message-row";
import { ModelSelector } from "@/components/model-selector";
import { ParameterFreezePanel, type ParameterFreezeRow } from "@/components/parameter-freeze-panel";
import { Button } from "@/components/ui/button";
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { Textarea } from "@/components/ui/textarea";
@@ -841,6 +842,16 @@ export default function Home() {
const profileComplete = isProfileComplete(profile);
const birthTimeDisplay = birthTimeDisplayState(profile);
const profileBirthPlace = selectedBirthPlace(profile);
const parameterFreezeRows: ParameterFreezeRow[] = profileComplete && profileBirthPlace ? [
{ label: "出生时间", value: `${profile.date} ${profile.time || "未定"}` },
{ label: "出生地点", value: profileBirthPlace.label },
{ label: "经纬度", value: `${profileBirthPlace.lat.toFixed(4)}, ${profileBirthPlace.lon.toFixed(4)}` },
{ label: "时区", value: `UTC+${profileBirthPlace.tz}` },
{ label: "Ayanamsa", value: "Lahiri / Sidereal" },
{ label: "Node mode", value: "True Node" },
{ label: "出生时间精度", value: birthTimeDisplay?.kind === "candidate" ? "候选时间" : birthTimeDisplay?.kind === "confirmed" ? "已确认" : "待校正" },
] : [];
const dailyStarlanguage = dailyStarlanguageCard ?? (profileComplete ? buildDailyStarlanguageCard(profile) : null);
const onboardingPending = profileComplete && !onboarding && !onboardingError;
const currentOnboardingMessage = onboardingJustCompleted
@@ -2417,6 +2428,7 @@ export default function Home() {
<div className="starter-loading" role="status"></div>
) : (
<div className="starter-list" aria-label="Jyotisha 推荐的初始问题">
{parameterFreezeRows.length > 0 && <ParameterFreezePanel rows={parameterFreezeRows} />}
<div className="product-entrypoints" aria-label="常用占星入口">
<article className="daily-starlanguage-card product-entrypoint-card" aria-label="今日星语">
<button
@@ -0,0 +1,23 @@
export type ParameterFreezeRow = {
label: string;
value: string;
};
export function ParameterFreezePanel({ rows }: { readonly rows: readonly ParameterFreezeRow[] }) {
return (
<section className="parameter-freeze-panel" aria-label="当前排盘参数冻结">
<div>
<b></b>
<span></span>
</div>
<dl>
{rows.map((row) => (
<div key={row.label}>
<dt>{row.label}</dt>
<dd>{row.value}</dd>
</div>
))}
</dl>
</section>
);
}
@@ -0,0 +1,18 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
const pageSource = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8");
const panelSource = readFileSync(new URL("../src/components/parameter-freeze-panel.tsx", import.meta.url), "utf8");
const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
test("starter workbench shows a parameter freeze panel when profile is complete", () => {
assert.match(pageSource, /ParameterFreezePanel/);
assert.match(pageSource, /parameterFreezeRows/);
assert.match(pageSource, /Ayanamsa/);
assert.match(pageSource, /Node mode/);
assert.match(pageSource, /出生时间精度/);
assert.match(panelSource, /当前排盘参数冻结/);
assert.match(panelSource, /这些参数会随咨询一起送入证据链/);
assert.match(globalStyles, /\.parameter-freeze-panel/);
});