"use client" import type React from "react" import { useState, useEffect } from "react" import type { FamilyMember, FamilyPhoto } from "@/types/family" 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { CalendarIcon, User, Scroll, Users, Images, BookOpen } from "lucide-react" import { ChineseCard, ChineseCardContent, ChineseCardHeader, ChineseCardTitle, ChineseCardDescription } from "@/components/ui/chinese-card" import { Switch } from "@/components/ui/switch" import { ImageUpload } from "@/components/ui/image-upload" import { PhotoGallery } from "./photo-gallery" import { StoryManager } from "./story-manager" import { DateInputWithLunar } from "@/components/ui/date-input-with-lunar" import { MemberNameWithStatus } from "@/components/member-name-with-status" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" interface MemberFormProps { initialData?: Partial existingMembers?: FamilyMember[] onSubmit: (data: FamilyMember) => void onCancel: () => void isFounder?: boolean hideTabs?: boolean activeTab?: string } export function MemberForm({ initialData, existingMembers = [], onSubmit, onCancel, isFounder = false, hideTabs = false, activeTab = "basic" }: MemberFormProps) { // 计算最大世系 const maxGeneration = existingMembers.length > 0 ? Math.max(...existingMembers.map(m => m.generation || 1)) : 1 // 获取始祖的姓氏(第1世成员) const ancestorSurname = existingMembers.find(m => m.generation === 1)?.surname || "" // 始祖专用样式 const founderCardClass = isFounder ? "border-2 border-amber-400 shadow-md" : "" // 生成兼容的UUID const generateUUID = () => { if (typeof crypto !== 'undefined' && crypto.randomUUID) { return crypto.randomUUID() } // 降级方案:生成简单的UUID return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0 const v = c === 'x' ? r : (r & 0x3 | 0x8) return v.toString(16) }) } // Initialize state with default values or initialData const [formData, setFormData] = useState>(() => { const defaults = { id: generateUUID(), surname: ancestorSurname, givenName: "", fullName: "", gender: "MALE" as "MALE" | "FEMALE", generation: maxGeneration, spouseIds: [], childrenIds: [], tags: [], photos: [] as FamilyPhoto[], photoIds: [] as string[], } if (!initialData) return defaults const normalizedPhotos: FamilyPhoto[] = initialData.photos && initialData.photos.length > 0 ? initialData.photos : (initialData.photoIds || []).map((url) => ({ url, uploadedAt: initialData.updatedAt || new Date().toISOString(), })) return { ...defaults, ...initialData, gender: (initialData.gender || "MALE").toUpperCase() as "MALE" | "FEMALE", spouseIds: initialData.spouseIds || [], childrenIds: initialData.childrenIds || [], tags: initialData.tags || [], fatherId: initialData.fatherId || undefined, motherId: initialData.motherId || undefined, photos: normalizedPhotos, photoIds: initialData.photoIds || normalizedPhotos.map((photo) => photo.url), } }) const [errors, setErrors] = useState([]) // 监听 initialData 变化,更新 formData useEffect(() => { if (!initialData) return setFormData((prev) => { const normalizedPhotos: FamilyPhoto[] = initialData.photos && initialData.photos.length > 0 ? initialData.photos : (initialData.photoIds || []).map((url) => ({ url, uploadedAt: initialData.updatedAt || new Date().toISOString(), })) // 优先使用 initialData 中的 motherId,如果没有才使用之前的值 const newMotherId = initialData.motherId !== undefined ? initialData.motherId : prev.motherId console.log('Calculating new motherId:', { initial: initialData.motherId, prev: prev.motherId, result: newMotherId, hasInitialMother: initialData.motherId !== undefined }) return { ...prev, ...initialData, // 确保特定字段被正确更新 gender: initialData.gender ? (initialData.gender.toUpperCase() as "MALE" | "FEMALE") : prev.gender, spouseIds: initialData.spouseIds || prev.spouseIds || [], childrenIds: initialData.childrenIds || prev.childrenIds || [], tags: initialData.tags || prev.tags || [], fatherId: initialData.fatherId || prev.fatherId, motherId: newMotherId, photos: initialData.photos ? normalizedPhotos : prev.photos, photoIds: initialData.photoIds || (initialData.photos ? normalizedPhotos.map((p) => p.url) : prev.photoIds), } }) }, [initialData]) const handleChange = (field: keyof FamilyMember, value: any) => { console.log('handleChange:', field, value) // 防御性检查:防止 Select 组件意外清空 initialData 中已有的值 // 这可能是由于 Select 组件在某些情况下(如选项尚未完全渲染)触发了无效的 onChange if ((field === 'motherId' || field === 'fatherId') && !value) { const initialValue = initialData?.[field] const currentValue = formData[field] // 只有当当前值等于初始值且尝试清空时才阻止 if (initialValue && currentValue === initialValue) { console.warn(`Prevented accidental clearing of ${field}`) return } // 如果当前值不为空,但尝试清空为空字符串,也阻止(因为Select组件可能发送空字符串而不是undefined) if (currentValue && value === '') { console.warn(`Prevented clearing of ${field} to empty string`) return } } setFormData((prev) => { const newData = { ...prev, [field]: value } // 自动更新全名 if (field === "surname" || field === "givenName") { newData.fullName = `${newData.surname || ""}${newData.givenName || ""}` } // 自动设置母亲从父亲 if (field === "fatherId" && value) { const father = existingMembers.find(m => m.id === value) if (father && father.spouseIds && father.spouseIds.length > 0) { const motherId = father.spouseIds[0] if (!newData.motherId) { // Only auto-set if motherId is not already present newData.motherId = motherId console.log('Auto-set mother from father:', { fatherId: value, motherId }) } } } // 自动设置父亲从母亲 if (field === "motherId" && value) { const mother = existingMembers.find(m => m.id === value) if (mother && mother.spouseIds && mother.spouseIds.length > 0) { const fatherId = mother.spouseIds[0] if (!newData.fatherId) { // Only auto-set if fatherId is not already present newData.fatherId = fatherId console.log('Auto-set father from mother:', { motherId: value, fatherId }) } } } return newData }) } const handlePhotosChange = (photos: FamilyPhoto[]) => { setFormData((prev) => ({ ...prev, photos, photoIds: photos.map(p => p.url), })) } const handleSpouseAdd = (spouseId: string) => { if (spouseId === "none") return setFormData((prev) => ({ ...prev, spouseIds: [...(prev.spouseIds || []), spouseId], })) } const handleSpouseRemove = (spouseId: string) => { setFormData((prev) => ({ ...prev, spouseIds: (prev.spouseIds || []).filter((id) => id !== spouseId), })) } const handleChildAdd = (childId: string) => { if (childId === "none") return setFormData((prev) => ({ ...prev, childrenIds: [...(prev.childrenIds || []), childId], })) } const handleChildRemove = (childId: string) => { setFormData((prev) => ({ ...prev, childrenIds: (prev.childrenIds || []).filter((id) => id !== childId), })) } const validateForm = (): boolean => { const newErrors: string[] = [] if (!formData.surname?.trim()) { newErrors.push("请填写姓氏") } if (!formData.givenName?.trim()) { newErrors.push("请填写名字") } if (!formData.gender) { newErrors.push("请选择性别") } if (!formData.generation || formData.generation < 1) { newErrors.push("请填写正确的世系") } // 关系验证:非始祖必须与家族建立联系 if (!isFounder) { // 1. 检查是否有主要成员的父母 const hasValidFather = formData.fatherId && existingMembers.some(m => m.id === formData.fatherId) const hasValidMother = formData.motherId && existingMembers.some(m => m.id === formData.motherId) // 2. 检查是否有主要成员的配偶 const hasValidSpouse = formData.spouseIds && formData.spouseIds.length > 0 && formData.spouseIds.some(id => existingMembers.some(m => m.id === id)) if (!hasValidFather && !hasValidMother && !hasValidSpouse) { newErrors.push("孤立成员:请选择家族成员作为父母,或添加家族成员为配偶") } } setErrors(newErrors) return newErrors.length === 0 } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (!validateForm()) { return } // 确保所有必填字段都有值 const memberData: FamilyMember = { id: formData.id || generateUUID(), surname: formData.surname || "", givenName: formData.givenName || "", fullName: formData.fullName || `${formData.surname || ""}${formData.givenName || ""}`, gender: formData.gender as "MALE" | "FEMALE", generation: formData.generation || 1, spouseIds: formData.spouseIds || [], childrenIds: formData.childrenIds || [], tags: formData.tags || [], photos: formData.photos || [], photoIds: formData.photoIds || [], fatherId: formData.fatherId, motherId: formData.motherId, spouseFatherName: formData.spouseFatherName, spouseMotherName: formData.spouseMotherName, phone: formData.phone, telephone: formData.telephone, email: formData.email, occupation: formData.occupation, courtesyName: formData.courtesyName, artName: formData.artName, generationName: formData.generationName, posthumousName: formData.posthumousName, birthDate: formData.birthDate, deathDate: formData.deathDate, isLunarDate: formData.isLunarDate || false, ancestralHome: formData.ancestralHome, birthPlace: formData.birthPlace, deathPlace: formData.deathPlace, burialPlace: formData.burialPlace, address: formData.address, bio: formData.bio, avatarUrl: formData.avatarUrl, stories: formData.stories || [], createdAt: formData.createdAt || new Date().toISOString(), updatedAt: new Date().toISOString(), } onSubmit(memberData) } const potentialRelatives = existingMembers.filter((m) => m.id !== formData.id) // 调试日志 console.log('MemberForm render:', { motherId: formData.motherId, existingMembersCount: existingMembers.length, motherInList: existingMembers.find(m => m.id === formData.motherId) }) return (
{errors.length > 0 && (

请检查以下问题:

    {errors.map((err, index) => (
  • {err}
  • ))}
)} {!hideTabs && (
基本信息 详细资料 生平影像 家族故事
)}
{/* 基本信息Tab - 包含基本信息和家庭关系 */} {/* 基本信息卡片 */} 基本信息 {/* 头像和基本信息两栏布局 */}
{/* 左侧:头像 */}
handleChange("avatarUrl", imageUrl || null)} />
{/* 右侧:表单 */}
handleChange("surname", e.target.value)} placeholder="例如:李" className={errors.includes("surname") ? "border-red-500" : ""} />
handleChange("givenName", e.target.value)} placeholder="例如:明" className={errors.includes("givenName") ? "border-red-500" : ""} />
handleChange("gender", val)} className="flex space-x-4" >
handleChange("generation", parseInt(e.target.value) || 0)} className="w-32" min={1} />
{/* 家庭关系 - 左右两个独立卡片 */}
{/* 左栏:父母 */} 父母 {!isFounder && ( 需关联父母或配偶以连接至家族树 )}
{isFounder ? ( handleChange("spouseFatherName", e.target.value)} /> ) : (
{!formData.fatherId && ( handleChange("spouseFatherName", e.target.value)} className="w-32" /> )}
)}
{isFounder ? ( handleChange("spouseMotherName", e.target.value)} /> ) : (
{!formData.motherId && ( handleChange("spouseMotherName", e.target.value)} className="w-32" /> )}
)}
{/* 右栏:配偶和子女 */} 配偶与子女 {!isFounder && ( 需关联父母或配偶以连接至家族树 )}
{formData.spouseIds && formData.spouseIds.length > 0 && (
{formData.spouseIds.map((spouseId, index) => { const spouse = existingMembers.find(m => m.id === spouseId) if (!spouse) return null return (
{index + 1}.
) })}
)}
{formData.childrenIds && formData.childrenIds.length > 0 && (
{formData.childrenIds.map((childId, index) => { const child = existingMembers.find(m => m.id === childId) if (!child) return null return (
{index + 1}.
) })}
)}
{/* 详细资料Tab */} {/* 使用两列布局放置两个卡片 */}
传统称谓
handleChange("courtesyName", e.target.value)} placeholder="例如:伯虎" />
handleChange("artName", e.target.value)} placeholder="例如:六如居士" />
handleChange("generationName", e.target.value)} />
handleChange("posthumousName", e.target.value)} />
生平日期
handleChange("birthDate", value)} showLunarToggle={false} /> handleChange("deathDate", value)} showLunarToggle={false} />
{/* 地点和简介卡片 */} 地点与简介
handleChange("ancestralHome", e.target.value)} placeholder="请输入籍贯" />
handleChange("birthPlace", e.target.value)} placeholder="请输入出生地" />
handleChange("address", e.target.value)} placeholder="请输入居住地" />
handleChange("deathPlace", e.target.value)} placeholder="请输入逝世地" />
handleChange("burialPlace", e.target.value)} placeholder="请输入安葬地" />
handleChange("occupation", e.target.value)} placeholder="请输入职业" />
handleChange("phone", e.target.value)} placeholder="请输入手机号" />
handleChange("telephone", e.target.value)} placeholder="请输入固定电话" />
handleChange("email", e.target.value)} placeholder="请输入电子邮箱" />