/** * Hook for CreateRequest event handlers * * Contains all handler functions for: * - Template selection * - Step navigation * - Document preview */ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { RequestTemplate, FormData, SystemPolicy } from '@/hooks/useCreateRequestForm'; import { PreviewDocument } from '../types/createRequest.types'; import { getDocumentPreviewUrl } from '@/services/workflowApi'; import { validateApprovers } from './useApproverValidation'; interface UseHandlersOptions { selectedTemplate: RequestTemplate | null; setSelectedTemplate: (template: RequestTemplate | null) => void; updateFormData: (field: keyof FormData, value: any) => void; formData: FormData; currentStep: number; isStepValid: () => boolean; wizardNextStep: () => void; wizardPrevStep: () => void; user: any; openValidationModal: ( type: 'error' | 'self-assign' | 'not-found', email: string, message: string ) => void; systemPolicy?: SystemPolicy; onPolicyViolation?: (violations: Array<{ type: string; message: string; currentValue?: number; maxValue?: number }>) => void; onSubmit?: (requestData: any) => void; goToStep?: (step: number) => void; } export function useCreateRequestHandlers({ selectedTemplate: _selectedTemplate, setSelectedTemplate, updateFormData, formData, currentStep, isStepValid, wizardNextStep, wizardPrevStep, user, openValidationModal, systemPolicy, onPolicyViolation, onSubmit, // goToStep, }: UseHandlersOptions) { const navigate = useNavigate(); const [showTemplateModal, setShowTemplateModal] = useState(false); const [previewDocument, setPreviewDocument] = useState(null); // Template selection handler const selectTemplate = (template: RequestTemplate) => { setSelectedTemplate(template); updateFormData('template', template.id); updateFormData('category', template.category); updateFormData('priority', template.priority); const suggestedDate = new Date(); suggestedDate.setDate(suggestedDate.getDate() + template.suggestedSLA); updateFormData('slaEndDate', suggestedDate); // Note: For 'existing-template', the modal will open when Next is clicked (handled in nextStep) if (template.id !== 'custom' && template.id !== 'existing-template') { // Redirect to dedicated Admin Request flow navigate(`/create-admin-request/${template.id}`); } }; const handleTemplateSelection = (templateId: string) => { // Navigate directly to the template-specific route when template is selected from modal if (templateId === 'claim-management') { navigate('/claim-management'); } else if (templateId === 'vendor-payment') { // Add vendor-payment route if it exists, otherwise fallback to onSubmit navigate('/vendor-payment'); } else if (onSubmit) { // Fallback to onSubmit for other template types onSubmit({ templateType: templateId }); } }; // Step navigation with validation const nextStep = async () => { if (!isStepValid()) return; // On step 1, if "existing-template" is selected, open the template selection modal if (currentStep === 1 && _selectedTemplate?.id === 'existing-template') { setShowTemplateModal(true); return; } if (window.innerWidth < 640) { window.scrollTo({ top: 0, behavior: 'smooth' }); } // Special validation when leaving step 3 (Approval Workflow) if (currentStep === 3) { // Validate approval level count against system policy if (systemPolicy && onPolicyViolation) { const approverCount = formData.approverCount || 1; if (approverCount > systemPolicy.maxApprovalLevels) { onPolicyViolation([{ type: 'Maximum Approval Levels Exceeded', message: `The request has ${approverCount} approval levels, which exceeds the maximum allowed (${systemPolicy.maxApprovalLevels}). Please reduce the number of approvers.`, currentValue: approverCount, maxValue: systemPolicy.maxApprovalLevels }]); return; } } const initiatorEmail = (user as any)?.email?.toLowerCase() || ''; const validation = await validateApprovers( formData.approvers, initiatorEmail ); if (!validation.success && validation.error) { openValidationModal( validation.error.type, validation.error.email, validation.error.message ); return; } if (validation.validatedApprovers) { updateFormData('approvers', validation.validatedApprovers); } } wizardNextStep(); }; const prevStep = () => { wizardPrevStep(); // Scroll to top on mobile to ensure content is visible if (window.innerWidth < 640) { window.scrollTo({ top: 0, behavior: 'smooth' }); } }; // Document preview handlers const handlePreviewDocument = (doc: any, isExisting: boolean) => { if (isExisting) { const docId = doc.documentId || doc.document_id || ''; setPreviewDocument({ fileName: doc.originalFileName || doc.fileName || 'Document', fileType: doc.fileType || doc.file_type || 'application/octet-stream', fileUrl: getDocumentPreviewUrl(docId), fileSize: Number(doc.fileSize || doc.file_size || 0), documentId: docId, }); } else { const fileUrl = URL.createObjectURL(doc); setPreviewDocument({ fileName: doc.name, fileType: doc.type || 'application/octet-stream', fileUrl: fileUrl, fileSize: doc.size, file: doc, }); } }; const closePreview = () => { if (previewDocument?.fileUrl && previewDocument?.file) { URL.revokeObjectURL(previewDocument.fileUrl); } setPreviewDocument(null); }; return { showTemplateModal, setShowTemplateModal, previewDocument, selectTemplate, handleTemplateSelection, nextStep, prevStep, handlePreviewDocument, closePreview, }; }