Files
ficheagent/resources/js/Components/App/AttachmentSection.vue

93 lines
3.9 KiB
Vue

<script setup>
import { useForm } from '@inertiajs/vue3';
import { ref } from 'vue';
const props = defineProps({
attachments: {
type: Array,
default: () => [],
},
taskId: {
type: Number,
required: true,
},
canManage: Boolean,
});
const fileInput = ref(null);
const form = useForm({
file: null,
});
const uploadFile = () => {
if (fileInput.value.files[0]) {
form.file = fileInput.value.files[0];
form.post(route('attachments.store', props.taskId), {
preserveScroll: true,
onSuccess: () => {
form.reset();
fileInput.value.value = '';
},
});
}
};
const deleteAttachment = (id) => {
if (confirm('Supprimer ce fichier ?')) {
router.delete(route('attachments.destroy', id), {
preserveScroll: true,
});
}
};
const formatSize = (bytes) => {
if (!bytes) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
</script>
<template>
<div class="mt-4 border-t border-gray-100 dark:border-gray-700 pt-4">
<h4 class="text-xs font-bold uppercase text-gray-400 mb-2">Pièces jointes ({{ attachments.length }})</h4>
<div class="space-y-2">
<div v-for="file in attachments" :key="file.id" class="flex items-center justify-between p-2 bg-gray-50 dark:bg-gray-900/30 rounded border border-gray-100 dark:border-gray-700">
<div class="flex items-center min-w-0">
<svg class="w-4 h-4 text-gray-400 mr-2 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path></svg>
<span class="text-sm text-gray-700 dark:text-gray-300 truncate" :title="file.original_name">
{{ file.original_name }}
</span>
<span class="ml-2 text-[10px] text-gray-400">({{ formatSize(file.size) }})</span>
</div>
<div class="flex items-center space-x-3 ml-4">
<a :href="route('attachments.download', file.id)" class="text-blue-500 hover:text-blue-700 text-xs font-bold">
Télécharger
</a>
<button v-if="canManage" @click="deleteAttachment(file.id)" class="text-red-400 hover:text-red-600">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
</button>
</div>
</div>
<div v-if="attachments.length === 0" class="text-xs text-gray-500 italic">Aucun fichier joint.</div>
<div v-if="canManage" class="mt-4">
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">Ajouter un fichier</label>
<div class="flex items-center space-x-2">
<input
type="file"
ref="fileInput"
@change="uploadFile"
class="block w-full text-xs text-gray-500 file:mr-4 file:py-1 file:px-2 file:rounded-md file:border-0 file:text-xs file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 dark:file:bg-gray-700 dark:file:text-gray-300"
>
<div v-if="form.processing" class="text-[10px] text-blue-500 animate-pulse">Upload...</div>
</div>
</div>
</div>
</div>
</template>