Files
chinese-family-tree-2/app/trees/new/page.tsx
T
freedakgmail 3b0d8255f6 0.0.8.1
2025-11-23 19:38:51 +08:00

180 lines
6.4 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 { useState } from "react"
import { useRouter } from "next/navigation"
import { useSession } from "next-auth/react"
import { SiteHeader } from "@/components/site-header"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Alert, AlertDescription } from "@/components/ui/alert"
import { ArrowLeft, TreePine } from "lucide-react"
import Link from "next/link"
export default function NewTreePage() {
const router = useRouter()
const { data: session } = useSession()
const [name, setName] = useState("")
const [description, setDescription] = useState("")
const [error, setError] = useState("")
const [loading, setLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!name.trim()) {
setError("请输入家族树名称")
return
}
setError("")
setLoading(true)
try {
const response = await fetch("/api/trees", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name.trim(),
description: description.trim() || undefined,
}),
})
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || "创建失败")
}
// 创建成功,强制刷新页面以更新家族树列表
window.location.href = `/?treeId=${data.tree.id}`
} catch (err: any) {
setError(err.message || "创建失败,请稍后重试")
} finally {
setLoading(false)
}
}
if (!session) {
return (
<div className="min-h-screen bg-background flex flex-col">
<SiteHeader />
<div className="flex-1 flex items-center justify-center">
<Card className="w-full max-w-md mx-4">
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardFooter>
<Button asChild className="w-full">
<Link href="/auth/signin"></Link>
</Button>
</CardFooter>
</Card>
</div>
</div>
)
}
return (
<div className="min-h-screen bg-background flex flex-col">
<SiteHeader />
<main className="container mx-auto py-12 px-4 md:px-6 flex-1">
<div className="max-w-2xl mx-auto">
<div className="mb-8 text-center">
<h1 className="text-4xl font-serif font-light mb-3 tracking-wide"></h1>
<p className="text-muted-foreground font-light">
</p>
</div>
<Card className="border-none shadow-sm bg-card/50 backdrop-blur">
<form onSubmit={handleSubmit}>
<CardHeader className="text-center pb-8">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 text-primary mb-4 mx-auto">
<TreePine className="h-8 w-8" strokeWidth={1.5} />
</div>
<CardTitle className="text-2xl font-serif font-light"></CardTitle>
<CardDescription className="font-light">
</CardDescription>
</CardHeader>
<CardContent className="space-y-8 px-8">
{error && (
<Alert variant="destructive">
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="space-y-3">
<Label htmlFor="name" className="text-base font-normal">
<span className="text-destructive">*</span>
</Label>
<Input
id="name"
placeholder="例如:王氏家族、李氏宗谱"
value={name}
onChange={(e) => setName(e.target.value)}
maxLength={50}
required
className="h-12"
/>
<p className="text-xs text-muted-foreground font-light">
使+/
</p>
</div>
<div className="space-y-3">
<Label htmlFor="description" className="text-base font-normal"></Label>
<Textarea
id="description"
placeholder="简要描述您的家族历史、祖籍地等信息"
value={description}
onChange={(e) => setDescription(e.target.value)}
rows={4}
maxLength={500}
className="resize-none"
/>
<p className="text-xs text-muted-foreground font-light">
{description.length}/500
</p>
</div>
<div className="rounded-lg bg-muted/30 p-6 space-y-2">
<p className="text-sm text-muted-foreground font-light leading-relaxed">
</p>
</div>
</CardContent>
<CardFooter className="flex gap-4 px-8 pt-8 pb-8">
<Button
type="button"
variant="outline"
onClick={() => router.back()}
disabled={loading}
className="flex-1 h-12"
>
</Button>
<Button
type="submit"
disabled={loading || !name.trim()}
className="flex-1 h-12 bg-primary text-primary-foreground hover:bg-primary/90"
>
{loading ? "创建中..." : "创建家族树"}
</Button>
</CardFooter>
</form>
</Card>
</div>
</main>
</div>
)
}