# All files / src/components/ui Feedback.tsx

0% Statements 0/7
0% Branches 0/9
0% Functions 0/4
0% Lines 0/7

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

     import { type ReactNode } from 'react';

    function Spinner({ size = 'md' }: { size?: 'sm' | 'md' | 'lg' }) {
      const sizes = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-8 w-8' };
      return (
        <div className={`animate-spin rounded-full border-2 border-gray-200 border-t-accent ${sizes[size]}`} />
      );
    }

    function Skeleton({ className = '' }: { className?: string }) {
      return (
        <div className={`animate-pulse rounded-input bg-gray-200 dark:bg-gray-200 ${className}`} />
      );
    }

    function Avatar({ src, name, size = 'md' }: { src?: string; name: string; size?: 'sm' | 'md' | 'lg' }) {
      const sizes = { sm: 'h-8 w-8 text-xs', md: 'h-10 w-10 text-sm', lg: 'h-16 w-16 text-lg' };
      const initials = name.slice(0, 2).toUpperCase();

      return (
        <div className={`${sizes[size]} rounded-full bg-accent text-white flex items-center justify-center font-semibold overflow-hidden`}>
          {src ? <img src={src} alt={name} className="h-full w-full object-cover" /> : initials}
        </div>
      );
    }

    function EmptyState({ icon, title, description }: { icon?: ReactNode; title: string; description?: string }) {
      return (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <div className="p-4 rounded-card bg-surface-secondary mb-4">
            {icon || (
              <svg className="w-16 h-16 text-text-tertiary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5m0 0H4m16 0a2 2 0 01-2 2H6a2 2 0 01-2-2" />
              </svg>
            )}
          </div>
          <h3 className="text-base font-medium text-text-primary">{title}</h3>
          {description && <p className="mt-1 text-sm text-text-secondary">{description}</p>}
        </div>
      );
    }

    export { Spinner, Skeleton, Avatar, EmptyState };