Display Module 13-05-2026
This commit is contained in:
parent
6a65354f4c
commit
9262132325
41 changed files with 496 additions and 334 deletions
|
|
@ -183,7 +183,7 @@
|
|||
|
||||
<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.display-versions', 'admin.cms.display-version-edit', 'admin.cms.displays', 'admin.cms.cabinet', 'admin.cms.cabinet-tablet'])"
|
||||
: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') }}
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
: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', 'admin.cms.display-versions', 'admin.cms.display-version-edit'])" wire:navigate>{{ __('Module') }}
|
||||
: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') }}
|
||||
|
|
|
|||
|
|
@ -171,9 +171,9 @@ $tabletStatus = computed(function () {
|
|||
Es besteht aus drei Bereichen, die Sie über die Kacheln oben erreichen:
|
||||
</p>
|
||||
<ul class="mt-2 ml-5 list-disc space-y-1">
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Mediathek</strong> - Zentrale Verwaltung aller Bilder und Videos fuer die Displays. Dateien bis 200 MB direkt hochladen oder groessere Videos als externe URL (Google Drive, OneDrive) einbinden.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Module</strong> – Wiederverwendbare Content-Pakete, die auf den Displays abgespielt werden. Jede Modul hat einen bestimmten Typ und enthält passende Inhalte (Videos, Bilder oder Angebots-Slides).</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Displays</strong> – Die physischen Bildschirme im Showroom. Jedem Display werden eine oder mehrere Module als Playlist zugewiesen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Mediathek</strong> - Zentrale Verwaltung aller Bilder, SVG-Logos und Videos fuer die Displays. Dateien bis 200 MB direkt hochladen oder groessere Videos als externe URL (Google Drive, OneDrive) einbinden.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Module</strong> – Wiederverwendbare Content-Pakete, die auf den Displays abgespielt werden. Jedes Modul hat einen bestimmten Typ, passende Inhalte und eigene Meta-Einstellungen fuer Logo, Claim, Footer, QR-Code oder Theme.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Displays</strong> – Die physischen Bildschirme im Showroom. Pro Display gibt es einen Live-Stand und optional einen Entwurf, der separat vorbereitet, getestet und bewusst veröffentlicht wird.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Info-Tablet</strong> – Das Tablet an der Eingangstür des Showrooms. Hier verwalten Sie Öffnungszeiten, den aktuellen Store-Status und Hinweise für Besucher.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -190,10 +190,10 @@ $tabletStatus = computed(function () {
|
|||
Sie ist unabhängig von der Website-Mediathek (Flux CMS) und speziell auf die Anforderungen der Displays zugeschnitten.
|
||||
</p>
|
||||
<ul class="mt-2 ml-5 list-disc space-y-1">
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Direkt-Upload:</strong> Bilder und Videos bis 200 MB direkt per Drag-and-drop oder Dateiauswahl hochladen. Die Dateien werden auf dem Server gespeichert und stehen sofort zur Verfügung.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Direkt-Upload:</strong> Bilder, SVG-Dateien und Videos bis 200 MB direkt per Drag-and-drop oder Dateiauswahl hochladen. Die Dateien werden auf dem Server gespeichert und stehen sofort zur Verfügung.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Externe URLs:</strong> Für Videos über 200 MB (z. B. 4K-Showroom-Rundgänge) können Sie einen Freigabe-Link von Google Drive, OneDrive oder anderen Cloud-Diensten hinterlegen. Diese URL wird wie ein normales Medium in der Mediathek verwaltet und kann genauso in Module eingebunden werden.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Sammlungen:</strong> Ordnen Sie Medien in Sammlungen wie <em>immobilien</em>, <em>moebel</em> oder <em>brand</em>, um bei vielen Dateien den Überblick zu behalten.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Medienauswahl im Editor:</strong> Beim Bearbeiten eines Moduls erscheint ein „Aus Mediathek"-Button. Darüber öffnen Sie die Medienauswahl und können bestehende Medien wählen oder direkt neue hochladen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Medienauswahl im Editor:</strong> Beim Bearbeiten eines Moduls erscheint ein „Aus Mediathek"-Button. Darüber öffnen Sie die Medienauswahl und können bestehende Medien wählen oder direkt neue Dateien inklusive SVG-Logos hochladen.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -211,19 +211,19 @@ $tabletStatus = computed(function () {
|
|||
<ul class="mt-2 ml-5 list-disc space-y-1">
|
||||
<li>
|
||||
<strong class="font-medium text-zinc-800 dark:text-zinc-200">Video-Display</strong> –
|
||||
Für Video-Playlists mit optionalem Footer. Inhalte: <em>Videos</em> (Dateiname, Titel, Position/Ausschnitt) und <em>Footer-Zeilen</em> (Überschrift, Unterzeile, optionaler QR-Code-Link).
|
||||
Für Video-Playlists mit optionalem Footer. Inhalte: <em>Videos</em> aus der Mediathek oder Legacy-Dateinamen, Position/Ausschnitt und <em>Footer-Zeilen</em> (Überschrift, Unterzeile, optionaler QR-Code-Link). Mediathek-URLs wie <code class="text-xs bg-zinc-100 dark:bg-zinc-800 px-1 py-0.5 rounded">/storage/...</code> werden direkt abgespielt.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="font-medium text-zinc-800 dark:text-zinc-200">B2in Display</strong> –
|
||||
Für Medien-Rotation (Bilder und Videos) im Marken-Design. Inhalte: <em>Media-Items</em> mit Kategorie (Immobilien / Möbel), Überschrift, Unterzeile und Anzeigedauer. Unterstützt Light-/Dark-Theme.
|
||||
Für Medien-Rotation (Bilder und Videos) im Marken-Design. Inhalte: <em>Media-Items</em> mit Kategorie (Immobilien / Möbel), Überschrift, Unterzeile und Anzeigedauer. Unterstützt Light-/Dark-Theme sowie zentrale Meta-Einstellungen für Header-Logo, Claim, Footer-Domain und QR-Code.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="font-medium text-zinc-800 dark:text-zinc-200">Angebote</strong> –
|
||||
Für Produkt-Slides im Angebotsformat. Verschiedene Slide-Layouts: Intro, Produkt-Hero, Produkt-Details und Impuls-Slides mit Preisen, Badges und QR-Codes.
|
||||
Für Produkt-Slides im Angebotsformat. Verschiedene Slide-Layouts: Intro, Produkt-Hero, Produkt-Details und Impuls-Slides mit Preisen, Badges und QR-Codes. Logo, Brand-Text, Footer-Claim und Web-/QR-URL werden einmal am Modul gepflegt und automatisch von allen Slides übernommen.
|
||||
</li>
|
||||
</ul>
|
||||
<p class="mt-2">
|
||||
Innerhalb eines Moduls können Sie beliebig viele Inhalte anlegen, die Reihenfolge per Hoch/Runter-Sortierung festlegen und einzelne Einträge aktivieren oder deaktivieren.
|
||||
Innerhalb eines Moduls können Sie beliebig viele Inhalte anlegen, die Reihenfolge per Hoch/Runter-Sortierung festlegen und einzelne Einträge aktivieren oder deaktivieren. Der Modul-Editor zeigt Inline-Vorschaubilder, eine 9:16-Player-Vorschau und eine Vollbild-Vorschau. Im Slide-Bearbeiten-Dialog wird nur der aktuell bearbeitete Slide als Einzel-Vorschau gerendert.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -238,9 +238,11 @@ $tabletStatus = computed(function () {
|
|||
Ein <strong class="font-medium text-zinc-800 dark:text-zinc-200">Display</strong> repräsentiert einen physischen Bildschirm im Showroom.
|
||||
</p>
|
||||
<ul class="mt-2 ml-5 list-disc space-y-1">
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Modul-Zuweisung:</strong> Jedem Display können Sie eine oder mehrere Module zuordnen. Die Module werden in der festgelegten Reihenfolge als Playlist abgespielt.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Live und Entwurf:</strong> Jedes Display zeigt den veröffentlichten Live-Stand und optional einen Entwurf. Entwürfe können aus Live angelegt, separat bearbeitet, verworfen oder veröffentlicht werden.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Modul-Zuweisung:</strong> Jedem Live- oder Entwurfsstand können Sie eine oder mehrere Module zuordnen. Die Module werden in der festgelegten Reihenfolge als Playlist abgespielt.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Vorschau:</strong> Live- und Entwurfs-URLs sind direkt kopierbar. Entwürfe und Module können zusätzlich im 9:16-Iframe oder im Vollbild geprüft werden.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Aktiv/Inaktiv:</strong> Über den Aktiv-Status können Sie einzelne Displays vorübergehend deaktivieren, ohne die Konfiguration zu verlieren.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">API-Anbindung:</strong> Jedes Display ruft seine Inhalte über eine JSON-API ab (<code class="text-xs bg-zinc-100 dark:bg-zinc-800 px-1 py-0.5 rounded">/api/display/{id}/config</code>). Änderungen werden beim nächsten Abruf automatisch übernommen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">API-Anbindung:</strong> Jedes Display ruft seine Live-Inhalte über eine JSON-API ab (<code class="text-xs bg-zinc-100 dark:bg-zinc-800 px-1 py-0.5 rounded">/api/display/{id}/config</code>). Entwürfe laufen über Preview-Tokens, Module über eigene Preview-Endpunkte.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -282,10 +284,12 @@ $tabletStatus = computed(function () {
|
|||
Typischer Workflow
|
||||
</flux:heading>
|
||||
<ol class="mt-2 ml-5 list-decimal space-y-1">
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Medien hochladen</strong> – Bilder, SVG-Logos oder Videos in der Display-Mediathek ablegen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Modul erstellen</strong> – Unter „Module" ein neues Modul mit passendem Typ anlegen (z. B. „Frühling 2026 Video").</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Inhalte hinzufügen</strong> – Im Modul Videos, Medien oder Slides anlegen, Reihenfolge festlegen und aktivieren.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Display zuweisen</strong> – Unter „Displays" das Modul einem physischen Bildschirm zuordnen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Fertig</strong> – Das Display lädt die neuen Inhalte automatisch über die API.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Meta-Einstellungen pflegen</strong> – Logo, Claim, Footer, QR-Code, Theme oder Anzeigezeiten einmal auf Modulebene setzen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Inhalte hinzufügen</strong> – Im Modul Videos, Medien oder Slides anlegen, Reihenfolge festlegen, aktivieren und per Vorschau prüfen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Display-Entwurf erstellen</strong> – Unter „Displays" aus dem Live-Stand einen Entwurf erzeugen und dort Module hinzufügen, sortieren oder entfernen.</li>
|
||||
<li><strong class="font-medium text-zinc-800 dark:text-zinc-200">Prüfen und veröffentlichen</strong> – Entwurf in der 9:16-Vorschau oder im Vollbild testen und anschließend bewusst veröffentlichen.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,29 @@
|
|||
</x-success-alert>
|
||||
@endif
|
||||
|
||||
@php
|
||||
$displayPlayerUrl = rtrim(config('display.player_url') ?: 'https://cabinet.b2in.eu/display', '/');
|
||||
$displayOverviewUrl = $displayPlayerUrl.'/';
|
||||
@endphp
|
||||
|
||||
<flux:card class="mb-6 border-blue-200 bg-blue-50/70 dark:border-blue-500/30 dark:bg-blue-950/20">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div>
|
||||
<flux:heading size="lg">{{ __('Öffentliche Display-Übersicht') }}</flux:heading>
|
||||
<flux:text class="mt-1">
|
||||
{{ __('Hier sehen Sie alle aktiven Live-Displays und können die Wiedergabe direkt öffnen.') }}
|
||||
</flux:text>
|
||||
<div class="mt-2 text-xs font-mono text-blue-700 dark:text-blue-300">
|
||||
{{ $displayOverviewUrl }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<flux:button href="{{ $displayOverviewUrl }}" target="_blank" variant="primary" icon="arrow-top-right-on-square">
|
||||
{{ __('Display-Übersicht öffnen') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</flux:card>
|
||||
|
||||
<flux:card>
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
|
|
@ -30,7 +53,7 @@
|
|||
<div class="space-y-4">
|
||||
@foreach($displays as $display)
|
||||
@php
|
||||
$liveDisplayUrl = url('/_cabinet/display/index.html').'?id='.$display->id;
|
||||
$liveDisplayUrl = $displayPlayerUrl.'/?id='.$display->id;
|
||||
$liveApiUrl = url('/api/display/'.$display->id.'/config');
|
||||
@endphp
|
||||
<div wire:key="display-{{ $display->id }}"
|
||||
|
|
@ -364,6 +387,7 @@
|
|||
wire:key="draft-preview-{{ $previewFrameRefreshCounter }}"
|
||||
src="{{ $draftPreviewUrl }}"
|
||||
class="h-full w-full border-0"
|
||||
loading="lazy"
|
||||
title="{{ __('Entwurfs-Vorschau') }}"
|
||||
></iframe>
|
||||
@else
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
wire:key="module-preview-{{ $previewFrameRefreshCounter }}"
|
||||
src="{{ $this->modulePreviewUrl() }}"
|
||||
class="h-full w-full border-0"
|
||||
loading="lazy"
|
||||
title="{{ __('Modul-Vorschau') }}"
|
||||
></iframe>
|
||||
</div>
|
||||
|
|
@ -250,6 +251,7 @@
|
|||
wire:key="item-modal-module-preview-{{ $previewFrameRefreshCounter }}"
|
||||
src="{{ $this->itemPreviewUrl() }}"
|
||||
class="h-full w-full border-0"
|
||||
loading="lazy"
|
||||
title="{{ __('Einzel-Vorschau im Bearbeiten-Dialog') }}"
|
||||
></iframe>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
accept="image/jpeg,image/png,image/gif,image/webp,image/svg+xml,.pdf,.doc,.docx,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone
|
||||
heading="Dateien hochladen"
|
||||
text="Bilder (JPG, PNG, WebP, SVG) und Dokumente (PDF, DOC) — max. 10 MB pro Datei"
|
||||
text="Bilder (JPG, PNG, WebP, SVG) und Dokumente (PDF, DOC) — max. 200 MB pro Datei"
|
||||
with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,15 @@
|
|||
</flux:badge>
|
||||
<span class="font-semibold text-sm">{{ $item->content['title'] ?? $item->content['filename'] ?? '–' }}</span>
|
||||
</div>
|
||||
<div class="text-xs text-zinc-600 dark:text-zinc-400 space-x-4">
|
||||
<span>{{ $item->content['filename'] ?? '–' }}</span>
|
||||
@php
|
||||
$videoSource = $item->content['filename'] ?? '';
|
||||
$isMediaLibrarySource = str_starts_with($videoSource, '/storage/') || str_starts_with($videoSource, 'http');
|
||||
@endphp
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<flux:badge size="sm" :color="$isMediaLibrarySource ? 'sky' : 'zinc'">
|
||||
{{ $isMediaLibrarySource ? __('Mediathek') : __('Legacy-Datei') }}
|
||||
</flux:badge>
|
||||
<span class="truncate">{{ $videoSource ?: '–' }}</span>
|
||||
<span>Position: {{ $item->content['position'] ?? 25 }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -272,16 +272,16 @@ new class extends Component
|
|||
$rules['deliveryRadius'] = 'required|integer|min:1|max:500';
|
||||
$rules['assemblyRadius'] = 'required|integer|min:1|max:500';
|
||||
$rules['newTeamPhotos'] = 'nullable|array|max:10';
|
||||
$rules['newTeamPhotos.*'] = 'image|mimes:jpeg,jpg,png|max:10240';
|
||||
$rules['newTeamPhotos.*'] = 'image|mimes:jpeg,jpg,png|max:204800';
|
||||
$rules['newShowroomPhotos'] = 'nullable|array|max:20';
|
||||
$rules['newShowroomPhotos.*'] = 'image|mimes:jpeg,jpg,png|max:10240';
|
||||
$rules['newShowroomPhotos.*'] = 'image|mimes:jpeg,jpg,png|max:204800';
|
||||
}
|
||||
|
||||
if ($this->isManufacturer()) {
|
||||
$rules['brandName'] = 'required|string|max:255';
|
||||
$rules['brandDescription'] = 'nullable|string|max:1000';
|
||||
$rules['newBrandImages'] = 'nullable|array|max:10';
|
||||
$rules['newBrandImages.*'] = 'image|mimes:jpeg,jpg,png|max:10240';
|
||||
$rules['newBrandImages.*'] = 'image|mimes:jpeg,jpg,png|max:204800';
|
||||
}
|
||||
|
||||
$this->validate($rules, [
|
||||
|
|
@ -305,11 +305,11 @@ new class extends Component
|
|||
'foundedYear.min' => __('Das Gründungsjahr muss nach 1800 liegen.'),
|
||||
'foundedYear.max' => __('Das Gründungsjahr darf nicht in der Zukunft liegen.'),
|
||||
'newTeamPhotos.*.image' => __('Nur Bilder (JPG, PNG) erlaubt.'),
|
||||
'newTeamPhotos.*.max' => __('Bilder dürfen maximal 10 MB groß sein.'),
|
||||
'newTeamPhotos.*.max' => __('Bilder dürfen maximal 200 MB groß sein.'),
|
||||
'newShowroomPhotos.*.image' => __('Nur Bilder (JPG, PNG) erlaubt.'),
|
||||
'newShowroomPhotos.*.max' => __('Bilder dürfen maximal 10 MB groß sein.'),
|
||||
'newShowroomPhotos.*.max' => __('Bilder dürfen maximal 200 MB groß sein.'),
|
||||
'newBrandImages.*.image' => __('Nur Bilder (JPG, PNG) erlaubt.'),
|
||||
'newBrandImages.*.max' => __('Bilder dürfen maximal 10 MB groß sein.'),
|
||||
'newBrandImages.*.max' => __('Bilder dürfen maximal 200 MB groß sein.'),
|
||||
]);
|
||||
|
||||
$specialties = array_values(array_filter(
|
||||
|
|
@ -793,7 +793,7 @@ new class extends Component
|
|||
<flux:card class="shadow-elegant">
|
||||
<div class="mb-4">
|
||||
<flux:heading size="lg">{{ __('Team-Fotos') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Nur JPG/PNG – max. 10 MB pro Bild') }}</flux:subheading>
|
||||
<flux:subheading>{{ __('Nur JPG/PNG – max. 200 MB pro Bild') }}</flux:subheading>
|
||||
</div>
|
||||
<flux:separator class="mb-6" />
|
||||
|
||||
|
|
@ -867,7 +867,7 @@ new class extends Component
|
|||
@endif
|
||||
|
||||
<flux:file-upload wire:model="newTeamPhotos" multiple accept="image/jpeg,image/png,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone heading="{{ __('Team-Fotos hochladen') }}" text="{{ __('JPEG oder PNG – max. 10 MB') }}" with-progress />
|
||||
<flux:file-upload.dropzone heading="{{ __('Team-Fotos hochladen') }}" text="{{ __('JPEG oder PNG – max. 200 MB') }}" with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
@if (count($newTeamPhotos) > 0)
|
||||
|
|
@ -892,7 +892,7 @@ new class extends Component
|
|||
<flux:card class="shadow-elegant">
|
||||
<div class="mb-4">
|
||||
<flux:heading size="lg">{{ __('Showroom-Galerie') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Bilder Ihres Showrooms für das öffentliche Profil – nur JPG/PNG, max. 10 MB') }}</flux:subheading>
|
||||
<flux:subheading>{{ __('Bilder Ihres Showrooms für das öffentliche Profil – nur JPG/PNG, max. 200 MB') }}</flux:subheading>
|
||||
</div>
|
||||
<flux:separator class="mb-6" />
|
||||
|
||||
|
|
@ -966,7 +966,7 @@ new class extends Component
|
|||
@endif
|
||||
|
||||
<flux:file-upload wire:model="newShowroomPhotos" multiple accept="image/jpeg,image/png,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone heading="{{ __('Showroom-Bilder hochladen') }}" text="{{ __('JPEG oder PNG – max. 10 MB') }}" with-progress />
|
||||
<flux:file-upload.dropzone heading="{{ __('Showroom-Bilder hochladen') }}" text="{{ __('JPEG oder PNG – max. 200 MB') }}" with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
@if (count($newShowroomPhotos) > 0)
|
||||
|
|
@ -993,7 +993,7 @@ new class extends Component
|
|||
<flux:card class="shadow-elegant">
|
||||
<div class="mb-4">
|
||||
<flux:heading size="lg">{{ __('Marken-Bilder') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Bilder für Ihre Marken-Präsentation (Atmosphäre, Brand-Story etc.) – nur JPG/PNG, max. 10 MB') }}</flux:subheading>
|
||||
<flux:subheading>{{ __('Bilder für Ihre Marken-Präsentation (Atmosphäre, Brand-Story etc.) – nur JPG/PNG, max. 200 MB') }}</flux:subheading>
|
||||
</div>
|
||||
<flux:separator class="mb-6" />
|
||||
|
||||
|
|
@ -1067,7 +1067,7 @@ new class extends Component
|
|||
@endif
|
||||
|
||||
<flux:file-upload wire:model="newBrandImages" multiple accept="image/jpeg,image/png,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone heading="{{ __('Marken-Bilder hochladen') }}" text="{{ __('JPEG oder PNG – max. 10 MB') }}" with-progress />
|
||||
<flux:file-upload.dropzone heading="{{ __('Marken-Bilder hochladen') }}" text="{{ __('JPEG oder PNG – max. 200 MB') }}" with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
@if (count($newBrandImages) > 0)
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ new class extends Component
|
|||
'status' => 'required|in:active,draft',
|
||||
// Bilder
|
||||
'mainImages' => 'nullable|array|min:0|max:10',
|
||||
'mainImages.*' => 'mimes:jpeg,jpg,png|max:10240',
|
||||
'mainImages.*' => 'mimes:jpeg,jpg,png|max:204800',
|
||||
// Maße & Material
|
||||
'widthCm' => 'nullable|integer|min:1',
|
||||
'heightCm' => 'nullable|integer|min:1',
|
||||
|
|
@ -546,7 +546,7 @@ new class extends Component
|
|||
'priceDisplayText.required_if' => __('Bei Ab-Preis ist eine Preisangabe erforderlich (z.B. "Ab 2.500 €").'),
|
||||
'mainImages.max' => __('Maximal 10 Produktbilder erlaubt.'),
|
||||
'mainImages.*.mimes' => __('Nur Bilder (JPG, JPEG, PNG) erlaubt.'),
|
||||
'mainImages.*.max' => __('Bilder dürfen maximal 10 MB groß sein.'),
|
||||
'mainImages.*.max' => __('Bilder dürfen maximal 200 MB groß sein.'),
|
||||
'sku.unique' => __('Diese Artikelnummer ist bereits vergeben.'),
|
||||
'sellingPrice.min' => __('Der Verkaufspreis muss größer als 0 sein.'),
|
||||
'countryOfOrigin.size' => __('Bitte geben Sie einen gültigen 2-stelligen ISO-Ländercode ein (z.B. DE).'),
|
||||
|
|
@ -1229,7 +1229,7 @@ new class extends Component
|
|||
<flux:card class="shadow-elegant">
|
||||
<div class="mb-4">
|
||||
<flux:heading size="lg">{{ __('Produktbilder') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Nur Bilder (JPG, JPEG, PNG) – max. 10 MB pro Bild, max. 10 Bilder') }}
|
||||
<flux:subheading>{{ __('Nur Bilder (JPG, JPEG, PNG) – max. 200 MB pro Bild, max. 10 Bilder') }}
|
||||
</flux:subheading>
|
||||
</div>
|
||||
<flux:separator class="mb-6" />
|
||||
|
|
@ -1309,7 +1309,7 @@ new class extends Component
|
|||
<flux:file-upload wire:model="mainImages" label="Upload files" multiple
|
||||
accept="image/jpeg,image/png,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone heading="{{ __('Bilder hochladen') }}"
|
||||
text="{{ __('Nur JPEG oder PNG – max. 10 MB') }}" with-progress />
|
||||
text="{{ __('Nur JPEG oder PNG – max. 200 MB') }}" with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
@if (isset($mainImages) && count($mainImages) > 0)
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ new class extends Component
|
|||
'status' => 'required|in:active,draft',
|
||||
'partnerProductNumber' => 'nullable|string|max:100',
|
||||
'mainImages' => 'nullable|array|min:0|max:10',
|
||||
'mainImages.*' => 'mimes:jpeg,jpg,png|max:10240',
|
||||
'mainImages.*' => 'mimes:jpeg,jpg,png|max:204800',
|
||||
];
|
||||
|
||||
$messages = [
|
||||
|
|
@ -250,7 +250,7 @@ new class extends Component
|
|||
'categoryId.required' => __('Bitte wählen Sie eine Kategorie aus.'),
|
||||
'mainImages.max' => __('Maximal 10 Produktbilder erlaubt.'),
|
||||
'mainImages.*.mimes' => __('Nur Bilder (JPG, JPEG, PNG) erlaubt.'),
|
||||
'mainImages.*.max' => __('Bilder dürfen maximal 10 MB groß sein.'),
|
||||
'mainImages.*.max' => __('Bilder dürfen maximal 200 MB groß sein.'),
|
||||
];
|
||||
|
||||
if ($isAdminWithoutPartner) {
|
||||
|
|
@ -459,7 +459,7 @@ new class extends Component
|
|||
<flux:card class="shadow-elegant">
|
||||
<div class="mb-4">
|
||||
<flux:heading size="lg">{{ $isEditing ? __('Produktbilder') : __('Produktbild') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Nur Bilder (JPG, JPEG, PNG) – max. 10 MB pro Bild, max. 10 Bilder') }}
|
||||
<flux:subheading>{{ __('Nur Bilder (JPG, JPEG, PNG) – max. 200 MB pro Bild, max. 10 Bilder') }}
|
||||
</flux:subheading>
|
||||
</div>
|
||||
<flux:separator class="mb-6" />
|
||||
|
|
@ -539,7 +539,7 @@ new class extends Component
|
|||
<flux:file-upload wire:model="mainImages" label="Upload files" multiple
|
||||
accept="image/jpeg,image/png,.jpg,.jpeg,.png">
|
||||
<flux:file-upload.dropzone heading="{{ __('Bilder hochladen') }}"
|
||||
text="{{ __('Nur JPEG oder PNG – max. 10 MB') }}" with-progress />
|
||||
text="{{ __('Nur JPEG oder PNG – max. 200 MB') }}" with-progress />
|
||||
</flux:file-upload>
|
||||
|
||||
@if (isset($mainImages) && count($mainImages) > 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue