66 lines
1.4 KiB
TypeScript
66 lines
1.4 KiB
TypeScript
const AVATAR_COLORS = [
|
|
"#adf661",
|
|
"#2ce1c1",
|
|
"#8b5cf6",
|
|
"#f59e0b",
|
|
"#ef4444",
|
|
"#3b82f6",
|
|
];
|
|
|
|
function hashName(name: string): number {
|
|
let hash = 0;
|
|
for (let i = 0; i < name.length; i++) {
|
|
hash = (hash * 31 + name.charCodeAt(i)) & 0xffff;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
interface TeamOwnerBadgeProps {
|
|
teamName: string;
|
|
ownerName?: string;
|
|
align?: "left" | "right";
|
|
}
|
|
|
|
export function TeamOwnerBadge({
|
|
teamName,
|
|
ownerName,
|
|
align = "left",
|
|
}: TeamOwnerBadgeProps) {
|
|
const initials =
|
|
teamName
|
|
.split(/\s+/)
|
|
.filter(Boolean)
|
|
.slice(0, 2)
|
|
.map((w) => w[0].toUpperCase())
|
|
.join("") || "?";
|
|
const color = AVATAR_COLORS[hashName(teamName) % AVATAR_COLORS.length];
|
|
|
|
const avatar = (
|
|
<div
|
|
role="img"
|
|
aria-label={teamName}
|
|
className="h-6 w-6 flex shrink-0 items-center justify-center font-bold text-[10px]"
|
|
style={{ backgroundColor: "#000", color }}
|
|
>
|
|
{initials}
|
|
</div>
|
|
);
|
|
|
|
const text = (
|
|
<div className={`min-w-0 ${align === "right" ? "text-right" : ""}`}>
|
|
<p className="text-xs font-medium truncate">{teamName}</p>
|
|
{ownerName && (
|
|
<p className="text-xs text-muted-foreground truncate">{ownerName}</p>
|
|
)}
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className={`flex items-center gap-2 ${align === "right" ? "flex-row-reverse" : ""}`}
|
|
>
|
|
{avatar}
|
|
{text}
|
|
</div>
|
|
);
|
|
}
|