57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
|
import { db } from "@/lib/db"
|
|
import { CircleUser, CircleUserRound } from "lucide-react"
|
|
import type { Gender } from "@/types/family"
|
|
|
|
interface AvatarDisplayProps {
|
|
imageId?: string
|
|
fallbackUrl?: string
|
|
fallbackText?: string
|
|
gender?: Gender
|
|
className?: string
|
|
}
|
|
|
|
export function AvatarDisplay({ imageId, fallbackUrl, fallbackText, gender, className }: AvatarDisplayProps) {
|
|
const [blobUrl, setBlobUrl] = useState<string | undefined>(undefined)
|
|
|
|
useEffect(() => {
|
|
if (imageId) {
|
|
db.images.get(imageId).then((image) => {
|
|
if (image) {
|
|
const url = URL.createObjectURL(image.blob)
|
|
setBlobUrl(url)
|
|
return () => URL.revokeObjectURL(url)
|
|
}
|
|
})
|
|
} else {
|
|
setBlobUrl(undefined)
|
|
}
|
|
}, [imageId])
|
|
|
|
// 如果有头像,显示头像
|
|
if (blobUrl) {
|
|
return (
|
|
<Avatar className={className}>
|
|
<AvatarImage src={blobUrl} />
|
|
<AvatarFallback className="text-lg font-serif bg-muted">{fallbackText}</AvatarFallback>
|
|
</Avatar>
|
|
)
|
|
}
|
|
|
|
// 没有头像,显示性别图标
|
|
return (
|
|
<Avatar className={className}>
|
|
<AvatarFallback className="bg-muted flex items-center justify-center">
|
|
{gender === 'female' ? (
|
|
<CircleUserRound className="h-8 w-8 text-pink-400" />
|
|
) : (
|
|
<CircleUser className="h-8 w-8 text-blue-400" />
|
|
)}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
)
|
|
}
|