b2in/resources/views/components/layouts/app/sidebar.blade.php
Kevin Adametz 6c6d683b9a 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>
2026-05-29 15:57:33 +00:00

388 lines
22 KiB
PHP

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
<head>
@include('partials.head')
</head>
<body class="min-h-screen bg-zinc-50 dark:bg-zinc-800 antialiased">
<flux:sidebar sticky stashable class="border-e border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
<flux:sidebar.toggle class="lg:hidden" icon="x-mark" />
<a href="{{ config('domains.domain_main_url') }}" class="me-5 flex items-center space-x-2 rtl:space-x-reverse">
<x-app-logo />
</a>
@if (session('impersonate_from'))
<div
class="mb-4 rounded-lg bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 p-3">
<div class="flex items-start gap-3 mb-2">
<flux:icon.exclamation-triangle
class="h-5 w-5 text-orange-600 dark:text-orange-400 flex-shrink-0 mt-0.5" />
<div class="flex-1 min-w-0">
<div class="text-sm font-semibold text-orange-900 dark:text-orange-100">
{{ __('Als :name eingeloggt', ['name' => Auth::user()->name]) }}
</div>
<div class="text-xs text-orange-700 dark:text-orange-300 mt-0.5">
{{ __('Sie sind temporär als dieser User angemeldet') }}
</div>
</div>
</div>
<form method="POST" action="{{ route('admin.impersonate.leave') }}" class="w-full">
@csrf
<flux:button type="submit" variant="primary" size="sm" icon="arrow-left-start-on-rectangle"
class="w-full">
{{ __('Zurück zum Admin') }}
</flux:button>
</form>
</div>
@endif
<flux:navlist variant="outline">
@hasrole('Customer')
<flux:navlist.group :heading="__('Customer')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')"
wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Daten')" class="grid mb-4">
<flux:navlist.item icon="building-office" :href="route('partner.my-data')"
:current="request()->routeIs('partner.my-data')" wire:navigate>{{ __('Meine Daten') }}
</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Retailer')
<flux:navlist.group :heading="__('Retailer')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')"
wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Produkte')" class="grid mb-4">
<flux:navlist.item icon="cube" :href="route('products.index')"
:current="request()->routeIs('products.index')" wire:navigate>{{ __('Produktliste') }}
</flux:navlist.item>
<flux:navlist.item icon="plus-circle" :href="route('products.create.teaser')"
:current="request()->routeIs('products.create.teaser')" wire:navigate>
{{ __('Neues Teaser-Produkt') }}
</flux:navlist.item>
<flux:navlist.item icon="plus-circle" :href="route('products.create.standard')"
:current="request()->routeIs('products.create.standard')" wire:navigate>
{{ __('Neues Standard-Produkt') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Daten')" class="grid mb-4">
<flux:navlist.item icon="building-office" :href="route('partner.my-data')"
:current="request()->routeIs('partner.my-data')" wire:navigate>{{ __('Meine Daten') }}
</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Manufacturer')
<flux:navlist.group :heading="__('Manufacturer')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')"
:current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Produkte')" class="grid mb-4">
<flux:navlist.item icon="cube" :href="route('products.index')"
:current="request()->routeIs('products.index')" wire:navigate>{{ __('Produktliste') }}
</flux:navlist.item>
<flux:navlist.item icon="plus-circle" :href="route('products.create.teaser')"
:current="request()->routeIs('products.create.teaser')" wire:navigate>
{{ __('Neues Teaser-Produkt') }}
</flux:navlist.item>
<flux:navlist.item icon="plus-circle" :href="route('products.create.standard')"
:current="request()->routeIs('products.create.standard')" wire:navigate>
{{ __('Neues Standard-Produkt') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Daten')" class="grid mb-4">
<flux:navlist.item icon="building-office" :href="route('partner.my-data')"
:current="request()->routeIs('partner.my-data')" wire:navigate>{{ __('Meine Daten') }}
</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Broker')
<flux:navlist.group :heading="__('Broker')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')"
:current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Daten')" class="grid mb-4">
<flux:navlist.item icon="building-office" :href="route('partner.my-data')"
:current="request()->routeIs('partner.my-data')" wire:navigate>{{ __('Meine Daten') }}
</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Admin|Super-Admin')
<flux:navlist.group :heading="__('Info')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')"
:current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Super-Admin|Admin')
<flux:navlist.group :heading="__('Admin')" class="grid mb-4">
<flux:navlist.group expandable
:expanded="request()->routeIs(['admin.users', 'admin.users.permissions', 'admin.partners.invite', 'admin.partners.registration-codes'])"
heading="Partner" class="grid">
<flux:navlist.item icon="user-group" :href="route('admin.users')"
:current="request()->routeIs('admin.users')" wire:navigate>{{ __('Benutzer') }}
</flux:navlist.item>
<flux:navlist.item icon="envelope" :href="route('admin.partners.invite')"
:current="request()->routeIs('admin.partners.invite')" wire:navigate>
{{ __('Partner einladen') }}</flux:navlist.item>
<flux:navlist.item icon="key" :href="route('admin.partners.registration-codes')"
:current="request()->routeIs('admin.partners.registration-codes')" wire:navigate>
{{ __('Registrierungscodes') }}</flux:navlist.item>
<flux:navlist.item icon="shield-check" :href="route('admin.users.permissions')"
:current="request()->routeIs('admin.users.permissions')" wire:navigate>{{ __('Permissions') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group expandable :expanded="request()->routeIs('testing')" heading="Testing"
class="hidden lg:grid mt-2">
<flux:navlist.item icon="user-group" :href="route('testing.landing')"
:current="request()->routeIs('testing.landing')" wire:navigate>{{ __('Register') }}
</flux:navlist.item>
</flux:navlist.group>
</flux:navlist.group>
<flux:navlist.group :heading="__('Produkte')" class="grid mb-4">
<flux:navlist.item icon="clipboard-document-check" :href="route('admin.products.index')"
:current="request()->routeIs('admin.products.*')" wire:navigate>
{{ __('Produkt-Verwaltung') }}
</flux:navlist.item>
<flux:navlist.item icon="cube" :href="route('products.index')"
:current="request()->routeIs('products.index')" wire:navigate>
{{ __('Alle Produkte') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('Regionen')" class="grid mb-4">
<flux:navlist.item icon="map" :href="route('admin.hubs.index')"
:current="request()->routeIs('admin.hubs.*')" wire:navigate>{{ __('Hub-Verwaltung') }}
</flux:navlist.item>
</flux:navlist.group>
<flux:navlist.group :heading="__('CMS')" class="grid mb-4">
<flux:navlist.group expandable
:expanded="request()->routeIs(['cms.dashboard', 'cms.content.index', 'cms.projects.index', 'cms.articles.index', 'cms.media.index'])"
heading="Website-Inhalte" class="grid">
<flux:navlist.item icon="rectangle-group" :href="route('cms.dashboard')"
:current="request()->routeIs('cms.dashboard')" wire:navigate>{{ __('Übersicht') }}
</flux:navlist.item>
<flux:navlist.item icon="document-text" :href="route('cms.content.index')"
:current="request()->routeIs('cms.content.index')" wire:navigate>{{ __('Inhalte') }}
</flux:navlist.item>
<flux:navlist.item icon="building-office" :href="route('cms.projects.index')"
:current="request()->routeIs('cms.projects.index')" wire:navigate>{{ __('Projekte') }}
</flux:navlist.item>
<flux:navlist.item icon="newspaper" :href="route('cms.articles.index')"
:current="request()->routeIs('cms.articles.index')" wire:navigate>{{ __('Magazin') }}
</flux:navlist.item>
<flux:navlist.item icon="photo" :href="route('cms.media.index')"
:current="request()->routeIs('cms.media.index')" wire:navigate>{{ __('Medien') }}
</flux:navlist.item>
</flux:navlist.group>
</flux:navlist.group>
<flux:navlist.group :heading="__('Cabinet')" class="grid mb-4">
<flux:navlist.group expandable
:expanded="request()->routeIs(['admin.cms.display-dashboard', 'admin.cms.display-media', 'admin.cms.display-modules', 'admin.cms.display-module-edit', 'admin.cms.displays', 'admin.cms.cabinet', 'admin.cms.cabinet-tablet'])"
heading="Store Displays" class="grid">
<flux:navlist.item icon="squares-2x2" :href="route('admin.cms.display-dashboard')"
:current="request()->routeIs('admin.cms.display-dashboard')" wire:navigate>{{ __('Übersicht') }}
</flux:navlist.item>
<flux:navlist.item icon="photo" :href="route('admin.cms.display-media')"
:current="request()->routeIs('admin.cms.display-media')" wire:navigate>{{ __('Mediathek') }}
</flux:navlist.item>
<flux:navlist.item icon="rectangle-group" :href="route('admin.cms.display-modules')"
:current="request()->routeIs(['admin.cms.display-modules', 'admin.cms.display-module-edit'])" wire:navigate>{{ __('Module') }}
</flux:navlist.item>
<flux:navlist.item icon="tv" :href="route('admin.cms.displays')"
:current="request()->routeIs('admin.cms.displays')" wire:navigate>{{ __('Displays') }}
</flux:navlist.item>
<flux:navlist.item icon="device-tablet" :href="route('admin.cms.cabinet-tablet')"
:current="request()->routeIs('admin.cms.cabinet-tablet')" wire:navigate>{{ __('Info-Tablet') }}
</flux:navlist.item>
</flux:navlist.group>
</flux:navlist.group>
@endhasrole
@hasrole('Super-Admin')
<flux:navlist.group :heading="__('Superadmin')" class="grid mb-4">
<flux:navlist.item icon="home" :href="route('dashboard')"
:current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
</flux:navlist.group>
@endhasrole
</flux:navlist>
<flux:spacer />
@hasrole('Super-Admin|Admin')
<flux:navlist.group :heading="__('Dokumentation')" class="grid mb-4">
<flux:navlist.item icon="document-text" :href="route('admin.documentation')"
:current="request()->routeIs('admin.documentation')" wire:navigate>{{ __('Projekt-Dokumentation') }}
</flux:navlist.item>
</flux:navlist.group>
@endhasrole
@hasrole('Super-Admin')
<flux:navlist variant="outline">
<flux:navlist.group :heading="__('Resources')">
<flux:navlist.item icon="pencil" href="https://tailwindcss.com/docs/installation/using-vite"
target="_blank">
{{ __('Tailwind CSS') }}
</flux:navlist.item>
<flux:navlist.item icon="shield-check" href="https://heroicons.com" target="_blank">
{{ __('Hero Icons') }}
</flux:navlist.item>
<flux:navlist.item icon="bolt" href="https://fluxui.dev/docs/installation" target="_blank">
{{ __('Flux UI') }}
</flux:navlist.item>
<flux:navlist.item icon="folder-git-2" href="https://github.com/laravel/livewire-starter-kit"
target="_blank">
{{ __('Repository') }}
</flux:navlist.item>
<flux:navlist.item icon="book-open-text" href="https://laravel.com/docs/starter-kits" target="_blank">
{{ __('Documentation') }}
</flux:navlist.item>
</flux:navlist.group>
</flux:navlist>
@endhasrole
<!-- Desktop User Menu -->
<flux:dropdown position="bottom" align="start">
<flux:profile :name="auth()->user()->name" :initials="auth()->user()->initials()"
icon-trailing="chevrons-up-down" />
<flux:menu class="w-[220px]">
<flux:menu.radio.group>
<div class="p-0 text-sm font-normal">
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-lg">
<span
class="flex h-full w-full items-center justify-center rounded-lg bg-neutral-200 text-black dark:bg-neutral-700 dark:text-white">
{{ auth()->user()->initials() }}
</span>
</span>
<div class="grid flex-1 text-start text-sm leading-tight">
<span class="truncate font-semibold">{{ auth()->user()->name }}</span>
<span class="truncate text-xs">{{ auth()->user()->email }}</span>
</div>
</div>
</div>
</flux:menu.radio.group>
<flux:menu.separator />
<flux:menu.radio.group>
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>
{{ __('Settings') }}</flux:menu.item>
</flux:menu.radio.group>
<flux:menu.separator />
<flux:menu.radio.group>
<div x-data="{
toggle() {
$flux.appearance = $flux.appearance === 'dark' ? 'light' : 'dark';
}
}">
<flux:menu.item x-show="$flux.appearance !== 'dark'" @click="toggle()" icon="moon">
{{ __('Dunkel') }}
</flux:menu.item>
<flux:menu.item x-show="$flux.appearance === 'dark'" x-cloak @click="toggle()"
icon="sun">
{{ __('Hell') }}
</flux:menu.item>
</div>
</flux:menu.radio.group>
<flux:menu.separator />
<form method="POST" action="{{ route('auth.logout') }}" class="w-full">
@csrf
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle"
class="w-full">
{{ __('Log Out') }}
</flux:menu.item>
</form>
</flux:menu>
</flux:dropdown>
</flux:sidebar>
<!-- Mobile User Menu -->
<flux:header class="lg:hidden">
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" />
<a href="{{ config('domains.domain_main_url') }}"
class="me-5 ml-2 flex items-center space-x-2 rtl:space-x-reverse">
<x-app-logo />
</a>
<flux:spacer />
<flux:dropdown position="top" align="end">
<flux:profile :initials="auth()->user()->initials()" icon-trailing="chevron-down" />
<flux:menu>
<flux:menu.radio.group>
<div class="p-0 text-sm font-normal">
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
<span class="relative flex h-8 w-8 shrink-0 overflow-hidden rounded-lg">
<span
class="flex h-full w-full items-center justify-center rounded-lg bg-neutral-200 text-black dark:bg-neutral-700 dark:text-white">
{{ auth()->user()->initials() }}
</span>
</span>
<div class="grid flex-1 text-start text-sm leading-tight">
<span class="truncate font-semibold">{{ auth()->user()->name }}</span>
<span class="truncate text-xs">{{ auth()->user()->email }}</span>
</div>
</div>
</div>
</flux:menu.radio.group>
<flux:menu.separator />
<flux:menu.radio.group>
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>
{{ __('Settings') }}</flux:menu.item>
</flux:menu.radio.group>
<flux:menu.separator />
<flux:menu.radio.group>
<div x-data="{
toggle() {
$flux.appearance = $flux.appearance === 'dark' ? 'light' : 'dark';
}
}">
<flux:menu.item x-show="$flux.appearance !== 'dark'" @click="toggle()" icon="moon">
{{ __('Dunkel') }}
</flux:menu.item>
<flux:menu.item x-show="$flux.appearance === 'dark'" x-cloak @click="toggle()"
icon="sun">
{{ __('Hell') }}
</flux:menu.item>
</div>
</flux:menu.radio.group>
<flux:menu.separator />
<form method="POST" action="{{ route('auth.logout') }}" class="w-full">
@csrf
<flux:menu.item as="button" type="submit" icon="arrow-right-start-on-rectangle"
class="w-full">
{{ __('Log Out') }}
</flux:menu.item>
</form>
</flux:menu>
</flux:dropdown>
</flux:header>
{{ $slot }}
<flux:toast />
{{-- Reihenfolge laut Flux-Doku: Livewire stellt das gebündelte Alpine bereit, danach registriert flux.js seine Alpine-Komponenten (fluxModal, ). --}}
@livewireScripts
@fluxScripts
</body>
</html>