212 lines
7.9 KiB
TypeScript
212 lines
7.9 KiB
TypeScript
import { toast } from 'sonner';
|
|
import { Dispatch, SetStateAction } from 'react';
|
|
import { onboardingService } from '../../../services/onboarding.service';
|
|
import { KT_MATRIX_CRITERIA } from './applicationDetails.shared';
|
|
|
|
interface UseApplicationDetailsFeedbackActionsParams {
|
|
ktMatrixScores: Record<string, number>;
|
|
setKtMatrixScores: Dispatch<SetStateAction<Record<string, number>>>;
|
|
setKtMatrixSelectedValues: Dispatch<SetStateAction<Record<string, string>>>;
|
|
ktMatrixRemarks: string;
|
|
setKtMatrixRemarks: Dispatch<SetStateAction<string>>;
|
|
selectedInterviewForFeedback: any;
|
|
interviews: any[];
|
|
setIsSubmittingKT: Dispatch<SetStateAction<boolean>>;
|
|
setShowKTMatrixModal: Dispatch<SetStateAction<boolean>>;
|
|
level2Feedback: any;
|
|
setLevel2Feedback: Dispatch<SetStateAction<any>>;
|
|
setIsSubmittingLevel2: Dispatch<SetStateAction<boolean>>;
|
|
setShowLevel2FeedbackModal: Dispatch<SetStateAction<boolean>>;
|
|
level3Feedback: any;
|
|
setLevel3Feedback: Dispatch<SetStateAction<any>>;
|
|
setIsSubmittingLevel3: Dispatch<SetStateAction<boolean>>;
|
|
setShowLevel3FeedbackModal: Dispatch<SetStateAction<boolean>>;
|
|
currentUser: any;
|
|
fetchInterviews: () => Promise<void>;
|
|
fetchApplication: (silent?: boolean) => Promise<void>;
|
|
}
|
|
|
|
const today = () => new Date().toISOString().split('T')[0];
|
|
|
|
const createInitialLevel2Feedback = (currentUser: any) => ({
|
|
strategicVision: '',
|
|
managementCapabilities: '',
|
|
operationalUnderstanding: '',
|
|
keyStrengths: '',
|
|
areasOfConcern: '',
|
|
additionalComments: '',
|
|
overallScore: '',
|
|
interviewerName: currentUser?.name || '',
|
|
interviewDate: today(),
|
|
});
|
|
|
|
const createInitialLevel3Feedback = (currentUser: any) => ({
|
|
strategicVision: '',
|
|
managementCapabilities: '',
|
|
operationalUnderstanding: '',
|
|
brandAlignment: '',
|
|
executiveSummary: '',
|
|
keyStrengths: '',
|
|
areasOfConcern: '',
|
|
additionalComments: '',
|
|
overallScore: '',
|
|
interviewerName: currentUser?.name || '',
|
|
interviewDate: today(),
|
|
});
|
|
|
|
export function useApplicationDetailsFeedbackActions({
|
|
ktMatrixScores,
|
|
setKtMatrixScores,
|
|
setKtMatrixSelectedValues,
|
|
ktMatrixRemarks,
|
|
setKtMatrixRemarks,
|
|
selectedInterviewForFeedback,
|
|
interviews,
|
|
setIsSubmittingKT,
|
|
setShowKTMatrixModal,
|
|
level2Feedback,
|
|
setLevel2Feedback,
|
|
setIsSubmittingLevel2,
|
|
setShowLevel2FeedbackModal,
|
|
level3Feedback,
|
|
setLevel3Feedback,
|
|
setIsSubmittingLevel3,
|
|
setShowLevel3FeedbackModal,
|
|
currentUser,
|
|
fetchInterviews,
|
|
fetchApplication,
|
|
}: UseApplicationDetailsFeedbackActionsParams) {
|
|
const handleKTMatrixChange = (criterionName: string, value: string, score: number) => {
|
|
setKtMatrixScores((prev) => ({ ...prev, [criterionName]: score }));
|
|
setKtMatrixSelectedValues((prev) => ({ ...prev, [criterionName]: value }));
|
|
};
|
|
|
|
const calculateKTScore = () => {
|
|
let totalWeightedScore = 0;
|
|
KT_MATRIX_CRITERIA.forEach((criterion) => {
|
|
const score = ktMatrixScores[criterion.name] || 0;
|
|
totalWeightedScore += (score / criterion.maxScore) * criterion.weight;
|
|
});
|
|
return totalWeightedScore.toFixed(2);
|
|
};
|
|
|
|
const handleSubmitKTMatrix = async () => {
|
|
if (Object.keys(ktMatrixScores).length < KT_MATRIX_CRITERIA.length) {
|
|
toast.warning('Please fill all fields in the KT Matrix');
|
|
return;
|
|
}
|
|
const interviewId = selectedInterviewForFeedback?.id || interviews.find((i) => i.status !== 'Completed')?.id || interviews[0]?.id;
|
|
if (!interviewId) {
|
|
toast.error('No active interview found to link this KT Matrix to.');
|
|
return;
|
|
}
|
|
try {
|
|
setIsSubmittingKT(true);
|
|
const criteriaScores = KT_MATRIX_CRITERIA.map((c) => ({
|
|
criterionName: c.name,
|
|
score: ktMatrixScores[c.name] || 0,
|
|
maxScore: c.maxScore,
|
|
weightage: c.weight,
|
|
}));
|
|
await onboardingService.submitKTMatrix({ interviewId, criteriaScores, feedback: ktMatrixRemarks, recommendation: null });
|
|
toast.success('KT Matrix submitted successfully');
|
|
setShowKTMatrixModal(false);
|
|
setKtMatrixScores({});
|
|
setKtMatrixSelectedValues({});
|
|
setKtMatrixRemarks('');
|
|
await fetchInterviews();
|
|
await fetchApplication();
|
|
} catch {
|
|
toast.error('Failed to submit KT Matrix');
|
|
} finally {
|
|
setIsSubmittingKT(false);
|
|
}
|
|
};
|
|
|
|
const handleLevel2Change = (field: string, value: string) => {
|
|
setLevel2Feedback((prev: any) => ({ ...prev, [field]: value }));
|
|
};
|
|
|
|
const handleSubmitLevel2Feedback = async () => {
|
|
if (!level2Feedback.overallScore) {
|
|
toast.warning('Please provide an overall score.');
|
|
return;
|
|
}
|
|
const interviewId = selectedInterviewForFeedback?.id || interviews.find((i) => i.status !== 'Completed' && i.level === 2)?.id;
|
|
if (!interviewId) {
|
|
toast.error('No active Level 2 interview found to link this feedback to.');
|
|
return;
|
|
}
|
|
try {
|
|
setIsSubmittingLevel2(true);
|
|
const feedbackItems = [
|
|
{ type: 'Strategic Vision', comments: level2Feedback.strategicVision },
|
|
{ type: 'Management Capabilities', comments: level2Feedback.managementCapabilities },
|
|
{ type: 'Operational Understanding', comments: level2Feedback.operationalUnderstanding },
|
|
{ type: 'Key Strengths', comments: level2Feedback.keyStrengths },
|
|
{ type: 'Areas of Concern', comments: level2Feedback.areasOfConcern },
|
|
{ type: 'Additional Comments', comments: level2Feedback.additionalComments },
|
|
].filter((item) => item.comments.trim() !== '');
|
|
await onboardingService.submitLevel2Feedback({ interviewId, overallScore: Number(level2Feedback.overallScore), feedbackItems });
|
|
toast.success('Level 2 Feedback submitted successfully');
|
|
setShowLevel2FeedbackModal(false);
|
|
setLevel2Feedback(createInitialLevel2Feedback(currentUser));
|
|
await fetchInterviews();
|
|
await fetchApplication();
|
|
} catch {
|
|
toast.error('Failed to submit Level 2 Feedback');
|
|
} finally {
|
|
setIsSubmittingLevel2(false);
|
|
}
|
|
};
|
|
|
|
const handleLevel3Change = (field: string, value: string) => {
|
|
setLevel3Feedback((prev: any) => ({ ...prev, [field]: value }));
|
|
};
|
|
|
|
const handleSubmitLevel3Feedback = async () => {
|
|
if (!level3Feedback.overallScore) {
|
|
toast.warning('Please provide an overall score.');
|
|
return;
|
|
}
|
|
const interviewId = selectedInterviewForFeedback?.id || interviews.find((i) => i.status !== 'Completed' && i.level === 3)?.id;
|
|
if (!interviewId) {
|
|
toast.error('No active Level 3 interview found to link this feedback to.');
|
|
return;
|
|
}
|
|
try {
|
|
setIsSubmittingLevel3(true);
|
|
const feedbackItems = [
|
|
{ type: 'Business Vision & Strategy', comments: level3Feedback.strategicVision },
|
|
{ type: 'Leadership & Decision Making', comments: level3Feedback.managementCapabilities },
|
|
{ type: 'Operational & Financial Readiness', comments: level3Feedback.operationalUnderstanding },
|
|
{ type: 'Brand Alignment', comments: level3Feedback.brandAlignment },
|
|
{ type: 'Key Strengths', comments: level3Feedback.keyStrengths },
|
|
{ type: 'Areas of Concern', comments: level3Feedback.areasOfConcern },
|
|
{ type: 'Executive Summary', comments: level3Feedback.executiveSummary },
|
|
{ type: 'Additional Comments', comments: level3Feedback.additionalComments },
|
|
].filter((item) => item.comments.trim() !== '');
|
|
await onboardingService.submitLevel2Feedback({ interviewId, overallScore: Number(level3Feedback.overallScore), feedbackItems });
|
|
toast.success('Level 3 Feedback submitted successfully');
|
|
setShowLevel3FeedbackModal(false);
|
|
setLevel3Feedback(createInitialLevel3Feedback(currentUser));
|
|
await fetchInterviews();
|
|
await fetchApplication();
|
|
} catch {
|
|
toast.error('Failed to submit Level 3 Feedback');
|
|
} finally {
|
|
setIsSubmittingLevel3(false);
|
|
}
|
|
};
|
|
|
|
return {
|
|
handleKTMatrixChange,
|
|
calculateKTScore,
|
|
handleSubmitKTMatrix,
|
|
handleLevel2Change,
|
|
handleSubmitLevel2Feedback,
|
|
handleLevel3Change,
|
|
handleSubmitLevel3Feedback,
|
|
};
|
|
}
|