112 lines
5.5 KiB
TypeScript
112 lines
5.5 KiB
TypeScript
/**
|
|
* Approver's Actions Statistics Component
|
|
*/
|
|
|
|
import { CheckCircle, XCircle, Clock, FileText, Users, Target, Award, AlertCircle, BarChart3 } from 'lucide-react';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import type { ApproverPerformance } from '@/services/dashboard.service';
|
|
import type { ApproverPerformanceStats } from '../types/approverPerformance.types';
|
|
|
|
interface ApproverPerformanceActionsStatsProps {
|
|
approverName: string;
|
|
approverStats: ApproverPerformance | null;
|
|
calculatedStats: ApproverPerformanceStats;
|
|
}
|
|
|
|
export function ApproverPerformanceActionsStats({
|
|
approverName,
|
|
approverStats,
|
|
calculatedStats
|
|
}: ApproverPerformanceActionsStatsProps) {
|
|
return (
|
|
<Card data-testid="approver-actions-stats">
|
|
<CardHeader>
|
|
<CardTitle>Approver's Actions (Filtered)</CardTitle>
|
|
<CardDescription>
|
|
Statistics based on {approverName}'s actions with current filters applied
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{/* Approver's Actions - What the approver actually did */}
|
|
<div className="mb-6">
|
|
<h4 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
|
|
<Users className="w-4 h-4" />
|
|
Approver's Actions
|
|
</h4>
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3">
|
|
<div className="p-4 bg-green-50 rounded-lg border border-green-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<CheckCircle className="w-5 h-5 text-green-600" />
|
|
<span className="text-xs text-green-600 font-medium">
|
|
{calculatedStats.completedActions > 0 ? `${calculatedStats.approvalRate}%` : '0%'}
|
|
</span>
|
|
</div>
|
|
<div className="text-2xl font-bold text-green-700">{calculatedStats.approvedByApprover}</div>
|
|
<div className="text-xs text-gray-600 mt-1">Approved by Approver</div>
|
|
</div>
|
|
<div className="p-4 bg-red-50 rounded-lg border border-red-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<XCircle className="w-5 h-5 text-red-600" />
|
|
<span className="text-xs text-red-600 font-medium">
|
|
{calculatedStats.completedActions > 0 ? `${calculatedStats.rejectionRate}%` : '0%'}
|
|
</span>
|
|
</div>
|
|
<div className="text-2xl font-bold text-red-700">{calculatedStats.rejectedByApprover}</div>
|
|
<div className="text-xs text-gray-600 mt-1">Rejected by Approver</div>
|
|
</div>
|
|
<div className="p-4 bg-yellow-50 rounded-lg border border-yellow-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<Clock className="w-5 h-5 text-yellow-600" />
|
|
</div>
|
|
<div className="text-2xl font-bold text-yellow-700">{calculatedStats.pendingByApprover}</div>
|
|
<div className="text-xs text-gray-600 mt-1">Pending Actions</div>
|
|
</div>
|
|
<div className="p-4 bg-blue-50 rounded-lg border border-blue-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<FileText className="w-5 h-5 text-blue-600" />
|
|
</div>
|
|
<div className="text-2xl font-bold text-blue-700">{calculatedStats.total}</div>
|
|
<div className="text-xs text-gray-600 mt-1">Total Requests</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* TAT Compliance Stats */}
|
|
<div className="mb-6 pt-4 border-t">
|
|
<h4 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
|
|
<Target className="w-4 h-4" />
|
|
TAT Compliance
|
|
</h4>
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
|
|
<div className="p-4 bg-green-50 rounded-lg border border-green-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<Award className="w-5 h-5 text-green-600" />
|
|
<span className="text-xs text-green-600 font-medium">
|
|
{approverStats?.tatCompliancePercent !== undefined ? `${approverStats.tatCompliancePercent}%` : (calculatedStats.completedActions > 0 ? `${calculatedStats.tatComplianceRate}%` : 'N/A')}
|
|
</span>
|
|
</div>
|
|
<div className="text-2xl font-bold text-green-700">{calculatedStats.compliant}</div>
|
|
<div className="text-xs text-gray-600 mt-1">TAT Compliant</div>
|
|
</div>
|
|
<div className="p-4 bg-red-50 rounded-lg border border-red-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<AlertCircle className="w-5 h-5 text-red-600" />
|
|
</div>
|
|
<div className="text-2xl font-bold text-red-700">{calculatedStats.breached}</div>
|
|
<div className="text-xs text-gray-600 mt-1">TAT Breached</div>
|
|
</div>
|
|
<div className="p-4 bg-purple-50 rounded-lg border border-purple-200">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<BarChart3 className="w-5 h-5 text-purple-600" />
|
|
</div>
|
|
<div className="text-2xl font-bold text-purple-700">{calculatedStats.completedActions}</div>
|
|
<div className="text-xs text-gray-600 mt-1">Completed Actions</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|
|
|