Dealer_Onboard_Frontend/src/components/applications/FinanceFnFDetailsPage.tsx

1508 lines
68 KiB
TypeScript

import { useState } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card';
import { Badge } from '../ui/badge';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Textarea } from '../ui/textarea';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
import { Progress } from '../ui/progress';
import {
ArrowLeft,
DollarSign,
CheckCircle,
XCircle,
Upload,
FileText,
Calendar,
User,
MapPin,
AlertCircle,
Wallet,
Receipt,
TrendingUp,
TrendingDown,
Building,
CreditCard,
Hash,
Send,
Users,
Plus,
Edit2,
Trash2,
Save,
Calculator
} from 'lucide-react';
import { toast } from 'sonner';
import { departments } from '../../lib/mock-data';
interface FinanceFnFDetailsPageProps {
fnfId: string;
onBack: () => void;
}
// Mock data - in real app this would come from API
const getFnFData = (id: string) => {
return {
id: id,
caseNumber: 'FNF-2024-001',
dealerName: 'Rajesh Kumar',
dealerCode: 'DLR-001',
location: 'Mumbai, Maharashtra',
terminationType: 'Resignation',
submittedDate: '2025-09-15',
dueDate: '2025-10-20',
status: 'Pending Finance Review',
financialData: {
// Payables (Company owes dealer)
securityDeposit: 500000,
inventoryValue: 1200000,
equipmentValue: 300000,
// Receivables (Dealer owes company)
outstandingInvoices: 450000,
serviceDues: 75000,
partsDues: 125000,
advancesGiven: 200000,
penalties: 50000,
otherCharges: 25000,
// Deductions
warrantyPending: 100000,
},
bankDetails: {
accountName: 'Rajesh Kumar',
accountNumber: '1234567890',
ifscCode: 'HDFC0001234',
bankName: 'HDFC Bank',
branch: 'Mumbai Central'
},
documents: [
{ name: 'Resignation Letter.pdf', size: '245 KB', uploadedOn: '2025-09-15', type: 'Resignation' },
{ name: 'Asset Handover Receipt.pdf', size: '312 KB', uploadedOn: '2025-09-16', type: 'Asset' },
{ name: 'Inventory Report.xlsx', size: '856 KB', uploadedOn: '2025-09-17', type: 'Inventory' },
{ name: 'Bank Statement.pdf', size: '1.2 MB', uploadedOn: '2025-09-15', type: 'Financial' }
],
departmentResponses: departments.map((dept, index) => ({
id: `dept-${index + 1}`,
departmentName: dept,
status: index < 8 ? 'NOC Submitted' : index < 12 ? 'Dues Pending' : 'Pending',
remarks: index < 8 ? 'No outstanding dues, clearance provided' : index < 12 ? 'Outstanding amount to be recovered' : 'Awaiting department response',
amountType: index === 8 ? 'Recovery Amount' : index === 9 ? 'Payable Amount' : index === 10 ? 'Recovery Amount' : undefined,
amount: index === 8 ? 75000 : index === 9 ? 12000 : index === 10 ? 125000 : undefined,
submittedDate: index < 12 ? '2025-10-05' : undefined,
submittedBy: index < 12 ? `${dept} Head` : undefined
}))
};
};
const calculateSettlement = (financialData: any) => {
const payables = financialData.securityDeposit + financialData.inventoryValue + financialData.equipmentValue;
const receivables =
financialData.outstandingInvoices +
financialData.serviceDues +
financialData.partsDues +
financialData.advancesGiven +
financialData.penalties +
financialData.otherCharges;
const deductions = financialData.warrantyPending;
const netSettlement = payables - receivables - deductions;
return {
payables,
receivables,
deductions,
netSettlement,
settlementAmount: Math.abs(netSettlement),
settlementType: netSettlement > 0 ? 'Payable to Dealer' : 'Recovery from Dealer'
};
};
const getDepartmentStatusColor = (status: string) => {
switch (status) {
case 'NOC Submitted':
return 'bg-green-100 text-green-700 border-green-300';
case 'Dues Pending':
return 'bg-red-100 text-red-700 border-red-300';
case 'Completed':
return 'bg-green-100 text-green-700 border-green-300';
case 'Pending':
return 'bg-slate-100 text-slate-700 border-slate-300';
default:
return 'bg-slate-100 text-slate-700 border-slate-300';
}
};
interface FinancialLineItem {
id: string;
department: string;
description: string;
amount: number;
}
export function FinanceFnFDetailsPage({ fnfId, onBack }: FinanceFnFDetailsPageProps) {
const fnfCase = getFnFData(fnfId);
// Initialize editable line items from mock data
const [payableItems, setPayableItems] = useState<FinancialLineItem[]>([
{ id: '1', department: 'Security Deposit', description: 'Refundable security deposit', amount: fnfCase.financialData.securityDeposit },
{ id: '2', department: 'Inventory', description: 'Vehicle inventory value', amount: fnfCase.financialData.inventoryValue },
{ id: '3', department: 'Equipment', description: 'Equipment and fixtures value', amount: fnfCase.financialData.equipmentValue }
]);
const [receivableItems, setReceivableItems] = useState<FinancialLineItem[]>([
{ id: '1', department: 'Sales', description: 'Outstanding invoices', amount: fnfCase.financialData.outstandingInvoices },
{ id: '2', department: 'Service', description: 'Service dues', amount: fnfCase.financialData.serviceDues },
{ id: '3', department: 'Parts', description: 'Parts dues', amount: fnfCase.financialData.partsDues },
{ id: '4', department: 'Finance', description: 'Advances given to dealer', amount: fnfCase.financialData.advancesGiven },
{ id: '5', department: 'Compliance', description: 'Penalties and fines', amount: fnfCase.financialData.penalties },
{ id: '6', department: 'Other', description: 'Miscellaneous charges', amount: fnfCase.financialData.otherCharges }
]);
const [deductionItems, setDeductionItems] = useState<FinancialLineItem[]>([
{ id: '1', department: 'Warranty', description: 'Pending warranty claims', amount: fnfCase.financialData.warrantyPending }
]);
// Form states for adding new items
const [newPayable, setNewPayable] = useState({ department: '', description: '', amount: '' });
const [newReceivable, setNewReceivable] = useState({ department: '', description: '', amount: '' });
const [newDeduction, setNewDeduction] = useState({ department: '', description: '', amount: '' });
// Edit mode states
const [editingPayableId, setEditingPayableId] = useState<string | null>(null);
const [editingReceivableId, setEditingReceivableId] = useState<string | null>(null);
const [editingDeductionId, setEditingDeductionId] = useState<string | null>(null);
// Calculate dynamic settlement
const calculateDynamicSettlement = () => {
const payables = payableItems.reduce((sum, item) => sum + item.amount, 0);
const receivables = receivableItems.reduce((sum, item) => sum + item.amount, 0);
const deductions = deductionItems.reduce((sum, item) => sum + item.amount, 0);
const netSettlement = payables - receivables - deductions;
return {
payables,
receivables,
deductions,
netSettlement,
settlementAmount: Math.abs(netSettlement),
settlementType: netSettlement > 0 ? 'Payable to Dealer' : netSettlement < 0 ? 'Recovery from Dealer' : 'No Settlement Required'
};
};
const settlement = calculateDynamicSettlement();
const [settlementDetails, setSettlementDetails] = useState({
verificationTransactionId: '',
settlementAmount: settlement.settlementAmount.toString(),
settlementDate: new Date().toISOString().split('T')[0],
paymentMode: '',
bankReference: '',
verificationRemarks: '',
adjustments: '0'
});
const [uploadedDocuments, setUploadedDocuments] = useState<any[]>([]);
// Handlers for Payables
const handleAddPayable = () => {
if (!newPayable.department || !newPayable.description || !newPayable.amount) {
toast.error('Please fill in all fields');
return;
}
const item: FinancialLineItem = {
id: Date.now().toString(),
department: newPayable.department,
description: newPayable.description,
amount: parseFloat(newPayable.amount)
};
setPayableItems([...payableItems, item]);
setNewPayable({ department: '', description: '', amount: '' });
toast.success('Payable item added');
};
const handleUpdatePayable = (id: string, field: keyof FinancialLineItem, value: string | number) => {
setPayableItems(payableItems.map(item =>
item.id === id ? { ...item, [field]: field === 'amount' ? parseFloat(value.toString()) : value } : item
));
};
const handleDeletePayable = (id: string) => {
setPayableItems(payableItems.filter(item => item.id !== id));
toast.info('Payable item removed');
};
// Handlers for Receivables
const handleAddReceivable = () => {
if (!newReceivable.department || !newReceivable.description || !newReceivable.amount) {
toast.error('Please fill in all fields');
return;
}
const item: FinancialLineItem = {
id: Date.now().toString(),
department: newReceivable.department,
description: newReceivable.description,
amount: parseFloat(newReceivable.amount)
};
setReceivableItems([...receivableItems, item]);
setNewReceivable({ department: '', description: '', amount: '' });
toast.success('Receivable item added');
};
const handleUpdateReceivable = (id: string, field: keyof FinancialLineItem, value: string | number) => {
setReceivableItems(receivableItems.map(item =>
item.id === id ? { ...item, [field]: field === 'amount' ? parseFloat(value.toString()) : value } : item
));
};
const handleDeleteReceivable = (id: string) => {
setReceivableItems(receivableItems.filter(item => item.id !== id));
toast.info('Receivable item removed');
};
// Handlers for Deductions
const handleAddDeduction = () => {
if (!newDeduction.department || !newDeduction.description || !newDeduction.amount) {
toast.error('Please fill in all fields');
return;
}
const item: FinancialLineItem = {
id: Date.now().toString(),
department: newDeduction.department,
description: newDeduction.description,
amount: parseFloat(newDeduction.amount)
};
setDeductionItems([...deductionItems, item]);
setNewDeduction({ department: '', description: '', amount: '' });
toast.success('Deduction item added');
};
const handleUpdateDeduction = (id: string, field: keyof FinancialLineItem, value: string | number) => {
setDeductionItems(deductionItems.map(item =>
item.id === id ? { ...item, [field]: field === 'amount' ? parseFloat(value.toString()) : value } : item
));
};
const handleDeleteDeduction = (id: string) => {
setDeductionItems(deductionItems.filter(item => item.id !== id));
toast.info('Deduction item removed');
};
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
if (files && files.length > 0) {
const newDocs = Array.from(files).map(file => ({
name: file.name,
size: `${(file.size / 1024).toFixed(0)} KB`,
uploadedOn: new Date().toISOString().split('T')[0],
type: 'Settlement Verification'
}));
setUploadedDocuments([...uploadedDocuments, ...newDocs]);
toast.success(`${files.length} document(s) uploaded successfully`);
}
};
const handleApproveSettlement = () => {
if (!settlementDetails.verificationTransactionId || !settlementDetails.settlementDate || !settlementDetails.paymentMode) {
toast.error('Please fill in all required settlement details');
return;
}
const adjustedAmount = settlement.settlementAmount + parseFloat(settlementDetails.adjustments || '0');
if (adjustedAmount.toString() !== settlementDetails.settlementAmount) {
toast.warning('Settlement amount has been adjusted');
}
toast.success(`F&F Settlement approved for ${fnfCase.dealerName}`);
setTimeout(() => onBack(), 1500);
};
const handleRejectSettlement = () => {
if (!settlementDetails.verificationRemarks) {
toast.error('Please provide remarks for rejection');
return;
}
toast.error(`F&F Settlement rejected for ${fnfCase.dealerName}`);
setTimeout(() => onBack(), 1500);
};
const handleRequestClarification = () => {
if (!settlementDetails.verificationRemarks) {
toast.error('Please provide details for clarification request');
return;
}
toast.info(`Clarification request sent for ${fnfCase.dealerName}`);
setTimeout(() => onBack(), 1500);
};
return (
<div className="space-y-6">
{/* Header */}
<div className="flex items-center gap-4">
<Button variant="outline" size="icon" onClick={onBack}>
<ArrowLeft className="w-4 h-4" />
</Button>
<div>
<h1 className="text-3xl mb-1">F&F Settlement Review</h1>
<p className="text-slate-600">Full & Final Settlement for {fnfCase.dealerName}</p>
</div>
</div>
{/* Status Banner */}
<Card className="border-amber-200 bg-amber-50">
<CardContent className="pt-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-full bg-amber-100 flex items-center justify-center">
<DollarSign className="w-6 h-6 text-amber-600" />
</div>
<div>
<p className="text-slate-900">Settlement Pending Finance Approval</p>
<p className="text-sm text-slate-600">Case: {fnfCase.caseNumber} Due: {fnfCase.dueDate}</p>
</div>
</div>
<div className="flex gap-2">
<Badge className="bg-amber-600">
{fnfCase.status}
</Badge>
<Badge variant={fnfCase.terminationType === 'Resignation' ? 'default' : 'secondary'}>
{fnfCase.terminationType}
</Badge>
</div>
</div>
</CardContent>
</Card>
{/* Settlement Summary Card */}
<Card className={`${
settlement.settlementType === 'Payable to Dealer'
? 'border-red-300 bg-red-50'
: settlement.settlementType === 'Recovery from Dealer'
? 'border-green-300 bg-green-50'
: 'border-slate-300 bg-slate-50'
}`}>
<CardContent className="pt-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
{settlement.settlementType === 'Payable to Dealer' ? (
<TrendingDown className="w-12 h-12 text-red-600" />
) : settlement.settlementType === 'Recovery from Dealer' ? (
<TrendingUp className="w-12 h-12 text-green-600" />
) : (
<CheckCircle className="w-12 h-12 text-slate-600" />
)}
<div>
<p className={`text-sm ${
settlement.settlementType === 'Payable to Dealer'
? 'text-red-700'
: settlement.settlementType === 'Recovery from Dealer'
? 'text-green-700'
: 'text-slate-700'
}`}>
{settlement.settlementType}
</p>
<p className="text-3xl text-slate-900">
{settlement.settlementType === 'No Settlement Required'
? '₹0'
: `${settlement.settlementAmount.toLocaleString('en-IN')}`}
</p>
</div>
</div>
<div className="text-right">
<p className="text-sm text-slate-600">Net Settlement Amount</p>
<p className="text-xs text-slate-500 mt-1">
{settlement.settlementType === 'Payable to Dealer'
? 'Company will pay to dealer'
: settlement.settlementType === 'Recovery from Dealer'
? 'Dealer must pay to company'
: 'No payment required'}
</p>
</div>
</div>
</CardContent>
</Card>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Left Column - Case Details & Financial Info */}
<div className="lg:col-span-2 space-y-6">
<Tabs defaultValue="overview" className="w-full">
<TabsList className="grid w-full grid-cols-5">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="financial">Financial</TabsTrigger>
<TabsTrigger value="departments">Departments</TabsTrigger>
<TabsTrigger value="documents">Documents</TabsTrigger>
<TabsTrigger value="bank">Bank Details</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-4">
{/* Case Information */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<User className="w-5 h-5" />
Case Information
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-slate-500">Case Number</Label>
<p className="text-slate-900">{fnfCase.caseNumber}</p>
</div>
<div>
<Label className="text-slate-500">Dealer Code</Label>
<p className="text-slate-900">{fnfCase.dealerCode}</p>
</div>
<div>
<Label className="text-slate-500">Dealer Name</Label>
<p className="text-slate-900">{fnfCase.dealerName}</p>
</div>
<div>
<Label className="text-slate-500">Location</Label>
<p className="text-slate-900">{fnfCase.location}</p>
</div>
<div>
<Label className="text-slate-500">Termination Type</Label>
<Badge variant={fnfCase.terminationType === 'Resignation' ? 'default' : 'secondary'}>
{fnfCase.terminationType}
</Badge>
</div>
<div>
<Label className="text-slate-500">Status</Label>
<Badge className="bg-amber-600">
{fnfCase.status}
</Badge>
</div>
<div>
<Label className="text-slate-500">Submitted Date</Label>
<p className="text-slate-900">{fnfCase.submittedDate}</p>
</div>
<div>
<Label className="text-slate-500">Due Date</Label>
<p className="text-slate-900">{fnfCase.dueDate}</p>
</div>
<div>
<Label className="text-slate-500">Request Age</Label>
<p className="text-slate-900">
{(() => {
const submitted = new Date(fnfCase.submittedDate);
const today = new Date();
const diffTime = Math.abs(today.getTime() - submitted.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return `${diffDays} day${diffDays !== 1 ? 's' : ''}`;
})()}
</p>
</div>
<div>
<Label className="text-slate-500">Sales Code</Label>
<p className="text-slate-900">SAL-{fnfCase.dealerCode}</p>
</div>
<div>
<Label className="text-slate-500">Service Code</Label>
<p className="text-slate-900">SRV-{fnfCase.dealerCode}</p>
</div>
<div>
<Label className="text-slate-500">Gear Code</Label>
<p className="text-slate-900">GER-{fnfCase.dealerCode}</p>
</div>
<div>
<Label className="text-slate-500">GMA Code</Label>
<p className="text-slate-900">GMA-{fnfCase.dealerCode}</p>
</div>
</div>
</CardContent>
</Card>
{/* Settlement Calculation Overview */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<DollarSign className="w-5 h-5" />
Settlement Calculation Summary
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-3">
<div className="flex justify-between items-center p-3 bg-green-50 rounded-lg">
<span className="text-slate-900">Total Payables (to Dealer)</span>
<span className="text-green-700 text-lg">+ {settlement.payables.toLocaleString('en-IN')}</span>
</div>
<div className="flex justify-between items-center p-3 bg-red-50 rounded-lg">
<span className="text-slate-900">Total Receivables (from Dealer)</span>
<span className="text-red-700 text-lg">- {settlement.receivables.toLocaleString('en-IN')}</span>
</div>
<div className="flex justify-between items-center p-3 bg-amber-50 rounded-lg">
<span className="text-slate-900">Total Deductions</span>
<span className="text-amber-700 text-lg">- {settlement.deductions.toLocaleString('en-IN')}</span>
</div>
</div>
<div className="h-px bg-slate-300"></div>
<div className={`p-4 rounded-lg border-2 ${
settlement.settlementType === 'Payable to Dealer'
? 'bg-red-100 border-red-300'
: settlement.settlementType === 'Recovery from Dealer'
? 'bg-green-100 border-green-300'
: 'bg-slate-100 border-slate-300'
}`}>
<div className="flex items-center justify-between">
<div>
<span className="text-slate-900">Net Settlement</span>
<p className={`text-sm ${
settlement.settlementType === 'Payable to Dealer'
? 'text-red-700'
: settlement.settlementType === 'Recovery from Dealer'
? 'text-green-700'
: 'text-slate-700'
}`}>
{settlement.settlementType}
</p>
</div>
<span className="text-2xl text-slate-900">
{settlement.settlementType === 'No Settlement Required'
? '₹0'
: `${settlement.settlementAmount.toLocaleString('en-IN')}`}
</span>
</div>
</div>
<div className="flex items-start gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg">
<AlertCircle className="w-5 h-5 text-blue-600 mt-0.5" />
<div>
<p className="text-sm text-slate-900 mb-1">Calculation Formula</p>
<p className="text-sm text-slate-600">
Net Settlement = Payables - Receivables - Deductions<br/>
<span className="text-xs">All amounts are editable in the Financial tab</span>
</p>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="financial" className="space-y-4">
{/* Payables - Editable */}
<Card className="border-green-200 bg-green-50">
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base flex items-center gap-2">
<Wallet className="w-5 h-5 text-green-600" />
Payables to Dealer (Editable)
</CardTitle>
<CardDescription>Add or modify amounts company owes to dealer</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
{/* Existing Payables */}
<Table>
<TableHeader>
<TableRow>
<TableHead>Department</TableHead>
<TableHead>Description</TableHead>
<TableHead className="text-right">Amount ()</TableHead>
<TableHead className="w-[100px]">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{payableItems.map((item) => (
<TableRow key={item.id}>
<TableCell>
{editingPayableId === item.id ? (
<Input
value={item.department}
onChange={(e) => handleUpdatePayable(item.id, 'department', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-900">{item.department}</span>
)}
</TableCell>
<TableCell>
{editingPayableId === item.id ? (
<Input
value={item.description}
onChange={(e) => handleUpdatePayable(item.id, 'description', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-600">{item.description}</span>
)}
</TableCell>
<TableCell className="text-right">
{editingPayableId === item.id ? (
<Input
type="number"
value={item.amount}
onChange={(e) => handleUpdatePayable(item.id, 'amount', e.target.value)}
className="h-8 text-right"
/>
) : (
<span className="text-slate-900">{item.amount.toLocaleString('en-IN')}</span>
)}
</TableCell>
<TableCell>
<div className="flex gap-1">
{editingPayableId === item.id ? (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => {
setEditingPayableId(null);
toast.success('Changes saved');
}}
>
<Save className="w-4 h-4" />
</Button>
) : (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => setEditingPayableId(item.id)}
>
<Edit2 className="w-4 h-4" />
</Button>
)}
<Button
size="icon"
variant="ghost"
className="h-8 w-8 text-red-600 hover:text-red-700"
onClick={() => handleDeletePayable(item.id)}
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{/* Add New Payable */}
<div className="border-t border-green-300 pt-4 space-y-3">
<p className="text-sm text-slate-700">Add New Payable Item:</p>
<div className="grid grid-cols-12 gap-2">
<Input
placeholder="Department"
value={newPayable.department}
onChange={(e) => setNewPayable({ ...newPayable, department: e.target.value })}
className="col-span-3"
/>
<Input
placeholder="Description"
value={newPayable.description}
onChange={(e) => setNewPayable({ ...newPayable, description: e.target.value })}
className="col-span-5"
/>
<Input
type="number"
placeholder="Amount"
value={newPayable.amount}
onChange={(e) => setNewPayable({ ...newPayable, amount: e.target.value })}
className="col-span-3"
/>
<Button onClick={handleAddPayable} className="col-span-1 bg-green-600 hover:bg-green-700">
<Plus className="w-4 h-4" />
</Button>
</div>
</div>
{/* Total */}
<div className="pt-3 border-t-2 border-green-400">
<div className="flex justify-between items-center">
<span className="text-slate-900">Total Payables</span>
<span className="text-green-700 text-xl">
{settlement.payables.toLocaleString('en-IN')}
</span>
</div>
</div>
</CardContent>
</Card>
{/* Receivables - Editable */}
<Card className="border-red-200 bg-red-50">
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base flex items-center gap-2">
<Receipt className="w-5 h-5 text-red-600" />
Receivables from Dealer (Editable)
</CardTitle>
<CardDescription>Add or modify amounts dealer owes to company</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
{/* Existing Receivables */}
<Table>
<TableHeader>
<TableRow>
<TableHead>Department</TableHead>
<TableHead>Description</TableHead>
<TableHead className="text-right">Amount ()</TableHead>
<TableHead className="w-[100px]">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{receivableItems.map((item) => (
<TableRow key={item.id}>
<TableCell>
{editingReceivableId === item.id ? (
<Input
value={item.department}
onChange={(e) => handleUpdateReceivable(item.id, 'department', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-900">{item.department}</span>
)}
</TableCell>
<TableCell>
{editingReceivableId === item.id ? (
<Input
value={item.description}
onChange={(e) => handleUpdateReceivable(item.id, 'description', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-600">{item.description}</span>
)}
</TableCell>
<TableCell className="text-right">
{editingReceivableId === item.id ? (
<Input
type="number"
value={item.amount}
onChange={(e) => handleUpdateReceivable(item.id, 'amount', e.target.value)}
className="h-8 text-right"
/>
) : (
<span className="text-slate-900">{item.amount.toLocaleString('en-IN')}</span>
)}
</TableCell>
<TableCell>
<div className="flex gap-1">
{editingReceivableId === item.id ? (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => {
setEditingReceivableId(null);
toast.success('Changes saved');
}}
>
<Save className="w-4 h-4" />
</Button>
) : (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => setEditingReceivableId(item.id)}
>
<Edit2 className="w-4 h-4" />
</Button>
)}
<Button
size="icon"
variant="ghost"
className="h-8 w-8 text-red-600 hover:text-red-700"
onClick={() => handleDeleteReceivable(item.id)}
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{/* Add New Receivable */}
<div className="border-t border-red-300 pt-4 space-y-3">
<p className="text-sm text-slate-700">Add New Receivable Item:</p>
<div className="grid grid-cols-12 gap-2">
<Input
placeholder="Department"
value={newReceivable.department}
onChange={(e) => setNewReceivable({ ...newReceivable, department: e.target.value })}
className="col-span-3"
/>
<Input
placeholder="Description"
value={newReceivable.description}
onChange={(e) => setNewReceivable({ ...newReceivable, description: e.target.value })}
className="col-span-5"
/>
<Input
type="number"
placeholder="Amount"
value={newReceivable.amount}
onChange={(e) => setNewReceivable({ ...newReceivable, amount: e.target.value })}
className="col-span-3"
/>
<Button onClick={handleAddReceivable} className="col-span-1 bg-red-600 hover:bg-red-700">
<Plus className="w-4 h-4" />
</Button>
</div>
</div>
{/* Total */}
<div className="pt-3 border-t-2 border-red-400">
<div className="flex justify-between items-center">
<span className="text-slate-900">Total Receivables</span>
<span className="text-red-700 text-xl">
{settlement.receivables.toLocaleString('en-IN')}
</span>
</div>
</div>
</CardContent>
</Card>
{/* Deductions - Editable */}
<Card className="border-amber-200 bg-amber-50">
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base flex items-center gap-2">
<AlertCircle className="w-5 h-5 text-amber-600" />
Deductions (Editable)
</CardTitle>
<CardDescription>Add or modify pending claims and deductions</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
{/* Existing Deductions */}
<Table>
<TableHeader>
<TableRow>
<TableHead>Department</TableHead>
<TableHead>Description</TableHead>
<TableHead className="text-right">Amount ()</TableHead>
<TableHead className="w-[100px]">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{deductionItems.map((item) => (
<TableRow key={item.id}>
<TableCell>
{editingDeductionId === item.id ? (
<Input
value={item.department}
onChange={(e) => handleUpdateDeduction(item.id, 'department', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-900">{item.department}</span>
)}
</TableCell>
<TableCell>
{editingDeductionId === item.id ? (
<Input
value={item.description}
onChange={(e) => handleUpdateDeduction(item.id, 'description', e.target.value)}
className="h-8"
/>
) : (
<span className="text-slate-600">{item.description}</span>
)}
</TableCell>
<TableCell className="text-right">
{editingDeductionId === item.id ? (
<Input
type="number"
value={item.amount}
onChange={(e) => handleUpdateDeduction(item.id, 'amount', e.target.value)}
className="h-8 text-right"
/>
) : (
<span className="text-slate-900">{item.amount.toLocaleString('en-IN')}</span>
)}
</TableCell>
<TableCell>
<div className="flex gap-1">
{editingDeductionId === item.id ? (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => {
setEditingDeductionId(null);
toast.success('Changes saved');
}}
>
<Save className="w-4 h-4" />
</Button>
) : (
<Button
size="icon"
variant="ghost"
className="h-8 w-8"
onClick={() => setEditingDeductionId(item.id)}
>
<Edit2 className="w-4 h-4" />
</Button>
)}
<Button
size="icon"
variant="ghost"
className="h-8 w-8 text-red-600 hover:text-red-700"
onClick={() => handleDeleteDeduction(item.id)}
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{/* Add New Deduction */}
<div className="border-t border-amber-300 pt-4 space-y-3">
<p className="text-sm text-slate-700">Add New Deduction Item:</p>
<div className="grid grid-cols-12 gap-2">
<Input
placeholder="Department"
value={newDeduction.department}
onChange={(e) => setNewDeduction({ ...newDeduction, department: e.target.value })}
className="col-span-3"
/>
<Input
placeholder="Description"
value={newDeduction.description}
onChange={(e) => setNewDeduction({ ...newDeduction, description: e.target.value })}
className="col-span-5"
/>
<Input
type="number"
placeholder="Amount"
value={newDeduction.amount}
onChange={(e) => setNewDeduction({ ...newDeduction, amount: e.target.value })}
className="col-span-3"
/>
<Button onClick={handleAddDeduction} className="col-span-1 bg-amber-600 hover:bg-amber-700">
<Plus className="w-4 h-4" />
</Button>
</div>
</div>
{/* Total */}
<div className="pt-3 border-t-2 border-amber-400">
<div className="flex justify-between items-center">
<span className="text-slate-900">Total Deductions</span>
<span className="text-amber-700 text-xl">
{settlement.deductions.toLocaleString('en-IN')}
</span>
</div>
</div>
</CardContent>
</Card>
{/* Final Settlement Summary */}
<Card className="border-2 border-blue-300 bg-blue-50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Calculator className="w-5 h-5 text-blue-600" />
Final Settlement Summary
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-3">
<div className="flex justify-between items-center p-3 bg-white rounded-lg">
<span className="text-slate-900">Total Payables (to Dealer)</span>
<span className="text-green-700 text-lg">+ {settlement.payables.toLocaleString('en-IN')}</span>
</div>
<div className="flex justify-between items-center p-3 bg-white rounded-lg">
<span className="text-slate-900">Total Receivables (from Dealer)</span>
<span className="text-red-700 text-lg">- {settlement.receivables.toLocaleString('en-IN')}</span>
</div>
<div className="flex justify-between items-center p-3 bg-white rounded-lg">
<span className="text-slate-900">Total Deductions</span>
<span className="text-amber-700 text-lg">- {settlement.deductions.toLocaleString('en-IN')}</span>
</div>
</div>
<div className="h-px bg-blue-300"></div>
<div className={`p-4 rounded-lg border-2 ${
settlement.settlementType === 'Payable to Dealer'
? 'bg-red-100 border-red-400'
: settlement.settlementType === 'Recovery from Dealer'
? 'bg-green-100 border-green-400'
: 'bg-slate-100 border-slate-400'
}`}>
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-slate-600 mb-1">Net Settlement</p>
<p className={`text-lg ${
settlement.settlementType === 'Payable to Dealer'
? 'text-red-700'
: settlement.settlementType === 'Recovery from Dealer'
? 'text-green-700'
: 'text-slate-700'
}`}>
{settlement.settlementType}
</p>
</div>
<span className="text-3xl text-slate-900">
{settlement.settlementType === 'No Settlement Required'
? '₹0'
: `${settlement.settlementAmount.toLocaleString('en-IN')}`}
</span>
</div>
</div>
<div className="flex items-start gap-3 p-4 bg-white border border-blue-200 rounded-lg">
<AlertCircle className="w-5 h-5 text-blue-600 mt-0.5" />
<div>
<p className="text-sm text-slate-900 mb-1">Calculation Formula</p>
<p className="text-sm text-slate-600">
Net Settlement = Payables - Receivables - Deductions<br/>
{settlement.netSettlement > 0 && 'Positive value means company pays to dealer'}
{settlement.netSettlement < 0 && 'Negative value means dealer pays to company'}
{settlement.netSettlement === 0 && 'Zero means no payment required from either party'}
</p>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="departments" className="space-y-4">
{/* Progress Summary */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Users className="w-5 h-5" />
Department Response Progress
</CardTitle>
<CardDescription>
{fnfCase.departmentResponses.filter((d: any) => d.status !== 'Pending').length} of {fnfCase.departmentResponses.length} departments have responded
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Progress
value={(fnfCase.departmentResponses.filter((d: any) => d.status !== 'Pending').length / fnfCase.departmentResponses.length) * 100}
className="h-3"
/>
<div className="grid grid-cols-3 gap-4">
<div className="p-4 bg-green-50 rounded-lg border border-green-200">
<p className="text-sm text-green-700 mb-1">NOC Submitted</p>
<p className="text-2xl text-green-600">
{fnfCase.departmentResponses.filter((d: any) => d.status === 'NOC Submitted').length}
</p>
</div>
<div className="p-4 bg-red-50 rounded-lg border border-red-200">
<p className="text-sm text-red-700 mb-1">Dues Pending</p>
<p className="text-2xl text-red-600">
{fnfCase.departmentResponses.filter((d: any) => d.status === 'Dues Pending').length}
</p>
</div>
<div className="p-4 bg-slate-50 rounded-lg border border-slate-200">
<p className="text-sm text-slate-700 mb-1">Awaiting Response</p>
<p className="text-2xl text-slate-600">
{fnfCase.departmentResponses.filter((d: any) => d.status === 'Pending').length}
</p>
</div>
</div>
</CardContent>
</Card>
{/* Department Responses Table */}
<Card>
<CardHeader>
<CardTitle>All Department Responses</CardTitle>
<CardDescription>
Status of NOC and dues clearance from all 16 departments
</CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Department</TableHead>
<TableHead>Status</TableHead>
<TableHead>Amount Type</TableHead>
<TableHead>Amount</TableHead>
<TableHead>Submitted Date</TableHead>
<TableHead>Remarks</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{fnfCase.departmentResponses.map((dept: any) => (
<TableRow key={dept.id}>
<TableCell>{dept.departmentName}</TableCell>
<TableCell>
<Badge className={getDepartmentStatusColor(dept.status)}>
{dept.status}
</Badge>
</TableCell>
<TableCell>
{dept.amountType ? (
<Badge variant={dept.amountType === 'Recovery Amount' ? 'destructive' : 'default'}>
{dept.amountType}
</Badge>
) : (
'-'
)}
</TableCell>
<TableCell>
{dept.amount ? (
<span className={dept.amountType === 'Recovery Amount' ? 'text-red-600' : 'text-green-600'}>
{dept.amount.toLocaleString('en-IN')}
</span>
) : (
'-'
)}
</TableCell>
<TableCell>{dept.submittedDate || '-'}</TableCell>
<TableCell className="max-w-xs truncate">{dept.remarks || '-'}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
{/* Important Notes */}
<Card className="bg-blue-50 border-blue-200">
<CardContent className="pt-6">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-blue-600 mt-0.5" />
<div>
<p className="text-sm text-slate-900 mb-1">Department Response Guidelines</p>
<ul className="text-sm text-slate-700 space-y-1">
<li> <strong>NOC Submitted:</strong> Department has no outstanding dues and provided clearance</li>
<li> <strong>Dues Pending:</strong> Department has identified amounts to be recovered or paid</li>
<li> <strong>Pending:</strong> Department has not yet responded to the F&F request</li>
</ul>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="documents" className="space-y-4">
{/* Submitted Documents */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<FileText className="w-5 h-5" />
Submitted Documents
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
{fnfCase.documents.map((doc, index) => (
<div key={index} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg border border-slate-200">
<div className="flex items-center gap-3">
<FileText className="w-5 h-5 text-slate-400" />
<div>
<p className="text-slate-900">{doc.name}</p>
<p className="text-sm text-slate-500">{doc.size} {doc.type} Uploaded on {doc.uploadedOn}</p>
</div>
</div>
<Button variant="outline" size="sm">
Download
</Button>
</div>
))}
</div>
</CardContent>
</Card>
{/* Upload Additional Documents */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Upload className="w-5 h-5" />
Upload Settlement Verification Documents
</CardTitle>
<CardDescription>
Upload bank receipts, settlement proofs, or any additional documents
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="border-2 border-dashed border-slate-300 rounded-lg p-8 text-center hover:border-amber-400 hover:bg-amber-50 transition-colors">
<Upload className="w-8 h-8 text-slate-400 mx-auto mb-2" />
<p className="text-slate-600 mb-2">Click to upload or drag and drop</p>
<p className="text-sm text-slate-500">PDF, DOC, DOCX, PNG, JPG, XLSX (max 10MB)</p>
<input
type="file"
multiple
className="hidden"
id="file-upload"
onChange={handleFileUpload}
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.xlsx,.xls"
/>
<label htmlFor="file-upload">
<Button variant="outline" className="mt-4" asChild>
<span>Choose Files</span>
</Button>
</label>
</div>
{uploadedDocuments.length > 0 && (
<div className="space-y-2">
<Label>Uploaded Documents</Label>
{uploadedDocuments.map((doc, index) => (
<div key={index} className="flex items-center justify-between p-3 bg-green-50 rounded-lg border border-green-200">
<div className="flex items-center gap-3">
<CheckCircle className="w-5 h-5 text-green-600" />
<div>
<p className="text-slate-900">{doc.name}</p>
<p className="text-sm text-slate-500">{doc.size} {doc.type}</p>
</div>
</div>
</div>
))}
</div>
)}
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="bank" className="space-y-4">
{/* Bank Account Details */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Building className="w-5 h-5" />
Dealer Bank Account Details
</CardTitle>
<CardDescription>
Bank account for settlement transfer (if payable to dealer)
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-slate-500">Account Holder Name</Label>
<p className="text-slate-900">{fnfCase.bankDetails.accountName}</p>
</div>
<div>
<Label className="text-slate-500">Account Number</Label>
<p className="text-slate-900">{fnfCase.bankDetails.accountNumber}</p>
</div>
<div>
<Label className="text-slate-500">IFSC Code</Label>
<p className="text-slate-900">{fnfCase.bankDetails.ifscCode}</p>
</div>
<div>
<Label className="text-slate-500">Bank Name</Label>
<p className="text-slate-900">{fnfCase.bankDetails.bankName}</p>
</div>
<div>
<Label className="text-slate-500">Branch</Label>
<p className="text-slate-900">{fnfCase.bankDetails.branch}</p>
</div>
</div>
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-blue-600 mt-0.5" />
<div>
<p className="text-sm text-slate-900 mb-1">Bank Verification Required</p>
<p className="text-sm text-slate-600">
Please verify bank account details before processing settlement payment
</p>
</div>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
{/* Right Column - Settlement Verification Form */}
<div className="space-y-6">
<Card className="sticky top-6">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<CreditCard className="w-5 h-5" />
Settlement Verification
</CardTitle>
<CardDescription>
Enter settlement transaction details
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div>
<Label htmlFor="paymentMode">
Payment Mode <span className="text-red-500">*</span>
</Label>
<Input
id="paymentMode"
placeholder="e.g., NEFT, RTGS, Cheque"
value={settlementDetails.paymentMode}
onChange={(e) => setSettlementDetails({ ...settlementDetails, paymentMode: e.target.value })}
/>
</div>
<div>
<Label htmlFor="verificationTxnId">
Transaction ID / Reference <span className="text-red-500">*</span>
</Label>
<Input
id="verificationTxnId"
placeholder="Enter transaction reference"
value={settlementDetails.verificationTransactionId}
onChange={(e) => setSettlementDetails({ ...settlementDetails, verificationTransactionId: e.target.value })}
/>
</div>
<div>
<Label htmlFor="bankReference">
Bank Reference Number
</Label>
<Input
id="bankReference"
placeholder="Enter bank reference"
value={settlementDetails.bankReference}
onChange={(e) => setSettlementDetails({ ...settlementDetails, bankReference: e.target.value })}
/>
</div>
<div>
<Label htmlFor="settlementAmount">
Settlement Amount () <span className="text-red-500">*</span>
</Label>
<Input
id="settlementAmount"
type="number"
placeholder="Enter settlement amount"
value={settlementDetails.settlementAmount}
onChange={(e) => setSettlementDetails({ ...settlementDetails, settlementAmount: e.target.value })}
/>
</div>
<div>
<Label htmlFor="adjustments">
Adjustments ()
</Label>
<Input
id="adjustments"
type="number"
placeholder="Enter any adjustments"
value={settlementDetails.adjustments}
onChange={(e) => {
const adjustments = e.target.value;
const adjustedAmount = settlement.settlementAmount + parseFloat(adjustments || '0');
setSettlementDetails({
...settlementDetails,
adjustments,
settlementAmount: adjustedAmount.toString()
});
}}
/>
{parseFloat(settlementDetails.adjustments) !== 0 && (
<p className="text-sm text-amber-600 mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
Adjusted amount: {settlementDetails.settlementAmount}
</p>
)}
</div>
<div>
<Label htmlFor="settlementDate">
Settlement Date <span className="text-red-500">*</span>
</Label>
<Input
id="settlementDate"
type="date"
value={settlementDetails.settlementDate}
onChange={(e) => setSettlementDetails({ ...settlementDetails, settlementDate: e.target.value })}
/>
</div>
<div>
<Label htmlFor="verificationRemarks">Verification Remarks</Label>
<Textarea
id="verificationRemarks"
placeholder="Enter any remarks or notes..."
rows={4}
value={settlementDetails.verificationRemarks}
onChange={(e) => setSettlementDetails({ ...settlementDetails, verificationRemarks: e.target.value })}
/>
</div>
<div className="pt-4 space-y-3 border-t">
<Button
className="w-full bg-green-600 hover:bg-green-700"
onClick={handleApproveSettlement}
>
<CheckCircle className="w-4 h-4 mr-2" />
Approve Settlement
</Button>
<Button
variant="outline"
className="w-full border-blue-300 text-blue-600 hover:bg-blue-50"
onClick={handleRequestClarification}
>
<Send className="w-4 h-4 mr-2" />
Request Clarification
</Button>
<Button
variant="outline"
className="w-full border-red-300 text-red-600 hover:bg-red-50"
onClick={handleRejectSettlement}
>
<XCircle className="w-4 h-4 mr-2" />
Reject Settlement
</Button>
</div>
</CardContent>
</Card>
{/* Quick Info Card */}
<Card className="bg-blue-50 border-blue-200">
<CardHeader>
<CardTitle className="text-base">Settlement Checklist</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm text-slate-700">
<li className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-blue-600 mt-0.5" />
<span>Verify all financial calculations</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-blue-600 mt-0.5" />
<span>Confirm bank account details</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-blue-600 mt-0.5" />
<span>Review all submitted documents</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-blue-600 mt-0.5" />
<span>Upload settlement proof documents</span>
</li>
<li className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-blue-600 mt-0.5" />
<span>Enter transaction details accurately</span>
</li>
</ul>
</CardContent>
</Card>
</div>
</div>
</div>
);
}