"use client" import { UserRoundIcon } from "lucide-react" import { type ComponentProps, useContext } from "react" import { AuthUIContext } from "../lib/auth-ui-provider" import { getGravatarUrl } from "../lib/gravatar-utils" import { cn } from "../lib/utils" import type { AuthLocalization } from "../localization/auth-localization" import type { Profile } from "../types/profile" import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar" import { Skeleton } from "./ui/skeleton" export interface UserAvatarClassNames { base?: string image?: string fallback?: string fallbackIcon?: string skeleton?: string } export interface UserAvatarProps { classNames?: UserAvatarClassNames isPending?: boolean size?: "sm" | "default" | "lg" | "xl" | null user?: Profile | null /** * @default authLocalization * @remarks `AuthLocalization` */ localization?: Partial } /** * Displays a user avatar with image and fallback support * * Renders a user's avatar image when available, with appropriate fallbacks: * - Shows a skeleton when isPending is true * - Displays first two characters of user's name when no image is available * - Falls back to a generic user icon when neither image nor name is available */ export function UserAvatar({ className, classNames, isPending, size, user, localization: propLocalization, ...props }: UserAvatarProps & ComponentProps) { const { localization: contextLocalization, gravatar, avatar } = useContext(AuthUIContext) const localization = { ...contextLocalization, ...propLocalization } const name = user?.displayName || user?.name || user?.fullName || user?.firstName || user?.displayUsername || user?.username || user?.email const userImage = user?.image || user?.avatar || user?.avatarUrl // Calculate gravatar URL synchronously const gravatarUrl = gravatar && user?.email ? getGravatarUrl( user.email, gravatar === true ? undefined : gravatar ) : null const src = gravatar ? gravatarUrl : userImage if (isPending) { return ( ) } return ( {avatar?.Image ? ( ) : ( )} {firstTwoCharacters(name) || ( )} ) } const firstTwoCharacters = (name?: string | null) => name?.slice(0, 2)