- Hinweisleiste per B2IN_ANNOUNCEMENT_BAR ausgeblendet (Standard aus) - Hero: „Räume aus einer Hand.“ als neue Überschrift, zweiter Button entfernt - Projekttext mit zentralem deutschen Vertragspartner (Punkt statt Gedankenstrich) - Otterpohl als vierte Kernmarke: Text v2, Abschnitt „Montage“, Titelbild getauscht - Markenabschnitte: Absätze mit „- “ als Liste mit fetter Einleitung - Titelbilder und Galerien für CABINET, Rotpunkt, Febrü und Otterpohl (WebP) - Feedback 17.09. in den Markentexten, Demobilder entfernt, WhatsApp-Nummer - Palette „Modern“ fest ohne Schalter, Entwurf /entwurf mit Hero-Slideshow - Seeder-Liste fürs Deployment im Entwicklungsplan Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
2.9 KiB
PHP
98 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire\Web\Components\Sections;
|
||
|
||
use App\Models\CmsBrand;
|
||
use Livewire\Component;
|
||
|
||
/**
|
||
* Hero des Startseiten-Entwurfs (Nachtrag 19, Briefing Marcel 24.09.): Rahmen mit Goldkante,
|
||
* eine Überschrift, ein Button und statt des festen Bildes eine ruhige Slideshow.
|
||
*
|
||
* Die Slides kommen aus der Sektion `home/hero_slider` (Liste `slides`), sobald Marcel dort
|
||
* welche pflegt. Solange die Liste leer ist, laufen die Titelbilder der veröffentlichten
|
||
* Kernmarken in ihrer Reihenfolge – Marken ohne Bild fallen weg.
|
||
*/
|
||
class HeroSlider extends Component
|
||
{
|
||
/** @var array<string, mixed> */
|
||
public array $content = [];
|
||
|
||
/** @var array<int, array{image: string, alt: string, label: string, caption: string}> */
|
||
public array $slides = [];
|
||
|
||
public function mount(): void
|
||
{
|
||
$section = cms_theme_section('hero_slider');
|
||
$this->content = is_array($section) ? $section : [];
|
||
$this->slides = $this->slidesFromContent() ?: $this->slidesFromBrands();
|
||
}
|
||
|
||
/**
|
||
* @return array<int, array{image: string, alt: string, label: string, caption: string}>
|
||
*/
|
||
private function slidesFromContent(): array
|
||
{
|
||
$slides = [];
|
||
|
||
foreach ((array) ($this->content['slides'] ?? []) as $slide) {
|
||
if (! is_array($slide) || trim((string) ($slide['image'] ?? '')) === '') {
|
||
continue;
|
||
}
|
||
|
||
if (array_key_exists('active', $slide) && ! filter_var($slide['active'], FILTER_VALIDATE_BOOLEAN)) {
|
||
continue;
|
||
}
|
||
|
||
$label = trim((string) ($slide['label'] ?? $slide['title'] ?? ''));
|
||
|
||
$slides[] = [
|
||
'image' => (string) $slide['image'],
|
||
'alt' => trim((string) ($slide['alt'] ?? $label)),
|
||
'label' => $label,
|
||
'caption' => trim((string) ($slide['caption'] ?? '')),
|
||
];
|
||
}
|
||
|
||
return $slides;
|
||
}
|
||
|
||
/**
|
||
* @return array<int, array{image: string, alt: string, label: string, caption: string}>
|
||
*/
|
||
private function slidesFromBrands(): array
|
||
{
|
||
$slides = [];
|
||
|
||
foreach (CmsBrand::forFrontend() as $brand) {
|
||
$image = trim((string) ($brand['image'] ?? ''));
|
||
|
||
if ($image === '') {
|
||
continue;
|
||
}
|
||
|
||
$name = (string) ($brand['name'] ?? '');
|
||
|
||
$slides[] = [
|
||
'image' => $image,
|
||
'alt' => $name.' – '.strip_tags((string) ($brand['tagline'] ?? '')),
|
||
'label' => $name,
|
||
'caption' => strip_tags((string) ($brand['tagline'] ?? '')),
|
||
];
|
||
}
|
||
|
||
return $slides;
|
||
}
|
||
|
||
public function getIntervalMsProperty(): int
|
||
{
|
||
$seconds = (float) ($this->content['interval'] ?? 7);
|
||
|
||
return (int) round(max(3, min(30, $seconds)) * 1000);
|
||
}
|
||
|
||
public function render(): \Illuminate\View\View
|
||
{
|
||
return view('livewire.web.components.sections.hero-slider');
|
||
}
|
||
}
|