Re_Figma_Code/src/components/sla/SLAProgressBar/SLAProgressBar.tsx

107 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Badge } from '@/components/ui/badge';
import { Progress } from '@/components/ui/progress';
import { Clock } from 'lucide-react';
export interface SLAData {
status: 'normal' | 'approaching' | 'critical' | 'breached';
percentageUsed: number;
elapsedText: string;
elapsedHours: number;
remainingText: string;
remainingHours: number;
deadline?: string;
}
interface SLAProgressBarProps {
sla: SLAData | null;
requestStatus: string;
testId?: string;
}
export function SLAProgressBar({
sla,
requestStatus,
testId = 'sla-progress'
}: SLAProgressBarProps) {
// If request is closed/approved/rejected or no SLA data, show status message
if (!sla || requestStatus === 'approved' || requestStatus === 'rejected' || requestStatus === 'closed') {
return (
<div className="flex items-center gap-2" data-testid={`${testId}-status-only`}>
<Clock className="h-4 w-4 text-gray-500" />
<span className="text-sm font-medium text-gray-700">
{requestStatus === 'closed' ? '🔒 Request Closed' :
requestStatus === 'approved' ? '✅ Request Approved' :
requestStatus === 'rejected' ? '❌ Request Rejected' : 'SLA Not Available'}
</span>
</div>
);
}
return (
<div data-testid={testId}>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<Clock className="h-4 w-4 text-blue-600" />
<span className="text-sm font-semibold text-gray-900">SLA Progress</span>
</div>
<Badge
className={`text-xs ${
sla.status === 'breached' ? 'bg-red-600 text-white animate-pulse' :
sla.status === 'critical' ? 'bg-orange-600 text-white' :
sla.status === 'approaching' ? 'bg-yellow-600 text-white' :
'bg-green-600 text-white'
}`}
data-testid={`${testId}-badge`}
>
{sla.percentageUsed || 0}% elapsed
</Badge>
</div>
<Progress
value={sla.percentageUsed || 0}
className={`h-3 mb-2 ${
sla.status === 'breached' ? '[&>div]:bg-red-600' :
sla.status === 'critical' ? '[&>div]:bg-orange-600' :
sla.status === 'approaching' ? '[&>div]:bg-yellow-600' :
'[&>div]:bg-green-600'
}`}
data-testid={`${testId}-bar`}
/>
<div className="flex items-center justify-between text-xs mb-1">
<span className="text-gray-600" data-testid={`${testId}-elapsed`}>
{sla.elapsedText || `${sla.elapsedHours || 0}h`} elapsed
</span>
<span
className={`font-semibold ${
sla.status === 'breached' ? 'text-red-600' :
sla.status === 'critical' ? 'text-orange-600' :
'text-gray-700'
}`}
data-testid={`${testId}-remaining`}
>
{sla.remainingText || `${sla.remainingHours || 0}h`} remaining
</span>
</div>
{sla.deadline && (
<p className="text-xs text-gray-500" data-testid={`${testId}-deadline`}>
Due: {new Date(sla.deadline).toLocaleString()} {sla.percentageUsed || 0}% elapsed
</p>
)}
{sla.status === 'critical' && (
<p className="text-xs text-orange-600 font-semibold mt-1" data-testid={`${testId}-warning-critical`}>
Approaching Deadline
</p>
)}
{sla.status === 'breached' && (
<p className="text-xs text-red-600 font-semibold mt-1" data-testid={`${testId}-warning-breached`}>
🔴 URGENT - Deadline Passed
</p>
)}
</div>
);
}