This commit is contained in:
freedakgmail
2025-11-22 23:49:24 +08:00
parent b83382b604
commit c033e46782
3580 changed files with 1745279 additions and 2428 deletions
+148 -22
View File
@@ -7,10 +7,12 @@ import { useFamily } from "@/context/family-context"
import { SiteHeader } from "@/components/site-header"
import { MemberForm } from "@/components/members/member-form"
import { Button } from "@/components/ui/button"
import { ArrowLeft, Edit, Trash, Share2, Printer } from "lucide-react"
import { ArrowLeft, Edit, Trash, Share2, Printer, CircleUser, CircleUserRound, Images, BookOpen } from "lucide-react"
import { useState, useEffect } from "react"
import type { FamilyMember } from "@/types/family"
import { db } from "@/lib/db"
import { PhotoGallery } from "@/components/members/photo-gallery"
import { StoryManager } from "@/components/members/story-manager"
export default function MemberProfilePage() {
const { id } = useParams()
@@ -85,14 +87,18 @@ export default function MemberProfilePage() {
<div className="flex flex-col md:flex-row justify-between items-start gap-6 mb-8 border-b border-border pb-8">
<div className="flex items-start gap-6">
<div className="h-32 w-32 rounded-lg bg-muted flex items-center justify-center border-2 border-primary/20 overflow-hidden">
{avatarBlobUrl || member.avatarUrl ? (
{avatarBlobUrl ? (
<img
src={avatarBlobUrl || member.avatarUrl || "/placeholder.svg"}
src={avatarBlobUrl}
alt={member.fullName}
className="h-full w-full object-cover"
/>
) : (
<span className="text-4xl font-serif font-bold text-muted-foreground/50">{member.surname}</span>
member.gender === 'female' ? (
<CircleUserRound className="h-20 w-20 text-pink-400" />
) : (
<CircleUser className="h-20 w-20 text-blue-400" />
)
)}
</div>
<div>
@@ -152,6 +158,40 @@ export default function MemberProfilePage() {
</div>
</section>
{/* Photo Gallery */}
{member.photoIds && member.photoIds.length > 0 && (
<section>
<h2 className="text-2xl font-serif font-bold mb-4 flex items-center gap-2">
<Images className="h-6 w-6 text-primary" />
</h2>
<div className="bg-card p-6 rounded-lg border border-border shadow-sm">
<PhotoGallery
photoIds={member.photoIds}
onChange={(photoIds) => updateMember(member.id, { photoIds })}
readonly={false}
/>
</div>
</section>
)}
{/* Family Stories */}
{member.stories && member.stories.length > 0 && (
<section>
<h2 className="text-2xl font-serif font-bold mb-4 flex items-center gap-2">
<BookOpen className="h-6 w-6 text-primary" />
</h2>
<div className="bg-card p-6 rounded-lg border border-border shadow-sm">
<StoryManager
stories={member.stories}
onChange={(stories) => updateMember(member.id, { stories })}
readonly={false}
/>
</div>
</section>
)}
<section>
<h2 className="text-2xl font-serif font-bold mb-4 flex items-center gap-2">
<span className="w-1 h-6 bg-secondary rounded-full"></span>
@@ -167,12 +207,47 @@ export default function MemberProfilePage() {
href={`/members/${member.fatherId}`}
className="text-lg font-serif font-bold hover:underline text-primary"
>
{getMember(member.fatherId)?.fullName || member.fatherId}
</Link>
) : (
<span className="text-muted-foreground">-</span>
)}
</div>
<div className="bg-card p-4 rounded-lg border border-border">
<h3 className="font-medium text-muted-foreground mb-2 text-sm uppercase tracking-wider">
(Mother)
</h3>
{member.motherId ? (
<Link
href={`/members/${member.motherId}`}
className="text-lg font-serif font-bold hover:underline text-primary"
>
{getMember(member.motherId)?.fullName || member.motherId}
</Link>
) : (
<span className="text-muted-foreground">-</span>
)}
</div>
<div className="bg-card p-4 rounded-lg border border-border">
<h3 className="font-medium text-muted-foreground mb-2 text-sm uppercase tracking-wider">
(Spouse)
</h3>
<div className="flex flex-wrap gap-2">
{member.spouseIds?.length > 0 ? (
member.spouseIds.map((spouseId) => (
<Link
href={`/members/${spouseId}`}
key={spouseId}
className="px-3 py-1 bg-muted rounded hover:bg-muted/80 text-sm font-medium"
>
{getMember(spouseId)?.fullName || spouseId}
</Link>
))
) : (
<span className="text-muted-foreground"></span>
)}
</div>
</div>
<div className="bg-card p-4 rounded-lg border border-border">
<h3 className="font-medium text-muted-foreground mb-2 text-sm uppercase tracking-wider">
(Children)
@@ -185,7 +260,7 @@ export default function MemberProfilePage() {
key={childId}
className="px-3 py-1 bg-muted rounded hover:bg-muted/80 text-sm font-medium"
>
{childId} {/* In real app, fetch name */}
{getMember(childId)?.fullName || childId}
</Link>
))
) : (
@@ -206,24 +281,75 @@ export default function MemberProfilePage() {
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.birthDate || "-"}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.deathDate || "-"}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.generationName || "-"}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.posthumousName || "-"}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.burialPlace || "-"}</dd>
</div>
{member.deathDate && (
<>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.deathDate}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.posthumousName || "-"}</dd>
</div>
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.burialPlace || "-"}</dd>
</div>
</>
)}
{member.generationName && (
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.generationName}</dd>
</div>
)}
</dl>
</div>
{/* 联系方式 */}
{(member.phone || member.telephone || member.email || member.address) && (
<div className="bg-card rounded-lg border border-border p-6 shadow-sm">
<h3 className="font-serif font-bold text-lg mb-4 border-b border-border pb-2"></h3>
<dl className="space-y-4 text-sm">
{member.phone && (
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">
<a href={`tel:${member.phone}`} className="hover:text-primary">
{member.phone}
</a>
</dd>
</div>
)}
{member.telephone && (
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">
<a href={`tel:${member.telephone}`} className="hover:text-primary">
{member.telephone}
</a>
</dd>
</div>
)}
{member.email && (
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">
<a href={`mailto:${member.email}`} className="hover:text-primary">
{member.email}
</a>
</dd>
</div>
)}
{member.address && (
<div>
<dt className="text-muted-foreground"></dt>
<dd className="font-medium">{member.address}</dd>
</div>
)}
</dl>
</div>
)}
</div>
</div>
</main>