import { AlertCircle, Building2, Download, Eye, FileText, Info, Loader2, ShieldAlert, ShieldCheck, Upload } from 'lucide-react'; import { toast } from 'sonner'; import { onboardingService } from '@/services/onboarding.service'; import { cn, formatDateTime } from '@/components/ui/utils'; import { DocumentPreviewModal } from '@/components/ui/DocumentPreviewModal'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Separator } from '@/components/ui/separator'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Textarea } from '@/components/ui/textarea'; interface ApplicationDetailsExtendedModalsProps { [key: string]: any; } export function ApplicationDetailsExtendedModals(props: ApplicationDetailsExtendedModalsProps) { const { application, ktCriteria, l2Fields, l3Fields, showKTMatrixModal, setShowKTMatrixModal, ktMatrixSelectedValues, handleKTMatrixChange, ktMatrixRemarks, setKtMatrixRemarks, calculateKTScore, handleSubmitKTMatrix, isSubmittingKT, showLevel2FeedbackModal, setShowLevel2FeedbackModal, level2Feedback, handleLevel2Change, handleSubmitLevel2Feedback, isSubmittingLevel2, showFeedbackDetailsModal, setShowFeedbackDetailsModal, selectedEvaluationForView, showLevel3FeedbackModal, setShowLevel3FeedbackModal, level3Feedback, handleLevel3Change, handleSubmitLevel3Feedback, isSubmittingLevel3, showDocumentsModal, setShowDocumentsModal, showUploadForm, setShowUploadForm, selectedStage, getDocumentsForStage, setPreviewDoc, setShowPreviewModal, flattenedStages, setSelectedStage, uploadDocType, setUploadDocType, setUploadFile, isUploading, handleUpload, uploadFile, documentConfigs, showPreviewModal, previewDoc, showFddFinalizeModal, setShowFddFinalizeModal, currentUser, fddAuditRecommendation, setFddAuditRecommendation, fddAuditFindings, setFddAuditFindings, isFinalizingFdd, setIsFinalizingFdd, fetchApplication, showFddFlagModal, setShowFddFlagModal, isFddFlagging, setIsFddFlagging, showFirmTypeModal, setShowFirmTypeModal, tempFirmType, setTempFirmType, updatingFirmType, handleUpdateFirmType, } = props; return ( <> KT matrix Level 1 interview · {application.name} {Object.keys(ktMatrixSelectedValues).length} of {ktCriteria.length} criteria answered {ktCriteria.map((criterion: any, idx: number) => ( {idx + 1}. {criterion.name} *{' '} ({criterion.weight}%) { const option = criterion.options.find((o: any) => o.value === value); if (option) handleKTMatrixChange(criterion.name, option.value, option.score); }} > {criterion.options.map((option: any) => ( {option.label} ({option.score}) ))} ))} Notes (optional) setKtMatrixRemarks(e.target.value)} data-testid="onboarding-kt-matrix-remarks-textarea" /> Weighted total {calculateKTScore()} / 100 setShowKTMatrixModal(false)} data-testid="onboarding-kt-matrix-cancel">Cancel {isSubmittingKT ? 'Saving…' : 'Submit'} Level 2 Interview Feedback Provide detailed feedback from the Level 2 interview (DD Lead + ZBH evaluation). Interview Date * Interviewer Name * Overall Performance Score * handleLevel2Change('overallScore', value)}> Outstanding (9-10)Excellent (7-8)Good (5-6)Average (3-4)Below Average (1-2) {(l2Fields || []).map((field: any, idx: number) => ( {field.label} {field.isRequired && *} {field.type === 'select' ? ( handleLevel2Change(field.itemKey, value)}> {(field.options || []).map((opt: any, oIdx: number) => ( {opt.optionLabel || opt.label} ))} ) : field.type === 'number' ? ( handleLevel2Change(field.itemKey, e.target.value)} /> ) : ( handleLevel2Change(field.itemKey, e.target.value)} /> )} ))} setShowLevel2FeedbackModal(false)} data-testid="onboarding-level2-feedback-cancel">Cancel {isSubmittingLevel2 ? 'Submitting...' : 'Submit Feedback'} Interview Feedback Details {selectedEvaluationForView && ( Interviewer{selectedEvaluationForView.evaluator?.fullName} Role{selectedEvaluationForView.evaluator?.role?.roleName || 'N/A'} {selectedEvaluationForView.interview?.level === 1 ? 'Score (KT Matrix)' : 'Overall Score'}{selectedEvaluationForView.ktMatrixScore ? `${selectedEvaluationForView.ktMatrixScore}/${selectedEvaluationForView.interview?.level === 1 ? '100' : '10'}` : 'N/A'} Recommendation{selectedEvaluationForView.recommendation || 'N/A'} Detailed Feedback {selectedEvaluationForView.feedbackDetails?.length > 0 ? ( {selectedEvaluationForView.feedbackDetails.map((detail: any, index: number) => ( {detail.feedbackType} {detail.comments} ))} ) : ( No detailed feedback available. )} )} Level 3 Interview Feedback Provide detailed feedback from the Level 3 interview (NBH + DD-Head evaluation). Interview Date * Interviewer Name * Overall Performance Score * handleLevel3Change('overallScore', value)}> Outstanding (9-10)Excellent (7-8)Good (5-6)Average (3-4)Below Average (1-2) {(l3Fields || []).map((field: any, idx: number) => ( {field.label} {field.isRequired && *} {field.type === 'select' ? ( handleLevel3Change(field.itemKey, value)}> {(field.options || []).map((opt: any, oIdx: number) => ( {opt.optionLabel || opt.label} ))} ) : field.type === 'number' ? ( handleLevel3Change(field.itemKey, e.target.value)} /> ) : ( handleLevel3Change(field.itemKey, e.target.value)} /> )} ))} setShowLevel3FeedbackModal(false)} data-testid="onboarding-level3-feedback-cancel">Cancel {isSubmittingLevel3 ? 'Submitting...' : 'Submit Feedback'} { setShowDocumentsModal(open); if (!open) setShowUploadForm(false); }}> Documents - {selectedStage || 'General'} View and manage documents uploaded for this stage. {!showUploadForm ? ( {getDocumentsForStage(selectedStage || '').length > 0 ? ( Document Name Type Upload Date Uploaded By Actions {getDocumentsForStage(selectedStage || '').map((doc: any, index: number) => ( {doc.fileName} {doc.documentType?.toLowerCase() || 'Other'} {formatDateTime(doc.createdAt)} {doc.uploader?.fullName || (doc.uploadedBy ? 'System User' : 'Applicant')} { setPreviewDoc(doc); setShowPreviewModal(true); }} data-testid={`onboarding-document-preview-${index}`}> { const baseUrl = (import.meta as any).env?.VITE_API_URL || 'http://localhost:5000'; window.open(`${baseUrl}/${doc.filePath}`, '_blank'); }} data-testid={`onboarding-document-download-${index}`}> ))} ) : ( No Documents FoundNo documents have been uploaded for this stage yet. )} setShowUploadForm(true)} data-testid="onboarding-documents-upload-button">Upload Document setShowDocumentsModal(false)} data-testid="onboarding-documents-close-button">Close ) : ( Stage context * setSelectedStage(val === 'null' ? null : val)}> General / No Stage {flattenedStages.map((s: any, idx: number) => {s.parentBranch ? `${s.parentBranch}: ${s.name}` : s.name})} Document Type * {(() => { const baseDocs = ['Other']; const stageConfigs = documentConfigs.filter((c: any) => { const cfgStage = c.stageCode?.trim(); const selStage = (selectedStage || 'General').trim(); if (cfgStage === selStage) return true; if (selStage.startsWith('EOR:') && cfgStage === 'EOR') return true; if (!selectedStage && cfgStage === 'General') return true; return false; }); let filteredDocs: string[] = []; if (stageConfigs.length > 0) filteredDocs = stageConfigs.map((c: any) => c.documentType); else if (!selectedStage || selectedStage === 'General') { filteredDocs = ['PAN Card', 'GST Certificate', 'Aadhaar Card', 'Passport Size Photograph', 'Partnership Deed', 'LLP Agreement', 'Certificate of Incorporation', 'Board Resolution', 'Firm Registration Certificate', 'Cancelled Check', 'Bank Statement', 'Other']; } else if (selectedStage?.toLowerCase().includes('architecture')) { filteredDocs = ['Architecture Blueprint', 'Site Plan', 'Proposed Site City Map', 'Site Readiness Report', 'Architecture Completion Certificate', 'Other']; } else if (selectedStage?.toLowerCase().includes('fdd')) { filteredDocs = ['FDD Final Audit Report', 'Bank Statement', 'Income Tax Returns (ITR)', 'CIBIL Report', 'Other']; } else filteredDocs = baseDocs; if (selectedStage?.startsWith('EOR: ')) { const eorItem = selectedStage.replace('EOR: ', ''); if (!filteredDocs.includes(eorItem)) filteredDocs = [eorItem, ...filteredDocs]; } return Array.from(new Set(filteredDocs)).map((doc, idx) => {doc}); })()} Select File * setUploadFile(e.target.files ? e.target.files[0] : null)} data-testid="onboarding-documents-file-input" /> setShowUploadForm(false)} disabled={isUploading} data-testid="onboarding-documents-upload-cancel">Cancel { await handleUpload(); setShowUploadForm(false); }} disabled={!uploadFile || !uploadDocType || isUploading} data-testid="onboarding-documents-upload-submit"> {isUploading ? Uploading... : Confirm Upload} )} setShowPreviewModal(false)} document={previewDoc} /> Finalize FDD Audit You are about to submit your final findings. This action will lock the audit session and trigger the LOI approval workflow. {(currentUser?.role !== 'FDD' && currentUser?.roleCode !== 'FDD') && ( Auditor Recommendation * {['Recommended', 'Qualified with Observations', 'Not Recommended'].map((rec) => ( setFddAuditRecommendation(rec)} data-testid={`onboarding-fdd-recommendation-${rec.replace(/\s+/g, '-').toLowerCase()}`}>{rec} ))} )} Findings Summary setFddAuditFindings(e.target.value)} data-testid="onboarding-fdd-findings-textarea" /> Ensure the final PDF report is uploaded first. This satisfies the FDD statutory requirement. setShowFddFinalizeModal(false)} disabled={isFinalizingFdd} data-testid="onboarding-fdd-finalize-cancel">Cancel { try { setIsFinalizingFdd(true); await onboardingService.submitStageDecision({ applicationId: application!.id, stageCode: 'FDD_VERIFICATION', decision: 'Approved', remarks: (currentUser?.role === 'FDD' || currentUser?.roleCode === 'FDD') ? `Findings: ${fddAuditFindings}` : `[RECOMMENDATION: ${fddAuditRecommendation}] \nFindings: ${fddAuditFindings}`, nextStatus: 'LOI In Progress', nextProgress: 65 }); toast.success('FDD Audit finalized and submitted.'); setShowFddFinalizeModal(false); fetchApplication(); } catch { toast.error('Submission failed'); } finally { setIsFinalizingFdd(false); } }} > {isFinalizingFdd ? : 'Confirm & Submit'} Flag Non-Responsive Are you sure you want to flag this applicant? This will notify the DD Admin that the audit cannot proceed due to applicant's non-cooperation. "Applicant is unresponsive to multiple queries and financial document requests." setShowFddFlagModal(false)} disabled={isFddFlagging} data-testid="onboarding-fdd-flag-cancel">Go Back { try { setIsFddFlagging(true); await onboardingService.submitStageDecision({ applicationId: application!.id, stageCode: 'FDD_VERIFICATION', decision: 'Rejected', remarks: 'Applicant is non-responsive to FDD queries.' }); toast.error('Applicant flagged as non-responsive.'); setShowFddFlagModal(false); fetchApplication(); } catch { toast.error('Action failed'); } finally { setIsFddFlagging(false); } }} > {isFddFlagging ? : 'Confirm Flag'} Update Firm Type Select the proposed legal constitution for this dealership application. Proposed Legal Constitution * Proprietorship Partnership LLP (Limited Liability partnership) Private Limited Company Public Limited Company setShowFirmTypeModal(false)} disabled={updatingFirmType} data-testid="onboarding-firm-type-cancel">Cancel {updatingFirmType ? : 'Update Type'} > ); }
Weighted total {calculateKTScore()} / 100
Interviewer
{selectedEvaluationForView.evaluator?.fullName}
Role
{selectedEvaluationForView.evaluator?.role?.roleName || 'N/A'}
{selectedEvaluationForView.interview?.level === 1 ? 'Score (KT Matrix)' : 'Overall Score'}
{selectedEvaluationForView.ktMatrixScore ? `${selectedEvaluationForView.ktMatrixScore}/${selectedEvaluationForView.interview?.level === 1 ? '100' : '10'}` : 'N/A'}
Recommendation
{detail.feedbackType}
{detail.comments}
No detailed feedback available.
No documents have been uploaded for this stage yet.
Ensure the final PDF report is uploaded first. This satisfies the FDD statutory requirement.
"Applicant is unresponsive to multiple queries and financial document requests."
Select the proposed legal constitution for this dealership application.