CMS: Standorte an der Marke, Seitenbaum mit Vorschau, Referenzen-Modul
Nachtrag 11: Herkunfts-Sektion liest Ort, Entfernung und Rolle aus der Markenverwaltung (drei neue Felder an cms_brands, BrandOriginSeeder), Kartenpositionen im Code, „Marken“ in der Sidebar. Nachtrag 12: Inhalte-Editor zeigt die Seiten der Website mit ihren Sektionen in Reihenfolge (config/cms_pages.php, CmsPageTree), Felder in Klartext, fehlende Sektionen aus der Sprachdatei anlegbar, Vorschau der echten Seite im iframe mit Sprung zur Sektion; Anker an allen lebenden Sektionen nachgezogen. Nachtrag 13: Referenzen als eigenes Modul (CmsReference, Portal-Seite, /referenzen mit Fallback auf die Markengalerien); Immobilien-Projekte aus Sidebar und CMS-Übersicht genommen, Route bleibt. Dazu .gitignore für _b2in_interior_shop/ und docs/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
7953a8c9a1
commit
90aa079cf7
50 changed files with 2580 additions and 324 deletions
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding flex items-center relative border-b border-border/30">
|
||||
<section id="seitenkopf" class="section-padding flex items-center relative border-b border-border/30">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 bg-[hsl(var(--hero-container))] rounded-[20px] w-[95%]">
|
||||
<div class="grid lg:grid-cols-2 gap-16 items-center">
|
||||
<div class="space-y-8 slide-right delay-200">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="{{ $bg }} text-secondary-foreground section-padding">
|
||||
<section id="cta" class="{{ $bg }} text-secondary-foreground section-padding">
|
||||
<div class="container-narrow text-center">
|
||||
<div class="spacing-section">
|
||||
<h2 class="text-section-title text-white slide-up delay-300">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{-- Livewire braucht ein Wurzelelement. Solange kein Display veröffentlicht ist, bleibt es leer –
|
||||
lieber gar keine Sektion als ein Rahmen mit ewigem Ladebalken. --}}
|
||||
<div>
|
||||
<div id="displays">
|
||||
@if ($displayId !== null)
|
||||
<section class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
@php($faqCounter = 0)
|
||||
<div x-data="{ openIndex: null }">
|
||||
<section class="section-padding {{ $bg }}">
|
||||
<section id="faq" class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
{{-- Section Title --}}
|
||||
<div class="text-center mb-16">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="py-8 bg-background border-b border-border/30">
|
||||
<section id="gruender" class="py-8 bg-background border-b border-border/30">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col sm:flex-row items-center gap-6 sm:gap-8">
|
||||
@if(isset($content['image']))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding flex items-center relative border-b border-border/30">
|
||||
<section id="hero" class="section-padding flex items-center relative border-b border-border/30">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 bg-hero-container rounded-[20px] w-[95%]">
|
||||
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||
{{-- Left Content --}}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
@if (!empty($content))
|
||||
<section class="relative h-[30vh] min-h-[220px] overflow-hidden">
|
||||
<section id="bild" class="relative h-[30vh] min-h-[220px] overflow-hidden">
|
||||
<x-web-picture
|
||||
src="{{ theme_image_url($content['image'] ?? '') }}"
|
||||
alt="{{ $content['image_alt'] ?? 'Dekoratives Bild' }}"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{-- Bewusst klein und dezent: wer gezielt sucht, findet den Weg; wer wegen Einrichtung
|
||||
kommt, wird nicht abgelenkt. Keine Preise, keine Renditeversprechen. --}}
|
||||
<section class="py-12 {{ $bg }}">
|
||||
<section id="immobilien" class="py-12 {{ $bg }}">
|
||||
<div class="container-narrow">
|
||||
<div class="border-t border-border pt-10 text-center">
|
||||
<h2 class="text-xl font-medium">{!! $content['title'] ?? '' !!}</h2>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding">
|
||||
<section id="magazin" class="section-padding">
|
||||
<div class="container-padding">
|
||||
<div class="text-center mb-16">
|
||||
<h1 class="text-hero mb-6">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding bg-secondary text-secondary-foreground">
|
||||
<section id="marken-cta" class="section-padding bg-secondary text-secondary-foreground">
|
||||
<div class="container-narrow text-center spacing-section">
|
||||
<h2 class="text-section-title text-white">{!! $content['title'] ?? '' !!}</h2>
|
||||
<p class="text-large max-w-2xl mx-auto leading-relaxed">{{ $content['text'] ?? '' }}</p>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{-- Optionaler Block laut Spec – über das CMS-Feld `enabled` abschaltbar. --}}
|
||||
@if ($content['enabled'] ?? true)
|
||||
<section class="py-16 {{ $bg }}">
|
||||
<section id="wachstum" class="py-16 {{ $bg }}">
|
||||
<div class="container-narrow text-center">
|
||||
<h2 class="text-2xl font-medium">{!! $content['title'] ?? '' !!}</h2>
|
||||
<p class="text-muted-foreground leading-relaxed mt-4">{{ $content['text'] ?? '' }}</p>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
}
|
||||
@endphp
|
||||
|
||||
<section class="section-padding {{ $bg }}">
|
||||
<section id="netzwerk" class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
<div class="container-narrow text-center">
|
||||
<h2 class="text-section-title">{!! $content['title'] ?? '' !!}</h2>
|
||||
|
|
|
|||
|
|
@ -14,9 +14,12 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Ohne gepflegten Fertigungsort bleibt nur die Überschrift und der Ablauf-Block. --}}
|
||||
@if ($this->locations !== [])
|
||||
<div class="grid lg:grid-cols-2 gap-10 lg:gap-16 items-center">
|
||||
{{-- Schematische Karte: Bielefeld als Drehscheibe, die vier Standorte als Speichen.
|
||||
Keine Geografie, nur Richtung und Entfernung. Unter md tragen die Kacheln alles. --}}
|
||||
{{-- Schematische Karte: Bielefeld als Drehscheibe, die Standorte als Speichen.
|
||||
Keine Geografie, nur Richtung und Entfernung. Positionen aus OriginSection::MAP_POSITIONS,
|
||||
eine Marke ohne Position steht nur in den Kacheln. Unter md tragen die Kacheln alles. --}}
|
||||
<div class="hidden md:block card-elevated rounded-2xl p-6 lg:p-8 slide-left delay-400">
|
||||
<svg class="origin-map" viewBox="0 0 640 400" role="img"
|
||||
aria-label="{{ $content['map_alt'] ?? '' }}">
|
||||
|
|
@ -27,10 +30,10 @@
|
|||
@endif
|
||||
|
||||
@foreach ($this->locations as $index => $location)
|
||||
@continue(empty($location['map']))
|
||||
@php
|
||||
$x = (int) ($location['x'] ?? 0);
|
||||
$y = (int) ($location['y'] ?? 0);
|
||||
$left = ($location['label'] ?? 'right') === 'left';
|
||||
$x = $location['map']['x'];
|
||||
$y = $location['map']['y'];
|
||||
$midX = (int) round(($hubX + $x) / 2);
|
||||
$midY = (int) round(($hubY + $y) / 2);
|
||||
@endphp
|
||||
|
|
@ -41,10 +44,11 @@
|
|||
@endforeach
|
||||
|
||||
@foreach ($this->locations as $index => $location)
|
||||
@continue(empty($location['map']))
|
||||
@php
|
||||
$x = (int) ($location['x'] ?? 0);
|
||||
$y = (int) ($location['y'] ?? 0);
|
||||
$left = ($location['label'] ?? 'right') === 'left';
|
||||
$x = $location['map']['x'];
|
||||
$y = $location['map']['y'];
|
||||
$left = $location['map']['label'] === 'left';
|
||||
$labelX = $left ? $x - 14 : $x + 14;
|
||||
@endphp
|
||||
<circle class="origin-map-dot" cx="{{ $x }}" cy="{{ $y }}" r="7" />
|
||||
|
|
@ -63,10 +67,10 @@
|
|||
</svg>
|
||||
</div>
|
||||
|
||||
{{-- Die vier Standorte --}}
|
||||
{{-- Eine Kachel je Marke mit Fertigungsort --}}
|
||||
<div class="grid sm:grid-cols-2 gap-6 slide-right delay-400">
|
||||
@foreach ($this->locations as $index => $location)
|
||||
<div class="card-elevated rounded-2xl p-6 flex flex-col gap-2" wire:key="origin-{{ $index }}">
|
||||
@foreach ($this->locations as $location)
|
||||
<div class="card-elevated rounded-2xl p-6 flex flex-col gap-2" wire:key="origin-{{ $location['slug'] }}">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-secondary">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"
|
||||
aria-hidden="true">
|
||||
|
|
@ -84,9 +88,9 @@
|
|||
@if (!empty($location['distance']))
|
||||
<span class="text-clay">{{ $location['distance'] }} {{ $content['distance_suffix'] ?? '' }}</span>
|
||||
@endif
|
||||
@if (!empty($location['link']) && !empty($location['link_text']))
|
||||
@if (!empty($location['link']) && !empty($content['link_text']))
|
||||
<a href="{{ $location['link'] }}" class="font-medium text-primary hover:text-secondary transition-colors">
|
||||
{{ $location['link_text'] }}
|
||||
{{ $content['link_text'] }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -94,6 +98,7 @@
|
|||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Gefertigt oder vertrieben? Der Weg eines Maßmöbels am Beispiel CABINET. --}}
|
||||
@if ($steps !== [])
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding">
|
||||
<section id="geschichte" class="section-padding">
|
||||
<div class="container-padding text-center">
|
||||
<div class="text-center mb-16 slide-up delay-200">
|
||||
<h2 class="text-section-title text-foreground mb-12">
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function renderHeroIcon($iconName, $style = 'outline') {
|
|||
}
|
||||
}
|
||||
@endphp
|
||||
<section class="section-padding bg-accent">
|
||||
<section id="werte" class="section-padding bg-accent">
|
||||
<div class="container-padding">
|
||||
<div class="text-center mb-16 slide-up delay-300">
|
||||
<h2 class="text-section-title">{!! $content['title'] !!}</h2>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{-- Seitenkopf für Unterseiten – abgesetzte graue Fläche wie der Hero auf Startseite und
|
||||
Netzwerkseite, damit er sich klar von den Blöcken darunter absetzt. --}}
|
||||
<section class="section-padding flex items-center relative border-b border-border/30 {{ $bg }}">
|
||||
<section id="seitenkopf" class="section-padding flex items-center relative border-b border-border/30 {{ $bg }}">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 lg:py-20 bg-hero-container rounded-[20px] w-[95%]">
|
||||
{{-- Breadcrumb: Home → Marken --}}
|
||||
<nav aria-label="Breadcrumb" class="mb-8">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="{{ $bg }} text-secondary-foreground section-padding">
|
||||
<section id="cta" class="{{ $bg }} text-secondary-foreground section-padding">
|
||||
<div class="container-narrow text-center">
|
||||
<div class="spacing-section">
|
||||
<h2 class="text-section-title text-white slide-up delay-300">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding {{ $bg }}">
|
||||
<section id="projekte" class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
<div class="text-center max-w-2xl mx-auto">
|
||||
<h2 class="text-section-title">{!! $content['title'] ?? '' !!}</h2>
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<figure class="card-elevated rounded-2xl overflow-hidden group" wire:key="ref-{{ $project['key'] }}">
|
||||
<div class="relative overflow-hidden">
|
||||
<img src="{{ theme_image_url($project['image']) }}"
|
||||
alt="{{ $project['caption'] ?: $project['brand'] }}" loading="lazy"
|
||||
alt="{{ $project['caption'] ?: ($project['brands'][0]['name'] ?? '') }}" loading="lazy"
|
||||
class="w-full aspect-[4/3] object-cover transition-transform duration-300 group-hover:scale-105" />
|
||||
<span class="absolute top-3 left-3 rounded-full bg-black/60 px-3 py-1 text-xs font-medium text-white backdrop-blur-sm">
|
||||
{{ __('ui.brand_gallery_badge_project') }}
|
||||
|
|
@ -23,13 +23,32 @@
|
|||
@if (!empty($project['caption']))
|
||||
<p class="font-medium">{{ $project['caption'] }}</p>
|
||||
@endif
|
||||
@if ($project['has_detail_page'])
|
||||
<a href="{{ route('marken.show', ['slug' => $project['brand_slug']]) }}"
|
||||
class="text-sm text-secondary underline underline-offset-2 hover:no-underline mt-1 inline-block">
|
||||
{{ $project['brand'] }}
|
||||
</a>
|
||||
@else
|
||||
<p class="text-sm text-muted-foreground mt-1">{{ $project['brand'] }}</p>
|
||||
@if (!empty($project['meta']))
|
||||
<p class="text-xs uppercase tracking-wider text-clay mt-1">{{ $project['meta'] }}</p>
|
||||
@endif
|
||||
@if (!empty($project['description']))
|
||||
<p class="text-sm text-muted-foreground leading-relaxed mt-2">{{ $project['description'] }}</p>
|
||||
@endif
|
||||
@if (!empty($project['gallery']))
|
||||
{{-- Weitere Bilder der Referenz als kleine Reihe --}}
|
||||
<div class="flex gap-2 mt-3 overflow-x-auto">
|
||||
@foreach ($project['gallery'] as $item)
|
||||
<img src="{{ theme_image_url($item['image']) }}" alt="{{ $item['caption'] ?: $project['caption'] }}"
|
||||
loading="lazy" class="h-14 w-20 shrink-0 rounded-md object-cover" />
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@if (!empty($project['brands']))
|
||||
<p class="text-sm mt-2 flex flex-wrap gap-x-3 gap-y-1">
|
||||
@foreach ($project['brands'] as $brand)
|
||||
@if (!empty($brand['link']))
|
||||
<a href="{{ $brand['link'] }}"
|
||||
class="text-secondary underline underline-offset-2 hover:no-underline">{{ $brand['name'] }}</a>
|
||||
@else
|
||||
<span class="text-muted-foreground">{{ $brand['name'] }}</span>
|
||||
@endif
|
||||
@endforeach
|
||||
</p>
|
||||
@endif
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding {{ $bg }}">
|
||||
<section id="engagement" class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
<div class="text-center mb-12 slide-up delay-300">
|
||||
<h2 class="text-section-title">{!! $content['title'] ?? '' !!}</h2>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<section class="section-padding {{ $bg }}">
|
||||
<section id="vision" class="section-padding {{ $bg }}">
|
||||
<div class="container-padding">
|
||||
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<div>
|
||||
<!-- Hero Section with Contact Form -->
|
||||
<section class="py-10 flex items-center relative overflow-hidden">
|
||||
<section id="kontakt" class="py-10 flex items-center relative overflow-hidden">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 bg-[hsl(var(--hero-container))] rounded-[20px] w-[95%]">
|
||||
<div class="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<!-- Left Side - Hero Text -->
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Immobilien dunkel mit negativem Logo (Tokens `--footer-*` in theme-b2in.css, Logo in mount()).
|
||||
pb-28 auf kleinen Schirmen: darunter schwebt das Terminanfrage-Widget, das sonst die
|
||||
letzten Zeilen des Footers verdecken wuerde. --}}
|
||||
<footer class="section-footer section-padding pb-28 sm:pb-16">
|
||||
<footer id="footer" class="section-footer section-padding pb-28 sm:pb-16">
|
||||
<div class="container-padding">
|
||||
{{-- Main Content --}}
|
||||
<div class="text-center spacing-section">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue