Added Frontend

This commit is contained in:
2026-01-06 12:09:31 +01:00
250 changed files with 29602 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
<script setup>
const props = defineProps({
item: { type: Object, required: true },
type: { type: String, required: true },
topLevelType: { type: String, required: true },
platform: { type: String, required: true }
})
const emit = defineEmits(["updateNeeded"])
const files = useFiles()
const availableFiles = ref([])
const activeFile = ref(null)
const showViewer = ref(false)
const setup = async () => {
if (props.item.files?.length > 0) {
availableFiles.value =
(await files.selectSomeDocuments(props.item.files.map((f) => f.id))) || []
}
}
setup()
// Datei öffnen (Mobile/Tablet)
function openFile(file) {
activeFile.value = file
showViewer.value = true
}
function closeViewer() {
showViewer.value = false
activeFile.value = null
}
// PDF oder Bild?
function isPdf(file) {
return file.path.includes("pdf")
}
function isImage(file) {
return file.mimetype?.startsWith("image/")
}
</script>
<template>
<UCard class="mt-5" :style="props.platform !== 'mobile' ? 'height: 80vh' : ''">
<template #header>
<span>Dateien</span>
</template>
<!-- Upload -->
<Toolbar>
<DocumentUpload
:type="props.topLevelType.substring(0, props.topLevelType.length - 1)"
:element-id="props.item.id"
@uploadFinished="emit('updateNeeded')"
/>
</Toolbar>
<!-- 📱 MOBILE: File Cards -->
<div v-if="props.platform === 'mobile'" class="space-y-3 mt-3">
<div
v-for="file in availableFiles"
:key="file.id"
class="p-4 border rounded-xl bg-gray-50 dark:bg-gray-900 flex items-center justify-between active:scale-95 transition cursor-pointer"
@click="openFile(file)"
>
<div>
<p class="font-semibold truncate max-w-[200px]">{{ file?.path?.split("/").pop() }}</p>
</div>
<UIcon
name="i-heroicons-chevron-right-20-solid"
class="w-5 h-5 text-gray-400"
/>
</div>
<UAlert
v-if="!availableFiles.length"
icon="i-heroicons-x-mark"
title="Keine Dateien verfügbar"
/>
</div>
<!-- 🖥 DESKTOP: Classic List -->
<template v-else>
<DocumentList
:key="props.item.files.length"
:documents="availableFiles"
v-if="availableFiles.length > 0"
/>
<UAlert v-else icon="i-heroicons-x-mark" title="Keine Dateien verfügbar" />
</template>
</UCard>
<!-- 📱 PDF / IMG Viewer Slideover -->
<UModal v-model="showViewer" side="bottom" class="h-[100dvh]" fullscreen>
<!-- Header -->
<div class="p-4 border-b flex justify-between items-center flex-shrink-0">
<h3 class="font-bold truncate max-w-[70vw]">{{ activeFile?.path?.split("/").pop() }}</h3>
<UButton icon="i-heroicons-x-mark" variant="ghost" @click="closeViewer" />
</div>
<!-- Content -->
<div class="flex-1 overflow-y-auto m-2">
<!-- PDF -->
<div v-if="activeFile && isPdf(activeFile)" class="h-full">
<PDFViewer
:no-controls="true"
:file-id="activeFile.id"
location="fileviewer-mobile"
class="h-full"
/>
</div>
<!-- IMAGE -->
<div
v-else-if="activeFile && isImage(activeFile)"
class="p-4 flex justify-center"
>
<img
:src="activeFile.url"
class="max-w-full max-h-[80vh] rounded-lg shadow"
/>
</div>
<UAlert
v-else
title="Nicht unterstützter Dateityp"
icon="i-heroicons-exclamation-triangle"
/>
</div>
</UModal>
</template>