initiation librodrome

This commit is contained in:
Yvv
2026-02-20 12:55:10 +01:00
commit 35e2897a73
208 changed files with 18951 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
<template>
<div
class="upload-zone"
:class="{ 'upload-zone--active': isDragging }"
@dragenter.prevent="isDragging = true"
@dragleave.prevent="isDragging = false"
@dragover.prevent
@drop.prevent="handleDrop"
>
<input
ref="fileInput"
type="file"
multiple
accept="image/*,audio/*,.pdf"
class="hidden"
@change="handleFiles"
/>
<div v-if="uploading" class="upload-progress">
<div class="i-lucide-loader-2 h-6 w-6 animate-spin text-primary" />
<span>Upload en cours...</span>
</div>
<div v-else class="upload-content" @click="fileInput?.click()">
<div class="i-lucide-upload h-8 w-8 text-white/30 mb-2" />
<p class="text-sm text-white/50">Glissez des fichiers ici ou cliquez pour sélectionner</p>
<p class="text-xs text-white/30 mt-1">Images, audio, PDF</p>
</div>
</div>
</template>
<script setup lang="ts">
const emit = defineEmits<{
uploaded: [files: string[]]
}>()
const fileInput = ref<HTMLInputElement>()
const isDragging = ref(false)
const uploading = ref(false)
function handleDrop(e: DragEvent) {
isDragging.value = false
const files = e.dataTransfer?.files
if (files) upload(files)
}
function handleFiles(e: Event) {
const target = e.target as HTMLInputElement
if (target.files) upload(target.files)
}
async function upload(files: FileList) {
uploading.value = true
try {
const formData = new FormData()
for (const file of files) {
formData.append('file', file)
}
const result = await $fetch<{ files: string[] }>('/api/admin/media/upload', {
method: 'POST',
body: formData,
})
emit('uploaded', result.files)
}
finally {
uploading.value = false
if (fileInput.value) fileInput.value.value = ''
}
}
</script>
<style scoped>
.upload-zone {
border: 2px dashed hsl(20 8% 22%);
border-radius: 0.75rem;
padding: 2rem;
text-align: center;
cursor: pointer;
transition: all 0.2s;
}
.upload-zone:hover {
border-color: hsl(12 76% 48% / 0.4);
}
.upload-zone--active {
border-color: hsl(12 76% 48%);
background: hsl(12 76% 48% / 0.05);
}
.upload-progress {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
color: hsl(20 8% 55%);
font-size: 0.85rem;
}
.upload-content {
display: flex;
flex-direction: column;
align-items: center;
}
</style>