This commit is contained in:
freedakgmail
2025-11-22 19:52:55 +08:00
commit 43c8389705
28950 changed files with 3640981 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
"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>
)
}