b2in/resources/views/livewire/web/components/ui/header.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

107 lines
6.3 KiB
PHP

<header class="header-normal" id="header">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<a href="{{ $domainUrl }}" class="flex items-center">
<img src="{{ asset(\App\Helpers\ThemeHelper::getLogoPath('positive')) }}"
alt="{{ $domainName ?? 'B2in Interior' }} Logo" class="h-12 w-auto" />
</a>
<nav class="hidden md:flex items-center space-x-8" aria-label="{{ __('ui.main_navigation') }}">
@if(isset($content['navigation']) && is_array($content['navigation']))
@foreach ($content['navigation'] as $navItem)
<a href="{{ $navItem['url'] }}"
class="text-sm font-medium transition-colors relative
@if ($this->isActiveRoute($navItem['url'])) text-secondary after:absolute after:bottom-[-4px] after:left-0 after:w-full after:h-0.5 after:bg-secondary after:rounded-full
@else
text-primary hover:text-secondary @endif">
{{ $navItem['label'] }}
</a>
@endforeach
@endif
</nav>
<div class="flex items-center space-x-4">
{{-- Language Switcher --}}
<div class="hidden md:flex items-center space-x-1 text-sm" role="group" aria-label="Language">
@foreach ($availableLocales as $locale => $label)
<button wire:click="switchLanguage('{{ $locale }}')"
class="px-2 py-1 rounded transition-colors duration-200
{{ $currentLocale === $locale
? 'text-secondary font-semibold'
: 'text-muted-foreground hover:text-foreground' }}"
@if($currentLocale === $locale) aria-current="true" @endif>
{{ $label }}
</button>
@if (!$loop->last)
<span class="text-border">|</span>
@endif
@endforeach
</div>
<a href="{{ route('contact') }}"
class="hidden md:block rounded-md px-5 py-2.5 text-sm font-medium bg-secondary hover-bg-primary glow-medium text-white transition-all duration-200">
{{ __('ui.contact') }}
</a>
<button wire:click="toggleMobileMenu"
class="md:hidden w-5 h-5 text-muted-foreground hover:text-foreground transition-colors"
aria-label="{{ $this->isMobileMenuOpen ? __('ui.menu_close') : __('ui.menu_open') }}"
aria-expanded="{{ $this->isMobileMenuOpen ? 'true' : 'false' }}">
@if ($this->isMobileMenuOpen)
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12"></path>
</svg>
@else
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
@endif
</button>
</div>
</div>
{{-- Mobile Menu --}}
@if ($this->isMobileMenuOpen)
<div class="md:hidden border-t border-border bg-background/95 backdrop-blur-sm">
<nav class="px-4 py-6 space-y-4" aria-label="{{ __('ui.mobile_navigation') }}">
@if(isset($content['navigation']) && is_array($content['navigation']))
@foreach ($content['navigation'] as $navItem)
<a href="{{ $navItem['url'] }}"
class="block text-sm font-medium transition-colors py-2 px-3 rounded-md
@if ($this->isActiveRoute($navItem['url'])) text-secondary bg-secondary/10 border-l-2 border-secondary
@else
text-foreground hover:text-secondary hover:bg-muted/50 @endif"
wire:click="closeMobileMenu">
{{ $navItem['label'] }}
</a>
@endforeach
@endif
<div class="pt-4 border-t border-border space-y-3">
{{-- Mobile Language Switcher --}}
<div class="flex items-center space-x-1 text-sm px-3" role="group" aria-label="Language">
@foreach ($availableLocales as $locale => $label)
<button wire:click="switchLanguage('{{ $locale }}')"
class="px-3 py-1.5 rounded transition-colors duration-200
{{ $currentLocale === $locale
? 'text-secondary font-semibold bg-secondary/10'
: 'text-muted-foreground hover:text-foreground' }}"
@if($currentLocale === $locale) aria-current="true" @endif>
{{ $label }}
</button>
@if (!$loop->last)
<span class="text-border">|</span>
@endif
@endforeach
</div>
<a href="{{ route('contact') }}"
class="block rounded-md px-5 py-2.5 text-sm font-medium bg-secondary hover-bg-primary glow-medium text-white transition-all duration-200 text-center">
{{ __('ui.contact') }}
</a>
</div>
</nav>
</div>
@endif
</div>
</header>