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>
113 lines
3.5 KiB
PHP
113 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Web\Components\Sections;
|
|
|
|
use App\Models\CmsBrand;
|
|
use App\Models\CmsReference;
|
|
use Livewire\Component;
|
|
|
|
/**
|
|
* Realisierte Projekte auf /referenzen.
|
|
*
|
|
* Seit Nachtrag 13 pflegt Marcel Referenzen als eigene Einträge im Portal (Titelbild, weitere
|
|
* Bilder, beteiligte Marken). Solange dort nichts veröffentlicht ist, greift der Stand aus AP5:
|
|
* die als „Realisiertes Projekt“ markierten Bilder aus den Markengalerien, über alle Marken
|
|
* hinweg gesammelt. Visualisierungen und Entwürfe bleiben in beiden Fällen draußen.
|
|
*/
|
|
class ReferenceProjects extends Component
|
|
{
|
|
/** @var array<string, mixed> */
|
|
public array $content = [];
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $projects = [];
|
|
|
|
public string $bg = '';
|
|
|
|
public int $limit = 0;
|
|
|
|
public function mount(string $bg = '', int $limit = 0): void
|
|
{
|
|
$section = cms_theme_section('reference_projects');
|
|
$this->content = is_array($section) ? $section : [];
|
|
$this->bg = $bg;
|
|
$this->limit = $limit;
|
|
|
|
$projects = $this->fromReferences();
|
|
|
|
if ($projects === []) {
|
|
$projects = $this->fromBrandGalleries();
|
|
}
|
|
|
|
$this->projects = $this->limit > 0 ? array_slice($projects, 0, $this->limit) : $projects;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
private function fromReferences(): array
|
|
{
|
|
$references = CmsReference::query()->published()->ordered()->get();
|
|
|
|
if ($references->isEmpty()) {
|
|
return [];
|
|
}
|
|
|
|
$brands = CmsBrand::forFrontend();
|
|
$projects = [];
|
|
|
|
foreach ($references as $reference) {
|
|
$gallery = CmsReference::normalizeGallery($reference->gallery);
|
|
$image = (string) ($reference->image ?: ($gallery[0]['image'] ?? ''));
|
|
|
|
if ($image === '') {
|
|
continue;
|
|
}
|
|
|
|
$projects[] = [
|
|
'key' => 'ref-'.$reference->id,
|
|
'image' => $image,
|
|
'caption' => (string) $reference->title,
|
|
'meta' => implode(' · ', array_filter([$reference->location, $reference->year])),
|
|
'description' => (string) $reference->description,
|
|
'gallery' => array_values(array_filter($gallery, fn (array $item) => $item['image'] !== $image)),
|
|
'brands' => $reference->resolveBrands($brands),
|
|
];
|
|
}
|
|
|
|
return $projects;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
private function fromBrandGalleries(): array
|
|
{
|
|
$projects = [];
|
|
|
|
foreach (CmsBrand::forFrontend() as $slug => $brand) {
|
|
foreach (CmsBrand::groupGallery($brand['gallery'] ?? [])['projects'] as $index => $item) {
|
|
$projects[] = [
|
|
'key' => $slug.'-'.$index,
|
|
'image' => $item['image'],
|
|
'caption' => $item['caption'],
|
|
'meta' => '',
|
|
'description' => '',
|
|
'gallery' => [],
|
|
'brands' => [[
|
|
'slug' => $slug,
|
|
'name' => (string) ($brand['name'] ?? ''),
|
|
'link' => ! empty($brand['has_detail_page']) ? '/marken/'.$slug : null,
|
|
]],
|
|
];
|
|
}
|
|
}
|
|
|
|
return $projects;
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.web.components.sections.reference-projects');
|
|
}
|
|
}
|