Files
thrilltrack-explorer/src-old/components/moderation/TransactionStatusIndicator.tsx

110 lines
3.3 KiB
TypeScript

import { memo } from 'react';
import { Loader2, Clock, Database, CheckCircle2, XCircle } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
export type TransactionStatus =
| 'idle'
| 'processing'
| 'timeout'
| 'cached'
| 'completed'
| 'failed';
interface TransactionStatusIndicatorProps {
status: TransactionStatus;
message?: string;
className?: string;
showLabel?: boolean;
}
export const TransactionStatusIndicator = memo(({
status,
message,
className,
showLabel = true,
}: TransactionStatusIndicatorProps) => {
if (status === 'idle') return null;
const getStatusConfig = () => {
switch (status) {
case 'processing':
return {
icon: Loader2,
label: 'Processing',
description: 'Transaction in progress...',
variant: 'secondary' as const,
className: 'bg-blue-100 text-blue-800 border-blue-200 dark:bg-blue-950 dark:text-blue-200 dark:border-blue-800',
iconClassName: 'animate-spin',
};
case 'timeout':
return {
icon: Clock,
label: 'Timeout',
description: message || 'Transaction timed out. Lock may have been auto-released.',
variant: 'destructive' as const,
className: 'bg-orange-100 text-orange-800 border-orange-200 dark:bg-orange-950 dark:text-orange-200 dark:border-orange-800',
iconClassName: '',
};
case 'cached':
return {
icon: Database,
label: 'Cached',
description: message || 'Using cached result from duplicate request',
variant: 'outline' as const,
className: 'bg-purple-100 text-purple-800 border-purple-200 dark:bg-purple-950 dark:text-purple-200 dark:border-purple-800',
iconClassName: '',
};
case 'completed':
return {
icon: CheckCircle2,
label: 'Completed',
description: 'Transaction completed successfully',
variant: 'default' as const,
className: 'bg-green-100 text-green-800 border-green-200 dark:bg-green-950 dark:text-green-200 dark:border-green-800',
iconClassName: '',
};
case 'failed':
return {
icon: XCircle,
label: 'Failed',
description: message || 'Transaction failed',
variant: 'destructive' as const,
className: '',
iconClassName: '',
};
default:
return null;
}
};
const config = getStatusConfig();
if (!config) return null;
const Icon = config.icon;
return (
<Tooltip>
<TooltipTrigger asChild>
<Badge
variant={config.variant}
className={cn(
'flex items-center gap-1.5 px-2 py-1',
config.className,
className
)}
>
<Icon className={cn('h-3.5 w-3.5', config.iconClassName)} />
{showLabel && <span className="text-xs font-medium">{config.label}</span>}
</Badge>
</TooltipTrigger>
<TooltipContent>
<p className="text-sm">{config.description}</p>
</TooltipContent>
</Tooltip>
);
});
TransactionStatusIndicator.displayName = 'TransactionStatusIndicator';