Store calculation history on server with bazi input and chart snapshots.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { Download, Trash2 } from "lucide-react";
|
||||
import PageShell from "@/components/page-shell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ZenCard } from "@/components/ui/zen-card";
|
||||
import BaziChartDisplay from "@/components/modes/bazi-chart";
|
||||
import Markdown from "react-markdown";
|
||||
import {
|
||||
buildHistoryMarkdown,
|
||||
@@ -18,21 +19,46 @@ import { MODE_LABELS, type CalcHistoryEntry } from "@/lib/history/types";
|
||||
export default function HistoryPageClient() {
|
||||
const [items, setItems] = useState<CalcHistoryEntry[]>([]);
|
||||
const [activeId, setActiveId] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const list = loadHistory();
|
||||
setItems(list);
|
||||
setActiveId(list[0]?.id ?? null);
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
try {
|
||||
const list = await loadHistory();
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
setItems(list);
|
||||
setActiveId(list[0]?.id ?? null);
|
||||
} catch (e) {
|
||||
if (!cancelled) {
|
||||
setError(e instanceof Error ? e.message : String(e));
|
||||
}
|
||||
} finally {
|
||||
if (!cancelled) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const active = items.find((e) => e.id === activeId) ?? null;
|
||||
|
||||
function handleDelete(id: string) {
|
||||
deleteHistoryEntry(id);
|
||||
const next = loadHistory();
|
||||
setItems(next);
|
||||
if (activeId === id) {
|
||||
setActiveId(next[0]?.id ?? null);
|
||||
async function handleDelete(id: string) {
|
||||
try {
|
||||
await deleteHistoryEntry(id);
|
||||
const next = items.filter((item) => item.id !== id);
|
||||
setItems(next);
|
||||
if (activeId === id) {
|
||||
setActiveId(next[0]?.id ?? null);
|
||||
}
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : String(e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +67,17 @@ export default function HistoryPageClient() {
|
||||
<div className="mb-6 text-center">
|
||||
<h1 className="text-2xl font-bold tracking-wide">测算历史</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
本机浏览器保存,清除缓存后可能丢失
|
||||
保存在服务器,按登录账号区分
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{items.length === 0 ? (
|
||||
{loading ? (
|
||||
<ZenCard className="text-center text-sm text-muted-foreground">
|
||||
加载中…
|
||||
</ZenCard>
|
||||
) : error ? (
|
||||
<ZenCard className="text-center text-sm text-destructive">{error}</ZenCard>
|
||||
) : items.length === 0 ? (
|
||||
<ZenCard className="text-center text-sm text-muted-foreground">
|
||||
<p>暂无测算记录</p>
|
||||
<Link href="/liuyao" className="mt-3 inline-block text-primary underline">
|
||||
@@ -70,6 +102,14 @@ export default function HistoryPageClient() {
|
||||
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
|
||||
{item.question}
|
||||
</p>
|
||||
{item.baziChart && (
|
||||
<p className="mt-1 font-mono text-xs text-muted-foreground">
|
||||
{item.baziChart.pillars.year.ganZhi}{" "}
|
||||
{item.baziChart.pillars.month.ganZhi}{" "}
|
||||
{item.baziChart.pillars.day.ganZhi}{" "}
|
||||
{item.baziChart.pillars.time.ganZhi}
|
||||
</p>
|
||||
)}
|
||||
<p className="mt-1 text-xs text-muted-foreground">
|
||||
{MODE_LABELS[item.mode]} ·{" "}
|
||||
{new Date(item.createdAt).toLocaleString("zh-CN")}
|
||||
@@ -87,6 +127,27 @@ export default function HistoryPageClient() {
|
||||
{active.summary && (
|
||||
<p className="text-sm text-muted-foreground">{active.summary}</p>
|
||||
)}
|
||||
{active.baziInput && (
|
||||
<div className="rounded-md border bg-background/50 p-3 text-sm text-muted-foreground">
|
||||
<p>
|
||||
出生:{active.baziInput.birthPlaceName} ·{" "}
|
||||
{active.baziInput.date}{" "}
|
||||
{active.baziInput.unknownHour
|
||||
? "时辰不详"
|
||||
: active.baziInput.time}{" "}
|
||||
· {active.baziInput.gender === "male" ? "男" : "女"}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{active.baziChart && <BaziChartDisplay chart={active.baziChart} />}
|
||||
{active.hexagram && (
|
||||
<div className="rounded-md border bg-background/50 p-3 text-sm">
|
||||
<p className="font-medium">{active.hexagram.guaTitle}</p>
|
||||
<p className="mt-1 text-muted-foreground">
|
||||
{active.hexagram.guaResult}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
|
||||
Reference in New Issue
Block a user