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
87
database/seeders/BrandOriginSeeder.php
Normal file
87
database/seeders/BrandOriginSeeder.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\CmsBrand;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* Trägt den Fertigungsort der Kernmarken nach (Nachtrag 11 zu Arbeitsplan 14.09.2026, Punkt 1.3).
|
||||
*
|
||||
* Die Herkunfts-Sektion „Aus der Region gefertigt“ liest Ort, Entfernung und Rolle aus der
|
||||
* Marke. {@see CmsBrandSeeder} bringt dieselben Werte für frische Installationen mit,
|
||||
* überspringt aber bereits angelegte Marken. Dieser Seeder fasst nur die drei Felder an und
|
||||
* auch nur bei Marken, deren Fertigungsort noch leer ist – ein im Admin eingetragener Ort
|
||||
* bleibt stehen. Mehrfaches Ausführen ist unbedenklich.
|
||||
*
|
||||
* Entfernungen gerundet, Straße ab Bielefeld Mitte. ⚠️ Rolle CABINET nach Kevins Verständnis
|
||||
* (Fertigung Köln, Beratung im Store Bielefeld) – von Marcel bestätigen lassen.
|
||||
*
|
||||
* php artisan db:seed --class=BrandOriginSeeder
|
||||
*/
|
||||
class BrandOriginSeeder extends Seeder
|
||||
{
|
||||
/** @var array<string, array{origin_city: array<string, string>, origin_distance: array<string, string>, origin_role: array<string, string>}> */
|
||||
private const ORIGINS = [
|
||||
'cabinet' => [
|
||||
'origin_city' => ['de' => 'Köln', 'en' => 'Cologne'],
|
||||
'origin_distance' => ['de' => 'rund 200 km', 'en' => 'about 200 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Gefertigt in der Kölner Manufaktur, beraten und geplant im CABINET Store Bielefeld.',
|
||||
'en' => 'Made in the Cologne manufactory, advised and planned at the CABINET Store Bielefeld.',
|
||||
],
|
||||
],
|
||||
'rotpunkt' => [
|
||||
'origin_city' => ['de' => 'Bünde', 'en' => 'Bünde'],
|
||||
'origin_distance' => ['de' => 'rund 30 km', 'en' => 'about 30 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Küchen aus eigener Fertigung in Bünde – geplant bei uns im Küchenstudio.',
|
||||
'en' => 'Kitchens from their own production in Bünde – planned with us in the kitchen studio.',
|
||||
],
|
||||
],
|
||||
'februe' => [
|
||||
'origin_city' => ['de' => 'Herford', 'en' => 'Herford'],
|
||||
'origin_distance' => ['de' => 'rund 20 km', 'en' => 'about 20 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Büro- und Objektmöbel aus eigener Fertigung in Herford.',
|
||||
'en' => 'Office and contract furniture from their own production in Herford.',
|
||||
],
|
||||
],
|
||||
'tischlerei' => [
|
||||
'origin_city' => ['de' => 'Rheda-Wiedenbrück', 'en' => 'Rheda-Wiedenbrück'],
|
||||
'origin_distance' => ['de' => 'rund 35 km', 'en' => 'about 35 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Unsere Werkstatt für Aufbau, Sonderlösungen und Veredelung.',
|
||||
'en' => 'Our workshop for assembly, custom solutions and finishing.',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$set = 0;
|
||||
$kept = 0;
|
||||
|
||||
foreach (self::ORIGINS as $slug => $origin) {
|
||||
$brand = CmsBrand::query()->where('slug', $slug)->first();
|
||||
|
||||
if (! $brand) {
|
||||
$this->command?->warn("Marke „{$slug}“ nicht gefunden – übersprungen.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trim((string) $brand->getTranslation('origin_city', 'de', false)) !== '') {
|
||||
$kept++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$brand->fill($origin);
|
||||
$brand->save();
|
||||
$set++;
|
||||
}
|
||||
|
||||
$this->command?->info("Fertigungsorte gesetzt: {$set}, vorhandene behalten: {$kept}.");
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,8 @@ use Illuminate\Database\Seeder;
|
|||
* Partnerbetriebs gehört laut Plan auf die Detailseite, nicht in die Marke.
|
||||
*
|
||||
* Bestehende Marken werden nicht überschrieben – Marcel pflegt sie im Admin. Für bereits
|
||||
* angelegte Marken setzt {@see BrandLogoSeeder} die Logos nach.
|
||||
* angelegte Marken setzt {@see BrandLogoSeeder} die Logos nach und {@see BrandOriginSeeder}
|
||||
* den Fertigungsort für die Herkunfts-Sektion (Nachtrag 11).
|
||||
*
|
||||
* Stimmungsbilder und Galerien fehlen als Zulieferung und bleiben leer; die Kacheln und
|
||||
* Detailseiten zeigen so lange einen Platzhalter.
|
||||
|
|
@ -77,6 +78,12 @@ Experience the possibilities in our Bielefeld showroom.',
|
|||
['title' => 'Montage durch Fachleute', 'description' => 'Wir liefern und montieren – bis zum letzten Detail.'],
|
||||
],
|
||||
'showroom' => 'Showroom Bielefeld',
|
||||
'origin_city' => ['de' => 'Köln', 'en' => 'Cologne'],
|
||||
'origin_distance' => ['de' => 'rund 200 km', 'en' => 'about 200 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Gefertigt in der Kölner Manufaktur, beraten und geplant im CABINET Store Bielefeld.',
|
||||
'en' => 'Made in the Cologne manufactory, advised and planned at the CABINET Store Bielefeld.',
|
||||
],
|
||||
'is_published' => true,
|
||||
],
|
||||
[
|
||||
|
|
@ -112,6 +119,12 @@ Consultation and planning in our kitchen studio.',
|
|||
['title' => 'Lieferung und Aufbau', 'description' => 'Koordiniert aus einer Hand, inklusive Anschluss.'],
|
||||
],
|
||||
'showroom' => 'Küchenstudio',
|
||||
'origin_city' => ['de' => 'Bünde', 'en' => 'Bünde'],
|
||||
'origin_distance' => ['de' => 'rund 30 km', 'en' => 'about 30 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Küchen aus eigener Fertigung in Bünde – geplant bei uns im Küchenstudio.',
|
||||
'en' => 'Kitchens from their own production in Bünde – planned with us in the kitchen studio.',
|
||||
],
|
||||
'is_published' => true,
|
||||
],
|
||||
[
|
||||
|
|
@ -143,6 +156,12 @@ Consultation and planning in our kitchen studio.',
|
|||
['title' => 'Akustik und Ordnung', 'description' => 'Stauraum und Raumgliederung, die Konzentration ermöglichen.'],
|
||||
],
|
||||
'showroom' => '',
|
||||
'origin_city' => ['de' => 'Herford', 'en' => 'Herford'],
|
||||
'origin_distance' => ['de' => 'rund 20 km', 'en' => 'about 20 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Büro- und Objektmöbel aus eigener Fertigung in Herford.',
|
||||
'en' => 'Office and contract furniture from their own production in Herford.',
|
||||
],
|
||||
'is_published' => true,
|
||||
],
|
||||
[
|
||||
|
|
@ -223,6 +242,12 @@ It complements CABINET and Rotpunkt wherever making to drawing is required: asse
|
|||
],
|
||||
],
|
||||
'showroom' => '',
|
||||
'origin_city' => ['de' => 'Rheda-Wiedenbrück', 'en' => 'Rheda-Wiedenbrück'],
|
||||
'origin_distance' => ['de' => 'rund 35 km', 'en' => 'about 35 km'],
|
||||
'origin_role' => [
|
||||
'de' => 'Unsere Werkstatt für Aufbau, Sonderlösungen und Veredelung.',
|
||||
'en' => 'Our workshop for assembly, custom solutions and finishing.',
|
||||
],
|
||||
'is_published' => true,
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -2,13 +2,21 @@
|
|||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use FluxCms\Core\Models\CmsContent;
|
||||
use FluxCms\Core\Services\CmsContentService;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* Herkunfts-Sektion „Aus der Region gefertigt“ ins CMS legen (Arbeitsplan 14.09.2026, Punkt 1.3).
|
||||
*
|
||||
* Legt die Sektion nur an, wenn sie fehlt. Ein bestehender Eintrag bleibt unangetastet,
|
||||
* damit Korrekturen aus dem Admin (Entfernungen, Ablauf CABINET) nicht verloren gehen.
|
||||
* Legt die Sektion nur an, wenn sie fehlt. Ein bestehender Eintrag bleibt inhaltlich unangetastet,
|
||||
* damit Korrekturen aus dem Admin (Ablauf CABINET) nicht verloren gehen.
|
||||
*
|
||||
* Einzige Ausnahme (Nachtrag 11): Der Schlüssel `locations` stammt aus dem ersten Stand, als die
|
||||
* Standorte noch im Sektions-JSON lagen. Seitdem kommen sie aus den Marken
|
||||
* ({@see BrandOriginSeeder}), das Frontend liest den Schlüssel nicht mehr. Er wird aus einem
|
||||
* bestehenden Eintrag entfernt, damit er im Inhalte-Editor nicht als Pflegefeld auftaucht.
|
||||
* Mehrfaches Ausführen ist unbedenklich.
|
||||
*
|
||||
* php artisan db:seed --class=OriginSectionCmsSeeder
|
||||
*/
|
||||
|
|
@ -24,6 +32,38 @@ class OriginSectionCmsSeeder extends Seeder
|
|||
$seeder->onlySections = self::SECTIONS;
|
||||
$seeder->run();
|
||||
|
||||
$this->dropLegacyLocations();
|
||||
|
||||
$this->command?->info('Herkunfts-Sektion: angelegt, falls sie fehlte.');
|
||||
}
|
||||
|
||||
private function dropLegacyLocations(): void
|
||||
{
|
||||
$row = CmsContent::query()->where('group', 'home')->where('key', 'origin_section')->first();
|
||||
|
||||
if (! $row) {
|
||||
return;
|
||||
}
|
||||
|
||||
$value = $row->getTranslations('value');
|
||||
$changed = false;
|
||||
|
||||
foreach ($value as $locale => $section) {
|
||||
if (is_array($section) && array_key_exists('locations', $section)) {
|
||||
unset($section['locations']);
|
||||
$value[$locale] = $section;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! $changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
$row->value = $value;
|
||||
$row->save();
|
||||
app(CmsContentService::class)->clearCache('home');
|
||||
|
||||
$this->command?->info('Herkunfts-Sektion: veralteten Schlüssel „locations“ entfernt – die Standorte kommen aus den Marken.');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue