b2in/app/Livewire/Web/Components/Sections/OriginSection.php
Kevin Adametz 90aa079cf7 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>
2026-09-15 14:58:45 +00:00

83 lines
2.8 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;
/**
* „Aus der Region gefertigt“: die Standorte der Kernmarken rund um Bielefeld
* (Arbeitsplan 14.09.2026, Punkt 1.3, Nachtrag 11).
*
* Überschrift, Karte, Drehscheibe und Ablauf-Block kommen aus dem CMS (Fallback Lang-Datei).
* Die Standorte kommen aus den veröffentlichten Marken: Ort, Entfernung und Rolle pflegt
* Marcel in der Markenverwaltung. Die Positionen in der schematischen Karte gehören zur
* Zeichnung und bleiben hier im Code.
*/
class OriginSection extends Component
{
/**
* Position je Marke in der Karte (viewBox 640×400) und Seite der Beschriftung.
*
* Eine Marke ohne Eintrag erscheint in den Kacheln, aber nicht in der Karte.
*
* @var array<string, array{x: int, y: int, label: string}>
*/
public const MAP_POSITIONS = [
'rotpunkt' => ['x' => 330, 'y' => 55, 'label' => 'left'],
'februe' => ['x' => 480, 'y' => 90, 'label' => 'right'],
'tischlerei' => ['x' => 295, 'y' => 285, 'label' => 'left'],
'cabinet' => ['x' => 80, 'y' => 345, 'label' => 'right'],
];
/** @var array<string, mixed> */
public array $content = [];
public string $bg = '';
public function mount(string $bg = ''): void
{
$section = cms_theme_section('origin_section');
$this->content = is_array($section) ? $section : [];
$this->bg = $bg;
}
/**
* Veröffentlichte Marken mit gepflegtem Fertigungsort, in der Reihenfolge der Marken.
*
* Eine unveröffentlichte Marke fällt heraus, eine Marke ohne Ort ebenfalls. Der Link zur
* Markenseite hängt daran, ob die Marke eine Detailseite hat (Lang-Fallback: keine).
*
* @return list<array{slug: string, city: string, brand: string, role: string, distance: string, link: ?string, map: ?array{x: int, y: int, label: string}}>
*/
public function getLocationsProperty(): array
{
$out = [];
foreach (CmsBrand::forFrontend() as $slug => $brand) {
$city = trim((string) ($brand['origin_city'] ?? ''));
$name = trim((string) ($brand['name'] ?? ''));
if ($city === '' || $name === '') {
continue;
}
$out[] = [
'slug' => (string) $slug,
'city' => $city,
'brand' => $name,
'role' => trim((string) ($brand['origin_role'] ?? '')),
'distance' => trim((string) ($brand['origin_distance'] ?? '')),
'link' => ! empty($brand['has_detail_page']) ? '/marken/'.$slug : null,
'map' => self::MAP_POSITIONS[$slug] ?? null,
];
}
return $out;
}
public function render()
{
return view('livewire.web.components.sections.origin-section');
}
}