All files / src/components/features/admin/monitoring/alerts/StatusIndicator index.tsx

100% Statements 95/95
83.33% Branches 5/6
100% Functions 1/1
100% Lines 95/95

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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 961x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 87x 22x 22x 22x 22x 22x 22x 87x 87x 87x 87x 87x 87x 21x 21x 21x 87x 87x 87x 87x 1x 1x  
'use client';
 
import { cn } from '@/lib/core';
 
export interface StatusIndicatorProps {
  /** The current status */
  status: 'ok' | 'warning' | 'critical' | 'active' | 'acknowledged' | 'resolved';
  /** Size of the indicator */
  size?: 'sm' | 'md' | 'lg';
  /** Show label text */
  showLabel?: boolean;
  /** Whether to animate (pulse) */
  animate?: boolean;
  /** Additional CSS classes */
  className?: string;
}
 
const statusConfig = {
  ok: {
    color: 'bg-green-500',
    label: 'OK',
    textColor: 'text-green-700 dark:text-green-400',
  },
  warning: {
    color: 'bg-yellow-500',
    label: 'Warning',
    textColor: 'text-yellow-700 dark:text-yellow-400',
  },
  critical: {
    color: 'bg-red-500',
    label: 'Critical',
    textColor: 'text-red-700 dark:text-red-400',
  },
  active: {
    color: 'bg-blue-500',
    label: 'Active',
    textColor: 'text-blue-700 dark:text-blue-400',
  },
  acknowledged: {
    color: 'bg-purple-500',
    label: 'Acknowledged',
    textColor: 'text-purple-700 dark:text-purple-400',
  },
  resolved: {
    color: 'bg-gray-500',
    label: 'Resolved',
    textColor: 'text-gray-600 dark:text-gray-400',
  },
};
 
const sizeConfig = {
  sm: 'h-2 w-2',
  md: 'h-3 w-3',
  lg: 'h-4 w-4',
};
 
/**
 * StatusIndicator displays a colored dot with optional label
 * indicating the status of an alert or configuration.
 */
export function StatusIndicator({
  status,
  size = 'md',
  showLabel = false,
  animate = false,
  className,
}: StatusIndicatorProps) {
  const config = statusConfig[status];
  const sizeClass = sizeConfig[size];
 
  return (
    <div data-testid="status-indicator" className={cn('flex items-center gap-2', className)}>
      <span className="relative flex">
        {animate && (status === 'warning' || status === 'critical' || status === 'active') && (
          <span
            className={cn(
              'absolute inline-flex h-full w-full rounded-full opacity-75 animate-ping',
              config.color
            )}
          />
        )}
        <span
          className={cn('relative inline-flex rounded-full', sizeClass, config.color)}
        />
      </span>
      {showLabel && (
        <span className={cn('text-sm font-medium', config.textColor)}>
          {config.label}
        </span>
      )}
    </div>
  );
}
 
export default StatusIndicator;