/**
* — overlapping avatar stack for meeting participants.
*
* Granola-style: up to 4 avatars (-space-x), then "+N" pill. Each avatar
* gets a shadcn Tooltip showing name/email. Used on both list cards and
* detail headers.
*/
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
export interface AttendeeStackParticipant {
id?: string;
email: string;
name?: string | null;
isOrganizer?: boolean;
}
export function attendeeInitials(p: AttendeeStackParticipant | string): string {
const src =
typeof p === "string" ? p : p.name?.trim() || p.email?.trim() || "?";
const parts = src
.replace(/@.*$/, "")
.split(/\s+|[._-]/)
.filter(Boolean);
if (parts.length === 0) return "?";
if (parts.length === 1) return parts[0]!.slice(0, 2).toUpperCase();
return ((parts[0]![0] ?? "") + (parts[1]![0] ?? "")).toUpperCase();
}
interface AttendeeStackProps {
participants: AttendeeStackParticipant[];
max?: number;
size?: "xs" | "sm" | "md";
}
export function AttendeeStack({
participants,
max = 4,
size = "sm",
}: AttendeeStackProps) {
if (!participants || participants.length === 0) return null;
const visible = participants.slice(0, max);
const extra = participants.length - visible.length;
const sizeClass =
size === "xs"
? "h-5 w-5 text-[8px]"
: size === "md"
? "h-7 w-7 text-[11px]"
: "h-6 w-6 text-[9px]";
return (
{visible.map((p, i) => (
{attendeeInitials(p)}
{p.name || p.email}
{p.name && (
{p.email}
)}
))}
{extra > 0 && (
+{extra}
)}
);
}