Files
Sankofa/src/components/data/avatar.tsx
defiQUG 6f28146ac3 Initial Phoenix Sankofa Cloud setup
- Complete project structure with Next.js frontend
- GraphQL API backend with Apollo Server
- Portal application with NextAuth
- Crossplane Proxmox provider
- GitOps configurations
- CI/CD pipelines
- Testing infrastructure (Vitest, Jest, Go tests)
- Error handling and monitoring
- Security hardening
- UI component library
- Documentation
2025-11-28 12:54:33 -08:00

45 lines
1.0 KiB
TypeScript

import * as React from 'react'
import { cn } from '@/lib/utils'
interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
src?: string
alt?: string
fallback?: string
size?: 'sm' | 'md' | 'lg'
}
const sizeClasses = {
sm: 'h-8 w-8 text-xs',
md: 'h-10 w-10 text-sm',
lg: 'h-12 w-12 text-base',
}
export function Avatar({ src, alt, fallback, size = 'md', className, ...props }: AvatarProps) {
const [error, setError] = React.useState(false)
return (
<div
className={cn(
'relative flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-studio-medium',
sizeClasses[size],
className
)}
{...props}
>
{src && !error ? (
<img
src={src}
alt={alt}
className="h-full w-full object-cover"
onError={() => setError(true)}
/>
) : (
<span className="font-medium text-foreground">
{fallback || (alt ? alt.charAt(0).toUpperCase() : '?')}
</span>
)}
</div>
)
}