import { ref } from 'vue' import { useApi } from './useApi' import { useToast } from './useToast' import { normalizeRelationIds } from '~/shared/apiRelations' import { extractCollection } from '~/shared/utils/apiHelpers' export interface Document { id: string name: string filename: string mimeType: string size: number path: string siteId?: string machineId?: string composantId?: string productId?: string pieceId?: string } export interface UploadContext { siteId?: string machineId?: string composantId?: string productId?: string pieceId?: string } export interface DocumentResult { success: boolean data?: Document | Document[] error?: string } const documents = ref([]) const loading = ref(false) const fileToBase64 = (file: File): Promise => new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = () => resolve(reader.result as string) reader.onerror = () => reject(new Error(`Lecture du fichier ${file.name} impossible`)) reader.readAsDataURL(file) }) export function useDocuments() { const { get, post, delete: del } = useApi() const { showError, showSuccess } = useToast() const loadFromEndpoint = async ( endpoint: string, { updateStore = false }: { updateStore?: boolean } = {}, ): Promise => { loading.value = true try { const result = await get(endpoint) if (result.success) { const data = extractCollection(result.data) if (updateStore) { documents.value = data } return { success: true, data } } if (result.error) { showError(result.error) } return result as DocumentResult } catch (error) { const err = error as Error console.error(`Erreur lors du chargement des documents (${endpoint}):`, error) showError('Impossible de charger les documents') return { success: false, error: err.message } } finally { loading.value = false } } const loadDocuments = async ( options: { updateStore?: boolean } = {}, ): Promise => { return loadFromEndpoint('/documents', { updateStore: options.updateStore ?? true }) } const loadDocumentsBySite = async ( siteId: string, options: { updateStore?: boolean } = {}, ): Promise => { if (!siteId) { return { success: false, error: 'Aucun site sélectionné' } } return loadFromEndpoint(`/documents/site/${siteId}`, { updateStore: options.updateStore ?? false }) } const loadDocumentsByMachine = async ( machineId: string, options: { updateStore?: boolean } = {}, ): Promise => { if (!machineId) { return { success: false, error: 'Aucune machine sélectionnée' } } return loadFromEndpoint(`/documents/machine/${machineId}`, { updateStore: options.updateStore ?? false }) } const loadDocumentsByComponent = async ( componentId: string, options: { updateStore?: boolean } = {}, ): Promise => { if (!componentId) { return { success: false, error: 'Aucun composant sélectionné' } } return loadFromEndpoint(`/documents/composant/${componentId}`, { updateStore: options.updateStore ?? false }) } const loadDocumentsByProduct = async ( productId: string, options: { updateStore?: boolean } = {}, ): Promise => { if (!productId) { return { success: false, error: 'Aucun produit sélectionné' } } return loadFromEndpoint(`/documents/product/${productId}`, { updateStore: options.updateStore ?? false }) } const loadDocumentsByPiece = async ( pieceId: string, options: { updateStore?: boolean } = {}, ): Promise => { if (!pieceId) { return { success: false, error: 'Aucune pièce sélectionnée' } } return loadFromEndpoint(`/documents/piece/${pieceId}`, { updateStore: options.updateStore ?? false }) } const uploadDocuments = async ( { files, context = {} }: { files: File[]; context?: UploadContext }, { updateStore = false }: { updateStore?: boolean } = {}, ): Promise => { if (!files.length) { return { success: false, error: 'Aucun fichier sélectionné' } } loading.value = true const created: Document[] = [] try { for (const file of files) { const dataUrl = await fileToBase64(file) const payload = normalizeRelationIds({ name: file.name, filename: file.name, mimeType: file.type || 'application/octet-stream', size: file.size, path: dataUrl, ...context, }) const result = await post('/documents', payload) if (result.success) { created.push(result.data as Document) showSuccess(`Document "${file.name}" ajouté`) } else if (result.error) { showError(`Erreur sur ${file.name} : ${result.error}`) } } if (created.length) { if (updateStore) { documents.value = [...created, ...documents.value] } return { success: true, data: created } } return { success: false, error: 'Aucun document ajouté' } } catch (error) { const err = error as Error console.error("Erreur lors de l'upload des documents:", error) showError("Échec de l'ajout des documents") return { success: false, error: err.message } } finally { loading.value = false } } const deleteDocument = async ( id: string | number, { updateStore = false }: { updateStore?: boolean } = {}, ): Promise => { if (!id) { return { success: false, error: 'Identifiant manquant' } } loading.value = true try { const result = await del(`/documents/${id}`) if (result.success) { if (updateStore) { documents.value = documents.value.filter((doc) => doc.id !== id) } showSuccess('Document supprimé') } return result as DocumentResult } catch (error) { const err = error as Error console.error('Erreur lors de la suppression du document:', error) showError('Impossible de supprimer le document') return { success: false, error: err.message } } finally { loading.value = false } } return { documents, loading, loadDocuments, loadDocumentsBySite, loadDocumentsByMachine, loadDocumentsByComponent, loadDocumentsByPiece, loadDocumentsByProduct, uploadDocuments, deleteDocument, } }