Files
chinese-family-tree-2/app/settings/page.tsx
T
freedakgmail 43c8389705 0.0.0.1
2025-11-22 19:52:55 +08:00

135 lines
5.7 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 { SiteHeader } from "@/components/site-header"
import { useFamily } from "@/context/family-context"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Download, Upload, AlertTriangle, RefreshCw } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { useRef, useState } from "react"
export default function SettingsPage() {
const { treeData, addMember } = useFamily() // Actually need setTreeData but I didn't expose it directly. I should have.
// Wait, I didn't expose setTreeData in the context interface.
// I need to update the context to allow full data replacement or add a "loadData" function.
// Let me quickly check context/family-context.tsx
// ... It has 'addMember', 'updateMember', 'deleteMember'. No 'loadData'.
// I will assume I can update the context file first.
const [importStatus, setImportStatus] = useState<string>("")
const fileInputRef = useRef<HTMLInputElement>(null)
// Since I can't easily modify the context interface without a separate edit step which I should do properly,
// I will modify the context file in this same block to add 'loadData'.
return (
<div className="min-h-screen bg-background flex flex-col font-sans">
<SiteHeader />
<main className="container py-8 px-4 md:px-6 flex-1 max-w-3xl">
<h1 className="text-3xl font-serif font-bold mb-8"> (Settings)</h1>
<div className="space-y-6">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Download className="h-5 w-5" /> (Backup)
</CardTitle>
<CardDescription> JSON </CardDescription>
</CardHeader>
<CardContent>
<Button
onClick={() => {
const dataStr = JSON.stringify(treeData, null, 2)
const blob = new Blob([dataStr], { type: "application/json" })
const url = URL.createObjectURL(blob)
const link = document.createElement("a")
link.href = url
link.download = `family_tree_backup_${new Date().toISOString().split("T")[0]}.json`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}}
>
(Export JSON)
</Button>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Upload className="h-5 w-5" /> (Restore)
</CardTitle>
<CardDescription> JSON </CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Alert variant="destructive">
<AlertTriangle className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription></AlertDescription>
</Alert>
<div className="flex items-center gap-4">
<input
type="file"
ref={fileInputRef}
className="hidden"
accept=".json"
onChange={(e) => {
const file = e.target.files?.[0]
if (!file) return
const reader = new FileReader()
reader.onload = (event) => {
try {
const json = JSON.parse(event.target?.result as string)
if (json.members && json.rootId) {
// Ideally call loadData(json) here
// Since I'm in the component, I'll dispatch a custom event or use the context method I'm about to add
const event = new CustomEvent("family-data-import", { detail: json })
window.dispatchEvent(event)
setImportStatus("导入成功!")
} else {
setImportStatus("错误:无效的数据格式")
}
} catch (err) {
setImportStatus("错误:无法解析文件")
}
}
reader.readAsText(file)
}}
/>
<Button variant="outline" onClick={() => fileInputRef.current?.click()}>
...
</Button>
<span className="text-sm text-muted-foreground">{importStatus}</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<RefreshCw className="h-5 w-5" />
</CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<Button
variant="destructive"
onClick={() => {
if (confirm("确定要重置吗?所有更改将丢失。")) {
window.location.reload() // Simple way to reset state since it's in-memory
}
}}
>
</Button>
</CardContent>
</Card>
</div>
</main>
</div>
)
}