Initial Commit

This commit is contained in:
2026-10-03 20:07:49 +02:00
commit a1346c98b1
427 changed files with 59320 additions and 0 deletions
+95
View File
@@ -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>