Files
zhimingge/components/history/history-page.tsx
T
2026-06-13 09:39:38 +08:00

125 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
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 Markdown from "react-markdown";
import {
buildHistoryMarkdown,
deleteHistoryEntry,
downloadMarkdown,
loadHistory,
} from "@/lib/history/storage";
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);
useEffect(() => {
const list = loadHistory();
setItems(list);
setActiveId(list[0]?.id ?? null);
}, []);
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);
}
}
return (
<PageShell className="py-8">
<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 ? (
<ZenCard className="text-center text-sm text-muted-foreground">
<p></p>
<Link href="/liuyao" className="mt-3 inline-block text-primary underline">
</Link>
</ZenCard>
) : (
<div className="grid gap-6 lg:grid-cols-[minmax(0,280px)_1fr]">
<div className="space-y-2">
{items.map((item) => (
<button
key={item.id}
type="button"
onClick={() => setActiveId(item.id)}
className={`w-full rounded-xl border px-4 py-3 text-left text-sm transition ${
activeId === item.id
? "border-primary/40 bg-primary/5"
: "border-border/60 bg-card/80 hover:border-primary/20"
}`}
>
<p className="font-medium">{item.title}</p>
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
{item.question}
</p>
<p className="mt-1 text-xs text-muted-foreground">
{MODE_LABELS[item.mode]} ·{" "}
{new Date(item.createdAt).toLocaleString("zh-CN")}
</p>
</button>
))}
</div>
{active && (
<ZenCard
title={active.title}
subtitle={`${MODE_LABELS[active.mode]} · ${new Date(active.createdAt).toLocaleString("zh-CN")}`}
>
<p className="text-sm text-muted-foreground">{active.question}</p>
{active.summary && (
<p className="text-sm text-muted-foreground">{active.summary}</p>
)}
<div className="flex flex-wrap gap-2">
<Button
size="sm"
variant="outline"
onClick={() =>
downloadMarkdown(
buildHistoryMarkdown(active),
`${active.title}.md`,
)
}
>
<Download size={14} className="mr-1" />
Markdown
</Button>
<Button
size="sm"
variant="outline"
onClick={() => handleDelete(active.id)}
>
<Trash2 size={14} className="mr-1" />
</Button>
</div>
<div className="max-h-[60vh] overflow-y-auto rounded-md border bg-background/50 p-4">
<Markdown className="prose max-w-none text-sm dark:prose-invert">
{active.completion}
</Markdown>
</div>
</ZenCard>
)}
</div>
)}
</PageShell>
);
}