Files
Inventory/app/components/machine/MachineDocumentsCard.vue
Matthieu daaa1c4cb9 refactor(machine): decompose detail page into composables + 7 components (F1.1)
Extract 2 composables (useMachineDetailData, useMachineSkeletonEditor) and
7 UI components from machine/[id].vue, reducing it from 2989 to 219 LOC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:19:22 +01:00

117 lines
3.9 KiB
Vue

<template>
<div class="card bg-base-100 shadow-lg mt-6">
<div class="card-body space-y-4">
<div class="flex items-center justify-between">
<div>
<h2 class="card-title">Documents de la machine</h2>
<p class="text-xs text-gray-500">Ajoutez ou consultez les documents liés à cette machine.</p>
</div>
<span v-if="isEditMode && files.length" class="badge badge-outline">
{{ files.length }} fichier{{ files.length > 1 ? 's' : '' }} sélectionné{{ files.length > 1 ? 's' : '' }}
</span>
</div>
<DocumentUpload
v-if="isEditMode"
:model-value="files"
@update:model-value="$emit('update:files', $event)"
title="Déposer des fichiers pour la machine"
subtitle="Formats acceptés : PDF, images, documents..."
@files-added="$emit('files-added', $event)"
/>
<div v-if="documents.length" class="space-y-2">
<div
v-for="doc in documents"
:key="doc.id"
class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2"
>
<div class="flex items-center gap-3 text-sm">
<div
class="flex-shrink-0 overflow-hidden rounded-md border border-base-200 bg-base-200/70 flex items-center justify-center"
:class="documentThumbnailClass(doc)"
>
<img
v-if="isImageDocument(doc) && doc.path"
:src="doc.path"
class="h-full w-full object-cover"
:alt="`Aperçu de ${doc.name}`"
>
<iframe
v-else-if="shouldInlinePdf(doc)"
:src="documentPreviewSrc(doc)"
class="h-full w-full border-0 bg-white"
title="Aperçu PDF"
/>
<component
v-else
:is="documentIcon(doc).component"
class="h-6 w-6"
:class="documentIcon(doc).colorClass"
aria-hidden="true"
/>
</div>
<div>
<div class="font-medium">{{ doc.name }}</div>
<div class="text-xs text-gray-500">
{{ doc.mimeType || 'Inconnu' }} &bull; {{ formatSize(doc.size) }}
</div>
</div>
</div>
<div class="flex items-center gap-2">
<button
type="button"
class="btn btn-ghost btn-xs"
:disabled="!canPreviewDocument(doc)"
:title="canPreviewDocument(doc) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
@click="$emit('preview', doc)"
>
Consulter
</button>
<button type="button" class="btn btn-ghost btn-xs" @click="$emit('download', doc)">
Télécharger
</button>
<button
v-if="isEditMode"
type="button"
class="btn btn-error btn-xs"
:disabled="uploading"
@click="$emit('remove', doc.id)"
>
Supprimer
</button>
</div>
</div>
</div>
<p v-else class="text-xs text-gray-500">Aucun document lié à cette machine.</p>
</div>
</div>
</template>
<script setup lang="ts">
import DocumentUpload from '~/components/DocumentUpload.vue'
import { canPreviewDocument, isImageDocument } from '~/utils/documentPreview'
import {
formatSize,
shouldInlinePdf,
documentPreviewSrc,
documentThumbnailClass,
documentIcon,
} from '~/shared/utils/documentDisplayUtils'
defineProps<{
documents: any[]
isEditMode: boolean
uploading: boolean
files: File[]
}>()
defineEmits<{
'update:files': [files: File[]]
'files-added': [files: File[]]
'preview': [doc: any]
'download': [doc: any]
'remove': [documentId: string]
}>()
</script>