This commit is contained in:
freedakgmail
2025-11-30 12:04:05 +08:00
parent 5f002e2ce6
commit 0281885f73
156 changed files with 494 additions and 341 deletions
+9 -14
View File
@@ -655,20 +655,15 @@ export default function MemberProfilePage() {
<Images className="h-5 w-5 text-primary" />
</h3>
{member.photoIds && member.photoIds.length > 0 ? (
<PhotoGallery
photoIds={member.photoIds}
onChange={async (photoIds) => {
await updateMember(member.id, { photoIds })
setLastSaveTime(Date.now())
}}
readonly={false}
/>
) : (
<div className="text-sm text-muted-foreground text-center py-10">
</div>
)}
<PhotoGallery
photos={member.photos}
photoIds={member.photoIds}
onChange={async (photos) => {
await updateMember(member.id, { photos, photoIds: undefined })
setLastSaveTime(Date.now())
}}
readonly={false}
/>
</div>
</TabsContent>
+51 -20
View File
@@ -6,7 +6,7 @@ import Image from "next/image"
import dynamic from "next/dynamic"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Dialog, DialogContent } from "@/components/ui/dialog"
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"
import { SiteHeader } from "@/components/site-header"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
@@ -158,16 +158,32 @@ export default function DashboardPage() {
const allPhotos = useMemo(() => {
const photos: Array<{
url: string
caption?: string
uploadedAt: string
memberId: string
memberName: string
isDead: boolean
}> = []
Object.values(treeData.members).forEach(member => {
if (member.photoIds && member.photoIds.length > 0) {
// 优先使用新格式 photos
if (member.photos && member.photos.length > 0) {
member.photos.forEach(photo => {
photos.push({
url: photo.url,
caption: photo.caption,
uploadedAt: photo.uploadedAt,
memberId: member.id,
memberName: member.fullName,
isDead: !!member.deathDate
})
})
} else if (member.photoIds && member.photoIds.length > 0) {
// 兼容旧格式 photoIds
member.photoIds.forEach(url => {
photos.push({
url,
uploadedAt: member.updatedAt || new Date().toISOString(),
memberId: member.id,
memberName: member.fullName,
isDead: !!member.deathDate
@@ -176,8 +192,8 @@ export default function DashboardPage() {
}
})
// 随机打乱顺序,让展示更有趣
return photos.sort(() => Math.random() - 0.5)
// 按上传时间倒序排列(最新的在前)
return photos.sort((a, b) => new Date(b.uploadedAt).getTime() - new Date(a.uploadedAt).getTime())
}, [treeData])
// 获取本月纪念日(生日和忌日)- 支持农历
@@ -546,25 +562,39 @@ export default function DashboardPage() {
>
<img
src={photo.url}
alt={`${photo.memberName}的照片`}
alt={photo.caption || `${photo.memberName}的照片`}
className="w-full h-auto object-cover"
loading="lazy"
/>
</div>
{/* 底部显示成员名称 - 点击跳转 */}
<div className="px-3 py-2 bg-card border-t border-border/30">
<div className="flex items-center gap-1.5 text-xs">
<span className="text-muted-foreground"></span>
<Link
href={`/members/${photo.memberId}${currentTree?.id ? `?treeId=${currentTree.id}` : ''}`}
className="hover:text-primary hover:underline"
>
<MemberNameWithStatus
name={photo.memberName}
isDead={photo.isDead}
className="text-foreground font-medium"
/>
</Link>
{/* 底部显示信息 */}
<div className="px-3 py-2 bg-card border-t border-border/30 space-y-1">
{/* 照片说明 */}
<div className="text-xs line-clamp-2">
{photo.caption ? (
<span className="text-foreground">{photo.caption}</span>
) : (
<span className="text-muted-foreground/70"></span>
)}
</div>
{/* 分享人和时间 */}
<div className="flex items-center justify-between gap-1.5 text-xs">
<div className="flex items-center gap-1">
<span className="text-muted-foreground"></span>
<Link
href={`/members/${photo.memberId}${currentTree?.id ? `?treeId=${currentTree.id}` : ''}`}
className="hover:text-primary hover:underline"
>
<MemberNameWithStatus
name={photo.memberName}
isDead={photo.isDead}
className="text-foreground font-medium"
/>
</Link>
</div>
<span className="text-muted-foreground/70 text-[10px]">
{format(new Date(photo.uploadedAt), 'yyyy-MM-dd')}
</span>
</div>
</div>
</div>
@@ -992,7 +1022,8 @@ export default function DashboardPage() {
{/* 照片放大预览 Dialog */}
<Dialog open={!!selectedPhoto} onOpenChange={() => setSelectedPhoto(null)}>
<DialogContent className="max-w-4xl p-0 bg-black/95 border-none">
<DialogContent className="max-w-4xl p-0 bg-black/95 border-none" aria-describedby={undefined}>
<DialogTitle className="sr-only"></DialogTitle>
{selectedPhoto && (
<img
src={selectedPhoto}