Files
WebAPP/resources/views/components/file-preview-modal.blade.php
Rhino 2e24a40d68 Stand: SMTP-Test, Admin-Mail-Tab, Notifiable-Fix, Lazy-Quill
- Fix: Notifiable-Trait zum User-Model hinzugefuegt (behebt notify()-500er)
- Installer: SMTP-Verbindungstest mit EsmtpTransport + Ueberspringen-Link
- Admin: Neuer E-Mail-Tab mit SMTP-Konfiguration + Verbindungstest
- Admin: Lazy Quill-Initialisierung (nur sichtbare Locale wird geladen)
- Uebersetzungen: 17 neue Mail-Keys in allen 6 Sprachen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 07:30:37 +01:00

110 lines
5.6 KiB
PHP

{{-- File Preview Modal (Alpine.js) --}}
<div x-data="filePreviewModal()" x-cloak @open-file-preview.window="openFile($event.detail)" @keydown.escape.window="close()">
{{-- Backdrop --}}
<div x-show="open"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
@click="close()"
class="fixed inset-0 bg-black/60 z-40"></div>
{{-- Modal --}}
<div x-show="open"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="fixed inset-0 flex items-center justify-center z-50 p-4 sm:p-6">
<div @click.away="close()"
class="bg-white rounded-xl shadow-2xl flex flex-col overflow-hidden"
:class="(file.isPdf || file.isHtml) ? 'w-full max-w-3xl max-h-[92vh]' : 'w-full max-w-lg max-h-[90vh]'">
{{-- Header --}}
<div class="flex items-center justify-between px-5 py-3 border-b min-w-0">
<h3 class="font-semibold text-gray-900 truncate pr-4" x-text="file.name"></h3>
<button @click="close()" class="flex-shrink-0 text-gray-400 hover:text-gray-600">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
</div>
{{-- Content --}}
<div class="flex-1 overflow-y-auto p-5" :class="(file.isPdf || file.isHtml) ? 'p-0' : 'p-5'">
{{-- Image Preview --}}
<template x-if="file.isImage && file.previewUrl">
<div class="flex justify-center mb-4 bg-gray-50 rounded-lg p-2 mx-5 mt-5">
<img :src="file.previewUrl" :alt="file.name" class="max-w-full max-h-80 rounded object-contain" loading="lazy">
</div>
</template>
{{-- PDF Preview --}}
<template x-if="file.isPdf && file.previewUrl">
<iframe :src="file.previewUrl" class="w-full border-0" style="height: 70vh;"></iframe>
</template>
{{-- HTML Preview --}}
<template x-if="file.isHtml && file.previewUrl">
<iframe :src="file.previewUrl" class="w-full border-0" style="height: 70vh;"></iframe>
</template>
{{-- Non-Image/Non-PDF/Non-HTML: Large Icon --}}
<template x-if="!file.isImage && !file.isPdf && !file.isHtml">
<div class="flex justify-center mb-4 mx-5 mt-5">
<div class="w-20 h-20 rounded-xl flex items-center justify-center" :class="file.iconBg">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8l-6-6zm-1 2l5 5h-5V4z"/></svg>
</div>
</div>
</template>
{{-- File Info (nicht bei PDF/HTML, da dort der iframe den Platz braucht) --}}
<template x-if="!file.isPdf && !file.isHtml">
<div class="space-y-2 text-center px-5 pb-2">
<div>
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-700" x-text="file.category"></span>
</div>
<p class="text-sm text-gray-500" x-text="file.size"></p>
</div>
</template>
</div>
{{-- Footer --}}
<div class="px-5 py-3 border-t bg-gray-50 flex justify-between items-center">
<div class="flex items-center gap-3">
<button @click="close()" class="text-sm text-gray-500 hover:text-gray-700">{{ __('ui.close') }}</button>
<template x-if="file.isPdf || file.isHtml">
<span class="text-xs text-gray-400">
<span x-text="file.category"></span> &middot; <span x-text="file.size"></span>
</span>
</template>
</div>
<a :href="file.downloadUrl" class="inline-flex items-center gap-1.5 bg-blue-600 text-white px-4 py-2 rounded-md text-sm hover:bg-blue-700">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
{{ __('ui.download') }}
</a>
</div>
</div>
</div>
</div>
<script>
function filePreviewModal() {
return {
open: false,
file: { name: '', category: '', size: '', downloadUrl: '', previewUrl: null, isImage: false, isPdf: false, isHtml: false, iconBg: '' },
openFile(detail) {
this.file = detail;
this.open = true;
document.body.style.overflow = 'hidden';
},
close() {
this.open = false;
document.body.style.overflow = '';
}
}
}
</script>