/** * ProcessDetailsCard Component * Displays process-related details: IO Number, DMS Number, Claim Amount, and Budget Breakdowns * Visibility controlled by user role */ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; import { Activity, Receipt, DollarSign, Pen } from 'lucide-react'; import { format } from 'date-fns'; // Local minimal types to avoid external dependency issues interface IODetails { ioNumber?: string; remarks?: string; availableBalance?: number; blockedAmount?: number; remainingBalance?: number; blockedByName?: string; blockedAt?: string; } interface DMSDetails { dmsNumber?: string; remarks?: string; createdByName?: string; createdAt?: string; } interface ClaimAmountDetails { amount: number; lastUpdatedBy?: string; lastUpdatedAt?: string; } interface CostBreakdownItem { description: string; amount: number; } interface RoleBasedVisibility { showIODetails: boolean; showDMSDetails: boolean; showClaimAmount: boolean; canEditClaimAmount: boolean; } interface ProcessDetailsCardProps { ioDetails?: IODetails; dmsDetails?: DMSDetails; claimAmount?: ClaimAmountDetails; estimatedBudgetBreakdown?: CostBreakdownItem[]; closedExpensesBreakdown?: CostBreakdownItem[]; visibility: RoleBasedVisibility; onEditClaimAmount?: () => void; className?: string; } export function ProcessDetailsCard({ ioDetails, dmsDetails, claimAmount, estimatedBudgetBreakdown, closedExpensesBreakdown, visibility, onEditClaimAmount, className, }: ProcessDetailsCardProps) { const formatCurrency = (amount?: number | null) => { if (amount === undefined || amount === null || Number.isNaN(amount)) { return '₹0.00'; } return `₹${amount.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; }; const formatDate = (dateString?: string | null) => { if (!dateString) return ''; try { return format(new Date(dateString), 'MMM d, yyyy, h:mm a'); } catch { return dateString || ''; } }; const calculateTotal = (items?: CostBreakdownItem[]) => { if (!items || items.length === 0) return 0; return items.reduce((sum, item) => sum + (item.amount ?? 0), 0); }; // Don't render if nothing to show const hasContent = (visibility.showIODetails && ioDetails) || (visibility.showDMSDetails && dmsDetails) || (visibility.showClaimAmount && claimAmount && claimAmount.amount !== undefined && claimAmount.amount !== null) || (estimatedBudgetBreakdown && estimatedBudgetBreakdown.length > 0) || (closedExpensesBreakdown && closedExpensesBreakdown.length > 0); if (!hasContent) { return null; } return ( Process Details Workflow reference numbers {/* IO Details - Only visible to internal RE users */} {visibility.showIODetails && ioDetails && (

{ioDetails.ioNumber}

{ioDetails.remarks && (

Remark:

{ioDetails.remarks}

)} {/* Budget Details */} {(ioDetails.availableBalance !== undefined || ioDetails.blockedAmount !== undefined) && (
{ioDetails.availableBalance !== undefined && (
Available Balance: {formatCurrency(ioDetails.availableBalance)}
)} {ioDetails.blockedAmount !== undefined && (
Blocked Amount: {formatCurrency(ioDetails.blockedAmount)}
)} {ioDetails.remainingBalance !== undefined && (
Remaining Balance: {formatCurrency(ioDetails.remainingBalance)}
)}
)}

By {ioDetails.blockedByName}

{formatDate(ioDetails.blockedAt)}

)} {/* DMS Details */} {visibility.showDMSDetails && dmsDetails && (

{dmsDetails.dmsNumber}

{dmsDetails.remarks && (

Remarks:

{dmsDetails.remarks}

)}

By {dmsDetails.createdByName}

{formatDate(dmsDetails.createdAt)}

)} {/* Claim Amount */} {visibility.showClaimAmount && claimAmount && (
{visibility.canEditClaimAmount && onEditClaimAmount && ( )}

{formatCurrency(claimAmount.amount)}

{claimAmount.lastUpdatedBy && (

Last updated by {claimAmount.lastUpdatedBy}

{claimAmount.lastUpdatedAt && (

{formatDate(claimAmount.lastUpdatedAt)}

)}
)}
)} {/* Estimated Budget Breakdown */} {estimatedBudgetBreakdown && estimatedBudgetBreakdown.length > 0 && (
{estimatedBudgetBreakdown.map((item, index) => (
{item.description} {formatCurrency(item.amount)}
))}
Total {formatCurrency(calculateTotal(estimatedBudgetBreakdown))}
)} {/* Closed Expenses Breakdown */} {closedExpensesBreakdown && closedExpensesBreakdown.length > 0 && (
{closedExpensesBreakdown.map((item, index) => (
{item.description} {formatCurrency(item.amount)}
))}
Total {formatCurrency(calculateTotal(closedExpensesBreakdown))}
)}
); }