Dealer_Onboard_Frontend/src/features/onboarding/hooks/useApplicationDetailsData.ts

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,
};
}