Display CMS Optimierungen 29-05-2026

- Mediathek: Video-Vorschaubilder statt Icons (FFmpeg-Thumbnails + Backfill-Command), Kategorie "Sonstiges"
- B2in Media-Picker zeigt alle Medientypen, Typ wird automatisch erkannt; Thumbnail-Preview vor allen Medien-URL-Feldern
- B2in Marke/Footer: Footer ein/aus, Logo+Claim frei positionierbar (Ecken) mit Constraints, separate Anzeige-Schalter
- Angebote-Modul dynamisch: kein Slide-Typ mehr, einheitliches Detail-Layout mit ein-/ausblendbaren Bloecken, Logo/Brand pro Slide, Streichpreis-Option
- Player: leere Module stoppen Endlosschleife, dynamische Layout-Anpassung bei verstecktem Footer/Header
- Fix: Script-Ladereihenfolge (Livewire vor Flux), entfernte stale public/flux/flux.js, Modal-Crash beim Aktualisieren behoben

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin Adametz 2026-05-29 15:57:33 +00:00
parent 9262132325
commit 6c6d683b9a
42 changed files with 2267 additions and 13905 deletions

View file

@ -6,18 +6,18 @@
<flux:card>
<div class="flex items-center justify-between mb-6">
<div>
<flux:heading size="lg">{{ __('Slides') }}</flux:heading>
<flux:subheading>{{ __('Angebots-Slides werden in der angegebenen Reihenfolge angezeigt') }}</flux:subheading>
<flux:heading size="lg">{{ __('Angebote') }}</flux:heading>
<flux:subheading>{{ __('Angebote werden im einheitlichen Detail-Layout in der angegebenen Reihenfolge angezeigt') }}</flux:subheading>
</div>
<flux:button wire:click="openItemModal(null, 'slide')" icon="plus">
{{ __('Slide hinzufügen') }}
{{ __('Angebot hinzufügen') }}
</flux:button>
</div>
@if($slides->isEmpty())
<div class="text-center py-12 text-zinc-500 dark:text-zinc-400">
<flux:icon.presentation-chart-bar class="w-16 h-16 mx-auto mb-4 opacity-50" />
<p>{{ __('Noch keine Slides vorhanden.') }}</p>
<p>{{ __('Noch keine Angebote vorhanden.') }}</p>
</div>
@else
<div class="space-y-3">
@ -42,29 +42,30 @@
</div>
<div class="flex-1 min-w-0">
@php
$c = $item->content;
$enabledBlocks = collect([
'Badge' => ($c['show_badge'] ?? ! empty($c['badge_text'])) && ! empty($c['badge_text']),
'Aufzählung' => ($c['show_bullets'] ?? ! empty($c['bullets'])) && ! empty($c['bullets']),
'Preis' => ($c['show_price'] ?? ! empty($c['price'])) && ! empty($c['price']),
'QR' => ($c['show_qr'] ?? ! empty($c['qr_url'])) && ! empty($c['qr_url']),
'Kontakt' => ($c['show_contact'] ?? ! empty($c['contact'])) && ! empty($c['contact']),
])->filter()->keys();
@endphp
<div class="flex items-center gap-3 mb-1">
<flux:badge :color="$item->is_active ? 'green' : 'zinc'" size="sm">
{{ $item->is_active ? __('Aktiv') : __('Inaktiv') }}
</flux:badge>
<flux:badge color="amber" size="sm">
{{ match($item->content['type'] ?? '') {
'intro' => 'Intro',
'product-hero' => 'Produkt-Hero',
'product-details' => 'Produkt-Details',
'product-impulse' => 'Produkt-Impuls',
default => $item->content['type'] ?? '',
} }}
</flux:badge>
<span class="font-semibold text-sm">{{ $item->content['title'] ?? '' }}</span>
<span class="font-semibold text-sm truncate">{{ $c['title'] ?? '' }}</span>
</div>
<div class="text-xs text-zinc-600 dark:text-zinc-400 space-x-4">
@if(!empty($item->content['price']))
<span class="font-medium">{{ $item->content['price'] }}</span>
@endif
<span>{{ number_format(($item->content['duration'] ?? 8000) / 1000, 1) }}s</span>
@if(!empty($item->content['badge_text']))
<span>{{ $item->content['badge_text'] }}</span>
<div class="flex flex-wrap items-center gap-2 text-xs text-zinc-600 dark:text-zinc-400">
<span>{{ number_format(($c['duration'] ?? 8000) / 1000, 1) }}s</span>
@if(!empty($c['price']) && ($c['show_price'] ?? ! empty($c['price'])))
<span class="font-medium">{{ $c['price'] }}</span>
@endif
@foreach($enabledBlocks as $block)
<flux:badge color="zinc" size="sm">{{ $block }}</flux:badge>
@endforeach
</div>
</div>