import { defineStore } from "pinia"; import { ref, computed } from "vue"; import DocumentAttachmentService from "@/services/documentAttachment"; import type { DocumentAttachment, CreateAttachmentPayload, UpdateAttachmentPayload, BulkDeletePayload, ReorderAttachmentPayload, } from "@/services/documentAttachment"; export const useDocumentAttachmentStore = defineStore( "documentAttachment", () => { // State const attachments = ref([]); const loading = ref(false); const error = ref(null); const success = ref(false); // Getters const allAttachments = computed(() => attachments.value); const isLoading = computed(() => loading.value); const hasError = computed(() => error.value !== null); const getError = computed(() => error.value); const isSuccess = computed(() => success.value); const getAttachmentsByType = computed(() => (type: string) => attachments.value?.filter( (attachment) => attachment.attachable_type === type ) || [] ); const getAttachmentsById = computed(() => (id: number) => attachments.value?.filter( (attachment) => attachment.attachable_id === id ) || [] ); const getInterventionAttachments = computed( () => (interventionId: number) => attachments.value?.filter( (attachment) => attachment.attachable_type === "App\\Models\\Intervention" && attachment.attachable_id === interventionId ) || [] ); const getClientAttachments = computed(() => (clientId: number) => attachments.value?.filter( (attachment) => attachment.attachable_type === "App\\Models\\Client" && attachment.attachable_id === clientId ) || [] ); const getDeceasedAttachments = computed(() => (deceasedId: number) => attachments.value?.filter( (attachment) => attachment.attachable_type === "App\\Models\\Deceased" && attachment.attachable_id === deceasedId ) || [] ); // Actions const setLoading = (isLoading: boolean) => { loading.value = isLoading; }; const setError = (err: string | null) => { error.value = err; }; const clearError = () => { error.value = null; }; const setSuccess = (isSuccess: boolean) => { success.value = isSuccess; }; const clearSuccess = () => { success.value = false; }; const setAttachments = (newAttachments: DocumentAttachment[]) => { attachments.value = newAttachments || []; }; const addAttachment = (attachment: DocumentAttachment) => { if (!attachments.value) { attachments.value = []; } attachments.value.push(attachment); }; const updateAttachment = (updatedAttachment: DocumentAttachment) => { if (!attachments.value) return; const index = attachments.value.findIndex( (attachment) => attachment.id === updatedAttachment.id ); if (index !== -1) { attachments.value[index] = updatedAttachment; } }; const removeAttachment = (attachmentId: number) => { if (!attachments.value) return; attachments.value = attachments.value.filter( (attachment) => attachment.id !== attachmentId ); }; const removeAttachments = (attachmentIds: number[]) => { if (!attachments.value) return; attachments.value = attachments.value.filter( (attachment) => !attachmentIds.includes(attachment.id) ); }; /** * Attach a file to a model */ const attachFile = async (payload: CreateAttachmentPayload) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.attachFile(payload); addAttachment(response.data); setSuccess(true); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec de l'attachement du fichier"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Detach a file from a model */ const detachFile = async (attachmentId: number) => { setLoading(true); setError(null); setSuccess(false); try { await DocumentAttachmentService.detachFile(attachmentId); removeAttachment(attachmentId); setSuccess(true); return { message: "Fichier détaché avec succès" }; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du détachement du fichier"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Update file attachment metadata */ const updateAttachmentMetadata = async ( attachmentId: number, payload: UpdateAttachmentPayload ) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.updateAttachment( attachmentId, payload ); updateAttachment(response.data); setSuccess(true); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec de la mise à jour du document"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Get files attached to a specific model */ const fetchAttachedFiles = async ( attachableType: string, attachableId: number ) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.getAttachedFiles( attachableType, attachableId ); setAttachments(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du chargement des fichiers attachés"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Get files attached to an intervention */ const fetchInterventionFiles = async (interventionId: number) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.getInterventionFiles( interventionId ); setAttachments(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du chargement des fichiers de l'intervention"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Get files attached to a client */ const fetchClientFiles = async (clientId: number) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.getClientFiles( clientId ); setAttachments(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du chargement des fichiers du client"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Get files attached to a deceased */ const fetchDeceasedFiles = async (deceasedId: number) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.getDeceasedFiles( deceasedId ); setAttachments(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du chargement des fichiers du défunt"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Detach multiple files at once */ const detachMultipleFiles = async (payload: BulkDeletePayload) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.detachMultiple( payload ); removeAttachments(payload.attachment_ids); setSuccess(true); return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec de la suppression des fichiers"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Reorder file attachments */ const reorderAttachments = async (payload: ReorderAttachmentPayload) => { setLoading(true); setError(null); setSuccess(false); try { const response = await DocumentAttachmentService.reorderAttachments( payload ); // Update sort order in local state if (attachments.value) { payload.attachments.forEach((item) => { const attachment = attachments.value.find((a) => a.id === item.id); if (attachment) { attachment.sort_order = item.sort_order; } }); // Sort attachments by sort_order attachments.value.sort((a, b) => a.sort_order - b.sort_order); } setSuccess(true); return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec de la réorganisation des fichiers"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Upload and attach files to a model */ const uploadAndAttachFiles = async ( files: File[], attachableType: string, attachableId: number, options?: { labels?: string[]; onProgress?: (progress: number) => void; } ) => { setLoading(true); setError(null); setSuccess(false); try { const uploadedAttachments = await DocumentAttachmentService.uploadAndAttachFiles( files, attachableType, attachableId, options ); // Add all uploaded attachments to the store uploadedAttachments.forEach((attachment) => { addAttachment(attachment); }); setSuccess(true); return uploadedAttachments; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Échec du téléchargement des fichiers"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Validate file before upload */ const validateFile = ( file: File, maxSize: number = 10 * 1024 * 1024 ): { valid: boolean; error?: string } => { return DocumentAttachmentService.validateFile(file, maxSize); }; /** * Format file size for display */ const formatFileSize = (bytes: number | null): string => { return DocumentAttachmentService.formatFileSize(bytes); }; /** * Get file icon based on MIME type */ const getFileIcon = (mimeType: string | null): string => { return DocumentAttachmentService.getFileIcon(mimeType); }; /** * Reset the state */ const resetState = () => { attachments.value = []; loading.value = false; error.value = null; success.value = false; }; return { // State attachments, loading, error, success, // Getters allAttachments, isLoading, hasError, getError, isSuccess, getAttachmentsByType, getAttachmentsById, getInterventionAttachments, getClientAttachments, getDeceasedAttachments, // Actions setLoading, setError, clearError, setSuccess, clearSuccess, setAttachments, addAttachment, updateAttachment, removeAttachment, removeAttachments, attachFile, detachFile, updateAttachmentMetadata, fetchAttachedFiles, fetchInterventionFiles, fetchClientFiles, fetchDeceasedFiles, detachMultipleFiles, reorderAttachments, uploadAndAttachFiles, validateFile, formatFileSize, getFileIcon, resetState, }; } ); export default useDocumentAttachmentStore;