forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<script setup lang="ts">
|
||||
import FileDropzone from '@/components/FileDropzone.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverDescription,
|
||||
PopoverHeader,
|
||||
PopoverTitle,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover'
|
||||
|
||||
const { user } = useAuth()
|
||||
const open = ref(false)
|
||||
const file = ref<File | null>(null)
|
||||
const url = ref('')
|
||||
const errorMessage = ref('')
|
||||
const loading = ref(false)
|
||||
|
||||
async function onSubmit() {
|
||||
if (loading.value || (!file.value && !url.value.trim())) return
|
||||
loading.value = true
|
||||
errorMessage.value = ''
|
||||
try {
|
||||
if (url.value.trim()) {
|
||||
await $fetch('/api/uploads', {
|
||||
method: 'POST',
|
||||
body: { url: url.value.trim() },
|
||||
})
|
||||
}
|
||||
else {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file.value!)
|
||||
await $fetch('/api/uploads', { method: 'POST', body: formData })
|
||||
}
|
||||
file.value = null
|
||||
url.value = ''
|
||||
open.value = false
|
||||
await refreshNuxtData('uploads')
|
||||
await navigateTo('/')
|
||||
}
|
||||
catch (err) {
|
||||
const e = err as { data?: { statusMessage?: string, message?: string } }
|
||||
errorMessage.value = e.data?.statusMessage ?? e.data?.message ?? 'Upload fehlgeschlagen'
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover v-model:open="open">
|
||||
<PopoverTrigger as-child>
|
||||
<Button variant="ghost">
|
||||
<Icon name="ph:cloud-arrow-up-fill" class="size-4" />
|
||||
Hochladen
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start" class="w-160">
|
||||
<template v-if="user">
|
||||
<PopoverHeader>
|
||||
<PopoverTitle>Hochladen</PopoverTitle>
|
||||
<PopoverDescription>Datei oder URL — Bilder, Videos, Audio (MP3/FLAC), YouTube- und Twitch-Links.</PopoverDescription>
|
||||
</PopoverHeader>
|
||||
<form class="space-y-4" @submit.prevent="onSubmit">
|
||||
<div class="space-y-1.5">
|
||||
<Label>Datei</Label>
|
||||
<FileDropzone v-model="file" :disabled="!!url.trim()" />
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<Label for="upload-url">oder URL</Label>
|
||||
<Input id="upload-url" v-model="url" type="url" placeholder="https://…" :disabled="!!file" />
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Direkte Bild-/Video-URLs werden gespeichert, YouTube- und Twitch-Links eingebettet.
|
||||
</p>
|
||||
</div>
|
||||
<p v-if="errorMessage" class="text-sm text-destructive">
|
||||
{{ errorMessage }}
|
||||
</p>
|
||||
<Button type="submit" class="w-full" :disabled="loading || (!file && !url.trim())">
|
||||
{{ loading ? 'Lädt hoch…' : 'Hochladen' }}
|
||||
</Button>
|
||||
</form>
|
||||
</template>
|
||||
<p v-else class="text-sm text-muted-foreground">
|
||||
<NuxtLink to="/login" class="text-primary underline" @click="open = false">
|
||||
Melde dich an
|
||||
</NuxtLink>, um Dateien hochzuladen.
|
||||
</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</template>
|
||||
Reference in New Issue
Block a user