"use client" import { useState, useRef, useEffect } from "react" import { Button } from "@/components/ui/button" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Upload, X, Loader2 } from "lucide-react" import { db } from "@/lib/db" import { v4 as uuidv4 } from "uuid" interface ImageUploadProps { value?: string // The image ID onChange: (imageId: string | undefined) => void className?: string } export function ImageUpload({ value, onChange, className }: ImageUploadProps) { const [previewUrl, setPreviewUrl] = useState(undefined) const [isLoading, setIsLoading] = useState(false) const fileInputRef = useRef(null) // Load preview if value (imageId) exists useEffect(() => { let objectUrl: string | undefined const loadPreview = async () => { if (!value) { setPreviewUrl(undefined) return } try { const image = await db.images.get(value) if (image) { objectUrl = URL.createObjectURL(image.blob) setPreviewUrl(objectUrl) } } catch (error) { console.error("Failed to load image:", error) } } loadPreview() return () => { if (objectUrl) URL.revokeObjectURL(objectUrl) } }, [value]) const handleFileSelect = async (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (!file) return setIsLoading(true) try { // Basic validation if (!file.type.startsWith("image/")) { alert("请选择图片文件") return } if (file.size > 5 * 1024 * 1024) { alert("图片大小不能超过 5MB") return } // Save to DB const imageId = uuidv4() await db.images.add({ id: imageId, blob: file, mimeType: file.type, createdAt: new Date().toISOString(), }) onChange(imageId) } catch (error) { console.error("Failed to save image:", error) alert("图片上传失败") } finally { setIsLoading(false) // Reset input if (fileInputRef.current) fileInputRef.current.value = "" } } const handleRemove = () => { onChange(undefined) } return (
{isLoading ? : }
{value && ( )}
) }