b2in/resources/views/livewire/web/components/sections/audience-switch.blade.php
Kevin Adametz 6d53243ea6 B2in Interior: Relaunch der Website, Kernmarken-CMS und Terminanfrage
Umsetzung von AP0-AP6 aus dev/2026-08-28/entwicklungsplan.md sowie der
vorab gefundenen Befunde T1 und B1-B13.

Befunde
- CmsContentSeeder überschrieb bei jedem Lauf alle redaktionellen Inhalte;
  jetzt Redaktionsschutz plus gezielter Relaunch-Seeder (B1)
- Magazin-CMS war nicht ans Frontend angebunden, Artikel jetzt über Slugs
  mit 301 von den alten numerischen URLs (B2)
- Vier veröffentlichte Display-Playlists zeigten auf b2in.test und wären
  live nicht ladbar gewesen (B13)
- Info-Tablet speicherte geleerte Öffnungszeiten nicht (T1)
- /service und /portfolio lieferten seit Februar 500 (B12)

Website
- Startseite neu strukturiert und umgetextet, eigene Seite /marken mit
  Detailseite je Kernmarke, /netzwerk und Altrouten leiten dorthin
- Galerie je Marke, getrennt nach realisierten Projekten und
  Visualisierungen; ohne gesetzte Kategorie gilt ein Bild als Entwurf
- Seite /referenzen, gespeist aus den Markengalerien
- Showroom-Display im 9:16-Rahmen über eine schreibgeschützte Embed-Route
  ohne Preview-Token
- Terminanfrage-Widget auf allen Seiten, Markenauswahl aus dem CMS,
  WhatsApp per Klick-zum-Chat-Link mit vorbereitetem Text
- FAQ, Über-uns, Kontakt und Magazin inhaltlich auf Interior umgestellt

Sonstiges
- Vorschau-Instanzen liefern noindex und verlinken sich bei unbekanntem
  Host auf sich selbst statt auf eine fremde Domain
- Seeder-Zugangsdaten aus dem Code in die Konfiguration (B8)
- Ablauf für die Vorschau: dev/2026-08-28/preview-deployment.md

833 Tests grün (3084 Assertions), Pint sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:31:19 +00:00

51 lines
2.3 KiB
PHP

@php
if (!function_exists('renderHeroIcon')) {
function renderHeroIcon($iconName, $style = 'outline', $color = 'text-secondary')
{
$iconPath = public_path("heroicons/optimized/24/{$style}/{$iconName}.svg");
$fallbackPath = public_path('heroicons/optimized/24/outline/sparkles.svg');
if (file_exists($iconPath)) {
return str_replace('<svg', '<svg class="w-10 h-10 ' . $color . '"', file_get_contents($iconPath));
}
if (file_exists($fallbackPath)) {
return str_replace('<svg', '<svg class="w-10 h-10 ' . $color . '"', file_get_contents($fallbackPath));
}
return '';
}
}
@endphp
<section class="section-padding {{ $bg }}" id="wege">
<div class="container-padding">
<div class="text-center mb-16 slide-up delay-300">
<h2 class="text-section-title">{!! $content['title'] ?? '' !!}</h2>
@if (!empty($content['subtitle']))
<p class="text-large text-muted-foreground mt-4 max-w-2xl mx-auto">{{ $content['subtitle'] }}</p>
@endif
</div>
<div class="grid md:grid-cols-2 gap-8 lg:gap-12 slide-up delay-400">
@foreach ($content['cards'] ?? [] as $index => $card)
<div class="card-elevated rounded-2xl p-8 flex flex-col" wire:key="audience-card-{{ $index }}">
<div class="w-20 h-20 icon-secondary-linear glow-soft rounded-2xl flex items-center justify-center mb-6">
{!! renderHeroIcon($card['icon'] ?? 'home', 'outline', 'text-secondary-foreground') !!}
</div>
<h3 class="text-xl font-medium mb-3">{{ $card['title'] ?? '' }}</h3>
<p class="text-muted-foreground leading-relaxed grow">{!! $card['description'] ?? '' !!}</p>
@if (!empty($card['button_text']))
<div class="pt-6">
<a href="{{ $card['button_link'] ?? '/contact' }}" class="btn-primary-accent px-6 py-3 inline-block">
{{ $card['button_text'] }}
</a>
</div>
@endif
</div>
@endforeach
</div>
</div>
</section>