diff --git a/app/components/DocumentUpload.vue b/app/components/DocumentUpload.vue new file mode 100644 index 0000000..e459002 --- /dev/null +++ b/app/components/DocumentUpload.vue @@ -0,0 +1,151 @@ + + + diff --git a/app/composables/useDocuments.js b/app/composables/useDocuments.js new file mode 100644 index 0000000..8cbe590 --- /dev/null +++ b/app/composables/useDocuments.js @@ -0,0 +1,126 @@ +import { ref } from 'vue' +import { useApi } from './useApi' +import { useToast } from './useToast' + +const documents = ref([]) +const loading = ref(false) + +const fileToBase64 = (file) => + new Promise((resolve, reject) => { + const reader = new FileReader() + reader.onload = () => resolve(reader.result) + 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 loadDocuments = async () => { + loading.value = true + try { + const result = await get('/documents') + if (result.success) { + documents.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors du chargement des documents:', error) + showError("Impossible de charger les documents") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const loadDocumentsBySite = async (siteId) => { + if (!siteId) return { success: false, error: 'Aucun site sélectionné' } + loading.value = true + try { + const result = await get(`/documents/site/${siteId}`) + if (result.success) { + documents.value = result.data + } + return result + } catch (error) { + console.error('Erreur lors du chargement des documents du site:', error) + showError("Impossible de charger les documents du site") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const uploadDocuments = async ({ files = [], context = {} }) => { + if (!files.length) return { success: false, error: 'Aucun fichier sélectionné' } + + loading.value = true + const created = [] + + try { + for (const file of files) { + const dataUrl = await fileToBase64(file) + + const payload = { + 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) + showSuccess(`Document "${file.name}" ajouté`) + } else if (result.error) { + showError(`Erreur sur ${file.name} : ${result.error}`) + } + } + + if (created.length) { + documents.value = [...created, ...documents.value] + return { success: true, data: created } + } + + return { success: false, error: 'Aucun document ajouté' } + } catch (error) { + console.error('Erreur lors de l\'upload des documents:', error) + showError("Échec de l'ajout des documents") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + const deleteDocument = async (id) => { + if (!id) return { success: false, error: 'Identifiant manquant' } + + loading.value = true + try { + const result = await del(`/documents/${id}`) + if (result.success) { + documents.value = documents.value.filter(doc => doc.id !== id) + showSuccess('Document supprimé') + } + return result + } catch (error) { + console.error('Erreur lors de la suppression du document:', error) + showError("Impossible de supprimer le document") + return { success: false, error: error.message } + } finally { + loading.value = false + } + } + + return { + documents, + loading, + loadDocuments, + loadDocumentsBySite, + uploadDocuments, + deleteDocument, + } +} diff --git a/app/pages/documents.vue b/app/pages/documents.vue new file mode 100644 index 0000000..0c0cca3 --- /dev/null +++ b/app/pages/documents.vue @@ -0,0 +1,180 @@ + + + diff --git a/app/pages/sites.vue b/app/pages/sites.vue index b12bda8..522a4cd 100644 --- a/app/pages/sites.vue +++ b/app/pages/sites.vue @@ -291,11 +291,60 @@ +
+
+
+

Documents liés

+

Ajoutez des documents (PDF, images...) relatifs à ce site.

+
+ + {{ selectedFiles.length }} fichier{{ selectedFiles.length > 1 ? 's' : '' }} prêt{{ selectedFiles.length > 1 ? 's' : '' }} à être ajouté + +
+ + + +
+
Documents existants
+
+
+
+
{{ document.name }}
+
+ {{ document.mimeType || 'Inconnu' }} • {{ formatSize(document.size) }} +
+
+
+ + +
+
+
+
+
+ @@ -306,11 +355,14 @@