import { useState, useEffect } from "react"; import { User } from "lucide-react"; interface AvatarProps { /** URL do avatar, objeto com avatar_url, ou userId para buscar */ src?: | string | { avatar_url?: string | null } | { profile?: { avatar_url?: string | null } } | { id?: string }; /** Nome completo para gerar iniciais */ name?: string; /** Tamanho do avatar */ size?: "xs" | "sm" | "md" | "lg" | "xl"; /** Cor do gradiente (se não tiver imagem) */ color?: | "blue" | "green" | "purple" | "orange" | "pink" | "teal" | "indigo" | "red"; /** Classe CSS adicional */ className?: string; /** Se deve mostrar borda */ border?: boolean; } const sizeClasses = { xs: "w-6 h-6 text-xs", sm: "w-8 h-8 text-xs", md: "w-10 h-10 text-sm", lg: "w-12 h-12 text-base", xl: "w-16 h-16 text-xl", }; const colorClasses = { blue: "from-blue-400 to-blue-600", green: "from-green-400 to-green-600", purple: "from-purple-400 to-purple-600", orange: "from-orange-400 to-orange-600", pink: "from-pink-400 to-pink-600", teal: "from-teal-400 to-teal-600", indigo: "from-indigo-400 to-indigo-600", red: "from-red-400 to-red-600", }; /** * Componente Avatar * - Mostra imagem se disponível * - Mostra iniciais como fallback * - Suporta diferentes tamanhos e cores */ export function Avatar({ src, name = "", size = "md", color = "blue", className = "", border = false, }: AvatarProps) { const [imageUrl, setImageUrl] = useState(null); const [imageError, setImageError] = useState(false); // Extrai URL do avatar useEffect(() => { if (!src) { setImageUrl(null); return; } if (typeof src === "string") { setImageUrl(src); } else if ("avatar_url" in src && src.avatar_url) { setImageUrl(src.avatar_url); } else if ("profile" in src && src.profile?.avatar_url) { setImageUrl(src.profile.avatar_url); } else if ("id" in src && src.id) { // Gera URL pública do Supabase Storage const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; setImageUrl( `${SUPABASE_URL}/storage/v1/object/public/avatars/${src.id}/avatar` ); } else { setImageUrl(null); } setImageError(false); }, [src]); // Gera iniciais do nome const getInitials = (fullName: string): string => { if (!fullName) return "?"; const parts = fullName.trim().split(" "); if (parts.length === 1) { return parts[0].substring(0, 2).toUpperCase(); } return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); }; const initials = getInitials(name); const shouldShowImage = imageUrl && !imageError; return (
{shouldShowImage ? ( {name setImageError(true)} /> ) : ( {initials} )}
); } /** * Avatar com ícone padrão (para casos sem nome) */ export function AvatarIcon({ size = "md", className = "", }: Pick) { return (
); }