73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
'use client';
|
|
|
|
import { UserRound } from 'lucide-react';
|
|
|
|
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
import { cn } from '@/lib/utils';
|
|
import type { TicketActor } from '@/types';
|
|
import { getPersonLabel } from '@/utils/person';
|
|
|
|
type PersonAvatarProps = {
|
|
person: TicketActor | null | undefined;
|
|
size?: 'default' | 'sm' | 'lg';
|
|
className?: string;
|
|
};
|
|
|
|
export function PersonAvatar({
|
|
person,
|
|
size = 'default',
|
|
className,
|
|
}: PersonAvatarProps) {
|
|
const avatarUrl = person?.avatar_url?.trim();
|
|
|
|
return (
|
|
<Avatar size={size} className={className}>
|
|
{avatarUrl ? (
|
|
<AvatarImage src={avatarUrl} alt={getPersonLabel(person)} />
|
|
) : null}
|
|
<AvatarFallback className="bg-muted text-muted-foreground">
|
|
<UserRound
|
|
className={cn(
|
|
'shrink-0',
|
|
size === 'sm' ? 'size-3.5' : size === 'lg' ? 'size-5' : 'size-4',
|
|
)}
|
|
aria-hidden
|
|
/>
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
);
|
|
}
|
|
|
|
type PersonInfoProps = {
|
|
person: TicketActor | null | undefined;
|
|
size?: 'default' | 'sm' | 'lg';
|
|
className?: string;
|
|
};
|
|
|
|
export function PersonInfo({
|
|
person,
|
|
size = 'sm',
|
|
className,
|
|
}: PersonInfoProps) {
|
|
if (!person) {
|
|
return <p className="text-sm text-muted-foreground">-</p>;
|
|
}
|
|
|
|
const name = person.name?.trim();
|
|
const email = person.email?.trim();
|
|
|
|
return (
|
|
<div className={cn('flex min-w-0 items-center gap-2.5', className)}>
|
|
<PersonAvatar person={person} size={size} />
|
|
<div className="min-w-0">
|
|
<p className="truncate text-sm text-foreground">
|
|
{name || email || 'Unknown'}
|
|
</p>
|
|
{name && email ? (
|
|
<p className="truncate text-xs text-muted-foreground">{email}</p>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|