66 lines
1.4 KiB
TypeScript
66 lines
1.4 KiB
TypeScript
|
|
import { resolveUserAvatarData } from "~/lib/avatar-data";
|
||
|
|
import { cn } from "~/lib/utils";
|
||
|
|
import { FlagSvg } from "~/components/ui/FlagSvg";
|
||
|
|
import type { RawFlagConfig } from "~/lib/flag-types";
|
||
|
|
import { cloudinaryAvatarUrl } from "~/lib/cloudinary-url";
|
||
|
|
|
||
|
|
interface UserAvatarProps {
|
||
|
|
userId: string;
|
||
|
|
name?: string | null;
|
||
|
|
email?: string | null;
|
||
|
|
customAvatarUrl?: string | null;
|
||
|
|
flagConfig?: RawFlagConfig | null;
|
||
|
|
avatarType?: string | null;
|
||
|
|
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
||
|
|
className?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
const sizeClasses = {
|
||
|
|
xs: "h-5 w-5 text-[9px]",
|
||
|
|
sm: "h-6 w-6 text-[10px]",
|
||
|
|
md: "h-9 w-9 text-sm",
|
||
|
|
lg: "h-12 w-12 text-base",
|
||
|
|
xl: "h-16 w-16 text-xl",
|
||
|
|
};
|
||
|
|
|
||
|
|
const pixelSizes = {
|
||
|
|
xs: 20,
|
||
|
|
sm: 24,
|
||
|
|
md: 36,
|
||
|
|
lg: 48,
|
||
|
|
xl: 64,
|
||
|
|
};
|
||
|
|
|
||
|
|
export function UserAvatar({
|
||
|
|
userId,
|
||
|
|
name,
|
||
|
|
email,
|
||
|
|
customAvatarUrl,
|
||
|
|
flagConfig,
|
||
|
|
avatarType,
|
||
|
|
size = "md",
|
||
|
|
className,
|
||
|
|
}: UserAvatarProps) {
|
||
|
|
const avatar = resolveUserAvatarData({ id: userId, customAvatarUrl, flagConfig, avatarType });
|
||
|
|
const label = name ?? email ?? "User avatar";
|
||
|
|
|
||
|
|
if (avatar.type === "image") {
|
||
|
|
return (
|
||
|
|
<img
|
||
|
|
src={cloudinaryAvatarUrl(avatar.url, pixelSizes[size])}
|
||
|
|
alt={label}
|
||
|
|
className={cn(sizeClasses[size], "object-cover shrink-0", className)}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<FlagSvg
|
||
|
|
config={avatar.config}
|
||
|
|
size={pixelSizes[size]}
|
||
|
|
title={label}
|
||
|
|
className={cn(sizeClasses[size], className)}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
}
|