b2in/app/Livewire/Web/Components/Sections/HeroSlider.php
Kevin Adametz 4b07bbdcae Startseite ruhiger, Otterpohl mit Montage, Marken-Bilder und Farbwelt-Entwurf
- 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>
2026-10-01 10:34:21 +00:00

98 lines
2.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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');
}
}