This commit is contained in:
freedakgmail
2025-11-23 18:03:04 +08:00
parent 9cdd751a56
commit e44dd0bd95
489 changed files with 264491 additions and 4157 deletions
+47 -35
View File
@@ -14,6 +14,7 @@ import { useSession } from "next-auth/react"
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import { ChangePassword } from "@/components/settings/change-password"
import { useDialog } from "@/components/ui/alert-dialog-custom"
import { permissions } from "@/lib/permissions"
interface UserProfile {
id: string
@@ -30,7 +31,8 @@ interface UserProfile {
}
export default function SettingsPage() {
const { treeData, loadData, resetData } = useFamily()
const { treeData, currentTree, loadData, resetData } = useFamily()
const role = currentTree?.currentUserRole
const { data: session } = useSession()
const { showAlert, showConfirm } = useDialog()
const [importStatus, setImportStatus] = useState<string>("")
@@ -147,7 +149,8 @@ export default function SettingsPage() {
<p className="text-sm font-medium text-destructive mb-2 flex items-center gap-2">
<AlertTriangle className="h-4 w-4" />
</p>
<Button
{permissions.canClearData(role) && (
<Button
variant="destructive"
size="sm"
className="w-full"
@@ -157,10 +160,11 @@ export default function SettingsPage() {
await resetData()
await showAlert("数据已重置为演示状态。", "成功")
}
}}
>
</Button>
}}
>
</Button>
)}
</div>
</CardContent>
</Card>
@@ -185,8 +189,9 @@ export default function SettingsPage() {
<Download className="h-4 w-4" />
</h3>
<p className="text-sm text-muted-foreground"> JSON </p>
<Button
onClick={() => {
{permissions.canExport(role) && (
<Button
onClick={() => {
const dataStr = JSON.stringify(treeData, null, 2)
const blob = new Blob([dataStr], { type: "application/json" })
const url = URL.createObjectURL(blob)
@@ -196,10 +201,11 @@ export default function SettingsPage() {
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}}
>
(Export JSON)
</Button>
}}
>
(Export JSON)
</Button>
)}
</div>
<div className="border-t" />
@@ -213,8 +219,9 @@ export default function SettingsPage() {
<p className="text-sm text-muted-foreground mt-1"> JSON </p>
</div>
<div className="flex items-center gap-4">
<input
{permissions.canImport(role) && (
<div className="flex items-center gap-4">
<input
type="file"
ref={fileInputRef}
className="hidden"
@@ -244,12 +251,13 @@ export default function SettingsPage() {
}
reader.readAsText(file)
}}
/>
<Button variant="outline" onClick={() => fileInputRef.current?.click()}>
...
</Button>
<span className="text-sm text-muted-foreground">{importStatus}</span>
</div>
/>
<Button variant="outline" onClick={() => fileInputRef.current?.click()}>
...
</Button>
<span className="text-sm text-muted-foreground">{importStatus}</span>
</div>
)}
</div>
</CardContent>
</Card>
@@ -263,10 +271,11 @@ export default function SettingsPage() {
</CardHeader>
<CardContent className="space-y-4">
<div className="flex flex-col gap-4">
<Button
variant="outline"
className="justify-start"
onClick={() => {
{permissions.canExport(role) && (
<Button
variant="outline"
className="justify-start"
onClick={() => {
const gedcomText = exportToGedcom(treeData)
const blob = new Blob([gedcomText], { type: "text/plain;charset=utf-8" })
const url = URL.createObjectURL(blob)
@@ -275,14 +284,16 @@ export default function SettingsPage() {
link.download = `family_tree_${new Date().toISOString().split("T")[0]}.ged`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}}
>
<Download className="mr-2 h-4 w-4" />
GEDCOM
</Button>
document.body.removeChild(link)
}}
>
<Download className="mr-2 h-4 w-4" />
GEDCOM
</Button>
)}
<div className="flex items-center gap-2">
{permissions.canImport(role) && (
<div className="flex items-center gap-2">
<input
type="file"
ref={gedcomInputRef}
@@ -310,10 +321,11 @@ export default function SettingsPage() {
/>
<Button variant="outline" className="justify-start" onClick={() => gedcomInputRef.current?.click()}>
<Upload className="mr-2 h-4 w-4" />
GEDCOM
</Button>
{gedcomStatus && <span className="text-sm text-muted-foreground">{gedcomStatus}</span>}
</div>
GEDCOM
</Button>
{gedcomStatus && <span className="text-sm text-muted-foreground">{gedcomStatus}</span>}
</div>
)}
</div>
</CardContent>
</Card>