From c8899e2d7d1f9a58feaefb32d87774f1ddfc1658 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Thu, 3 Sep 2026 11:16:41 +0000 Subject: [PATCH] Markenlogos einbinden: Seitenkopf und alle Kacheln MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zulieferung dev/2026-08-28/markenlogos/ (CABINET und Rotpunkt als SVG, Februe als PNG). Die Dateien liegen unter public/img/assets/marken/ und haengen als `logo` an der jeweiligen Marke. - Kopf der Markenseite: Logo anstelle des Schriftzugs, im

, damit die Ueberschrift erhalten bleibt – den Text liefert das alt-Attribut. Ohne Logo erscheint weiterhin der Schriftzug. - Logo zusaetzlich auf der Startseiten-Kachel, im Block auf /marken und in den „Weitere Marken“-Kacheln am Seitenfuss. - Feste Box (Hoehe + Maximalbreite + object-contain) statt fester Hoehe: die Seitenverhaeltnisse gehen weit auseinander (Februe 2,3:1, Rotpunkt 1,2:1), mit reiner Hoehenangabe waere Februe doppelt so breit erschienen. Konvention aus der Sponsoring-Sektion. - Februe-Logo auf seinen Inhalt beschnitten: im Original waren knapp drei Viertel der Flaeche leerer Rand, in einer Box haette es winzig gewirkt. 53 KB → 15 KB. - BrandLogoSeeder traegt die Logos auf bestehenden Installationen nach – CmsBrandSeeder ueberspringt vorhandene Marken. Setzt nur `logo` und nur bei leerem Feld, ein im Admin hochgeladenes Logo bleibt stehen. Tests: 871 gruen (3215 Assertions), Pint sauber, alle Themes gebaut. Co-Authored-By: Claude Opus 5 --- database/seeders/BrandLogoSeeder.php | 59 +++++++++++++++++ database/seeders/CmsBrandSeeder.php | 11 +++- dev/2026-08-28/deploy/dateiliste.txt | 4 ++ dev/2026-08-28/entwicklungsplan.md | 47 ++++++++++++-- dev/2026-08-28/preview-deployment.md | 3 + public/img/assets/marken/cabinet.svg | 27 ++++++++ public/img/assets/marken/februe.png | Bin 0 -> 15359 bytes public/img/assets/marken/rotpunkt.svg | 55 ++++++++++++++++ .../sections/brand-detail.blade.php | 20 ++++-- .../sections/brand-overview.blade.php | 4 +- .../components/sections/core-brands.blade.php | 4 +- tests/Feature/BrandPageTest.php | 61 ++++++++++++++++++ 12 files changed, 282 insertions(+), 13 deletions(-) create mode 100644 database/seeders/BrandLogoSeeder.php create mode 100644 public/img/assets/marken/cabinet.svg create mode 100644 public/img/assets/marken/februe.png create mode 100644 public/img/assets/marken/rotpunkt.svg diff --git a/database/seeders/BrandLogoSeeder.php b/database/seeders/BrandLogoSeeder.php new file mode 100644 index 00000000..40ec4394 --- /dev/null +++ b/database/seeders/BrandLogoSeeder.php @@ -0,0 +1,59 @@ + */ + private const LOGOS = [ + 'cabinet' => 'marken/cabinet.svg', + 'rotpunkt' => 'marken/rotpunkt.svg', + 'februe' => 'marken/februe.png', + ]; + + public function run(): void + { + $set = 0; + $kept = 0; + + foreach (self::LOGOS as $slug => $logo) { + $brand = CmsBrand::query()->where('slug', $slug)->first(); + + if (! $brand) { + $this->command?->warn("Marke „{$slug}“ nicht gefunden – uebersprungen."); + + continue; + } + + if (trim((string) $brand->logo) !== '') { + $kept++; + + continue; + } + + $brand->logo = $logo; + $brand->save(); + $set++; + } + + $this->command?->info("Markenlogos gesetzt: {$set}, vorhandene behalten: {$kept}."); + } +} diff --git a/database/seeders/CmsBrandSeeder.php b/database/seeders/CmsBrandSeeder.php index 3f669530..57df1e2a 100644 --- a/database/seeders/CmsBrandSeeder.php +++ b/database/seeders/CmsBrandSeeder.php @@ -8,9 +8,11 @@ use Illuminate\Database\Seeder; /** * Legt die drei Kernmarken an. Texte aus dev/2026-08-28/umsetzung-inhalte.md §5. * - * Bestehende Marken werden nicht überschrieben – Marcel pflegt sie im Admin. - * Logos, Stimmungsbilder und Galerien fehlen als Zulieferung und bleiben leer; - * die Kacheln und Detailseiten zeigen so lange einen Platzhalter. + * Bestehende Marken werden nicht überschrieben – Marcel pflegt sie im Admin. Für bereits + * angelegte Marken setzt {@see BrandLogoSeeder} die Logos nach. + * + * Stimmungsbilder und Galerien fehlen als Zulieferung und bleiben leer; die Kacheln und + * Detailseiten zeigen so lange einen Platzhalter. */ class CmsBrandSeeder extends Seeder { @@ -38,6 +40,7 @@ class CmsBrandSeeder extends Seeder return [ [ 'slug' => 'cabinet', + 'logo' => 'marken/cabinet.svg', 'name' => ['de' => 'CABINET', 'en' => 'CABINET'], 'tagline' => ['de' => 'Einbauschränke nach Maß.', 'en' => 'Fitted wardrobes made to measure.'], 'teaser' => [ @@ -72,6 +75,7 @@ Experience the possibilities in our Bielefeld showroom.', ], [ 'slug' => 'rotpunkt', + 'logo' => 'marken/rotpunkt.svg', 'name' => ['de' => 'Rotpunkt Küchen', 'en' => 'Rotpunkt Küchen'], 'tagline' => ['de' => 'Küchen, die Haltung zeigen.', 'en' => 'Kitchens with character.'], 'teaser' => [ @@ -106,6 +110,7 @@ Consultation and planning in our kitchen studio.', ], [ 'slug' => 'februe', + 'logo' => 'marken/februe.png', 'name' => ['de' => 'Febrü', 'en' => 'Febrü'], 'tagline' => ['de' => 'Arbeiten, wo man gerne bleibt.', 'en' => 'Work where you like to stay.'], 'teaser' => [ diff --git a/dev/2026-08-28/deploy/dateiliste.txt b/dev/2026-08-28/deploy/dateiliste.txt index d1dcba5d..3a1a29b9 100644 --- a/dev/2026-08-28/deploy/dateiliste.txt +++ b/dev/2026-08-28/deploy/dateiliste.txt @@ -33,6 +33,7 @@ database/migrations/2026_08_28_110407_create_cms_brands_table.php database/migrations/2026_08_28_112244_add_summary_and_highlights_to_cms_brands_table.php database/migrations/2026_09_03_084254_add_page_sections_to_cms_brands_table.php database/seeders/BrandGalleryCaptionNormalizerSeeder.php +database/seeders/BrandLogoSeeder.php database/seeders/BrandPageTextSeeder.php database/seeders/CmsArticleSeeder.php database/seeders/CmsBrandSeeder.php @@ -45,6 +46,9 @@ database/seeders/InteriorRelaunchCmsSeeder.php public/_cabinet/assets/b2in-interior-logo-negative.svg public/_cabinet/assets/b2in-interior-logo-positive.svg public/_cabinet/display/index.html +public/img/assets/marken/cabinet.svg +public/img/assets/marken/februe.png +public/img/assets/marken/rotpunkt.svg public/img/assets/sponsoring/arminia-bielefeld.png public/img/assets/sponsoring/tc-bad-waldliesborn-horn.jpg public/img/assets/sponsoring/tc-hoevelhof.png diff --git a/dev/2026-08-28/entwicklungsplan.md b/dev/2026-08-28/entwicklungsplan.md index 8e2e4ce1..7e77a9b1 100644 --- a/dev/2026-08-28/entwicklungsplan.md +++ b/dev/2026-08-28/entwicklungsplan.md @@ -19,7 +19,7 @@ eingearbeitet. Offen: Bildmaterial, Rechtstexte und die Herstellerfreigaben. **Stand 03.09.2026:** T1 und B1–B13 abgearbeitet, **alle Arbeitspakete AP0–AP6 umgesetzt**, die Bestandsinhalte auf den Interior-Auftritt umgestellt, die Seite abgestimmt und alle vier Punkte der Abstimmungsrunde vom 03.09. umgesetzt (Nachtrag 5). Alle drei Markenseiten haben jetzt einen -ausführlichen Text. `php artisan test --compact`: **863 grün** (3194 Assertions), Pint sauber, +ausführlichen Text. `php artisan test --compact`: **871 grün** (3215 Assertions), Pint sauber, `npm run build:b2in` gebaut. **Die Seite ist testbereit** – die ausstehenden Zulieferungen trägt Marcel selbst im CMS nach. @@ -45,7 +45,7 @@ gebaut. Was fehlt, ist Material, kein Code. | Was | Wo im Admin | |---|---| -| Logos und Stimmungsbilder der drei Marken | Kernmarken → Marke bearbeiten | +| Stimmungsbilder der drei Marken (Logos liegen seit 03.09. vor) | Kernmarken → Marke bearbeiten | | Echte Projektfotos statt der Demobilder (siehe Warnung unten) | Kernmarken → Bildergalerie | | Herstellerseiten-URLs | Kernmarken → Herstellerseite | | Motiv für den Kopf von `/marken` | Inhalte → `marken` → `hero` | @@ -1026,6 +1026,36 @@ diese Lösung kommt ohne neue Abhängigkeit aus. Betrifft **beide** Akkordeons – die Vertiefungen auf den Markenseiten und das FAQ; sie hatten dasselbe Verhalten. +#### 6 · Markenlogos (Zulieferung 03.09.2026) + +Grundlage: `dev/2026-08-28/markenlogos/` – CABINET und Rotpunkt als SVG, Febrü als PNG. Sie +liegen jetzt unter `public/img/assets/marken/` und hängen als `logo` an der jeweiligen Marke. + +| Wo | Vorher | Jetzt | +|---|---|---| +| Kopf der Markenseite | Schriftzug als `

` | Logo **anstelle** des Schriftzugs, im `

` | +| Kachel auf der Startseite | ohne Logo | Logo über Name und Claim | +| Block auf `/marken` | ohne Logo | Logo über Name und Claim | +| „Weitere Marken" am Seitenfuß | ohne Logo | Logo über Name und Claim | + +Das Logo sitzt **im** `

`, nicht daneben: So bleibt die Seitenüberschrift erhalten, den Text +liefert das `alt`-Attribut. Fehlt ein Logo, erscheint weiterhin der Schriftzug – ein Test hält +beide Wege fest. + +**Feste Box statt fester Höhe.** Die drei Logos haben sehr unterschiedliche Seitenverhältnisse +(Febrü 2,3:1, Rotpunkt 1,2:1). Mit einer reinen Höhenangabe hätte Febrü doppelt so breit gewirkt +wie Rotpunkt. Jedes Logo bekommt deshalb Höhe **und** Maximalbreite plus `object-contain` – die +Konvention aus der Sponsoring-Sektion. + +**Am Febrü-Logo nachgearbeitet:** Im Original waren knapp drei Viertel der Bildfläche leerer +Rand (Inhalt 570 × 238 in 3084 × 1948). In einer Box hätte es dadurch winzig gewirkt. Es ist auf +seinen Inhalt beschnitten und auf 760 px Breite gerechnet – 53 KB → 15 KB. + +**Nachziehen auf bestehenden Installationen:** `CmsBrandSeeder` überspringt vorhandene Marken, +trägt die Logos also nur bei einer frischen Installation ein. `BrandLogoSeeder` **(neu)** setzt +sie auf bereits angelegten Marken nach – nur das Feld `logo` und nur, wenn es leer ist. Ein +selbst hochgeladenes Logo bleibt damit stehen; mehrfaches Ausführen ist unbedenklich. + #### Tests `BrandPageSectionsTest` und `BrandPageTest` erweitert: @@ -1045,8 +1075,12 @@ dasselbe Verhalten. - Weder Markenseite noch FAQ verwenden noch den Flächen-Hover. - Der Abschlussblock trägt das Verlaufsband; die weichen Kreise sind weg. - Die Ausnahme für `.variante-glass-flow` ist vorhanden – ohne sie steht der Abschluss hellgrau da. +- Das Logo steht im `

` der Markenseite; ohne Logo erscheint weiter der Schriftzug. +- Alle drei Logos erscheinen auf Startseite, `/marken` und den „Weitere Marken"-Kacheln. +- Die Dateien, auf die der Seeder zeigt, liegen tatsächlich unter `public/`. +- `BrandLogoSeeder` überschreibt kein selbst hochgeladenes Logo. -`php artisan test --compact`: **863 grün** (3194 Assertions), Pint sauber, `npm run build:b2in` +`php artisan test --compact`: **871 grün** (3215 Assertions), Pint sauber, `npm run build:b2in` gebaut. --- @@ -1182,6 +1216,10 @@ php artisan db:seed --class=BrandPageTextSeeder --force # Fasst nur den Text an, mehrfaches Ausführen ist unbedenklich. php artisan db:seed --class=BrandGalleryCaptionNormalizerSeeder --force +# 6. Markenlogos nachtragen. Setzt `logo` nur, wenn das Feld leer ist – ein im Admin +# hochgeladenes Logo bleibt stehen. Braucht public/img/assets/marken/ aus dem Archiv. +php artisan db:seed --class=BrandLogoSeeder --force + php artisan config:cache php artisan view:clear @@ -1205,7 +1243,8 @@ done - [ ] Startseite: Reihenfolge, Kernmarken-Anker `#marken`, Sponsoring-Logos - [ ] Markenseite `/marken` – Aufbau, Merkmale, „Alle Marken ansehen" von der Startseite - [ ] Kernmarken-Detailseiten `/marken/cabinet`, `/marken/rotpunkt`, `/marken/februe` – je mit - ausführlichem Text, aufklappbaren Vertiefungen und eigenem Abschlussblock + Logo im Kopf, ausführlichem Text, aufklappbaren Vertiefungen und eigenem Abschlussblock +- [ ] Logos erscheinen auf der Startseite, auf `/marken` und in den „Weitere Marken"-Kacheln - [ ] Auf dem Smartphone prüfen: Das Terminanfrage-Widget trägt auf der Markenseite die längere Beschriftung und darf keine Inhalte verdecken - [ ] `/netzwerk`, `/interior`, `/partner`, `/service` leiten auf `/marken` diff --git a/dev/2026-08-28/preview-deployment.md b/dev/2026-08-28/preview-deployment.md index 2aa08e86..9e655c70 100644 --- a/dev/2026-08-28/preview-deployment.md +++ b/dev/2026-08-28/preview-deployment.md @@ -186,6 +186,9 @@ php artisan db:seed --class=BrandPageTextSeeder --force # Nur nötig, wenn die Demogalerien schon eingespielt sind. Mehrfach ausführbar. php artisan db:seed --class=BrandGalleryCaptionNormalizerSeeder --force +# Markenlogos nachtragen. Setzt `logo` nur, wenn das Feld leer ist. +php artisan db:seed --class=BrandLogoSeeder --force + # Display-Branding auf das Interior-Logo php artisan db:seed --class=DisplayInteriorBrandingSeeder --force diff --git a/public/img/assets/marken/cabinet.svg b/public/img/assets/marken/cabinet.svg new file mode 100644 index 00000000..7957e0b8 --- /dev/null +++ b/public/img/assets/marken/cabinet.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + diff --git a/public/img/assets/marken/februe.png b/public/img/assets/marken/februe.png new file mode 100644 index 0000000000000000000000000000000000000000..53c2ca302b991ae5ad38ad61b88a8343250eeace GIT binary patch literal 15359 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�Jk9C#QmK0SIL3FKWH4o}CFuIe~wT;w$u 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 KTK&}K{r>{hRAzwy literal 0 HcmV?d00001 diff --git a/public/img/assets/marken/rotpunkt.svg b/public/img/assets/marken/rotpunkt.svg new file mode 100644 index 00000000..bb84b63f --- /dev/null +++ b/public/img/assets/marken/rotpunkt.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/views/livewire/web/components/sections/brand-detail.blade.php b/resources/views/livewire/web/components/sections/brand-detail.blade.php index 1bfbf82e..182aabc5 100644 --- a/resources/views/livewire/web/components/sections/brand-detail.blade.php +++ b/resources/views/livewire/web/components/sections/brand-detail.blade.php @@ -11,13 +11,20 @@
+ {{-- Liegt ein Logo vor, steht es anstelle des Schriftzugs. Es sitzt im

, + damit die Ueberschrift erhalten bleibt – den Text liefert das alt-Attribut. + Feste Box statt fester Hoehe: die Logos haben sehr unterschiedliche + Seitenverhaeltnisse (Februe breit, Rotpunkt fast quadratisch). --}} @if (!empty($brand['logo'])) - {{ $brand['name'] }} +

+ {{ $brand['name'] }} +

+ @else +

{{ $brand['name'] }}

@endif -

{{ $brand['name'] }}

-

{{ $brand['tagline'] }}

+

{{ $brand['tagline'] }}

@if (!empty($brand['showroom']))

@@ -346,6 +353,11 @@ + @if (!empty($other['logo'])) + {{ $other['name'] }} + @endif +

{{ $other['name'] }}

{{ $other['tagline'] }}

{!! $other['teaser'] !!}

diff --git a/resources/views/livewire/web/components/sections/brand-overview.blade.php b/resources/views/livewire/web/components/sections/brand-overview.blade.php index 2c0d6a07..40379d00 100644 --- a/resources/views/livewire/web/components/sections/brand-overview.blade.php +++ b/resources/views/livewire/web/components/sections/brand-overview.blade.php @@ -19,9 +19,11 @@
+ {{-- Feste Box statt fester Hoehe: die Markenlogos haben sehr + unterschiedliche Seitenverhaeltnisse und wirken sonst ungleich gross. --}} @if (!empty($brand['logo'])) {{ $brand['name'] }} + class="h-14 max-w-[12rem] w-auto mb-5 object-contain object-left" loading="lazy" /> @endif

{{ $brand['name'] }}

diff --git a/resources/views/livewire/web/components/sections/core-brands.blade.php b/resources/views/livewire/web/components/sections/core-brands.blade.php index 927c6f12..52c41a38 100644 --- a/resources/views/livewire/web/components/sections/core-brands.blade.php +++ b/resources/views/livewire/web/components/sections/core-brands.blade.php @@ -22,9 +22,11 @@ @endif
+ {{-- Feste Box statt fester Hoehe: die Markenlogos haben sehr + unterschiedliche Seitenverhaeltnisse und wirken sonst ungleich gross. --}} @if (!empty($brand['logo'])) {{ $brand['name'] }} + class="h-11 max-w-[10rem] w-auto mb-4 object-contain object-left" loading="lazy" /> @endif

{{ $brand['name'] }}

diff --git a/tests/Feature/BrandPageTest.php b/tests/Feature/BrandPageTest.php index fd464b24..f3311ce3 100644 --- a/tests/Feature/BrandPageTest.php +++ b/tests/Feature/BrandPageTest.php @@ -214,3 +214,64 @@ it('strips the old example prefix without touching image, category or order', fu ->and($gallery[0]['category'])->toBe('project') ->and($gallery[1]['caption'])->toBe('Entwurf Garderobe'); }); + +// ======================================== +// Markenlogos +// ======================================== + +it('shows the logo instead of the wordmark at the top of a brand page', function () { + $html = $this->get('/marken/rotpunkt')->assertSuccessful()->getContent(); + + // Das Logo sitzt im

, damit die Ueberschrift erhalten bleibt. + expect($html)->toMatch('/

\s*]*marken\/rotpunkt\.svg/') + ->and($html)->toContain('alt="Rotpunkt Küchen"'); +}); + +it('falls back to the wordmark for a brand without a logo', function () { + CmsBrand::where('slug', 'rotpunkt')->firstOrFail()->update(['logo' => '']); + + $this->get('/marken/rotpunkt') + ->assertSuccessful() + ->assertSee('

Rotpunkt Küchen

', false); +}); + +it('shows the logo on every tile that leads to a brand page', function (string $path) { + $html = $this->get($path)->assertSuccessful()->getContent(); + + foreach (['cabinet.svg', 'rotpunkt.svg', 'februe.png'] as $file) { + expect($html)->toContain('marken/'.$file); + } +})->with([ + 'Startseite' => ['/'], + 'Markenuebersicht' => ['/marken'], +]); + +it('shows the logo on the other-brands tiles of a detail page', function () { + $html = $this->get('/marken/rotpunkt')->assertSuccessful()->getContent(); + + // Auf der Rotpunkt-Seite verweisen die Kacheln auf CABINET und Februe. + expect($html)->toContain('marken/cabinet.svg') + ->and($html)->toContain('marken/februe.png'); +}); + +it('ships the logo files the seeder points at', function () { + foreach (['cabinet.svg', 'rotpunkt.svg', 'februe.png'] as $file) { + expect(public_path('img/assets/marken/'.$file))->toBeFile(); + } +}); + +it('keeps a logo that was uploaded in the admin', function () { + CmsBrand::where('slug', 'cabinet')->firstOrFail()->update(['logo' => 'eigenes-logo.svg']); + + $this->seed(\Database\Seeders\BrandLogoSeeder::class); + + expect(CmsBrand::where('slug', 'cabinet')->firstOrFail()->logo)->toBe('eigenes-logo.svg'); +}); + +it('adds the logo to a brand that has none yet', function () { + CmsBrand::where('slug', 'cabinet')->firstOrFail()->update(['logo' => '']); + + $this->seed(\Database\Seeders\BrandLogoSeeder::class); + + expect(CmsBrand::where('slug', 'cabinet')->firstOrFail()->logo)->toBe('marken/cabinet.svg'); +});