158 lines
4.2 KiB
TypeScript
158 lines
4.2 KiB
TypeScript
/**
|
|
* Hook for CreateRequest event handlers
|
|
*
|
|
* Contains all handler functions for:
|
|
* - Template selection
|
|
* - Step navigation
|
|
* - Document preview
|
|
*/
|
|
|
|
import { useState } from 'react';
|
|
import { RequestTemplate, FormData } 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;
|
|
onSubmit?: (requestData: any) => void;
|
|
}
|
|
|
|
export function useCreateRequestHandlers({
|
|
selectedTemplate: _selectedTemplate,
|
|
setSelectedTemplate,
|
|
updateFormData,
|
|
formData,
|
|
currentStep,
|
|
isStepValid,
|
|
wizardNextStep,
|
|
wizardPrevStep,
|
|
user,
|
|
openValidationModal,
|
|
onSubmit,
|
|
}: UseHandlersOptions) {
|
|
const [showTemplateModal, setShowTemplateModal] = useState(false);
|
|
const [previewDocument, setPreviewDocument] =
|
|
useState<PreviewDocument | null>(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);
|
|
|
|
if (template.id === 'existing-template') {
|
|
setShowTemplateModal(true);
|
|
}
|
|
};
|
|
|
|
const handleTemplateSelection = (templateId: string) => {
|
|
if (onSubmit) {
|
|
onSubmit({ templateType: templateId });
|
|
}
|
|
};
|
|
|
|
// Step navigation with validation
|
|
const nextStep = async () => {
|
|
if (!isStepValid()) return;
|
|
|
|
if (window.innerWidth < 640) {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
|
|
// Special validation when leaving step 3 (Approval Workflow)
|
|
if (currentStep === 3) {
|
|
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,
|
|
};
|
|
}
|
|
|