207 lines
8.1 KiB
TypeScript
207 lines
8.1 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react';
|
|
import { Application, ApplicationStatus } from '@/lib/mock-data';
|
|
import { onboardingService } from '@/services/onboarding.service';
|
|
import { eorService } from '@/services/eor.service';
|
|
import { auditService } from '@/services/audit.service';
|
|
import { collaborationService } from '@/services/collaboration.service';
|
|
|
|
interface UseApplicationDetailsDataParams {
|
|
applicationId: string;
|
|
}
|
|
|
|
export function useApplicationDetailsData({ applicationId }: UseApplicationDetailsDataParams) {
|
|
const [application, setApplication] = useState<Application | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [documents, setDocuments] = useState<any[]>([]);
|
|
const [eorData, setEorData] = useState<any>(null);
|
|
const [auditLogs, setAuditLogs] = useState<any[]>([]);
|
|
const [auditLoading, setAuditLoading] = useState(false);
|
|
const [worknotes, setWorknotes] = useState<any[]>([]);
|
|
const [deposits, setDeposits] = useState<any[]>([]);
|
|
const [paymentConfigs, setPaymentConfigs] = useState<any>({});
|
|
|
|
const refreshDocuments = useCallback(async () => {
|
|
try {
|
|
const docs = await onboardingService.getDocuments(applicationId);
|
|
setDocuments(docs || []);
|
|
} catch (error) {
|
|
console.error('Failed to refresh documents:', error);
|
|
}
|
|
}, [applicationId]);
|
|
|
|
const fetchApplication = useCallback(async (silent = false) => {
|
|
try {
|
|
if (!silent) setLoading(true);
|
|
const data = await onboardingService.getApplicationById(applicationId);
|
|
|
|
const getStageDate = (stageName: string, fallbackStatus?: string) => {
|
|
const stage = data.progressTracking?.find((p: any) => p.stageName === stageName);
|
|
if (stage?.stageCompletedAt) return new Date(stage.stageCompletedAt).toISOString();
|
|
if (stage?.stageStartedAt) return new Date(stage.stageStartedAt).toISOString();
|
|
if (fallbackStatus) {
|
|
const history = (data.statusHistory || []).find((h: any) => h.newStatus === fallbackStatus);
|
|
if (history) return new Date(history.createdAt).toISOString();
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
const mappedApp: Application = {
|
|
id: data.id,
|
|
registrationNumber: data.applicationId || 'N/A',
|
|
name: data.applicantName,
|
|
email: data.email,
|
|
phone: data.phone,
|
|
age: data.age,
|
|
education: data.education,
|
|
residentialAddress: data.address || data.city || '',
|
|
businessAddress: data.address || '',
|
|
preferredLocation: data.preferredLocation,
|
|
state: data.state,
|
|
ownsBike: data.ownRoyalEnfield === 'yes',
|
|
pastExperience: data.experienceYears ? `${data.experienceYears} years` : data.description || '',
|
|
status: data.overallStatus as ApplicationStatus,
|
|
questionnaireMarks: data.score || data.questionnaireMarks || 0,
|
|
questionnaireResponses: data.questionnaireResponses || [],
|
|
rank: 0,
|
|
totalApplicantsAtLocation: 0,
|
|
assignedUsers: [],
|
|
progress: data.progressPercentage || 0,
|
|
isShortlisted: data.isShortlisted || true,
|
|
companyName: data.companyName,
|
|
source: data.source,
|
|
existingDealer: data.existingDealer,
|
|
royalEnfieldModel: data.royalEnfieldModel,
|
|
description: data.description,
|
|
pincode: data.pincode,
|
|
locationType: data.locationType,
|
|
ownRoyalEnfield: data.ownRoyalEnfield,
|
|
address: data.address,
|
|
submissionDate: data.createdAt ? new Date(data.createdAt).toISOString() : '',
|
|
questionnaireDate: getStageDate('Questionnaire', 'Questionnaire Completed') || getStageDate('Questionnaire', 'Questionnaire Pending'),
|
|
shortlistDate: getStageDate('Shortlist', 'Shortlisted'),
|
|
level1InterviewDate: getStageDate('1st Level Interview', 'Level 1 Approved'),
|
|
level2InterviewDate: getStageDate('2nd Level Interview', 'Level 2 Approved'),
|
|
level3InterviewDate: getStageDate('3rd Level Interview', 'Level 3 Approved'),
|
|
fddDate: getStageDate('FDD', 'FDD Verification'),
|
|
loiApprovalDate: getStageDate('LOI Approval', 'LOI In Progress'),
|
|
securityDetailsDate: getStageDate('Security Details', 'Security Details'),
|
|
loiIssueDate: getStageDate('LOI Issue', 'LOI Issued'),
|
|
dealerCodeDate: getStageDate('Dealer Code Generation', 'Dealer Code Generation'),
|
|
architectureAssignedDate: getStageDate('Architecture Team Assigned', 'Architecture Team Assigned'),
|
|
architectureDocumentDate: getStageDate('Architecture Document Upload', 'Architecture Document Upload'),
|
|
architectureCompletionDate: getStageDate('Architecture Team Completion', 'Architecture Team Completion'),
|
|
loaDate: getStageDate('LOA', 'LOA Pending'),
|
|
eorCompleteDate: getStageDate('EOR Complete', 'EOR Complete'),
|
|
inaugurationDate: getStageDate('Inauguration', 'Inauguration'),
|
|
onboardedDate: data.overallStatus === 'Onboarded' ? (data.updatedAt ? new Date(data.updatedAt).toISOString() : new Date().toISOString()) : undefined,
|
|
progressTracking: data.progressTracking || [],
|
|
participants: data.participants || [],
|
|
dealerCode: data.dealerCode,
|
|
zoneId: data.zoneId,
|
|
regionId: data.regionId,
|
|
areaId: data.areaId,
|
|
districtId: data.districtId,
|
|
stageApprovals: data.stageApprovals || [],
|
|
fddAssignments: data.fddAssignments || [],
|
|
constitutionType: data.constitutionType,
|
|
architectureStatus: data.architectureStatus,
|
|
statutoryStatus: data.statutoryStatus,
|
|
panNumber: data.panNumber,
|
|
gstNumber: data.gstNumber,
|
|
bankName: data.bankName,
|
|
accountNumber: data.accountNumber,
|
|
ifscCode: data.ifscCode,
|
|
branchName: data.branchName,
|
|
accountHolderName: data.accountHolderName,
|
|
registeredAddress: data.registeredAddress,
|
|
};
|
|
|
|
setApplication(mappedApp);
|
|
if (data.uploadedDocuments) setDocuments(data.uploadedDocuments || []);
|
|
} catch (error) {
|
|
console.error('Failed to fetch application details', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [applicationId]);
|
|
|
|
const fetchEorData = useCallback(async () => {
|
|
if (!applicationId) return;
|
|
try {
|
|
const resp = await eorService.getChecklist(applicationId);
|
|
if (resp.success && resp.data) setEorData(resp.data);
|
|
} catch {
|
|
setEorData(null);
|
|
}
|
|
}, [applicationId]);
|
|
|
|
const getDeposit = (type: string) => deposits.find((d) => d.depositType === type);
|
|
|
|
useEffect(() => {
|
|
if (!applicationId) return;
|
|
fetchApplication();
|
|
refreshDocuments();
|
|
}, [applicationId]);
|
|
|
|
useEffect(() => {
|
|
if (applicationId) fetchEorData();
|
|
}, [applicationId, application?.status]);
|
|
|
|
useEffect(() => {
|
|
if (!application?.id) return;
|
|
const fetchAuditAndWorknotes = async () => {
|
|
setAuditLoading(true);
|
|
try {
|
|
const logs = await auditService.getAuditLogs('application', application.id, 1, 100);
|
|
setAuditLogs(Array.isArray(logs) ? logs : []);
|
|
} catch {
|
|
setAuditLogs([]);
|
|
} finally {
|
|
setAuditLoading(false);
|
|
}
|
|
try {
|
|
const res = await collaborationService.getWorknotes('application', application.id);
|
|
setWorknotes(res.data || []);
|
|
} catch {
|
|
setWorknotes([]);
|
|
}
|
|
};
|
|
fetchAuditAndWorknotes();
|
|
}, [application?.id]);
|
|
|
|
useEffect(() => {
|
|
if (!applicationId) return;
|
|
const fetchPaymentData = async () => {
|
|
try {
|
|
const [depositData, configData] = await Promise.all([
|
|
onboardingService.getSecurityDeposit(applicationId),
|
|
onboardingService.getSystemConfigs({ category: 'SECURITY_DEPOSIT', format: 'map' }),
|
|
]);
|
|
setDeposits(Array.isArray(depositData) ? depositData : [depositData].filter(Boolean));
|
|
setPaymentConfigs(configData || {});
|
|
} catch (error) {
|
|
console.error('Failed to fetch payment data', error);
|
|
}
|
|
};
|
|
fetchPaymentData();
|
|
}, [applicationId]);
|
|
|
|
return {
|
|
application,
|
|
loading,
|
|
setLoading,
|
|
documents,
|
|
setDocuments,
|
|
eorData,
|
|
auditLogs,
|
|
auditLoading,
|
|
worknotes,
|
|
deposits,
|
|
paymentConfigs,
|
|
refreshDocuments,
|
|
fetchApplication,
|
|
fetchEorData,
|
|
getDeposit,
|
|
};
|
|
}
|