"use client"; import { useState, useRef, ChangeEvent, useEffect } from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Camera, Upload, X, Loader2 } from "lucide-react"; import { cn } from "@/lib/utils"; import { useProfile } from "@/hooks/use-profile"; interface ProfilePictureUploadProps { initialImage?: string; onImageChange?: (file: File | null, imageUrl: string | null) => void; fallbackText?: string; size?: "sm" | "md" | "lg" | "xl"; className?: string; disabled?: boolean; useDatabase?: boolean; // Nova prop para usar ou não o banco de dados } const sizeClasses = { sm: "w-16 h-16", md: "w-24 h-24", lg: "w-32 h-32", xl: "w-40 h-40", }; export function ProfilePictureUpload({ initialImage, onImageChange, fallbackText = "U", size = "lg", className, disabled = false, useDatabase = true, }: ProfilePictureUploadProps) { const [selectedImage, setSelectedImage] = useState( initialImage || null ); const [isHovering, setIsHovering] = useState(false); const [isUploading, setIsUploading] = useState(false); const fileInputRef = useRef(null); // Usar o hook apenas se useDatabase for true const { profileImage, saveProfileImage, removeProfileImage, isLoading } = useDatabase ? useProfile() : { profileImage: null, saveProfileImage: async () => "", removeProfileImage: () => {}, isLoading: false, }; // Sincronizar com a imagem do banco de dados useEffect(() => { if (useDatabase && profileImage && !selectedImage) { setSelectedImage(profileImage); } }, [profileImage, selectedImage, useDatabase]); const handleImageChange = async (event: ChangeEvent) => { const file = event.target.files?.[0]; if (file) { // Validar tipo de arquivo const validTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"]; if (!validTypes.includes(file.type)) { alert( "Por favor, selecione um arquivo de imagem válido (JPG, PNG, GIF ou WebP)" ); return; } // Validar tamanho do arquivo (máximo 2MB) const maxSize = 2 * 1024 * 1024; // 2MB em bytes if (file.size > maxSize) { alert("O arquivo deve ter no máximo 2MB"); return; } setIsUploading(true); try { let imageUrl: string; if (useDatabase) { // Salvar no banco de dados local imageUrl = await saveProfileImage(file); } else { // Apenas criar URL local imageUrl = URL.createObjectURL(file); } setSelectedImage(imageUrl); // Chamar callback se fornecido onImageChange?.(file, imageUrl); } catch (error) { console.error("Erro ao processar imagem:", error); alert("Erro ao salvar a imagem. Tente novamente."); } finally { setIsUploading(false); } } }; const handleClick = () => { if (!disabled && !isUploading) { fileInputRef.current?.click(); } }; const handleRemoveImage = async (e: React.MouseEvent) => { e.stopPropagation(); if (useDatabase) { removeProfileImage(); } setSelectedImage(null); onImageChange?.(null, null); // Limpar o input if (fileInputRef.current) { fileInputRef.current.value = ""; } }; const isDisabled = disabled || isUploading || (useDatabase && isLoading); return (
Profile Photo
!isDisabled && setIsHovering(true)} onMouseLeave={() => setIsHovering(false)} onClick={handleClick} > {isLoading || isUploading ? ( ) : selectedImage ? null : ( fallbackText )} {/* Overlay com ícone */}
{isUploading ? ( ) : ( )}
{/* Botão de remover imagem */} {selectedImage && !isDisabled && ( )}

JPG, PNG ou GIF. Máximo 2MB.

{useDatabase && (

💾 Salvando automaticamente

)}
{/* Input file oculto */}
); }