import { FileText, Calendar, Building, Plus, Eye, ArrowRight, Shield, Loader2 } from 'lucide-react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card'; import { Badge } from '../ui/badge'; import { Button } from '../ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; import { Textarea } from '../ui/textarea'; import { useState, useEffect } from 'react'; import { User as UserType } from '../../lib/mock-data'; import { toast } from 'sonner'; import { API } from '../../api/API'; interface ConstitutionalChangePageProps { currentUser: UserType | null; onViewDetails: (id: string) => void; } // Document requirements mapping const documentRequirements: Record = { 'Partnership': [1, 2, 3, 4, 8, 9, 10, 16], 'LLP': [1, 2, 3, 7, 8, 9, 10, 16], 'Pvt Ltd': [1, 2, 3, 5, 6, 7, 8, 10, 16], 'Proprietorship': [1, 2, 3, 10, 16] }; // Document names const documentNames: Record = { 1: 'GST', 2: 'Firm Pan Copy', 3: 'Self attested KYC\'s', 4: 'Partnership Agreement (Notarised)', 5: 'MOA (Applicable for Only Pvt.Ltd)', 6: 'AOA (Applicable for Only Pvt.Ltd)', 7: 'COI (Applicable for Only Pvt.Ltd & LLP)', 8: 'BPA - Business Purchase Agreement', 9: 'Firm Registration Certificate (Partnership)', 10: 'Cancelled Cheque', 11: 'LLP Agreement (Notarised)', 12: 'ZBH Approval', 13: 'NBH Approval', 14: 'RBM Approval', 15: 'DD-Lead Approval', 16: 'Declaration / Authorization Letter' }; const getStatusColor = (status: string) => { if (status === 'Completed') return 'bg-green-100 text-green-700 border-green-300'; if (status.includes('Review') || status.includes('Pending')) return 'bg-yellow-100 text-yellow-700 border-yellow-300'; if (status.includes('Rejected')) return 'bg-red-100 text-red-700 border-red-300'; if (status.includes('Collection')) return 'bg-blue-100 text-blue-700 border-blue-300'; return 'bg-slate-100 text-slate-700 border-slate-300'; }; const getTypeColor = (type: string) => { switch(type) { case 'Proprietorship': return 'bg-purple-100 text-purple-700 border-purple-300'; case 'Partnership': return 'bg-blue-100 text-blue-700 border-blue-300'; case 'LLP': return 'bg-indigo-100 text-indigo-700 border-indigo-300'; case 'Pvt Ltd': return 'bg-cyan-100 text-cyan-700 border-cyan-300'; default: return 'bg-slate-100 text-slate-700 border-slate-300'; } }; export function ConstitutionalChangePage({ onViewDetails }: ConstitutionalChangePageProps) { const [isDialogOpen, setIsDialogOpen] = useState(false); const [dealerCode, setDealerCode] = useState(''); const [dealerData, setDealerData] = useState(null); const [targetType, setTargetType] = useState(''); const [reason, setReason] = useState(''); const [requiredDocs, setRequiredDocs] = useState([]); const [requests, setRequests] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isSubmitting, setIsSubmitting] = useState(false); useEffect(() => { fetchRequests(); }, []); const fetchRequests = async () => { try { setIsLoading(true); const response = await API.getConstitutionalChanges() as any; if (response.data.success) { setRequests(response.data.requests || []); } } catch (error) { console.error('Fetch requests error:', error); toast.error('Failed to fetch requests'); } finally { setIsLoading(false); } }; const handleDealerCodeChange = async (code: string) => { setDealerCode(code); if (code.length >= 5) { try { const response = await API.getOutletByCode(code) as any; if (response.data.success && response.data.outlet) { const outlet = response.data.outlet; setDealerData({ id: outlet.id, dealerName: outlet.name, address: outlet.address, dealershipName: outlet.name, gst: outlet.gstNumber || 'N/A', currentType: outlet.type || 'Proprietorship', region: outlet.region || 'N/A', zone: outlet.zone || 'N/A' }); toast.success('Dealer details loaded successfully'); } else { setDealerData(null); } } catch (error) { setDealerData(null); } } else { setDealerData(null); } }; const handleTargetTypeChange = (type: string) => { setTargetType(type); setRequiredDocs(documentRequirements[type] || []); }; const handleSubmitRequest = async (e: React.FormEvent) => { e.preventDefault(); if (!dealerData) { toast.error('Please enter a valid dealer code'); return; } if (!targetType) { toast.error('Please select target dealership type'); return; } if (!reason.trim()) { toast.error('Please provide a reason for constitutional change'); return; } if (dealerData.currentType === targetType) { toast.error('Target type cannot be same as current type'); return; } try { setIsSubmitting(true); const payload = { outletId: dealerData.id, changeType: targetType, description: reason, newEntityDetails: {} }; const response = await API.createConstitutionalChange(payload) as any; if (response.data.success) { toast.success('Constitutional change request submitted successfully'); setIsDialogOpen(false); fetchRequests(); // Reset form setDealerCode(''); setDealerData(null); setTargetType(''); setReason(''); setRequiredDocs([]); } } catch (error) { console.error('Submit request error:', error); toast.error('Failed to submit request'); } finally { setIsSubmitting(false); } }; // Statistics const stats = [ { title: 'Total Requests', value: requests.length, icon: FileText, color: 'bg-blue-500', }, { title: 'In Progress', value: requests.filter(r => r.status !== 'Completed' && !r.status.includes('Rejected')).length, icon: Calendar, color: 'bg-yellow-500', }, { title: 'Completed', value: requests.filter(r => r.status === 'Completed').length, icon: Shield, color: 'bg-green-500', }, { title: 'Pending Action', value: requests.filter(r => r.status.includes('Review') || r.status.includes('Pending')).length, icon: Building, color: 'bg-amber-500', }, ]; return (
{/* Loading Overlay */} {isLoading && (
)} {/* Header */}

Constitutional Change Management

Manage dealership constitutional change requests - Adding/Removing partners or changing business structure

Create Constitutional Change Request Submit a request for dealership constitutional change. All fields are mandatory.
{/* Dealer Code */}
handleDealerCodeChange(e.target.value)} required />
{/* Auto-populated Dealer Details */} {dealerData && (

Dealer Details

Dealer Name:

{dealerData.dealerName}

Dealership Name:

{dealerData.dealershipName}

Location:

{dealerData.address}

GST:

{dealerData.gst}

Current Type: {dealerData.currentType}
Region/Zone:

{dealerData.region} / {dealerData.zone}

)} {/* Target Dealership Type */}
{dealerData && targetType && dealerData.currentType === targetType && (

Target type cannot be same as current type

)}
{/* Required Documents Display */} {targetType && requiredDocs.length > 0 && (

Required Documents for {targetType}

{requiredDocs.map((docNum) => (
{docNum}. {documentNames[docNum]}
))}
)} {/* Reason */}