brackt/app/components/TeamAvatar.tsx
2026-05-06 14:47:37 -07:00

88 lines
1.9 KiB
TypeScript

import { avatarColor } from "~/lib/avatar-colors";
import { resolveTeamAvatarData } from "~/lib/avatar-data";
import type { AvatarData, RawFlagConfig } from "~/lib/flag-types";
import { FlagSvg } from "~/components/ui/FlagSvg";
import { cn } from "~/lib/utils";
import { cloudinaryAvatarUrl } from "~/lib/cloudinary-url";
export interface TeamAvatarProps {
teamId: string;
teamName: string;
logoUrl?: string | null;
flagConfig?: RawFlagConfig | null;
avatarType?: string | null;
ownerAvatarData?: AvatarData | null;
size?: "sm" | "md" | "lg" | "xl";
className?: string;
}
const sizeClasses = {
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 = {
sm: 24,
md: 36,
lg: 48,
xl: 64,
};
export function TeamAvatar({
teamId,
teamName,
logoUrl,
flagConfig,
avatarType,
ownerAvatarData,
size = "md",
className,
}: TeamAvatarProps) {
const avatar = resolveTeamAvatarData(
{ id: teamId, logoUrl, flagConfig, avatarType },
ownerAvatarData
);
if (avatar.type === "image") {
return (
<img
src={cloudinaryAvatarUrl(avatar.url, pixelSizes[size])}
alt={teamName}
className={cn(sizeClasses[size], "object-cover shrink-0", className)}
/>
);
}
if (avatar.type === "flag") {
return (
<FlagSvg
config={avatar.config}
size={pixelSizes[size]}
title={teamName}
className={cn(sizeClasses[size], className)}
/>
);
}
const color = avatarColor(teamId);
const initials =
teamName
.split(/\s+/)
.filter(Boolean)
.slice(0, 2)
.map((w) => w[0].toUpperCase())
.join("") || "?";
return (
<div
role="img"
aria-label={teamName}
className={cn(sizeClasses[size], "flex shrink-0 items-center justify-center font-bold", className)}
style={{ backgroundColor: "#000", color }}
>
{initials}
</div>
);
}