adds features
Build and Push Docker Image / build (push) Successful in 1m28s

This commit is contained in:
2026-08-27 07:38:35 +02:00
parent 891026ccbb
commit adaae41e44
33 changed files with 2771 additions and 396 deletions
+108
View File
@@ -0,0 +1,108 @@
<script lang="ts">
import FileDropzone from '$lib/components/FileDropzone.svelte';
import Button from '$lib/components/ui/button.svelte';
import { downloadBlob } from '$lib/download';
import { mergePdfFiles } from '$lib/pdf-processing';
import { Trash2 } from '@lucide/svelte';
let pdfFiles: File[] = $state([]);
let isProcessing = $state(false);
let error = $state<string | null>(null);
const handleFilesSelected = (files: File[]) => {
pdfFiles = [...pdfFiles, ...files];
error = null;
};
const removeFile = (index: number) => {
pdfFiles = pdfFiles.filter((_, i) => i !== index);
};
const moveFile = (fromIndex: number, toIndex: number) => {
if (toIndex < 0 || toIndex >= pdfFiles.length) return;
const newFiles = [...pdfFiles];
const [moved] = newFiles.splice(fromIndex, 1);
newFiles.splice(toIndex, 0, moved);
pdfFiles = newFiles;
};
const mergePdfs = async () => {
if (pdfFiles.length < 2) return;
isProcessing = true;
error = null;
try {
downloadBlob(await mergePdfFiles(pdfFiles), 'zusammengefuegt.pdf');
} catch (err) {
console.error('Merge failed:', err);
error = 'Fehler beim Zusammenfügen der PDFs.';
} finally {
isProcessing = false;
}
};
</script>
<div class="mx-auto max-w-4xl space-y-6">
<div>
<h1 class="text-2xl font-bold text-primary-900">PDFs zusammenfügen</h1>
<p class="mt-2 text-sm text-primary-700">
Fügen Sie mehrere PDF-Dateien zu einem einzigen Dokument zusammen.
</p>
</div>
<FileDropzone onFilesSelected={handleFilesSelected} multiple={true} />
{#if pdfFiles.length > 0}
<div class="space-y-4">
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold text-primary-900">
{pdfFiles.length} Datei{pdfFiles.length === 1 ? '' : 'en'} ausgewählt
</h2>
<Button onclick={mergePdfs} disabled={isProcessing || pdfFiles.length < 2}>
{isProcessing ? 'Wird zusammengefügt...' : 'PDFs zusammenfügen'}
</Button>
</div>
{#if error}
<div class="rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-800">
{error}
</div>
{/if}
<div class="space-y-2">
{#each pdfFiles as file, index}
<div class="flex items-center gap-3 rounded-lg border border-primary-200 bg-white p-3">
<span
class="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10 text-sm font-semibold text-primary"
>
{index + 1}
</span>
<span class="flex-1 truncate text-sm text-primary-900">{file.name}</span>
<div class="flex gap-1">
<Button
variant="tertiary"
class="min-w-0 px-3"
onclick={() => moveFile(index, index - 1)}
disabled={index === 0}
>
</Button>
<Button
variant="tertiary"
class="min-w-0 px-3"
onclick={() => moveFile(index, index + 1)}
disabled={index === pdfFiles.length - 1}
>
</Button>
<Button variant="tertiary" class="min-w-0 px-3" onclick={() => removeFile(index)}>
<Trash2 class="h-4 w-4" />
</Button>
</div>
</div>
{/each}
</div>
</div>
{/if}
</div>