93 lines
3.9 KiB
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>
|