B2in Interior: Relaunch der Website, Kernmarken-CMS und Terminanfrage
Umsetzung von AP0-AP6 aus dev/2026-08-28/entwicklungsplan.md sowie der vorab gefundenen Befunde T1 und B1-B13. Befunde - CmsContentSeeder überschrieb bei jedem Lauf alle redaktionellen Inhalte; jetzt Redaktionsschutz plus gezielter Relaunch-Seeder (B1) - Magazin-CMS war nicht ans Frontend angebunden, Artikel jetzt über Slugs mit 301 von den alten numerischen URLs (B2) - Vier veröffentlichte Display-Playlists zeigten auf b2in.test und wären live nicht ladbar gewesen (B13) - Info-Tablet speicherte geleerte Öffnungszeiten nicht (T1) - /service und /portfolio lieferten seit Februar 500 (B12) Website - Startseite neu strukturiert und umgetextet, eigene Seite /marken mit Detailseite je Kernmarke, /netzwerk und Altrouten leiten dorthin - Galerie je Marke, getrennt nach realisierten Projekten und Visualisierungen; ohne gesetzte Kategorie gilt ein Bild als Entwurf - Seite /referenzen, gespeist aus den Markengalerien - Showroom-Display im 9:16-Rahmen über eine schreibgeschützte Embed-Route ohne Preview-Token - Terminanfrage-Widget auf allen Seiten, Markenauswahl aus dem CMS, WhatsApp per Klick-zum-Chat-Link mit vorbereitetem Text - FAQ, Über-uns, Kontakt und Magazin inhaltlich auf Interior umgestellt Sonstiges - Vorschau-Instanzen liefern noindex und verlinken sich bei unbekanntem Host auf sich selbst statt auf eine fremde Domain - Seeder-Zugangsdaten aus dem Code in die Konfiguration (B8) - Ablauf für die Vorschau: dev/2026-08-28/preview-deployment.md 833 Tests grün (3084 Assertions), Pint sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102
dev/2026-08-28/B2in_Interior-Konzept.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# B2in Interieur
|
||||
## Konzept zur Neuausrichtung der Website – Richtung, Struktur und Textauszüge
|
||||
|
||||
*Adametz.Media | Kevin Adametz | Juli 2026 | Zur Abstimmung*
|
||||
|
||||
---
|
||||
|
||||
Hallo Marcel, dieses Dokument fasst zusammen, wie ich die Website auf die neue Ausrichtung umbaue – Struktur, Gewichtung und ausgewählte Textauszüge, damit Du die Richtung beurteilen kannst. Es sind bewusst nicht alle Texte enthalten, sondern die Stellen, die den Ton setzen. Nimm Dir in Ruhe die Zeit, es durchzugehen; Dein gesammeltes Feedback baue ich nach meinem Urlaub direkt ein.
|
||||
|
||||
---
|
||||
|
||||
## 1. Die neue Ausrichtung in drei Sätzen
|
||||
|
||||
B2in stellt künftig das Interieur und die Kernmarken nach vorne – CABINET, Rotpunkt Küchen, Febrü und weitere. Die Immobilien bleiben Teil des Angebots, rücken aber bewusst nach hinten: Ergänzung statt Aufmacher. Deine Idee der Doppelbedeutung nehme ich dabei auf:
|
||||
|
||||
> **B2in – Bridges to International. Bridges to Interior.**
|
||||
>
|
||||
> *Die internationale Herkunft bleibt Teil der Geschichte, das Interieur wird der Kern. Im Logo wird das sichtbar: B2in mit dem Zusatz „Interieur".*
|
||||
|
||||
Wichtiges Prinzip dabei: **B2in Interieur ist das Dach – die Kernmarken sind die Gesichter.** Jede Marke behält ihren eigenen Auftritt und ihre eigene Stärke; B2in verbindet sie, ohne sie zu vermischen. Genau das unterscheidet eine Premium-Gruppe von einem Gemischtwarenladen.
|
||||
|
||||
---
|
||||
|
||||
## 2. Der neue Seitenaufbau
|
||||
|
||||
Die Seite wird nicht neu gebaut – Struktur und Technik bleiben. Es ändern sich Reihenfolge, Gewichtung und Inhalte. So sieht der Aufbau der Startseite künftig aus:
|
||||
|
||||
| # | Bereich | Was passiert |
|
||||
|---|---------|--------------|
|
||||
| 1 | **Ankündigungsleiste** | Bleibt als Instrument, trägt künftig Interieur-Themen (z.B. Neuheiten aus den Showrooms) statt dauerhaft Immobilien-Launches. |
|
||||
| 2 | **Hero** | Neue Headline und neue Bildwelt: Interieur und Marken zuerst. Zwei Buttons: „Unsere Marken entdecken" und „Termin anfragen". |
|
||||
| 3 | **Weiche Privat / Geschäft** | Neu: Zwei klare Wege direkt unter dem Einstieg – Privatkunden (Einrichtung fürs Zuhause) und Geschäftskunden (Ausstattung für Projekte, „bis zur letzten Blume"). |
|
||||
| 4 | **Kernmarken** | Neu: Das Herzstück. Kacheln für CABINET, Rotpunkt, Febrü – über das CMS von Dir selbst erweiterbar, jede Marke mit eigener Detailseite. |
|
||||
| 5 | **Über Dich / Vertrauen** | Bleibt – Du als Gesicht und persönlicher Ansprechpartner. Text dreht sich: Einrichtungskompetenz zuerst, Immobilien als ergänzende Expertise am Ende. |
|
||||
| 6 | **Aktuelles (Display)** | Neu: Die Inhalte aus dem Display-CMS erscheinen auf der Website (9:16). Dazu kommt Deine neue, selbst pflegbare Rubrik-Seite als eigenes Web-Display. |
|
||||
| 7 | **Immobilien-Teaser** | Bleibt, aber klein und dezent am Ende der Seite – wer gezielt sucht, findet den Weg; wer wegen Einrichtung kommt, wird nicht abgelenkt. |
|
||||
| 8 | **Abschluss & Kontakt** | Terminanfrage-Widget (Name, E-Mail, Wunschtermin, Notiz, Markenauswahl) plus WhatsApp-Button, der direkt den Chat mit Dir öffnet. |
|
||||
|
||||
In der Navigation rückt **„Marken" nach vorne, „Immobilien" nach hinten**. Auch Titel und Beschreibung für Google werden auf die neue Ausrichtung umgestellt, damit die Seite auch in der Suche die richtige Geschichte erzählt.
|
||||
|
||||
---
|
||||
|
||||
## 3. Textauszüge – so klingt die neue Richtung
|
||||
|
||||
Drei Auszüge, die den Ton setzen. Alle weiteren Texte folgen dieser Linie.
|
||||
|
||||
### 3.1 Hero (Einstieg)
|
||||
|
||||
> **B2in Interieur – Premium-Einrichtung von starken Marken. Für Ihr Zuhause. Für Ihr Projekt.**
|
||||
>
|
||||
> *Von der einzelnen Maßanfertigung bis zur vollständigen Ausstattung – mit CABINET, Rotpunkt Küchen, Febrü und einem Netzwerk regionaler Fachexperten.*
|
||||
|
||||
### 3.2 Die Weiche: Privat / Geschäft
|
||||
|
||||
> **Einrichtung für Ihr Zuhause**
|
||||
>
|
||||
> Einzelne Möbelstücke, maßgefertigte Einbaulösungen oder die komplette Einrichtung: Unsere Kernmarken und unser Fachhandels-Netzwerk begleiten Sie von der ersten Idee bis zur Montage.
|
||||
|
||||
> **Ausstattung für Ihr Projekt**
|
||||
>
|
||||
> Vollständige Einrichtung für Objekte, Büros und Projektentwicklungen – koordiniert aus einer Hand, von der Küche bis zur letzten Blume. Mit deutscher Vertragssicherheit und einem eingespielten Herstellernetzwerk.
|
||||
|
||||
### 3.3 Beispiel Kernmarken-Kachel (CABINET)
|
||||
|
||||
> **CABINET – Einbauschränke nach Maß.**
|
||||
>
|
||||
> Maßgefertigte Schranklösungen, geplant bis auf den Millimeter – gefertigt für Räume, in denen Standard nicht genügt. Erleben Sie die Möglichkeiten in unserem Showroom in Bielefeld.
|
||||
|
||||
Rotpunkt und Febrü bekommen Kacheln im selben Stil. Bei Febrü setze ich den Schwerpunkt auf das Zuhause-Arbeiten (Home-Office) und nenne die Büro- und Unternehmensausstattung als zweiten Aspekt – so passt die Marke in beide Welten, mit der richtigen Gewichtung.
|
||||
|
||||
---
|
||||
|
||||
## 4. Was bewusst so bleibt
|
||||
|
||||
- **Die Immobilien** bleiben statisch wie bisher und rücken nur in der Gewichtung nach hinten. Der Bereich selbst bleibt vollständig erreichbar.
|
||||
- **Das Magazin** bleibt bestehen – die neue Rubrik-Seite ergänzt es, ersetzt es aber nicht.
|
||||
- **Videos** laufen über YouTube-Einbindung – unkompliziert und ohne eigene Videotechnik. Das Influencer-Video bekommt darüber einen gut sichtbaren Platz.
|
||||
|
||||
---
|
||||
|
||||
## 5. Dein Feedback – diese Punkte entscheide bitte Du
|
||||
|
||||
Damit ich nach dem Urlaub direkt umsetzen kann, brauche ich zu diesen Punkten Deine Rückmeldung:
|
||||
|
||||
| Punkt | Frage an Dich |
|
||||
|-------|---------------|
|
||||
| **Logo-Zusatz „Interieur"** | Freigabe der Ergänzung im Logo. Kläre bitte auch, ob Du eine Logo-Datei anpassen lässt oder ich das übernehmen soll. |
|
||||
| **Claim** | Vorschlag: „Premium-Einrichtung. Persönlich gemacht." (ersetzt „Connecting Design and Property"). Passt das – oder soll „Bridges to Interior" selbst als Claim-Zeile erscheinen? |
|
||||
| **Hero-Headline** | Passt Dir die Richtung aus Auszug 3.1? |
|
||||
| **Febrü-Tonalität** | Home-Office zuerst, Büro als zweiter Aspekt – einverstanden? |
|
||||
| **Name der neuen Rubrik** | „Aktuelles", „Referenzen", „Projekte" – oder ein anderer Name? |
|
||||
| **Bildmaterial** | Für Hero und Kernmarken brauche ich hochwertige Motive (Logos und Basis-Infos zu Rotpunkt und Febrü ebenfalls). Was kannst Du liefern, was soll ich auswählen? |
|
||||
|
||||
---
|
||||
|
||||
## 6. Zeitplan
|
||||
|
||||
- **Bis Anfang August:** Du gehst dieses Konzept in Ruhe durch und sammelst Dein Feedback zu den Punkten aus Abschnitt 5.
|
||||
- **Ab meiner Rückkehr:** Ich baue Dein Feedback ein und setze Struktur, Texte und Funktionen um. Zwischenstände zeige ich Dir vor dem Livegang.
|
||||
- **Ende August:** Livegang der neuen Ausrichtung – vorausgesetzt, Feedback und Zulieferungen (Bilder, Logos, Marken-Infos) liegen rechtzeitig vor.
|
||||
|
||||
*Bei Fragen erreichst Du mich nach dem Urlaub wie gewohnt – dringende Punkte gerne per Mail, ich arbeite sie der Reihe nach ab.*
|
||||
113
dev/2026-08-28/deploy/dateiliste.txt
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
.env.example
|
||||
app/Helpers/ThemeHelper.php
|
||||
app/Livewire/Admin/Cms/CabinetInfoTablet.php
|
||||
app/Livewire/Web/Components/Sections/MagazinDetail.php
|
||||
app/Livewire/Web/Components/Sections/MagazinList.php
|
||||
app/Livewire/Web/Components/UI/AnnouncementBar.php
|
||||
app/Livewire/Web/Components/UI/Footer.php
|
||||
app/Models/CmsArticle.php
|
||||
app/Providers/ThemeServiceProvider.php
|
||||
app/Support/DisplayModuleSettings.php
|
||||
app/helpers.php
|
||||
config/app.php
|
||||
config/cms_section_map.php
|
||||
database/seeders/CmsArticleSeeder.php
|
||||
database/seeders/CmsContentSeeder.php
|
||||
database/seeders/DatabaseSeeder.php
|
||||
public/_cabinet/display/index.html
|
||||
resources/lang/de/b2in.php
|
||||
resources/lang/de/ui.php
|
||||
resources/lang/en/b2in.php
|
||||
resources/lang/en/ui.php
|
||||
resources/views/livewire/admin/cms/cabinet-info-tablet.blade.php
|
||||
resources/views/livewire/admin/cms/content-index.blade.php
|
||||
resources/views/livewire/admin/cms/dashboard.blade.php
|
||||
resources/views/livewire/admin/cms/projects-index.blade.php
|
||||
resources/views/livewire/web/components/sections/magazin-list.blade.php
|
||||
resources/views/livewire/web/components/ui/announcement-bar.blade.php
|
||||
resources/views/livewire/web/components/ui/footer.blade.php
|
||||
resources/views/livewire/web/components/ui/header.blade.php
|
||||
resources/views/vendor/mail/html/header.blade.php
|
||||
resources/views/web/about.blade.php
|
||||
resources/views/web/contact.blade.php
|
||||
resources/views/web/cookie-policy.blade.php
|
||||
resources/views/web/faq.blade.php
|
||||
resources/views/web/home.blade.php
|
||||
resources/views/web/impressum.blade.php
|
||||
resources/views/web/layouts/web-master.blade.php
|
||||
resources/views/web/magazin-detail.blade.php
|
||||
resources/views/web/magazin.blade.php
|
||||
resources/views/web/netzwerk.blade.php
|
||||
resources/views/web/privacy.blade.php
|
||||
resources/views/web/terms.blade.php
|
||||
routes/admin.php
|
||||
routes/web.php
|
||||
tests/Feature/AnnouncementBarTest.php
|
||||
tests/Feature/CabinetInfoTabletTest.php
|
||||
tests/Feature/Cms/CmsArticleTest.php
|
||||
tests/Feature/Cms/CmsContentSeederTest.php
|
||||
tests/Feature/DisplayVersionApiTest.php
|
||||
tests/Feature/DisplayVersionTest.php
|
||||
tests/Feature/InteriorPageTest.php
|
||||
tests/Feature/LiveSiteReviewTest.php
|
||||
tests/Feature/MagazinPageTest.php
|
||||
app/Http/Controllers/DisplayEmbedController.php
|
||||
app/Livewire/Web/Components/Sections/AudienceSwitch.php
|
||||
app/Livewire/Web/Components/Sections/BrandDetail.php
|
||||
app/Livewire/Web/Components/Sections/BrandOverview.php
|
||||
app/Livewire/Web/Components/Sections/CoreBrands.php
|
||||
app/Livewire/Web/Components/Sections/DisplayFeed.php
|
||||
app/Livewire/Web/Components/Sections/ImmobilienTeaser.php
|
||||
app/Livewire/Web/Components/Sections/MarkenCta.php
|
||||
app/Livewire/Web/Components/Sections/MarkenGrowth.php
|
||||
app/Livewire/Web/Components/Sections/MarkenNetwork.php
|
||||
app/Livewire/Web/Components/Sections/PageHero.php
|
||||
app/Livewire/Web/Components/Sections/ReferenceProjects.php
|
||||
app/Livewire/Web/Components/Sections/Sponsoring.php
|
||||
app/Livewire/Web/Components/Ui/AppointmentWidget.php
|
||||
app/Models/CmsBrand.php
|
||||
config/seeding.php
|
||||
database/factories/CmsBrandFactory.php
|
||||
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/seeders/CmsBrandSeeder.php
|
||||
database/seeders/DemoBrandGallerySeeder.php
|
||||
database/seeders/DisplayInteriorBrandingSeeder.php
|
||||
database/seeders/DisplayMediaUrlNormalizerSeeder.php
|
||||
database/seeders/InteriorRelaunchCmsSeeder.php
|
||||
public/_cabinet/assets/b2in-interior-logo-negative.svg
|
||||
public/_cabinet/assets/b2in-interior-logo-positive.svg
|
||||
public/img/assets/sponsoring/
|
||||
public/img/logos/b2in-interior-logo-negative.png
|
||||
public/img/logos/b2in-interior-logo-negative.svg
|
||||
public/img/logos/b2in-interior-logo-positive.png
|
||||
public/img/logos/b2in-interior-logo-positive.svg
|
||||
resources/views/livewire/admin/cms/brands-index.blade.php
|
||||
resources/views/livewire/web/components/sections/audience-switch.blade.php
|
||||
resources/views/livewire/web/components/sections/brand-detail.blade.php
|
||||
resources/views/livewire/web/components/sections/brand-overview.blade.php
|
||||
resources/views/livewire/web/components/sections/core-brands.blade.php
|
||||
resources/views/livewire/web/components/sections/display-feed.blade.php
|
||||
resources/views/livewire/web/components/sections/immobilien-teaser.blade.php
|
||||
resources/views/livewire/web/components/sections/marken-cta.blade.php
|
||||
resources/views/livewire/web/components/sections/marken-growth.blade.php
|
||||
resources/views/livewire/web/components/sections/marken-network.blade.php
|
||||
resources/views/livewire/web/components/sections/page-hero.blade.php
|
||||
resources/views/livewire/web/components/sections/reference-projects.blade.php
|
||||
resources/views/livewire/web/components/sections/sponsoring.blade.php
|
||||
resources/views/livewire/web/components/ui/appointment-widget.blade.php
|
||||
resources/views/web/marken-show.blade.php
|
||||
resources/views/web/marken.blade.php
|
||||
resources/views/web/referenzen.blade.php
|
||||
tests/Feature/Admin/Cms/CmsBrandsIndexTest.php
|
||||
tests/Feature/AppointmentWidgetTest.php
|
||||
tests/Feature/BrandPageTest.php
|
||||
tests/Feature/Cms/CmsBrandTest.php
|
||||
tests/Feature/DisplayInteriorBrandingTest.php
|
||||
tests/Feature/DisplayMediaUrlNormalizerTest.php
|
||||
tests/Feature/DisplayWebFeedTest.php
|
||||
tests/Feature/FooterTest.php
|
||||
tests/Feature/HomePageStructureTest.php
|
||||
tests/Feature/MarkenPageTest.php
|
||||
tests/Feature/PreviewHostTest.php
|
||||
tests/Feature/ReferenzenPageTest.php
|
||||
982
dev/2026-08-28/entwicklungsplan.md
Normal file
|
|
@ -0,0 +1,982 @@
|
|||
# Entwicklungsplan: B2in Interior – Neuausrichtung Website & CMS
|
||||
|
||||
**Erstellt:** 28.08.2026 · zuletzt aktualisiert 28.08.2026
|
||||
**Basis:** `B2in_Interior-Konzept.md`, `umsetzungliste.md`, `umsetzung-inhalte.md`
|
||||
**Vorgänger:** `dev/2026-02-27/b2in-website-umsetzungsplan.md`
|
||||
**Rahmen:** 37–39 Std. freigegeben (18 + 8 + 4 + 3 + 4–6)
|
||||
**Status:** Revision 12 – Befunde abgearbeitet, **AP0–AP6 umgesetzt**. Testbereit; offen sind nur
|
||||
noch Zulieferungen und die Rechtstexte.
|
||||
**Umgebung:** Dev Container, `php artisan …` (nicht `vendor/bin/sail …`)
|
||||
|
||||
> **Verbindliche Schreibweisen:** **Interior** (nicht „Interieur"), **Febrü**, **Rotpunkt Küchen**, **CABINET**.
|
||||
> Das Konzeptpapier schreibt durchgehend „Interieur" – die Umsetzungsliste überschreibt das. Gilt für Code,
|
||||
> Texte, Commit-Messages und Datenbank-Inhalte.
|
||||
|
||||
---
|
||||
|
||||
## 0. Stand & nächste Schritte
|
||||
|
||||
**Stand 28.08.2026:** T1 und B1–B13 abgearbeitet, **alle Arbeitspakete AP0–AP6 umgesetzt**, die
|
||||
Bestandsinhalte auf den Interior-Auftritt umgestellt. `php artisan test --compact`: **826 grün**
|
||||
(3072 Assertions), Pint sauber, `npm run build:b2in` gebaut.
|
||||
**Die Seite ist testbereit** – die ausstehenden Zulieferungen trägt Marcel selbst im CMS nach.
|
||||
|
||||
| Paket | Stand |
|
||||
|---|---|
|
||||
| AP0 Vorbereitung | ✅ |
|
||||
| AP1 Umstrukturierung & Umtextung | ✅ |
|
||||
| AP2 Kernmarken-Modul + `/marken` + Galerie | ✅ |
|
||||
| AP3 Terminanfrage-Widget + WhatsApp-Link | ✅ (Nummer fehlt noch) |
|
||||
| AP6 Sponsoring | ✅ |
|
||||
| Bestandsinhalte FAQ / About / Kontakt / Magazin | ✅ |
|
||||
| AP4 Display-Spiegelung | ✅ |
|
||||
| AP5 Rubrik-Seite „Referenzen" | ✅ |
|
||||
|
||||
### Nächste Schritte
|
||||
|
||||
**Vor dem Versand des Testlinks — nichts.** Alle Seiten laden, die Suite ist grün, die Assets sind
|
||||
gebaut. Was fehlt, ist Material, kein Code.
|
||||
|
||||
**Was Marcel selbst nachträgt (alles im CMS, ohne Codeänderung):**
|
||||
|
||||
| Was | Wo im Admin |
|
||||
|---|---|
|
||||
| Logos und Stimmungsbilder der drei Marken | Kernmarken → Marke bearbeiten |
|
||||
| Echte Projektfotos statt der BEISPIEL-Bilder | Kernmarken → Bildergalerie |
|
||||
| Herstellerseiten-URLs | Kernmarken → Herstellerseite |
|
||||
| Motiv für den Kopf von `/marken` | Inhalte → `marken` → `hero` |
|
||||
| WhatsApp-Nummer | Inhalte → `global` → `contact` → `whatsapp` |
|
||||
| Welches Display auf der Website läuft | Inhalte → `referenzen` → `display_feed` → `display_id` |
|
||||
|
||||
**Beim Deployment mit erledigen (Abschnitt 8):**
|
||||
|
||||
1. **Rechtstexte** – AGB und Datenschutzerklärung beschreiben weiter das alte Geschäft
|
||||
(„Connecting Design and Property", Dubai/Lissabon, Supply-Chain-Management,
|
||||
`resources/lang/de/b2in_legal.php` Zeilen 117 und 221). Marcel lässt die Formulierung prüfen,
|
||||
danach eintragen. Der WhatsApp-Absatz kommt im selben Zug dazu.
|
||||
2. **OG-Bild** – das Layout verweist auf `img/assets/b2in-og-default.jpg`, die Datei existiert
|
||||
nicht. Bis dahin zeigt jede geteilte Seite eine Vorschau ohne Bild.
|
||||
3. **Seeder-Passwort rotieren** (B8) – steht weiter in der Git-Historie.
|
||||
4. Die zwei Magazin-Beiträge und die Sponsoren-Kurztexte gegenlesen lassen.
|
||||
|
||||
**Danach offen, aber nicht Teil dieses Auftrags:** YouTube-Einbindung mit Consent-Gate auf der
|
||||
Referenzen-Seite (Abschnitt 4). Sinnvoll, sobald es Videos gibt – vorher wäre es ein Consent-Gate
|
||||
ohne Inhalt.
|
||||
|
||||
---
|
||||
|
||||
## 1. Ist-Architektur (relevanter Ausschnitt)
|
||||
|
||||
### 1.1 Content-Pipeline
|
||||
|
||||
```
|
||||
resources/lang/de/b2in.php (themes.b2in.<section>) ← Quelltexte / Fallback
|
||||
├─ config/cms_section_map.php section → [group, key]
|
||||
├─ database/seeders/CmsContentSeeder.php
|
||||
▼
|
||||
flux_cms_contents (group, key, type, value:JSON, translatable de/en)
|
||||
├─ FluxCms\Core\Services\CmsContentService (Cache: flux_cms.content.__all__)
|
||||
▼
|
||||
cms_theme_section('hero') → CMS gewinnt, sonst trans('b2in.themes.b2in.hero')
|
||||
```
|
||||
|
||||
Redaktion unter `admin/flux-cms/content` → [`content-index.blade.php`](../../resources/views/livewire/admin/cms/content-index.blade.php)
|
||||
(Volt, 782 Z.): Group/Key-Editor mit JSON-Repeater-Modal, Medien-Picker, Flux-Editor für HTML.
|
||||
**Kann Werte ändern, aber keine Sektion neu anlegen.**
|
||||
|
||||
### 1.2 Seiten & Sektionen
|
||||
|
||||
- Startseite: `routes/web.php` → `resources/views/web/home.blade.php`
|
||||
- Sektionen = Livewire-Komponenten unter `app/Livewire/Web/Components/Sections/`,
|
||||
Muster `mount() { $this->content = cms_theme_section('<key>'); }`
|
||||
- Ist-Reihenfolge: `header → hero → founder-bar → content-section(synergie) → vision-section → ecosystem-core → cta-section → footer`
|
||||
- Navigation und Ankündigungsleiste liegen **bereits im CMS** (`global.header.navigation`, `global.announcement_bar`)
|
||||
→ Umbau ist Redaktion, kein Code.
|
||||
- SEO: `@section('title')` / `@section('meta_description')` je View; OG-Tags leiten sich
|
||||
in `web-master.blade.php` automatisch daraus ab → **OG kostet keinen Extra-Aufwand** (aber siehe B6).
|
||||
- Immobilien rendern statisch aus `resources/lang/de/immobilien-azizi.json` – wie gefordert.
|
||||
|
||||
### 1.3 Display-CMS
|
||||
|
||||
`Display` (Gerät) → `DisplayPlaylist` (draft/published) → `DisplayVersion` („Modul", Enum
|
||||
`DisplayVersionType`: `video-display` | `b2in` | `offers`) → `DisplayVersionItem`.
|
||||
[`DisplayPlaylistConfigBuilder`](../../app/Services/DisplayPlaylistConfigBuilder.php) erzeugt das
|
||||
Player-JSON. Player: `public/_cabinet/display/index.html`, festes 1080×1920-Raster (9:16), per Scale eingepasst.
|
||||
API vorhanden: `/api/display/{display}/config`, `/api/display/preview/{token}`,
|
||||
`/api/display/module/{module}/preview` – registriert für Portal-Domain **und** als Fallback für alle Domains.
|
||||
|
||||
### 1.4 Sonstiges
|
||||
|
||||
- Kontaktformular: `packages/acme/contact-form` – **unterstützt bereits `customFields` + Presets,
|
||||
Honeypot, Rate-Limit und `SpamDetector`.** Das Terminanfrage-Widget kann darauf aufsetzen.
|
||||
- Tests: Pest, SQLite in-memory, `php artisan test --compact`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Gefundene Bugs & Optimierungen
|
||||
|
||||
Beim Abgleich der Umsetzungsliste mit dem Code aufgefallen.
|
||||
|
||||
**Stand 28.08.2026: alle Befunde behoben, Suite grün (699 Tests, 2715 Assertions).**
|
||||
|
||||
| # | Befund | Status |
|
||||
|---|---|---|
|
||||
| T1 | Info-Tablet: Leeren per X wird nicht gespeichert | ✅ behoben |
|
||||
| B1 | CMS-Seeder überschreibt redaktionelle Inhalte | ✅ behoben |
|
||||
| B2 | Magazin-CMS nicht ans Frontend angeschlossen | ✅ behoben (Variante A: Slug-Routen + 301) |
|
||||
| B3 | Ankündigungsleiste bleibt nach Umtexten unsichtbar | ✅ behoben |
|
||||
| B4 | Footer hartkodiert, nicht pflegbar | ✅ behoben |
|
||||
| B5 | Englische Footer-Labels auf deutscher Seite | ✅ behoben |
|
||||
| B6 | 19 Seiten erben alte Dubai-Beschreibung | ✅ behoben (Fallback + canonical) |
|
||||
| B7 | Content-Seeder nicht registriert | ✅ behoben |
|
||||
| B8 | Klartext-Passwort im Seeder | ✅ behoben |
|
||||
| B9 | Medien-Picker greift bei leeren Logo-Feldern nicht | ✅ behoben |
|
||||
| B10 | Alt-Begriffe im Seiteninhalt | ✅ behoben in AP1 |
|
||||
| B12 | `/service` und `/portfolio` lieferten 500 | ✅ behoben (301) |
|
||||
| B11 | `/magazin/{unbekannt}` liefert 200 statt 404 | ✅ behoben |
|
||||
|
||||
---
|
||||
|
||||
### T1 · Info-Tablet: Leeren der Öffnungszeiten wird nicht gespeichert ✅
|
||||
|
||||
Gemeldet am 28.08.2026: „Wenn ich den Inhalt weg-X, kommt nicht Geschlossen. Der Wert kommt
|
||||
wieder, wenn ich in ein anderes Feld klicke. Setze ich Öffnung und Schluss auf X und speichere,
|
||||
ist Öffnung wieder der alte Wert."
|
||||
|
||||
**Drei Ursachen, alle in `cabinet-info-tablet.blade.php` bzw. `CabinetInfoTablet.php`:**
|
||||
|
||||
1. **Zwei Submit-Handler auf demselben Formular.** `wire:submit.prevent="save"` **und**
|
||||
`x-on:submit.prevent="… $wire.save(hours)"` waren gleichzeitig gebunden – `save()` lief pro
|
||||
Klick zweimal, einmal mit den DOM-Werten und einmal ohne. Welcher Aufruf zuletzt schrieb,
|
||||
war nicht deterministisch. Das erklärt „speichert nur den letzten".
|
||||
2. **`wire:model.live` auf den Zeit-Pickern.** Jede Änderung löste einen Roundtrip aus; beim
|
||||
erneuten Rendern hat Livewire ein zuvor geleertes Feld mit dem unveränderten Serverwert
|
||||
überschrieben. Das erklärt „der Wert kommt wieder, wenn ich in ein anderes Feld klicke".
|
||||
3. **Geöffnet/Geschlossen wurde serverseitig gerechnet** und konnte deshalb erst nach einem
|
||||
Roundtrip umspringen. Das erklärt „es kommt nicht Geschlossen".
|
||||
|
||||
**Behoben:** nur noch ein Submit-Pfad (das DOM ist die Quelle der Wahrheit), `.live` entfernt,
|
||||
die Geöffnet/Geschlossen-Anzeige rechnet clientseitig per Alpine und reagiert damit sofort auf das X.
|
||||
|
||||
**Zusätzlich:** `save(array $hours)` hat über `property_exists()` **jede** öffentliche Property
|
||||
aus dem Client-Payload beschreibbar gemacht – auch `storeStatus` und `contactEmail`. Jetzt greift
|
||||
eine Allowlist auf die 14 Zeitfelder.
|
||||
|
||||
**Tests:** 5 neue Fälle in `tests/Feature/CabinetInfoTabletTest.php` (15 grün) – u. a. mehrere Tage
|
||||
in einem Submit leeren, nur die Öffnung leeren, Fallback ohne DOM-Payload, Allowlist.
|
||||
|
||||
**Noch am Gerät zu prüfen:** die drei Ursachen liegen im Browser-Verhalten; die Tests sichern den
|
||||
Serverpfad ab. Bitte im Portal einmal gegenprüfen: mehrere Tage leeren → speichern → neu laden.
|
||||
|
||||
### B1 · Der CMS-Seeder überschreibt alles, was Marcel pflegt ✅
|
||||
|
||||
`database/seeders/CmsContentSeeder.php:76-90` – bestehende Einträge werden bedingungslos
|
||||
per `$content->update()` mit den Werten aus der Lang-Datei überschrieben. Geschützt sind nur
|
||||
die zwei Sektionen in `$skipSections`.
|
||||
|
||||
**Wirkung:** Jeder erneute Seeder-Lauf – auch der geplante nach der Umtextung – setzt sämtliche
|
||||
redaktionellen Änderungen zurück. Die Zusage „von Marcel selbst pflegbar" hält so nicht.
|
||||
|
||||
**Behoben:** Default ist jetzt „nur anlegen, wenn nicht vorhanden". Überschreiben nur noch über
|
||||
`$seeder->overwriteExisting = true`. Der Lauf meldet, wie viele Einträge unangetastet blieben, und
|
||||
leert den CMS-Cache, wenn er etwas geändert hat.
|
||||
**Tests:** 3 neue Fälle in `tests/Feature/Cms/CmsContentSeederTest.php` – gepflegter Inhalt bleibt,
|
||||
fehlende Sektionen werden trotzdem angelegt, bewusstes Überschreiben funktioniert.
|
||||
|
||||
### B2 · Das Magazin-CMS ist nicht mit dem Frontend verbunden ✅
|
||||
|
||||
- Admin `admin/flux-cms/articles` schreibt nach `cms_articles` (Model `CmsArticle`).
|
||||
- Frontend liest `trans('b2in.articles')`:
|
||||
`app/Livewire/Web/Components/Sections/MagazinList.php:20` und `MagazinDetail.php:48`.
|
||||
- `CmsArticle` wird **außerhalb des Admin-Bereichs nirgends verwendet** (verifiziert per Grep).
|
||||
|
||||
**Wirkung 1:** Was Marcel im Magazin-CMS bearbeitet, erscheint nicht auf der Website.
|
||||
**Wirkung 2 (für dieses Projekt entscheidend):** Die Umsetzungsliste sagt für die Kernmarken
|
||||
„adaptiert vom **Magazin-Muster**". Das Admin-CRUD ist als Vorlage brauchbar, die
|
||||
Frontend-Anbindung fehlt dort aber – **dieser Fehler darf nicht mitkopiert werden.**
|
||||
|
||||
**Bei der Umsetzung aufgefallen – das ist kein reiner Verdrahtungsfehler:**
|
||||
Die Artikel liegen in beiden Quellen (5 in `cms_articles`, 5 in der Lang-Datei, inhaltsgleich),
|
||||
**aber unter verschiedenen Schlüsseln**: die Lang-Datei nutzt 1–5, die Datenbank die IDs 8–12.
|
||||
Die öffentlichen URLs lauten heute `/magazin/1` … `/magazin/5`. Eine Umstellung auf das Model
|
||||
**ändert damit die öffentlichen URLs** und braucht eine Slug-Route plus Weiterleitungen von den
|
||||
alten numerischen IDs – sonst brechen bestehende Links und die Google-Indexierung.
|
||||
|
||||
**Deshalb bewusst nicht einfach umgestellt.** Entscheidung nötig:
|
||||
|
||||
| Variante | Aufwand | Wirkung |
|
||||
|---|---|---|
|
||||
| A · Slug-Routen `/magazin/{slug}` + 301 von den alten IDs | ≈3–4 Std. | sauber, CMS wird wirksam, URLs werden sprechend |
|
||||
| B · Numerische Route beibehalten, Auflösung über die DB-ID | ≈2 Std. | CMS wird wirksam, aber `/magazin/1` … `/magazin/5` werden zu 404 |
|
||||
| C · Vorerst so lassen | 0 | Magazin funktioniert, das Magazin-CMS bleibt aber wirkungslos |
|
||||
|
||||
**Umgesetzt: Variante A.**
|
||||
|
||||
- `CmsArticle::forFrontend()` liefert die veröffentlichten Artikel nach Slug indiziert.
|
||||
Das CMS gewinnt; solange keine Artikel gepflegt sind, greift die Lang-Datei als Fallback –
|
||||
dieselbe Reihenfolge wie bei `cms_theme_section()`, damit das Magazin auf einer frischen
|
||||
Installation nicht leer ist.
|
||||
- Die ID→Slug-Zuordnung lag als private Konstante im `CmsArticleSeeder` und ist jetzt
|
||||
`CmsArticle::LEGACY_ID_TO_SLUG` – eine Quelle für Seeder, Fallback und Weiterleitung.
|
||||
- `MagazinList` und `MagazinDetail` lesen aus dem Model statt aus `trans('b2in.articles')`;
|
||||
die Übersicht verlinkt über `route('magazin.detail')` statt über die numerische ID.
|
||||
- Neue Route `/magazin/{slug}`. Die alten `/magazin/1` … `/magazin/5` leiten dauerhaft (301)
|
||||
auf den Slug um; sie stehen per `whereNumber()` **vor** der Slug-Route, sonst würde diese
|
||||
die Ziffern selbst schlucken. Numerische IDs ohne Zuordnung liefern 404.
|
||||
- Die Detailseite fragte die Artikel zweimal ab (Artikel + verwandte Artikel) – jetzt gemerkt,
|
||||
eine Abfrage pro Seitenaufruf.
|
||||
|
||||
**Tests:** `tests/Feature/MagazinPageTest.php` auf 13 Fälle erweitert – Slug-Auslieferung,
|
||||
301 von jeder alten ID, 404 bei unbekanntem Slug, CMS schlägt Lang-Datei, unveröffentlichte
|
||||
Artikel sind unsichtbar, Fallback bei leerer Tabelle. `LiveSiteReviewTest` prüft für jede alte
|
||||
ID die Weiterleitung **und** dass das Ziel lädt.
|
||||
|
||||
⚠️ **Beim Deployment:** `/magazin/1` … `/magazin/5` sind indexiert. Die 301 fängt sie ab, aber
|
||||
nach dem Livegang bitte einmal in der Search Console gegenprüfen. Externe Links, die noch auf
|
||||
die alten URLs zeigen, bleiben funktionsfähig.
|
||||
|
||||
**Nebenbefund, nicht angefasst:** `MagazinDetail::$relatedArticles` wird berechnet, aber von
|
||||
keiner View gerendert – entweder die Sektion „verwandte Artikel" nachziehen oder die Property
|
||||
entfernen. Deine Entscheidung.
|
||||
|
||||
### B3 · Ankündigungsleiste: alte Wegklicker sehen die neue Leiste nie ✅
|
||||
|
||||
`announcement-bar.blade.php:2` merkt sich das Wegklicken in
|
||||
`localStorage['announcement_dismissed_<id>']`. Bleibt die `id` beim Umtexten gleich, bleibt die
|
||||
Leiste für alle Wiederkehrer unsichtbar.
|
||||
|
||||
**Behoben:** Der Dismiss-Schlüssel wird jetzt aus Inhalt **und** `id` abgeleitet
|
||||
(`AnnouncementBar::getDismissKeyProperty()`). Wird die Leiste im CMS neu belegt, sehen auch
|
||||
Wiederkehrer die neue Meldung – ohne dass jemand daran denken muss, die `id` mitzuändern.
|
||||
**Tests:** 2 neue Fälle in `tests/Feature/AnnouncementBarTest.php`.
|
||||
|
||||
### B4 · Der Footer ist vollständig hartkodiert ✅
|
||||
|
||||
`footer.blade.php` – Claim „Connecting Design and Property" steht in Zeile 15 im Markup,
|
||||
`Footer.php` lädt überhaupt keinen Content. Es gibt keine `footer`-Sektion in `cms_section_map.php`.
|
||||
|
||||
**Wirkung:** Sowohl „Footer-Claim ersetzen" als auch „FAQ in den Footer" aus der Umsetzungsliste
|
||||
erfordern einen kleinen Umbau; Marcel kann den Claim danach ohne CMS-Anbindung weiterhin nicht ändern.
|
||||
**Behoben:** Neue CMS-Sektion `global.footer` (Claim, Byline, Linkliste) in `cms_section_map.php`
|
||||
und in beiden Lang-Dateien. `Footer.php` lädt sie über `cms_theme_section('footer')`, die View
|
||||
rendert Claim und Links daraus und fällt ohne CMS-Eintrag auf sinnvolle Defaults zurück.
|
||||
Der Claim lautet jetzt „Premium-Einrichtung. Persönlich gemacht.", FAQ ist als erster Link drin.
|
||||
**Tests:** `tests/Feature/FooterTest.php` (4 Fälle).
|
||||
|
||||
### B5 · Englische Footer-Labels auf der deutschen Seite ✅
|
||||
|
||||
„Privacy Policy", „Terms of Service", „Cookie Policy" waren hartkodiert englisch, während
|
||||
„Impressum" korrekt über `__('ui.legal_notice')` lief.
|
||||
**Behoben:** neue Keys `privacy_policy`, `terms_of_service`, `cookie_policy`, `faq` in
|
||||
`resources/lang/{de,en}/ui.php`; die deutsche Seite zeigt jetzt Datenschutz / AGB /
|
||||
Cookie-Richtlinie / Häufige Fragen / Impressum.
|
||||
|
||||
### B6 · 19 Seiten tragen die alte Dubai-Beschreibung ✅
|
||||
|
||||
`web-master.blade.php:11` und `:18` haben als Fallback fest verdrahtet:
|
||||
„B2in – Connecting Design and Property. Exklusive Immobilien in Dubai & europäisches Einrichtungsnetzwerk."
|
||||
19 Views unter `resources/views/web/` setzen **kein** `@section('meta_description')` und erben damit
|
||||
diesen Text – darunter die Live-Seite `magazin-detail.blade.php`.
|
||||
|
||||
**Behoben:** Der Fallback in `web-master.blade.php` (Description **und** OG-Description) trägt
|
||||
jetzt den Interior-Text aus `umsetzung-inhalte.md` §0. Zusätzlich `<link rel="canonical">` ergänzt,
|
||||
das fehlte komplett.
|
||||
**Offen als B10:** Der Alt-Begriff-Bestand im Seiteninhalt („Supply-Chain", „Local-for-Local",
|
||||
„Ökosystem", „Investment", „Connecting Design") – **90 Treffer in 14 Dateien**, u. a. der
|
||||
Hero-`card_text`. Das ist Content-Arbeit mit den freigegebenen Texten und gehört in AP1, nicht
|
||||
in einen Bugfix.
|
||||
|
||||
### B7 · Content-Seeder sind nirgends registriert ✅
|
||||
|
||||
`DatabaseSeeder::run()` ruft nur `TestDisplaySeeder`. `CmsContentSeeder`, `CmsArticleSeeder`,
|
||||
`CmsProjectSeeder`, `CmsLegalSeeder`, `NetzwerkPageCmsSeeder` müssen von Hand aufgerufen werden;
|
||||
ein frisch aufgesetztes System hat keine CMS-Inhalte.
|
||||
**Behoben:** `CmsContentSeeder`, `CmsLegalSeeder`, `NetzwerkPageCmsSeeder`, `CmsArticleSeeder`
|
||||
und `CmsProjectSeeder` sind in `DatabaseSeeder::run()` registriert – nach dem B1-Fix gefahrlos,
|
||||
weil bestehende Inhalte unangetastet bleiben.
|
||||
|
||||
### B8 · Klartext-Passwort im Seeder ✅
|
||||
|
||||
`database/seeders/DatabaseSeeder.php` enthielt ein echtes Passwort im Repo.
|
||||
**Behoben:** Zugangsdaten kommen jetzt aus `config/seeding.php` bzw. `SEED_ADMIN_*` in der `.env`;
|
||||
`.env.example` ist ergänzt.
|
||||
⚠️ **Das alte Passwort steht weiterhin in der Git-Historie – bitte rotieren, falls es irgendwo
|
||||
sonst benutzt wird.**
|
||||
|
||||
### B9 · Medien-Picker greift bei leeren Logo-Feldern nicht ✅
|
||||
|
||||
`content-index.blade.php` → `_cmsFieldLooksLikeImage()` erkennt Bildfelder an einer festen
|
||||
Feldnamen-Liste **oder** an der Dateiendung **im Wert**. `logo` steht nicht in der Liste, und ein
|
||||
noch leeres Feld hat keinen Wert → wird als reines Textfeld gerendert.
|
||||
|
||||
**Wirkung:** Marcel kann bei einer neu angelegten Marke bzw. bei den Sponsoring-Logos das Bild
|
||||
nicht per Picker setzen, sondern müsste den Dateinamen abtippen. Betrifft AP2 und AP6 direkt.
|
||||
**Behoben:** `logo` in die Feldnamen-Liste und `_logo$` in die Suffix-Regex aufgenommen. Zusätzlich
|
||||
prüft `_cmsFieldLooksLikeImage()` den Feldnamen jetzt **vor** dem Wert – ein noch leeres Bildfeld
|
||||
wird dadurch als Bild erkannt und bekommt den Picker. (`logo_width` bleibt korrekt ein Textfeld.)
|
||||
|
||||
### B11 · `/magazin/{unbekannte-id}` liefert 200 statt 404 ✅
|
||||
|
||||
`MagazinDetail::loadArticle()` fiel bei unbekannten IDs still auf Artikel 1 zurück
|
||||
(`$articles[$this->articleId] ?? $articles[1]`). `/magazin/999` lieferte damit Status 200 mit dem
|
||||
Inhalt von Artikel 1 – beliebig viele URLs mit identischem Inhalt, schlecht für die Indexierung,
|
||||
und bei fehlendem Artikel 1 ein Fehler statt einer 404.
|
||||
|
||||
**Behoben:** `abort_unless(isset($articles[$this->articleId]), 404)`.
|
||||
**Tests:** 2 neue Fälle in `tests/Feature/MagazinPageTest.php`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Arbeitspakete
|
||||
|
||||
Gliederung folgt der Umsetzungsliste. Reihenfolge nach dem Vorschlag aus `umsetzung-inhalte.md`.
|
||||
|
||||
### AP0 · Vorbereitung (im Rahmen von AP1)
|
||||
|
||||
Branch `feature/b2in-interior`, DB-Backup, Backup der Startseite (Muster
|
||||
`dev/2026-02-27/backup-before-relaunch/`), `php artisan test --compact` als Referenzstand.
|
||||
|
||||
### AP1 · Website-Umstrukturierung & Umtextung — ✅ umgesetzt
|
||||
|
||||
**Global**
|
||||
- Meta-Title und Description auf Interior umgestellt; fünf Live-Seiten hatten gar keine eigene
|
||||
Description und erbten den Fallback – jetzt gesetzt (`magazin-detail`, `impressum`, `privacy`,
|
||||
`terms`, `cookie-policy`). OG-Tags leiten sich automatisch ab.
|
||||
- Navigation: `Home · Marken · Magazin · Immobilien · Über B2in`. „Netzwerk" ist raus (Seite bleibt
|
||||
erreichbar), FAQ steht im Footer. „Referenzen" kommt mit AP5 dazu.
|
||||
- Footer-Claim „Premium-Einrichtung. Persönlich gemacht." (siehe B4).
|
||||
|
||||
**Startseite** – neue Reihenfolge in `resources/views/web/home.blade.php`:
|
||||
`header → hero → marcel-badge → weiche → kernmarken → über-marcel → sponsoring → immobilien-teaser → abschluss-cta → footer`
|
||||
- Ankündigungsleiste neu belegt (Rotpunkt Küchen), inkl. neuer `id`.
|
||||
- Hero: neue Headline, Subline, zwei Buttons, drei Checkmarks, Bild-Badge „Einrichtung, die bleibt."
|
||||
- Marcel-Badge umgetextet.
|
||||
- **Neu:** `Sections/AudienceSwitch` (Weiche Privat/Geschäft) – ersetzt „Zwei Welten. Ein Netzwerk."
|
||||
- **Neu:** `Sections/CoreBrands` mit CABINET, Rotpunkt Küchen, Febrü (Anker `#marken`).
|
||||
Febrü bewusst mit Home-Office zuerst. **Datenquelle ist vorerst das CMS-Sektionsfeld –
|
||||
in AP2 wird sie durch das Model `CmsBrand` samt Detailseiten ersetzt.** Das Markup bleibt.
|
||||
- **Neu:** `Sections/Sponsoring` (AP6) und `Sections/ImmobilienTeaser`.
|
||||
- „Ein Ökosystem, drei Säulen" ist von der Startseite genommen, die Komponente bleibt als Archiv.
|
||||
|
||||
**Sponsoring-Logos:** je Verein eine Datei gewählt, auf max. 400 px Breite herunterskaliert
|
||||
(326 KB → 130 KB) und nach `public/img/assets/sponsoring/` übernommen. Die drei Seitenverhältnisse
|
||||
sind sehr unterschiedlich (500×262, 689×689, 2443×741), deshalb eine feste Box je Logo.
|
||||
`tc-bad-waldliesborn-horn` liegt nur als JPG vor und hat damit keinen transparenten Hintergrund.
|
||||
|
||||
**Durchgang Alt-Begriffe:** auf allen Live-Seiten bereinigt – Startseite, `/about`, `/contact`,
|
||||
`/immobilien` sind sauber; `/netzwerk` und `/faq` ebenfalls. Nicht angefasst: die
|
||||
**Magazin-Artikel**, die inhaltlich über Supply-Chain und Investments handeln – das sind
|
||||
redaktionelle Beiträge, keine Seitentexte.
|
||||
|
||||
**Tests:** `tests/Feature/HomePageStructureTest.php` (11 Fälle: Reihenfolge, Hero-Buttons und
|
||||
-Checkmarks, Kernmarken samt Anker, Febrü-Gewichtung, Navigation, SEO, Sponsoring-Logos);
|
||||
`AnnouncementBarTest` und `LiveSiteReviewTest` auf die neuen Inhalte gezogen.
|
||||
|
||||
---
|
||||
|
||||
#### ⚠️ Wichtig fürs Deployment: der Relaunch-Seeder
|
||||
|
||||
`cms_theme_section()` bevorzugt das CMS gegenüber der Lang-Datei. 14 der neu getexteten Sektionen
|
||||
lagen bereits mit den **alten** Texten im CMS und hätten die neuen Inhalte überdeckt – der reguläre
|
||||
`CmsContentSeeder` fasst bestehende Einträge seit B1 bewusst nicht mehr an.
|
||||
|
||||
Deshalb gibt es `InteriorRelaunchCmsSeeder`: er überschreibt **genau die 19 in AP1 geänderten
|
||||
Sektionen** aus den Lang-Dateien und lässt alles andere in Ruhe.
|
||||
|
||||
```
|
||||
php artisan db:seed --class=InteriorRelaunchCmsSeeder
|
||||
```
|
||||
|
||||
Auf der lokalen Datenbank bereits gelaufen (5 angelegt, 14 aktualisiert). **Auf dem Live-System
|
||||
vor dem Lauf ein DB-Backup ziehen** – er überschreibt in diesen Sektionen auch redaktionelle
|
||||
Änderungen. Danach `npm run build:web`.
|
||||
|
||||
---
|
||||
|
||||
#### Nebenbefund B12 · `/service` und `/portfolio` lieferten 500 ✅
|
||||
|
||||
Beide Seiten sind öffentlich erreichbar, aber ihre Content-Sektionen (`hero_image`,
|
||||
`content_section_left/right`, `portfolio`) existieren in keiner Lang-Datei mehr – vermutlich seit
|
||||
dem Februar-Relaunch. Sie warfen seitdem einen 500er; da sie in keinem Test vorkamen, ist es
|
||||
niemandem aufgefallen. **Verifiziert: älter als AP1, keine Regression.**
|
||||
|
||||
**Behoben** wie bei den anderen stillgelegten Seiten per 301 (`/service` → `/netzwerk`,
|
||||
`/portfolio` → `/immobilien`); die Views bleiben als Archiv liegen. Beide Ziele sind eine
|
||||
Zeile in `routes/web.php`, falls Du woandershin umleiten möchtest.
|
||||
|
||||
---
|
||||
|
||||
#### Was in AP1 offen bleibt
|
||||
|
||||
| Punkt | Grund |
|
||||
|---|---|
|
||||
| Hero-Bildmotiv, Kachelbilder, OG-Image | Zulieferung offen, Bestandsbild bleibt |
|
||||
| Navigationspunkt „Referenzen" | kommt mit der Seite in AP5 |
|
||||
| Teaser „Aktuelles aus unseren Showrooms" | kommt mit AP5, sonst zeigt er ins Leere |
|
||||
|
||||
---
|
||||
|
||||
#### Logo mit Zusatz „Interior" ✅ (Zulieferung eingetroffen)
|
||||
|
||||
Marcel hat die Dateien geliefert (`dev/2026-08-28/logos/`) – die typografische Eigenlösung
|
||||
entfällt damit. Beide Varianten sind identisch aufgebaut und unterscheiden sich nur im Füllwert:
|
||||
positiv `#314052`, negativ `#FFFFFF`; der blaue Akzent `#2C9FDA` bleibt in beiden. Trotz „CMYK"
|
||||
im Dateinamen enthalten die SVGs RGB-Hexwerte, die Schrift liegt in Pfaden.
|
||||
|
||||
**Zuschnitt war nötig:** Die Lieferung lag auf einem A4-Artboard (595,3 × 419,5) – gemessen
|
||||
**74 % leerer Weißraum**. Ungeschnitten hätte das Logo bei gleicher CSS-Höhe rund halb so groß
|
||||
gerendert wie das bisherige. Der Inhaltsrahmen wurde durch Rendern ermittelt und das viewBox auf
|
||||
`153 96 289.3 227.5` gezogen (98 % Füllgrad, gleichmäßige Randluft, Verhältnis 1,27:1).
|
||||
|
||||
Abgelegt als `public/img/logos/b2in-interior-logo-{positive,negative}.{svg,png}`; die alten
|
||||
`b2in-logo-*`-Dateien bleiben als Archiv liegen.
|
||||
|
||||
**Angepasst:** `ThemeHelper` (b2in → neue Dateien) · Header `h-10` → `h-12` und Footer `h-14` →
|
||||
`h-16`, weil das neue Lockup gestapelt ist und die Wortmarke bei gleicher Höhe kleiner wirkt ·
|
||||
Footer- und Mail-`width`/`height`-Attribute auf das neue Verhältnis korrigiert (standen auf
|
||||
2,14:1 bzw. 3,5:1 und passten schon vorher nicht) · Mail-Header nutzt das neue PNG.
|
||||
|
||||
**Display ebenfalls umgestellt** (Marcel möchte es laut Mail einheitlich):
|
||||
|
||||
- Beide Varianten liegen jetzt auch unter `public/_cabinet/assets/`.
|
||||
- `DisplayModuleSettings`: Default-Logo und Claim getauscht. Der Claim stand dort noch auf
|
||||
„Connecting Design & Property".
|
||||
- **Variante nach Theme:** Das Standard-Theme ist `dark`, dort liegt das Logo auf einem dunklen
|
||||
Scrim – bislang stand da die **dunkle** Variante (deshalb der `drop-shadow` im Player). Jetzt
|
||||
dunkles Theme → negativ/weiß, helles Theme → positiv.
|
||||
- Logo-Höhe im Player von `3.5vh` auf `4.6vh`, weil das neue Lockup gestapelt ist.
|
||||
- `DisplayInteriorBrandingSeeder` vereinheitlicht die bestehenden Module. Vorher liefen dort
|
||||
**vier verschiedene Logo-Quellen** nebeneinander (zwei Dateien aus der Medienbibliothek, ein
|
||||
relativer und ein absoluter Asset-Pfad) und zwei Module trugen den Claim „Hello".
|
||||
|
||||
---
|
||||
|
||||
#### B13 · Live-Displays zeigten auf eine lokale Entwicklungsdomain ⛔→✅
|
||||
|
||||
Beim Vereinheitlichen aufgefallen: Medien-URLs lagen als **absolute URLs mit fest verdrahtetem
|
||||
Host** in den Moduleinstellungen und Item-Inhalten – teils `b2in.eu`, teils **`b2in.test`**.
|
||||
Der Player gibt absolute URLs unverändert zurück, ein auf `b2in.test` verweisendes Medium kann auf
|
||||
dem Live-Display also nicht laden.
|
||||
|
||||
**Betroffen waren vier veröffentlichte Playlists:** „Display 4 – Innen", „Kundenstopper",
|
||||
„Display 2" und „Test-Display" – unter anderem über das Modul „Cabinet-Influencerin", das auf
|
||||
drei der vier Displays läuft.
|
||||
|
||||
**Behoben:** `DisplayMediaUrlNormalizerSeeder` schreibt Schema + Host auf einen reinen Pfad um.
|
||||
Relative Pfade löst der Player über `resolveDisplayUrl()` gegen die Portal-Basis auf und
|
||||
funktionieren damit auf Test- **und** Live-System. 23 Verweise umgeschrieben, 0 verblieben.
|
||||
|
||||
Ziel-Links (Footer-URL, QR-Ziel wie `cabinet-bielefeld.de`) bleiben bewusst absolut – der Filter
|
||||
greift nur bei einem B2in-Host **und** einem Pfad unterhalb von `/storage/`. Nachgeprüft: die
|
||||
fünf Ziel-Links stehen unverändert.
|
||||
|
||||
**Tests:** `DisplayInteriorBrandingTest` (6) und `DisplayMediaUrlNormalizerTest` (6).
|
||||
|
||||
⚠️ **Wichtig:** Ob die betroffenen Mediendateien auf dem Live-Server überhaupt vorhanden sind,
|
||||
kann ich von hier nicht prüfen. Wurden sie nur lokal hochgeladen, fehlen sie dort weiterhin –
|
||||
der relative Pfad ist dann trotzdem richtig, aber die Datei muss nachgezogen werden.
|
||||
Nach dem Deployment bitte die vier Displays einmal sichten.
|
||||
|
||||
**Deployment-Reihenfolge:**
|
||||
```
|
||||
php artisan db:seed --class=InteriorRelaunchCmsSeeder
|
||||
php artisan db:seed --class=DisplayInteriorBrandingSeeder
|
||||
php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder
|
||||
npm run build:web
|
||||
```
|
||||
|
||||
### AP2 · Kernmarken-Modul im CMS — ✅ umgesetzt
|
||||
|
||||
**Model + Migration:** `CmsBrand` / Tabelle `cms_brands`.
|
||||
⚠️ Bewusst **nicht** `Brand` – das Model existiert bereits im Produkt-/Partner-Kontext
|
||||
(`Partner::brand()`, `Product::brand()`) und bleibt unangetastet. Ein Test hält das fest.
|
||||
|
||||
Felder: `slug`, `name`, `tagline`, `teaser`, `description` (HTML), `logo`, `image`, `services`,
|
||||
`gallery`, `website_url`, `showroom`, `is_published`, `order`.
|
||||
Übersetzt werden `name`, `tagline`, `teaser`, `description`.
|
||||
|
||||
**Die Lehre aus B2 ist eingebaut:** Das Frontend liest direkt aus dem Model, nicht aus einer
|
||||
Lang-Datei. `CmsBrand::forFrontend()` liefert die veröffentlichten Marken nach Slug indiziert;
|
||||
solange keine Marke gepflegt ist, greift die Lang-Sektion `core_brands` als Fallback. Die
|
||||
Fallback-Einträge tragen `has_detail_page = false`, damit die Kachel dann nicht auf eine
|
||||
Detailseite verlinkt, die es noch nicht gibt.
|
||||
|
||||
**Admin:** `admin/flux-cms/brands` → `brands-index.blade.php` (Volt), aufgebaut nach dem
|
||||
Magazin-Muster. Medien über den bestehenden `MediaPicker` (Logo, Stimmungsbild, Galerie), die
|
||||
Einleitung über den Flux-Editor mit `CmsFluxEditorHtmlTransformer`. Slug wird auf Format und
|
||||
Eindeutigkeit geprüft. Eigene Karte im CMS-Dashboard.
|
||||
|
||||
**Frontend:**
|
||||
- `Sections/CoreBrands` rendert die Kacheln aus dem Model (Anker `#marken`).
|
||||
- Neue Route `/marken/{slug}` mit `Sections/BrandDetail` und der Vorlage-Struktur aus
|
||||
`umsetzung-inhalte.md` §5: Header (Logo + Claim + Stimmungsbild) → Einleitung → Leistungen →
|
||||
Galerie → CTA, dazu eine Leiste mit den übrigen Marken.
|
||||
- Eigener Title und eigene Description je Marke.
|
||||
- Unveröffentlichte Marken liefern 404 und verschwinden von der Startseite.
|
||||
|
||||
**Seeder:** `CmsBrandSeeder` legt CABINET, Rotpunkt Küchen und Febrü mit den Texten aus
|
||||
`umsetzung-inhalte.md` §5 sowie je vier Leistungen an – Febrü mit Home-Office zuerst.
|
||||
Bestehende Marken werden **nicht** überschrieben, Marcel pflegt sie im Admin.
|
||||
|
||||
**Tests:** `Cms/CmsBrandTest` (8), `BrandPageTest` (11), `Admin/Cms/CmsBrandsIndexTest` (11) –
|
||||
darunter die Gegenprobe zu B2: eine im CMS neu angelegte Marke erscheint ohne Codeänderung auf
|
||||
der Startseite **und** bekommt ihre Detailseite.
|
||||
|
||||
#### Nachtrag: eigene Unterseite `/marken`
|
||||
|
||||
Auf Wunsch nach der Sichtung – Grundlage `dev/2026-08-28/unterseite_marke.md`. Die Startseite
|
||||
bleibt wie sie ist, die Kernmarken-Sektion dort ist jetzt ein **Teaser**.
|
||||
|
||||
- **Neue Seite `/marken`** mit dem Aufbau aus der Spec: Seitenkopf mit Breadcrumb (Home → Marken)
|
||||
→ Kernmarken → Partnernetzwerk → „Markenwelt wächst" → Abschluss-CTA. Eigener Title und eigene
|
||||
Description.
|
||||
- **Zwei Textebenen je Marke.** Dafür kamen zwei Felder dazu (`summary`, `highlights`):
|
||||
|
||||
| Feld | Wo |
|
||||
|---|---|
|
||||
| `teaser` | Kachel auf der Startseite (gekürzt) |
|
||||
| `summary` | Text auf `/marken` (zwei Absätze) |
|
||||
| `highlights` | die drei Merkmale auf `/marken` |
|
||||
| `description` | Einleitung der Detailseite |
|
||||
| `services` | Leistungen der Detailseite |
|
||||
|
||||
- **Startseite:** Kacheln verlinken direkt auf die Detailseite, darunter der Button
|
||||
„Alle Marken ansehen" → `/marken`.
|
||||
- **Navigation:** „Marken" zeigt auf `/marken` statt auf den Anker `/#marken`; der Hero-Button
|
||||
ebenfalls. Der Anker `#marken` bleibt für Direktsprünge erhalten.
|
||||
- **Slug korrigiert:** Die Spec nennt `/marken/rotpunkt`, geseedet war `rotpunkt-kuechen`.
|
||||
Angepasst, solange nichts live ist – später wäre das ein Redirect gewesen.
|
||||
- **`/netzwerk` stillgelegt.** Der Inhalt geht im Abschnitt „Mehr als Marken: unser Netzwerk" auf
|
||||
`/marken` auf. `/netzwerk`, `/interior`, `/partner` und `/service` leiten jetzt **direkt** auf
|
||||
`/marken` – vorher liefen `/interior` und `/partner` über `/netzwerk`, also eine Redirect-Kette.
|
||||
Die View bleibt als Archiv liegen.
|
||||
- **WhatsApp-Button:** erscheint nur, wenn im CMS unter `global.contact.whatsapp` eine Nummer
|
||||
hinterlegt ist (`whatsapp_link()`). Solange die Nummer nicht bestätigt ist, zeigt der CTA nur
|
||||
„Termin anfragen" – kein Button auf eine erfundene Nummer.
|
||||
|
||||
**Tests:** `MarkenPageTest` (9), `InteriorPageTest` neu geschnitten (4), dazu zwei Fälle in
|
||||
`Admin/Cms/CmsBrandsIndexTest` – darunter die Gegenprobe, dass eine im Admin angelegte Marke
|
||||
mitsamt Text und Merkmalen auf `/marken` erscheint.
|
||||
|
||||
> **Notiz für spätere Reihenfolge-Tests:** `wire:snapshot` serialisiert die Komponentendaten als
|
||||
> JSON ins Attribut und escaped Umlaute zu `\uXXXX`. Ein `strpos`-Vergleich auf dem rohen HTML
|
||||
> misst dann den Snapshot statt des sichtbaren Textes. In `MarkenPageTest` werden die Snapshots
|
||||
> vorher entfernt.
|
||||
|
||||
**Offen:** Logos, Stimmungsbilder und Galerien fehlen als Zulieferung – Kacheln und Detailseiten
|
||||
zeigen so lange einen Platzhalter. Der WhatsApp-Button im CTA-Block kommt mit AP3, sobald die
|
||||
Nummer bestätigt ist.
|
||||
|
||||
---
|
||||
|
||||
#### Nachtrag 2: Galerie je Marke – realisierte Projekte und Inspirationen getrennt
|
||||
|
||||
Aus Marcels Mail: „Der Bereich Referenzen ist mir wichtig … Entscheidend ist für mich, dass dieser
|
||||
Bereich langfristig mitwachsen und von mir selbst gepflegt werden kann. Für den Start können wir
|
||||
ergänzend mit hochwertigen Visualisierungen und KI-unterstützten Darstellungen arbeiten. Dabei
|
||||
sollte allerdings klar zwischen tatsächlich realisierten Referenzen und Entwürfen beziehungsweise
|
||||
Inspirationen unterschieden werden."
|
||||
|
||||
Umgesetzt als Galerie **auf der Detailseite jeder Kernmarke**, mit zwei Rubriken.
|
||||
|
||||
- **Datenform.** Das bestehende JSON-Feld `cms_brands.gallery` bekommt je Eintrag
|
||||
`image`, `category` (`project` | `inspiration`) und `caption`. **Keine Migration nötig.**
|
||||
- **Sicherheitsnetz gegen die schädlichere Verwechslung:** `CmsBrand::normalizeGallery()` stuft
|
||||
jeden Eintrag ohne oder mit unbekannter Kategorie als **Inspiration** ein – nie als Projekt.
|
||||
Ein Entwurf, der versehentlich als Referenz durchgeht, wäre der teurere Fehler. Die
|
||||
Normalisierung greift beim Laden, beim Speichern und beim Ausspielen.
|
||||
- **Frontend** (`brand-detail.blade.php`): Abschnitt „Referenzen und Inspirationen" mit Umschalter,
|
||||
sobald beide Rubriken gefüllt sind; ist nur eine gefüllt, steht sie mit eigener Überschrift da.
|
||||
Jede Kachel trägt ein sichtbares Label („Realisiertes Projekt" / „Visualisierung"), über den
|
||||
Inspirationen zusätzlich der Satz „Diese Darstellungen sind Entwürfe und Visualisierungen –
|
||||
keine ausgeführten Projekte." Lightbox mit Pfeiltasten und Esc, Muster übernommen aus
|
||||
`immobilien-show.blade.php`.
|
||||
- **Admin** (`brands-index.blade.php`): zwei getrennte Buttons „+ Projekt" und „+ Inspiration", je
|
||||
Eintrag ein Auswahlfeld und eine Bildunterschrift, dazu ein Hinweis, was in welche Rubrik gehört.
|
||||
Die Kategorie wird beim Anlegen entschieden, nicht per stillem Vorgabewert.
|
||||
- **Abgrenzung zu AP5:** AP5 bleibt die Rubrik-Seite „Referenzen" mit dem zweiten Display. Die
|
||||
markenbezogene Galerie hier ist die pflegbare Grundlage dafür und ersetzt AP5 nicht.
|
||||
|
||||
**Tests:** 5 Fälle in `BrandPageTest` (keine Galerie → kein Abschnitt; beide Rubriken beschriftet;
|
||||
kein Umschalter bei nur einer Rubrik; Eintrag ohne Kategorie erscheint als Visualisierung; Hinweis
|
||||
sichtbar), 5 in `Cms/CmsBrandTest` (Normalisierung, Gruppierung), 4 in
|
||||
`Admin/Cms/CmsBrandsIndexTest` (Anlegen je Rubrik, Speichern, unbekannte Kategorie, Löschen).
|
||||
|
||||
**Offen:** Bildmaterial. Marcel setzt Projektfotos und Visualisierungen selbst ein.
|
||||
|
||||
---
|
||||
|
||||
### AP3 · Terminanfrage-Widget + WhatsApp — ✅ umgesetzt
|
||||
|
||||
**Korrektur gegenüber Revision 1:** kein Inline-Abschnitt, sondern ein **schwebendes Element
|
||||
unten rechts auf allen Seiten** → gehört ins Layout `web-master.blade.php`, nicht in `home.blade.php`.
|
||||
|
||||
- Aufsetzen auf `Acme\ContactForm\Livewire\ContactForm` per `customFields` – Honeypot,
|
||||
Rate-Limit und `SpamDetector` kommen damit geschenkt.
|
||||
- Felder: Name*, E-Mail*, Telefon, Anliegen/Marke (Auswahl), Wunschtermin, Nachricht.
|
||||
- **Markenauswahl speist sich aus `CmsBrand`** → Abhängigkeit zu AP2 (Reihenfolge einhalten),
|
||||
plus feste Einträge „Projektausstattung" und „Sonstiges".
|
||||
- WhatsApp-Button daneben, Nummer als CMS-Wert (`global.contact.whatsapp`), Link `https://wa.me/<nummer>`.
|
||||
- Cookie-Consent beachten (`packages/acme/CookieConsent`).
|
||||
|
||||
**Tests:** `AppointmentWidgetTest` (17 Fälle: Einbindung auf allen Seiten, Markenauswahl aus
|
||||
`CmsBrand`, Validierung inkl. Wunschtermin in der Vergangenheit, Übergabe an den
|
||||
`ContactFormService`, Honeypot, WhatsApp sichtbar/unsichtbar); `ContactFormTest` bleibt grün.
|
||||
|
||||
#### Umsetzungsnotizen
|
||||
|
||||
- **Abweichung vom Plan:** nicht auf `Acme\ContactForm\Livewire\ContactForm` per `customFields`
|
||||
aufgesetzt. Dessen mitgelieferte View bringt ein eigenes, blaues Layout mit, das nicht zum
|
||||
Auftritt passt. Stattdessen eine eigene Komponente wie `ContactForm` und `ImmobilienContactForm`
|
||||
der Seite, die `ContactFormService` und `SpamDetector` aus dem Paket nutzt – Honeypot,
|
||||
Rate-Limit und Spam-Erkennung sind damit trotzdem drin.
|
||||
- **Platzierung:** `web-master.blade.php`, unten rechts, `z-40`. Der Cookie-Button des
|
||||
Consent-Managers sitzt unten links (ebenfalls `z-40`), sein Dialog auf `z-50` – die Einwilligung
|
||||
bleibt also immer erreichbar und wird nie verdeckt.
|
||||
- **Kein eigener Consent nötig:** Das Widget setzt nichts im Browser, der WhatsApp-Link ist ein
|
||||
ausgehender Link ohne Einbettung.
|
||||
- Die `[x-cloak]`-Regel liegt jetzt einmal zentral im Layout – die Seiten brachten sie bisher nur
|
||||
teilweise selbst mit, das Widget braucht sie überall.
|
||||
- Felder: Name*, E-Mail*, Telefon, Anliegen (Auswahl), Wunschtermin, Nachricht, Einwilligung*.
|
||||
Der Wunschtermin ist auf heute oder später begrenzt, im Browser über `min` und serverseitig
|
||||
über `after_or_equal:today`.
|
||||
- Betreff der Mail: `Terminanfrage B2in Interior: <Anliegen>`, Log-Kontext `appointment-widget` –
|
||||
so lassen sich Widget-Anfragen von den übrigen Formularen unterscheiden. Die Seite, von der die
|
||||
Anfrage kam, steht als `source` in der Mail.
|
||||
- **WhatsApp** erscheint weiterhin nur, wenn unter `global.contact.whatsapp` eine Nummer im CMS
|
||||
steht. Ohne Nummer zeigt das Widget allein den Termin-Button.
|
||||
|
||||
#### WhatsApp: was technisch geht und was nicht
|
||||
|
||||
Eine echte WhatsApp-Anbindung (Nachrichten empfangen, im CMS beantworten, Verlauf speichern)
|
||||
setzt die WhatsApp Business Platform voraus: Meta-Verifizierung des Unternehmens, ein Anbieter
|
||||
für den API-Zugang, laufende Kosten je Konversation. Das ist nicht Teil dieses Auftrags.
|
||||
|
||||
Umgesetzt ist die dafür übliche Alternative, ein **Klick-zum-Chat-Link** (`wa.me`):
|
||||
|
||||
- Der Button sitzt im Terminanfrage-Panel unter dem Absenden-Button.
|
||||
- Auf dem Handy öffnet die installierte WhatsApp-App, am Rechner WhatsApp Web bzw. die
|
||||
Desktop-App. Ist WhatsApp nirgends vorhanden, landet man auf der Hinweisseite von `wa.me`.
|
||||
- Der Nachrichtentext ist **vorbereitet** und wird im Browser aus dem zusammengesetzt, was im
|
||||
Formular schon steht (Anliegen, Wunschtermin, Name). Der Einstiegssatz ist im CMS pflegbar
|
||||
(`global.appointment_widget.whatsapp_text`).
|
||||
- **Abgeschickt wird die Nachricht vom Besucher selbst** – das steht auch so unter dem Button.
|
||||
|
||||
Was das bedeutet, bewusst festgehalten:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Wo landet die Nachricht | in Marcels WhatsApp, nicht im CMS und nicht per Mail |
|
||||
| Was sehen wir davon | nichts – kein Eintrag, keine Statistik, kein Spamschutz |
|
||||
| Voraussetzung | eine Mobilnummer, die WhatsApp empfangen kann (sinnvoll: WhatsApp Business) |
|
||||
| Datenschutz | ausgehender Link zu Meta. In die Datenschutzerklärung gehört ein Absatz dazu; ein Consent-Banner braucht es nicht, weil nichts eingebettet wird und nichts gesetzt wird |
|
||||
|
||||
Wer eine Anfrage im System dokumentiert haben will, nutzt weiterhin das Formular – der
|
||||
WhatsApp-Weg ist die schnelle, aber unprotokollierte Abkürzung.
|
||||
|
||||
### Nachtrag 3 · Bestandsinhalte auf den Interior-Auftritt umgestellt ✅
|
||||
|
||||
Nach der Sichtung: Drei verlinkte Seiten erzählten noch die Dubai-/Plattform-Geschichte.
|
||||
`/immobilien` bleibt bewusst unverändert – die Seite ist der „Außerdem"-Bereich.
|
||||
|
||||
**`/faq`** – die beiden Rubriken „Fokus: Immobilien-Investoren (B2C)" und „Fokus: B2B-Partner"
|
||||
sind ersetzt durch **„Für Ihr Zuhause"** und **„Für Projekte und Objekte"** (je vier Fragen:
|
||||
Einstieg mit einem einzelnen Möbelstück, Kosten der Maßanfertigung, Montage, Showroom –
|
||||
bzw. Projektgröße, Termintreue, Architekten, Netzwerk). Von den allgemeinen Fragen waren zwei
|
||||
noch Dubai-lastig, die sind jetzt Beratungsablauf und Verlässlichkeit. Die englische Fassung war
|
||||
noch komplett auf dem alten Stand und ist mitgezogen.
|
||||
|
||||
**`/about`** – das Mission-Zitat sprach von „digitalen Werkzeugen" und „Brücken zwischen Märkten".
|
||||
Neu: wenige ausgewählte Hersteller, Fachbetriebe aus der Region, ein Ansprechpartner. Die sechs
|
||||
Werte waren Plattform-Vokabular (Innovation, Konnektivität, Design-Exzellenz) und heißen jetzt
|
||||
Beratung statt Verkauf, Maßarbeit, Ausgewählte Marken, Regional verwurzelt, Ein Ansprechpartner,
|
||||
Verlässlichkeit. In der Zeitleiste sind „Die Idee", „Das Fundament" und „Die Vision" umgeschrieben.
|
||||
|
||||
**`/contact`** – die Betreffliste beginnt jetzt mit Beratungstermin, Maßanfertigung und
|
||||
Küchenplanung; „Internationale Immobilien" rutscht nach hinten, bleibt aber erhalten.
|
||||
|
||||
**`/magazin`** – zwei neue Beiträge, die **an erster Stelle** stehen:
|
||||
`massanfertigung-warum-der-millimeter-zaehlt` und `kueche-planen-vom-wunsch-zum-grundriss`.
|
||||
Die vier Dubai-Beiträge bleiben, sie gehören zum Immobilienbereich.
|
||||
|
||||
> ⚠️ Die beiden Beiträge sind **Platzhalter**. Bewusst ohne Referenzen, Zahlen oder Namen
|
||||
> geschrieben, damit nichts behauptet wird, was nicht belegt ist – vor dem Livegang von Marcel
|
||||
> gegenlesen lassen. Als Bilder dienen vorhandene Motive aus dem Altbestand.
|
||||
|
||||
**Zwei technische Punkte dabei:**
|
||||
|
||||
- Neue Lang-Artikel bringen ihren Slug jetzt selbst mit (`'slug' => …`, aufgelöst über
|
||||
`CmsArticle::slugForLangArticle()`). `LEGACY_ID_TO_SLUG` bleibt damit das, was der Name sagt:
|
||||
die Karte für die alten `/magazin/{id}`-URLs. `/magazin/6` ist korrekt ein 404, weil es diese
|
||||
URL nie gab.
|
||||
- `CmsArticleSeeder` sortiert nicht mehr per `ksort`. Die Reihenfolge in der Lang-Datei bestimmt
|
||||
jetzt die Reihenfolge im Magazin – im CMS über `order`, im Lang-Fallback über die
|
||||
Array-Reihenfolge. Vorher konnten beide Wege auseinanderlaufen.
|
||||
|
||||
**Tests:** vier Fälle in `MagazinPageTest` (Reihenfolge, beide Slugs, kein erfundener Legacy-Link,
|
||||
Slug-Auflösung), drei in `LiveSiteReviewTest` (FAQ ohne Dubai mit neuen Rubriken, About mit den
|
||||
neuen Werten, Kontakt mit den neuen Betreffen).
|
||||
|
||||
**Nachkontrolle:** Gegen die Live-Seiten geprüft, nicht nur gegen die Sprachdatei – dabei fiel in
|
||||
der FAQ eine dritte Frage auf, die noch vom „Local for Local"-Netzwerk sprach. Ebenfalls korrigiert.
|
||||
|
||||
**Noch offen auf diesen Seiten:** eigene Beitragsbilder für die zwei neuen Artikel; die vier
|
||||
Dubai-Beiträge bleiben inhaltlich unverändert stehen.
|
||||
|
||||
---
|
||||
|
||||
### AP4 · Display-Spiegelung auf der Website — ✅ umgesetzt
|
||||
|
||||
**Korrektur gegenüber Revision 1:** Revision 1 empfahl, die Slides nativ zu rendern. Bei 3 Std.
|
||||
ist das nicht zu halten, und die Umsetzungsliste schreibt „nutzt die vorhandene Display-/Player-API
|
||||
als Datenquelle". → **Einbettung des vorhandenen Players im 9:16-Container.**
|
||||
|
||||
- Sektion `Sections/DisplayFeed` mit `aspect-ratio: 9/16`, darin der Player.
|
||||
- **Vorher zu klären:** Die `/preview/…`-Routen sind token- bzw. modulbasiert und für den internen
|
||||
Gebrauch gedacht. Für die öffentliche Domain braucht es eine schmale, read-only Route
|
||||
(z. B. `/embed/display/{display}`), die keine Preview-Tokens nach außen gibt.
|
||||
- Keine doppelte Pflege: Marcel pflegt weiterhin nur im Display-CMS.
|
||||
|
||||
#### Umsetzung
|
||||
|
||||
- **Route `GET /embed/display/{display}`** (`DisplayEmbedController`), bewusst getrennt von den
|
||||
Preview-Routen: Die arbeiten mit `preview_token` und zeigen den **Entwurf**. Nach außen darf
|
||||
weder ein Token noch ein unveröffentlichter Stand gelangen. Die Embed-Route kennt nur die
|
||||
numerische ID, liefert 404 bei inaktivem Display, bei reinem Entwurf und bei leerer Playlist,
|
||||
und setzt `X-Robots-Tag: noindex`.
|
||||
- **Kein Proxy, keine CORS-Frage:** Der Player liest die ID aus dem Pfad (`/display/{id}` steckt in
|
||||
`/embed/display/{id}`) und holt seine Konfiguration über die bereits öffentliche Route
|
||||
`/api/display/{display}/config` – dieselbe Quelle wie das physische Display. Da die API-Routen
|
||||
für alle Domains registriert sind, läuft der Abruf gleichursprünglich über `b2in.test`.
|
||||
Möglich wurde das durch **B13**: Vorher standen absolute `b2in.test`-URLs in den Playlists.
|
||||
- **Sektion `Sections/DisplayFeed`** im 9:16-Rahmen. Welches Display gezeigt wird, steht im CMS
|
||||
(`referenzen.display_feed.display_id`); ohne Eintrag greift das erste aktive Display mit
|
||||
veröffentlichter Playlist. Gibt es keins, rendert die Sektion **nichts** – lieber keine Sektion
|
||||
als ein Rahmen mit ewigem Ladebalken. Auch die Texte bleiben dann leer, sonst stünden sie
|
||||
im Livewire-Snapshot der Seite.
|
||||
- Eingebunden auf der Startseite (an der dafür vorgesehenen Stelle) und auf `/referenzen`.
|
||||
|
||||
**Tests:** `DisplayWebFeedTest` (10 Fälle: Embed liefert die Datei, kein Token im Ausgabe-Inhalt,
|
||||
404 bei inaktiv/Entwurf/leer/unbekannt, Einbindung auf der Startseite, CMS-Auswahl und Fallback).
|
||||
|
||||
### AP5 · Rubrik-Seite „Referenzen" — ✅ umgesetzt
|
||||
|
||||
**Korrektur gegenüber Revision 1:** Revision 1 schlug einen neuen `DisplayVersionType`-Case vor.
|
||||
Die Umsetzungsliste sagt „zweites, separates **Display** im Display-CMS" – das ist ein weiterer
|
||||
`Display`-Datensatz und braucht **keine Enum-Änderung**. Damit entfallen die Folgeänderungen an
|
||||
`DisplayPlaylistConfigBuilder::moduleData()`, `DisplayModuleSettings` und den
|
||||
`version-editor-*`-Partials. Deutlich risikoärmer und billiger.
|
||||
|
||||
- Zweites `Display` anlegen, Route `/referenzen`, View + Sektion, Aufnahme in die Navigation.
|
||||
- Startseiten-Teaser „Aktuelles aus unseren Showrooms" mit Button „Alle Referenzen ansehen →".
|
||||
- 2–3 Platzhalter-Einträge.
|
||||
- YouTube-Verlinkungen mit Consent-Gate.
|
||||
- Inhaltliche Regel dokumentieren: unter „Referenzen" nur realisierte Projekte; Visualisierungen
|
||||
und Entwürfe gehören in die Kernmarken-Detailseiten.
|
||||
- **Bereits vorhanden:** die markenbezogene Galerie mit den Rubriken „Realisierte Projekte" und
|
||||
„Inspirationen und Entwürfe" (siehe Nachtrag 2 zu AP2). AP5 baut darauf auf, statt eine zweite
|
||||
Pflegestelle für dieselben Bilder zu schaffen.
|
||||
|
||||
#### Umsetzung
|
||||
|
||||
- Seite `/referenzen`: Seitenkopf → realisierte Projekte → Showroom-Display → Abschluss-CTA.
|
||||
Navigationspunkt zwischen „Marken" und „Magazin".
|
||||
- **Kein zweites Display nötig, keine zweite Pflegestelle:** Die Projekte kommen aus den
|
||||
Markengalerien (AP2) und werden über alle Marken hinweg gesammelt. Es erscheinen ausschließlich
|
||||
Einträge der Rubrik **„Realisiertes Projekt"** – Visualisierungen bleiben draußen, damit
|
||||
„Referenzen" hält, was das Wort verspricht. Jede Kachel verlinkt zurück auf ihre Markenseite.
|
||||
- **Ehrlicher Leerzustand:** Solange keine Projekte gepflegt sind, steht dort ein Satz dazu und ein
|
||||
Terminlink – keine erfundene Referenz und keine leere Fläche.
|
||||
- Der Seitenkopf ist jetzt eine wiederverwendbare Sektion (`PageHero` mit `section` und
|
||||
`breadcrumb`), vorher war er auf `/marken` festgelegt.
|
||||
|
||||
**Tests:** `ReferenzenPageTest` (6 Fälle: Seite lädt mit eigenem Titel, Navigationspunkt,
|
||||
Projekte aus allen Marken, Visualisierungen bleiben draußen, Rückverlinkung, Leerzustand).
|
||||
|
||||
### AP6 · Engagement / Sponsoring — ✅ umgesetzt (im Rahmen von AP1)
|
||||
|
||||
Schlanke Sektion „Regional verbunden" nach der Marcel-Sektion: ein Einleitungssatz plus drei
|
||||
Logos in ruhiger Reihe (Graustufen/gedeckt).
|
||||
|
||||
Logos liegen bereits unter `dev/2026-08-28/sponsoren-logos/` – **7 Dateien für 3 Vereine**
|
||||
(Arminia, TCBWH, TCH in mehreren Varianten und Formaten). Vor der Umsetzung je Verein **eine**
|
||||
Datei auswählen, nach `public/img/assets/` bzw. in die Medienbibliothek übernehmen und
|
||||
vereinheitlichen (gleiche Höhe, transparenter Hintergrund – die `.jpg`-Varianten haben keinen).
|
||||
Setzt **B9** voraus, damit die Logos per Picker pflegbar sind.
|
||||
|
||||
---
|
||||
|
||||
## 4. Nicht Bestandteil dieses Auftrags ⏸
|
||||
|
||||
Referenzbereich voll ausgebaut · 16:9-Display-Modul · Immobilien-CMS · Dubai-Map ·
|
||||
Markenrichtlinie Fahrzeug/Print · weitere frei anlegbare Rubriken · eigene Videolösung.
|
||||
**Zusätzlich neu zu bewerten:** B2 (Magazin-CMS ans Frontend anschließen, ≈2–3 Std.)
|
||||
und B8 (Passwort aus dem Seeder).
|
||||
|
||||
---
|
||||
|
||||
## 5. Abhängigkeiten
|
||||
|
||||
```
|
||||
AP1 (Struktur, Umtextung, B1/B3/B4/B5/B6/B7)
|
||||
├─ AP2 (Kernmarken, B9) ──┐
|
||||
├─ AP4 (Display-Spiegelung)│
|
||||
├─ AP5 (Referenzen) │
|
||||
├─ AP6 (Sponsoring) ◄──────┤ braucht B9
|
||||
└─ AP3 (Termin-Widget) ◄───┘ Markenauswahl braucht CmsBrand
|
||||
```
|
||||
|
||||
**B1 zuerst.** Solange der Seeder überschreibt, ist jede redaktionelle Arbeit flüchtig.
|
||||
|
||||
---
|
||||
|
||||
## 6. Restrisiken & offene Punkte
|
||||
|
||||
| Punkt | Stand | Umgang |
|
||||
|---|---|---|
|
||||
| **Rechtstexte** nennen weiter „Connecting Design and Property", Dubai/Lissabon, Supply-Chain | ⚠️ offen | Formulierung freigeben lassen, dann eintragen – nicht selbst getextet |
|
||||
| **OG-Bild fehlt komplett** (`b2in-og-default.jpg` existiert nicht) | ⚠️ offen | Motiv wählen, ablegen |
|
||||
| WhatsApp-Nummer (+49 151 51002992?) | offen | bestätigen lassen; ohne Nummer bleibt der Button unsichtbar |
|
||||
| Logos, Stimmungsbilder, Galeriefotos der drei Marken | offen | Platzhalter stehen, Marcel trägt im CMS nach |
|
||||
| Zwei neue Magazin-Beiträge sind Platzhalter | offen | gegenlesen lassen |
|
||||
| Sponsoren-Kurztexte sind Entwürfe | offen | gegenlesen lassen |
|
||||
| Vier Dubai-Beiträge bleiben im Magazin | bewusst | gehören zum Immobilienbereich, der bestehen bleibt |
|
||||
| `ecosystem_stats` behauptet „1,7K+ Partner", „510+ Projekte", „98 %" | ruhend | Sektion wird auf keiner erreichbaren Seite gerendert – vor einer Wiederverwendung prüfen |
|
||||
| B1/B2 Entscheidung | ✅ erledigt | Redaktionsschutz im Seeder, Magazin am Frontend |
|
||||
| Logo mit Zusatz „Interior" | ✅ erledigt | Zulieferung eingetroffen und zugeschnitten |
|
||||
| Sponsoring-Logos uneinheitlich | ✅ erledigt | Kacheln mit weißer Bühne, JPG ohne Transparenz fällt nicht mehr auf |
|
||||
|
||||
**Spielregel aus der Umsetzungsliste:** eine Korrekturschleife je Bereich ist enthalten.
|
||||
Weitere Runden vorher melden und beziffern.
|
||||
|
||||
---
|
||||
|
||||
## 7. Definition of Done
|
||||
|
||||
- [x] Alle Live-Seiten laden (`LiveSiteReviewTest` grün)
|
||||
- [x] Marcel kann Marke anlegen, Logo per Picker setzen, Galerie pflegen – und die Änderung
|
||||
erscheint auf der Website (Gegenprobe zu B2, getestet in `CmsBrandsIndexTest`)
|
||||
- [x] Erneuter `CmsContentSeeder`-Lauf löscht keine redaktionellen Inhalte (Gegenprobe zu B1)
|
||||
- [x] `./vendor/bin/pint`
|
||||
- [x] `npm run build:b2in` (Build-Verzeichnis `build/b2in`)
|
||||
- [x] `php artisan test --compact` vollständig grün — 810 Tests, 3037 Assertions
|
||||
- [ ] Keine Treffer mehr für „Supply-Chain", „Local for Local", „Ökosystem", „Connecting Design"
|
||||
auf den Live-Seiten. **Stand: 8 statt ursprünglich 90.** Davon
|
||||
5 in `/magazin` (die vier Dubai-Beiträge, bleiben bewusst),
|
||||
1 in `/privacy` und 2 in `/terms` (Rechtstexte, siehe Abschnitt 0, Schritt 2).
|
||||
Erst abhakbar, wenn die Rechtstexte freigegeben sind.
|
||||
- [ ] OG-Bild vorhanden
|
||||
- [ ] Rechtstexte freigegeben und eingetragen
|
||||
|
||||
---
|
||||
|
||||
## 7a. Vorschau-Instanz für die Abstimmung
|
||||
|
||||
Für die erste Abstimmung läuft der neue Stand als **eigenständige Vorschau** unter
|
||||
`preview.b2in.eu` – eigenes Verzeichnis, eigene `.env`, eigene Datenbank. Live bleibt unangetastet.
|
||||
|
||||
**Ablauf Schritt für Schritt: `dev/2026-08-28/preview-deployment.md`.**
|
||||
Dateien dafür: `dev/2026-08-28/deploy/b2in-interior-update.tar.gz` (geänderte Dateien plus
|
||||
gebaute Assets) und `deploy/dateiliste.txt`.
|
||||
|
||||
Zwei Punkte, die dabei leicht übersehen werden:
|
||||
|
||||
- **Die Vorschau braucht `DOMAIN_B2IN=preview.b2in.eu` in ihrer `.env`.** Der
|
||||
`ThemeServiceProvider` setzt `URL::forceRootUrl()` auf die konfigurierte Domain; ein unbekannter
|
||||
Host fällt auf `APP_URL` zurück. Ohne diesen Eintrag rendert die Vorschau zwar, aber jeder
|
||||
interne Link springt auf die Live-Seite.
|
||||
- **Eigene Datenbank, keine geteilte.** `InteriorRelaunchCmsSeeder` überschreibt 23 CMS-Sektionen –
|
||||
auf der Live-DB ausgeführt wäre der alte Stand weg.
|
||||
|
||||
Neu dafür im Code: `config('app.indexable')`. Außerhalb von `APP_ENV=production` liefert jede Seite
|
||||
`noindex, nofollow`, damit eine Vorschau nicht mit dem Original um Suchergebnisse konkurriert.
|
||||
Über `SITE_INDEXABLE` einzeln steuerbar.
|
||||
|
||||
---
|
||||
|
||||
## 8. Deployment-Checkliste (Livegang)
|
||||
|
||||
> **Diese Liste beim Livegang von oben nach unten abarbeiten.** Sie wird mit jedem Arbeitspaket
|
||||
> ergänzt – zuletzt aktualisiert nach AP1 und der Display-Umstellung.
|
||||
|
||||
### 8.1 Vorher
|
||||
|
||||
- [ ] **DB-Backup ziehen.** Die Seeder unter 8.2 schreiben in `flux_cms_contents`,
|
||||
`display_versions` und `display_version_items`.
|
||||
- [ ] `.env` prüfen: `SEED_ADMIN_NAME`, `SEED_ADMIN_EMAIL`, `SEED_ADMIN_PASSWORD` gesetzt
|
||||
(neu seit B8 – vorher stand das Passwort im Repo).
|
||||
- [ ] Wartungsfenster mit Marcel abstimmen: die Displays holen ihre Konfiguration zyklisch,
|
||||
ein Neustart ist nicht nötig, aber ein sichtbarer Wechsel mitten im Ladengeschäft schon.
|
||||
|
||||
### 8.2 Deployment
|
||||
|
||||
```bash
|
||||
php artisan migrate --force # legt u. a. cms_brands an (AP2)
|
||||
|
||||
# 0. Kernmarken anlegen (CABINET, Rotpunkt Küchen, Febrü).
|
||||
# Überschreibt nichts – bereits gepflegte Marken bleiben unberührt.
|
||||
php artisan db:seed --class=CmsBrandSeeder --force
|
||||
|
||||
# 1. Neue Texte ins CMS. Überschreibt GENAU die 19 in AP1 geänderten Sektionen,
|
||||
# alles andere bleibt unangetastet.
|
||||
php artisan db:seed --class=InteriorRelaunchCmsSeeder --force
|
||||
|
||||
# 2. Display-Branding auf das Interior-Logo vereinheitlichen (Logo je Theme + neuer Claim).
|
||||
php artisan db:seed --class=DisplayInteriorBrandingSeeder --force
|
||||
|
||||
# 3. Medien-URLs host-unabhängig machen. Ohne diesen Schritt zeigen vier veröffentlichte
|
||||
# Playlists weiterhin auf b2in.test und laden auf dem Live-Display nicht.
|
||||
php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder --force
|
||||
|
||||
php artisan config:cache
|
||||
php artisan view:clear
|
||||
npm ci && npm run build:web
|
||||
```
|
||||
|
||||
### 8.3 Nachher prüfen
|
||||
|
||||
- [ ] 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`
|
||||
- [ ] `/netzwerk`, `/interior`, `/partner`, `/service` leiten auf `/marken`
|
||||
- [ ] Im Admin unter „Kernmarken" eine Marke ändern und prüfen, dass es auf der Seite ankommt
|
||||
- [ ] Ankündigungsleiste erscheint (Dismiss-Key hängt seit B3 am Inhalt – wer die alte Leiste
|
||||
weggeklickt hatte, sieht die neue wieder)
|
||||
- [ ] Logo in Header, Footer **und** in einer Test-Mail
|
||||
- [ ] Alte Magazin-URLs `/magazin/1` … `/magazin/5` leiten per 301 auf den Slug
|
||||
- [ ] `/service` und `/portfolio` leiten um statt 500 zu liefern
|
||||
- [ ] **Die vier Displays sichten:** „Display 4 – Innen", „Kundenstopper", „Display 2",
|
||||
„Test-Display". Besonders das Modul „Cabinet-Influencerin" – dessen Video lag auf
|
||||
`b2in.test`. Ob die Datei auf dem Live-Server überhaupt existiert, ließ sich lokal nicht
|
||||
prüfen; fehlt sie, muss sie nachgeladen werden.
|
||||
- [ ] Search Console: die alten Magazin-URLs waren indexiert, die 301 fängt sie ab
|
||||
- [ ] Search Console: `/netzwerk` war indexiert und leitet jetzt auf `/marken`
|
||||
|
||||
### 8.4 Zurückrollen
|
||||
|
||||
Die Seeder sind nicht umkehrbar. Rückweg ist das Backup aus 8.1 – für die betroffenen Tabellen
|
||||
genügt ein selektives Zurückspielen von `flux_cms_contents`, `display_versions` und
|
||||
`display_version_items`.
|
||||
|
||||
### 8.5 Nicht vergessen
|
||||
|
||||
- [ ] Altes Seeder-Passwort rotieren, falls es anderswo benutzt wird – es steht weiterhin in der
|
||||
Git-Historie (B8).
|
||||
- [ ] WhatsApp-Nummer bestätigen lassen – erst dann erscheint der Button im Terminanfrage-Widget
|
||||
und in den CTA-Blöcken (CMS: `global.contact.whatsapp`).
|
||||
- [ ] `CONTACT_FORM_RECIPIENT` in der Live-`.env` prüfen: dorthin gehen auch die Terminanfragen
|
||||
aus dem Widget.
|
||||
- [ ] Datenschutzerklärung um einen Absatz zum WhatsApp-Link ergänzen, sobald die Nummer steht.
|
||||
- [ ] **Rechtstexte:** AGB (`b2in_legal.php` Zeile 117) und Datenschutzerklärung (Zeile 221)
|
||||
nennen weiter „Connecting Design and Property", Dubai/Lissabon und Supply-Chain-Management.
|
||||
Von Marcel prüfen lassen, dann eintragen.
|
||||
- [ ] Prüfen, welches Display auf der Website laufen soll (`referenzen.display_feed.display_id`).
|
||||
Ohne Eintrag zeigt die Seite das erste aktive Display mit veröffentlichter Playlist.
|
||||
- [ ] Die zwei neuen Magazin-Beiträge von Marcel gegenlesen lassen – sie sind Platzhalter.
|
||||
- [ ] OG-Bild anlegen: das Layout verweist auf `img/assets/b2in-og-default.jpg`, die Datei
|
||||
existiert nicht. Bis dahin zeigt jede geteilte Seite eine Vorschau ohne Bild.
|
||||
- [ ] Sponsoring-Logo `tc-bad-waldliesborn-horn` liegt nur als JPG vor, also ohne transparenten
|
||||
Hintergrund. Falls Marcel eine PNG-Variante hat, austauschen.
|
||||
- [ ] Markengalerien vor dem Livegang durchsehen: jedes Bild muss in der richtigen Rubrik stehen.
|
||||
Ohne gesetzte Kategorie erscheint ein Bild als „Visualisierung" – für ein echtes Projektfoto
|
||||
also bewusst „Realisiertes Projekt" wählen.
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 30.8.0, SVG Export Plug-In . SVG Version: 9.03 Build 0) -->
|
||||
<svg version="1.0" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 595.3 419.5" style="enable-background:new 0 0 595.3 419.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#2C9FDA;}
|
||||
.st2{fill:none;stroke:#2C9FDA;stroke-width:3;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M156.8,262.4V158.9h40.7c7.5,0,13.8,1.1,18.9,3.4c5,2.3,8.8,5.4,11.3,9.4c2.5,4,3.8,8.6,3.8,13.8
|
||||
c0,4.1-0.8,7.6-2.4,10.7c-1.6,3-3.8,5.5-6.6,7.4c-2.8,1.9-5.9,3.3-9.5,4.1v1c3.9,0.1,7.5,1.2,10.9,3.3c3.4,2.1,6.2,4.9,8.3,8.6
|
||||
c2.1,3.7,3.2,8.1,3.2,13.2c0,5.5-1.3,10.3-4,14.7c-2.7,4.3-6.6,7.7-11.8,10.2c-5.2,2.5-11.7,3.7-19.5,3.7H156.8z M177.8,202.4
|
||||
h16.6c3,0,5.7-0.5,8.1-1.6c2.4-1.1,4.3-2.6,5.6-4.7c1.4-2,2-4.4,2-7.2c0-3.8-1.3-6.8-4-9.2c-2.6-2.4-6.4-3.5-11.3-3.5h-17V202.4
|
||||
z M177.8,244.9H196c6.2,0,10.7-1.2,13.5-3.6c2.8-2.4,4.3-5.6,4.3-9.5c0-2.9-0.7-5.5-2.1-7.7c-1.4-2.2-3.4-4-6-5.3
|
||||
c-2.6-1.3-5.6-1.9-9.2-1.9h-18.8V244.9z"/>
|
||||
<path class="st0" d="M249.4,262.4v-15.3l36.4-34.4c3.1-3.1,5.8-5.8,7.9-8.3c2.1-2.5,3.8-4.9,4.9-7.3c1.1-2.4,1.7-5,1.7-7.7
|
||||
c0-3.1-0.7-5.8-2.1-8c-1.4-2.2-3.3-3.9-5.7-5.1c-2.4-1.2-5.1-1.8-8.2-1.8c-3.2,0-6,0.6-8.3,1.9c-2.4,1.3-4.2,3.1-5.5,5.6
|
||||
c-1.3,2.4-1.9,5.3-1.9,8.7h-20.1c0-6.7,1.5-12.6,4.6-17.5c3.1-5,7.3-8.8,12.7-11.5c5.4-2.7,11.7-4.1,18.8-4.1
|
||||
c7.3,0,13.6,1.3,19,3.9c5.4,2.6,9.6,6.2,12.7,10.8c3,4.6,4.5,9.9,4.5,15.8c0,3.8-0.7,7.6-2.2,11.4c-1.5,3.8-4.2,8-8,12.6
|
||||
c-3.8,4.7-9.3,10.2-16.3,16.7l-15.5,15.4v0.8h43.4v17.4H249.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M345,262.2v-74.1h18.2v74.1H345z"/>
|
||||
<path class="st0" d="M395.1,262.2h-18.2v-74.1h18.2v12.4h0.7c1.5-4,3.9-7.3,7.2-10c3.3-2.7,7.8-4,13.6-4c7.6,0,13.4,2.5,17.5,7.6
|
||||
c4.1,5.1,6.2,12.2,6.2,21.4v46.8h-18.2v-45c0-5.3-0.9-9.3-2.8-11.9c-1.9-2.6-5-4-9.4-4c-2.5,0-4.8,0.5-7.1,1.3
|
||||
c-2.3,0.9-4.1,2.2-5.5,4c-1.4,1.8-2.1,4-2.1,6.6V262.2z"/>
|
||||
</g>
|
||||
<path class="st1" d="M354.1,152.3c2.5,0,4.7,0.3,6.6,0.8c-14-32.8-49-56-89.9-56c-41.5,0-76.8,23.9-90.5,57.3h14.3
|
||||
c8.8-30.8,39.6-53.5,76.1-53.5c36.1,0,66.6,22.2,75.8,52.5C348.6,152.7,351.1,152.3,354.1,152.3z"/>
|
||||
<path class="st0" d="M354.1,178.1c-3.7,0-6.4-0.9-8.1-2.6c-1.7-1.7-2.6-3.9-2.6-6.5v-2.8c0-2.6,0.9-4.8,2.6-6.5
|
||||
c1.7-1.7,4.4-2.6,8.1-2.6s6.4,0.9,8.1,2.6c1.7,1.7,2.6,3.9,2.6,6.5v2.8c0,2.6-0.9,4.7-2.6,6.5
|
||||
C360.5,177.2,357.8,178.1,354.1,178.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M156.4,321.9v-5.4h4v-20.5h-4v-5.4h14.9v5.4h-4v20.5h4v5.4H156.4z"/>
|
||||
<path class="st0" d="M196.8,307l-3-6.3h-0.1v21.1h-6.4v-31.4h7.5l8.6,14.8l3,6.3h0.1v-21.1h6.4v31.4h-7.5L196.8,307z"/>
|
||||
<path class="st0" d="M243.1,296.5v25.3h-6.8v-25.3h-8.5v-6.1h23.8v6.1H243.1z"/>
|
||||
<path class="st0" d="M266.4,321.9v-31.4h21.4v6.1h-14.5v6.4h12.5v6h-12.5v6.8h14.5v6.1H266.4z"/>
|
||||
<path class="st0" d="M310.7,321.9h-6.8v-31.4h14.9c5.8,0,9.5,4,9.5,10c0,4.2-1.9,7.6-5.7,9l6.2,12.3h-7.6l-5.5-11.5h-4.9V321.9z
|
||||
M317.9,304.6c2,0,3.3-1.1,3.3-3.1v-2c0-2-1.3-3.1-3.3-3.1h-7.2v8.2H317.9z"/>
|
||||
<path class="st0" d="M343.2,321.9v-5.4h4v-20.5h-4v-5.4h14.9v5.4h-4v20.5h4v5.4H343.2z"/>
|
||||
<path class="st0" d="M372.8,306.2c0-10.7,5.5-16.2,13.8-16.2c8.3,0,13.8,5.6,13.8,16.2c0,10.7-5.5,16.2-13.8,16.2
|
||||
C378.3,322.4,372.8,316.8,372.8,306.2z M393.2,308.5v-4.7c0-5-2.5-7.8-6.6-7.8s-6.6,2.8-6.6,7.8v4.7c0,5,2.5,7.8,6.6,7.8
|
||||
S393.2,313.5,393.2,308.5z"/>
|
||||
<path class="st0" d="M423.1,321.9h-6.8v-31.4h14.9c5.8,0,9.5,4,9.5,10c0,4.2-1.9,7.6-5.7,9l6.2,12.3h-7.6l-5.5-11.5h-4.9V321.9z
|
||||
M430.3,304.6c2,0,3.3-1.1,3.3-3.1v-2c0-2-1.3-3.1-3.3-3.1h-7.2v8.2H430.3z"/>
|
||||
</g>
|
||||
<line class="st2" x1="154.1" y1="275.5" x2="440.2" y2="275.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 30.8.0, SVG Export Plug-In . SVG Version: 9.03 Build 0) -->
|
||||
<svg version="1.0" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 595.3 419.5" style="enable-background:new 0 0 595.3 419.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#314052;}
|
||||
.st1{fill:#2C9FDA;}
|
||||
.st2{fill:none;stroke:#2C9FDA;stroke-width:3;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M156.8,262.4V158.9h40.7c7.5,0,13.8,1.1,18.9,3.4c5,2.3,8.8,5.4,11.3,9.4c2.5,4,3.8,8.6,3.8,13.8
|
||||
c0,4.1-0.8,7.6-2.4,10.7c-1.6,3-3.8,5.5-6.6,7.4c-2.8,1.9-5.9,3.3-9.5,4.1v1c3.9,0.1,7.5,1.2,10.9,3.3c3.4,2.1,6.2,4.9,8.3,8.6
|
||||
c2.1,3.7,3.2,8.1,3.2,13.2c0,5.5-1.3,10.3-4,14.7c-2.7,4.3-6.6,7.7-11.8,10.2c-5.2,2.5-11.7,3.7-19.5,3.7H156.8z M177.8,202.4
|
||||
h16.6c3,0,5.7-0.5,8.1-1.6c2.4-1.1,4.3-2.6,5.6-4.7c1.4-2,2-4.4,2-7.2c0-3.8-1.3-6.8-4-9.2c-2.6-2.4-6.4-3.5-11.3-3.5h-17V202.4
|
||||
z M177.8,244.9H196c6.2,0,10.7-1.2,13.5-3.6c2.8-2.4,4.3-5.6,4.3-9.5c0-2.9-0.7-5.5-2.1-7.7c-1.4-2.2-3.4-4-6-5.3
|
||||
c-2.6-1.3-5.6-1.9-9.2-1.9h-18.8V244.9z"/>
|
||||
<path class="st0" d="M249.4,262.4v-15.3l36.4-34.4c3.1-3.1,5.8-5.8,7.9-8.3c2.1-2.5,3.8-4.9,4.9-7.3c1.1-2.4,1.7-5,1.7-7.7
|
||||
c0-3.1-0.7-5.8-2.1-8c-1.4-2.2-3.3-3.9-5.7-5.1c-2.4-1.2-5.1-1.8-8.2-1.8c-3.2,0-6,0.6-8.3,1.9c-2.4,1.3-4.2,3.1-5.5,5.6
|
||||
c-1.3,2.4-1.9,5.3-1.9,8.7h-20.1c0-6.7,1.5-12.6,4.6-17.5c3.1-5,7.3-8.8,12.7-11.5c5.4-2.7,11.7-4.1,18.8-4.1
|
||||
c7.3,0,13.6,1.3,19,3.9c5.4,2.6,9.6,6.2,12.7,10.8c3,4.6,4.5,9.9,4.5,15.8c0,3.8-0.7,7.6-2.2,11.4c-1.5,3.8-4.2,8-8,12.6
|
||||
c-3.8,4.7-9.3,10.2-16.3,16.7l-15.5,15.4v0.8h43.4v17.4H249.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M345,262.2v-74.1h18.2v74.1H345z"/>
|
||||
<path class="st0" d="M395.1,262.2h-18.2v-74.1h18.2v12.4h0.7c1.5-4,3.9-7.3,7.2-10c3.3-2.7,7.8-4,13.6-4c7.6,0,13.4,2.5,17.5,7.6
|
||||
c4.1,5.1,6.2,12.2,6.2,21.4v46.8h-18.2v-45c0-5.3-0.9-9.3-2.8-11.9c-1.9-2.6-5-4-9.4-4c-2.5,0-4.8,0.5-7.1,1.3
|
||||
c-2.3,0.9-4.1,2.2-5.5,4c-1.4,1.8-2.1,4-2.1,6.6V262.2z"/>
|
||||
</g>
|
||||
<path class="st1" d="M354.1,152.3c2.5,0,4.7,0.3,6.6,0.8c-14-32.8-49-56-89.9-56c-41.5,0-76.8,23.9-90.5,57.3h14.3
|
||||
c8.8-30.8,39.6-53.5,76.1-53.5c36.1,0,66.6,22.2,75.8,52.5C348.6,152.7,351.1,152.3,354.1,152.3z"/>
|
||||
<path class="st0" d="M354.1,178.1c-3.7,0-6.4-0.9-8.1-2.6c-1.7-1.7-2.6-3.9-2.6-6.5v-2.8c0-2.6,0.9-4.8,2.6-6.5
|
||||
c1.7-1.7,4.4-2.6,8.1-2.6s6.4,0.9,8.1,2.6c1.7,1.7,2.6,3.9,2.6,6.5v2.8c0,2.6-0.9,4.7-2.6,6.5
|
||||
C360.5,177.2,357.8,178.1,354.1,178.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M156.4,321.9v-5.4h4v-20.5h-4v-5.4h14.9v5.4h-4v20.5h4v5.4H156.4z"/>
|
||||
<path class="st0" d="M196.8,307l-3-6.3h-0.1v21.1h-6.4v-31.4h7.5l8.6,14.8l3,6.3h0.1v-21.1h6.4v31.4h-7.5L196.8,307z"/>
|
||||
<path class="st0" d="M243.1,296.5v25.3h-6.8v-25.3h-8.5v-6.1h23.8v6.1H243.1z"/>
|
||||
<path class="st0" d="M266.4,321.9v-31.4h21.4v6.1h-14.5v6.4h12.5v6h-12.5v6.8h14.5v6.1H266.4z"/>
|
||||
<path class="st0" d="M310.7,321.9h-6.8v-31.4h14.9c5.8,0,9.5,4,9.5,10c0,4.2-1.9,7.6-5.7,9l6.2,12.3h-7.6l-5.5-11.5h-4.9V321.9z
|
||||
M317.9,304.6c2,0,3.3-1.1,3.3-3.1v-2c0-2-1.3-3.1-3.3-3.1h-7.2v8.2H317.9z"/>
|
||||
<path class="st0" d="M343.2,321.9v-5.4h4v-20.5h-4v-5.4h14.9v5.4h-4v20.5h4v5.4H343.2z"/>
|
||||
<path class="st0" d="M372.8,306.2c0-10.7,5.5-16.2,13.8-16.2c8.3,0,13.8,5.6,13.8,16.2c0,10.7-5.5,16.2-13.8,16.2
|
||||
C378.3,322.4,372.8,316.8,372.8,306.2z M393.2,308.5v-4.7c0-5-2.5-7.8-6.6-7.8s-6.6,2.8-6.6,7.8v4.7c0,5,2.5,7.8,6.6,7.8
|
||||
S393.2,313.5,393.2,308.5z"/>
|
||||
<path class="st0" d="M423.1,321.9h-6.8v-31.4h14.9c5.8,0,9.5,4,9.5,10c0,4.2-1.9,7.6-5.7,9l6.2,12.3h-7.6l-5.5-11.5h-4.9V321.9z
|
||||
M430.3,304.6c2,0,3.3-1.1,3.3-3.1v-2c0-2-1.3-3.1-3.3-3.1h-7.2v8.2H430.3z"/>
|
||||
</g>
|
||||
<line class="st2" x1="154.1" y1="275.5" x2="440.2" y2="275.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
322
dev/2026-08-28/preview-deployment.md
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
# Vorschau-Instanz auf dem Live-Server einrichten
|
||||
|
||||
**Ziel:** `https://preview.b2in.eu` zeigt den neuen Stand zur Abstimmung. **Die Live-Seite bleibt
|
||||
unangetastet** – es wird keine einzige Datei im Live-Verzeichnis überschrieben und keine Zeile in
|
||||
der Live-Datenbank geändert.
|
||||
|
||||
**Prinzip:** zweites, eigenständiges Verzeichnis · eigene `.env` · eigene Datenbank.
|
||||
|
||||
```
|
||||
/var/www/b2in/ ← Live, bleibt wie es ist
|
||||
/var/www/b2in-preview/ ← Kopie davon, darauf das Update
|
||||
```
|
||||
|
||||
> Pfade unten sind Beispiele. Ersetze `/var/www/b2in` durch das echte Live-Verzeichnis und
|
||||
> `b2in_live` / `b2in_preview` durch die echten Datenbanknamen.
|
||||
|
||||
---
|
||||
|
||||
## 0. Warum nicht einfach die Live-Dateien tauschen
|
||||
|
||||
Zwei Gründe, die diesen Aufwand rechtfertigen:
|
||||
|
||||
1. **Der Relaunch-Seeder überschreibt CMS-Sektionen.** `InteriorRelaunchCmsSeeder` schreibt 23
|
||||
Sektionen mit den neuen Texten. Auf der Live-Datenbank ausgeführt wäre der alte Stand weg.
|
||||
2. **Migrationen sind nicht umkehrbar.** `cms_brands` und die beiden Spalten `summary` /
|
||||
`highlights` kommen neu dazu.
|
||||
|
||||
Mit einer eigenen Datenbank kann beim Testen nichts passieren, was die Live-Seite betrifft.
|
||||
|
||||
---
|
||||
|
||||
## 1. Voraussetzungen
|
||||
|
||||
- [ ] DNS-Eintrag `preview.b2in.eu` → dieselbe Server-IP wie `b2in.eu`
|
||||
- [ ] SSL-Zertifikat für die Subdomain (Let's Encrypt genügt)
|
||||
- [ ] vhost mit `DocumentRoot /var/www/b2in-preview/public`
|
||||
- [ ] Zweite MySQL-Datenbank plus Benutzer
|
||||
- [ ] Genug Plattenplatz für eine Kopie des Live-Verzeichnisses (vor allem `storage/`)
|
||||
|
||||
---
|
||||
|
||||
## 2. Sicherung ziehen
|
||||
|
||||
Auch wenn wir live nichts anfassen – der Dump ist zugleich die Grundlage für die Vorschau-DB.
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in
|
||||
mysqldump -u USER -p b2in_live > ~/b2in_live_$(date +%F_%H%M).sql
|
||||
ls -lh ~/b2in_live_*.sql # Größe prüfen, darf nicht 0 sein
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Vorschau-Verzeichnis anlegen
|
||||
|
||||
Kopie des Live-Standes, **inklusive `vendor/`**. Das erspart ein `composer install` auf dem
|
||||
Server – für `livewire/flux-pro` bräuchte es sonst die Zugangsdaten aus `auth.json`.
|
||||
|
||||
```bash
|
||||
cp -a /var/www/b2in /var/www/b2in-preview
|
||||
cd /var/www/b2in-preview
|
||||
|
||||
# Laufzeit-Reste der Kopie entfernen
|
||||
rm -rf bootstrap/cache/*.php
|
||||
rm -f public/storage # Symlink wird in Schritt 7 neu gesetzt
|
||||
```
|
||||
|
||||
**Zu `storage/app/public` (Medienbibliothek, Display-Videos):** Durch `cp -a` liegt eine echte
|
||||
Kopie in der Vorschau – sauber getrennt, kostet aber den Speicherplatz. Wenn das zu groß ist:
|
||||
|
||||
```bash
|
||||
rm -rf storage/app/public
|
||||
ln -s /var/www/b2in/storage/app/public storage/app/public
|
||||
```
|
||||
|
||||
⚠️ Mit dem Symlink landen **Uploads aus der Vorschau in den Live-Dateien**. Zum Anschauen in
|
||||
Ordnung, zum Testen von Uploads nicht. Im Zweifel kopieren.
|
||||
|
||||
---
|
||||
|
||||
## 4. `.env` der Vorschau anpassen
|
||||
|
||||
Der wichtigste Schritt. Der `ThemeServiceProvider` sucht den aufgerufenen Host in
|
||||
`config/domains.php` und setzt `URL::forceRootUrl()` samt Asset-Origin auf die dort hinterlegte
|
||||
URL. Fehlt `DOMAIN_B2IN_URL`, greift der Vorgabewert **`https://b2in.test`** – eine Domain, die es
|
||||
im Internet nicht gibt. Dann laden Bilder, Favicon und `livewire.min.js` nicht mehr.
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in-preview
|
||||
nano .env
|
||||
```
|
||||
|
||||
Diese Werte ändern:
|
||||
|
||||
```dotenv
|
||||
APP_ENV=preview
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://preview.b2in.eu
|
||||
APP_DOMAIN_NAME=preview.b2in.eu
|
||||
|
||||
# Vorschau-Domain, damit Routing, Links und Assets stimmen
|
||||
DOMAIN_B2IN=preview.b2in.eu
|
||||
DOMAIN_B2IN_URL=https://preview.b2in.eu
|
||||
|
||||
# Assets ebenfalls auf die Vorschau-Domain, sonst laedt der Browser sie von woanders
|
||||
ASSET_URL=https://preview.b2in.eu
|
||||
|
||||
# Eigene Datenbank
|
||||
DB_DATABASE=b2in_preview
|
||||
DB_USERNAME=…
|
||||
DB_PASSWORD=…
|
||||
|
||||
# Eigener Cache-/Session-Namensraum, damit sich Live und Vorschau nicht ins Gehege kommen
|
||||
CACHE_PREFIX=b2in_preview
|
||||
SESSION_COOKIE=b2in_preview_session
|
||||
|
||||
# Keine Mails aus der Vorschau verschicken
|
||||
MAIL_MAILER=log
|
||||
```
|
||||
|
||||
`APP_ENV=preview` sorgt automatisch für `noindex, nofollow` in jeder Seite
|
||||
(`config/app.php` → `app.indexable`). Wer ganz sichergehen will, setzt zusätzlich
|
||||
`SITE_INDEXABLE=false`.
|
||||
|
||||
**Nicht ändern:** `APP_KEY` – sonst sind verschlüsselte Werte in der kopierten Datenbank
|
||||
nicht mehr lesbar.
|
||||
|
||||
---
|
||||
|
||||
## 5. Datenbank der Vorschau befüllen
|
||||
|
||||
```bash
|
||||
mysql -u USER -p -e "CREATE DATABASE b2in_preview CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
mysql -u USER -p b2in_preview < ~/b2in_live_JJJJ-MM-TT_HHMM.sql
|
||||
```
|
||||
|
||||
Gegenprobe, dass die Vorschau wirklich auf ihrer eigenen DB steht:
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in-preview
|
||||
php artisan tinker --execute="echo config('database.connections.mysql.database');"
|
||||
# muss b2in_preview ausgeben – wenn hier b2in_live steht: STOPP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Update einspielen
|
||||
|
||||
Das Archiv `dev/2026-08-28/deploy/b2in-interior-update.tar.gz` enthält genau die geänderten und
|
||||
neuen Dateien plus die gebauten Assets (`public/build/b2in`, `public/build/portal`). **Node wird
|
||||
auf dem Server nicht gebraucht.** Die enthaltene Dateiliste steht in `deploy/dateiliste.txt`.
|
||||
|
||||
```bash
|
||||
# Archiv hochladen, dann:
|
||||
cd /var/www/b2in-preview
|
||||
tar xzf ~/b2in-interior-update.tar.gz
|
||||
```
|
||||
|
||||
Das Archiv enthält bewusst **keine** `.env`, kein `vendor/` und nichts aus `storage/`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Artisan-Schritte
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in-preview
|
||||
|
||||
php artisan config:clear
|
||||
php artisan storage:link
|
||||
|
||||
php artisan migrate --force # legt cms_brands an, ergänzt summary/highlights
|
||||
|
||||
# Kernmarken anlegen – überschreibt nichts, was schon gepflegt ist
|
||||
php artisan db:seed --class=CmsBrandSeeder --force
|
||||
|
||||
# Die neuen Texte ins CMS: genau die 23 umgetexteten Sektionen
|
||||
php artisan db:seed --class=InteriorRelaunchCmsSeeder --force
|
||||
|
||||
# Magazin: die zwei neuen Beiträge plus Reihenfolge
|
||||
php artisan db:seed --class=CmsArticleSeeder --force
|
||||
|
||||
# Display-Branding auf das Interior-Logo
|
||||
php artisan db:seed --class=DisplayInteriorBrandingSeeder --force
|
||||
|
||||
# Medien-URLs host-unabhängig (sonst zeigen vier Playlists auf b2in.test)
|
||||
php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder --force
|
||||
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:clear
|
||||
```
|
||||
|
||||
**Optional, nur für die Abstimmung:** Beispielbilder in die Markengalerien, damit Galerie,
|
||||
Referenzen-Seite und Lightbox nicht leer sind. Alle Bildunterschriften beginnen mit „BEISPIEL".
|
||||
|
||||
```bash
|
||||
php artisan db:seed --class=DemoBrandGallerySeeder --force
|
||||
```
|
||||
|
||||
Wieder entfernen:
|
||||
|
||||
```bash
|
||||
php artisan tinker --execute="App\Models\CmsBrand::query()->update(['gallery' => null]);"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Vorschau abschirmen
|
||||
|
||||
**Suchmaschinen** – `noindex` kommt schon aus `APP_ENV=preview`, die `robots.txt` gehört
|
||||
zusätzlich umgestellt:
|
||||
|
||||
```bash
|
||||
printf 'User-agent: *\nDisallow: /\n' > /var/www/b2in-preview/public/robots.txt
|
||||
```
|
||||
|
||||
**Passwortschutz** (empfohlen, damit die Vorschau nicht zufällig gefunden wird):
|
||||
|
||||
```bash
|
||||
htpasswd -c /etc/apache2/.htpasswd-preview vorschau
|
||||
```
|
||||
|
||||
Apache:
|
||||
|
||||
```apache
|
||||
<Directory /var/www/b2in-preview/public>
|
||||
AuthType Basic
|
||||
AuthName "B2in Vorschau"
|
||||
AuthUserFile /etc/apache2/.htpasswd-preview
|
||||
Require valid-user
|
||||
</Directory>
|
||||
```
|
||||
|
||||
Nginx:
|
||||
|
||||
```nginx
|
||||
auth_basic "B2in Vorschau";
|
||||
auth_basic_user_file /etc/nginx/.htpasswd-preview;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Prüfen
|
||||
|
||||
| Seite | Erwartung |
|
||||
|---|---|
|
||||
| `/` | Hero → Marken-Teaser → Vision → Sponsoring → Showroom-Display → Immobilien → CTA |
|
||||
| `/marken` | Grauer Seitenkopf mit Bild, drei gerahmte Markenblöcke |
|
||||
| `/marken/cabinet` | Detailseite, Galerie mit den zwei Rubriken (falls Demo-Seeder lief) |
|
||||
| `/referenzen` | Realisierte Projekte, darunter das Showroom-Display im Hochformat |
|
||||
| `/magazin` | Die zwei Interior-Beiträge stehen oben |
|
||||
| `/faq` | Rubriken „Für Ihr Zuhause" und „Für Projekte und Objekte" |
|
||||
| `/about` | Werte: Beratung statt Verkauf, Maßarbeit, … |
|
||||
| `/contact` | Betreffliste beginnt mit Beratungstermin |
|
||||
| `/immobilien` | unverändert |
|
||||
|
||||
Und diese vier Punkte:
|
||||
|
||||
- [ ] Terminanfrage-Widget unten rechts öffnet sich, Absenden zeigt die Bestätigung
|
||||
- [ ] Alle Links bleiben auf `preview.b2in.eu` – **springt einer auf `b2in.eu`, stimmt Schritt 4 nicht**
|
||||
- [ ] Seitenquelltext enthält `<meta name="robots" content="noindex, nofollow">`
|
||||
- [ ] Die Live-Seite `https://b2in.eu` sieht unverändert aus
|
||||
|
||||
---
|
||||
|
||||
## 10. Aufräumen
|
||||
|
||||
Vorschau wieder abbauen:
|
||||
|
||||
```bash
|
||||
rm -rf /var/www/b2in-preview
|
||||
mysql -u USER -p -e "DROP DATABASE b2in_preview;"
|
||||
# vhost und DNS-Eintrag entfernen
|
||||
```
|
||||
|
||||
Beim späteren echten Livegang gilt **Abschnitt 8 des Entwicklungsplans**, nicht dieses Dokument.
|
||||
Vorher offen: Rechtstexte, OG-Bild, Seeder-Passwort rotieren.
|
||||
|
||||
---
|
||||
|
||||
## Wenn etwas nicht stimmt
|
||||
|
||||
| Symptom | Ursache |
|
||||
|---|---|
|
||||
| **„Kein Server mit dem angegebenen Hostnamen gefunden" für Bilder, Favicon, `livewire.min.js`** | `DOMAIN_B2IN_URL` fehlt oder ist falsch geschrieben → Vorgabewert `https://b2in.test`. Siehe Diagnose unten. |
|
||||
| Links springen auf `b2in.eu` | `DOMAIN_B2IN` / `DOMAIN_B2IN_URL` in Schritt 4 nicht gesetzt, oder `config:cache` fehlt |
|
||||
| Seite ohne Styles | `public/build/b2in` fehlt – Archiv nicht vollständig entpackt |
|
||||
| „Vite manifest not found" | dasselbe, oder `build/portal` fehlt für das Admin-Panel |
|
||||
| Bilder fehlen | `php artisan storage:link` vergessen, oder `storage/app/public` nicht mitkopiert |
|
||||
| Display-Kachel bleibt leer | Kein aktives Display mit veröffentlichter Playlist – dann wird die Sektion bewusst gar nicht angezeigt |
|
||||
| Änderungen wirken nicht | `php artisan config:clear && php artisan config:cache` |
|
||||
|
||||
### Diagnose: Assets zeigen auf den falschen Host
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in-preview
|
||||
|
||||
# 1. Was steht in der .env?
|
||||
grep -E '^(APP_ENV|APP_URL|APP_DOMAIN_NAME|ASSET_URL|DOMAIN_B2IN|DOMAIN_B2IN_URL)=' .env
|
||||
|
||||
# 2. Was macht die Anwendung daraus? (zeigt den zwischengespeicherten Stand)
|
||||
php artisan tinker --execute="echo config('domains.domains.b2in.domain_name').' -> '.config('domains.domains.b2in.url').PHP_EOL;"
|
||||
|
||||
# 3. Liegt ein alter Config-Cache herum?
|
||||
ls -l bootstrap/cache/config.php 2>/dev/null
|
||||
```
|
||||
|
||||
Steht in Zeile 2 etwas mit `.test`, fehlen die beiden `DOMAIN_B2IN*`-Zeilen. Beheben:
|
||||
|
||||
```bash
|
||||
cd /var/www/b2in-preview
|
||||
php artisan config:clear # zuerst den Cache weg, sonst wirkt die .env nicht
|
||||
nano .env # DOMAIN_B2IN, DOMAIN_B2IN_URL, ASSET_URL, APP_URL setzen
|
||||
php artisan config:cache
|
||||
php artisan view:clear
|
||||
```
|
||||
|
||||
**Sicherheitsnetz seit dieser Runde:** Findet der `ThemeServiceProvider` den aufgerufenen Host
|
||||
nicht in der Konfiguration, verwendet er außerhalb von `APP_ENV=production` den tatsächlich
|
||||
aufgerufenen Origin – die Vorschau verlinkt sich dann auf sich selbst statt auf eine fremde
|
||||
Domain. In `production` bleibt es bei der konfigurierten URL, damit ein gefälschter Host-Header
|
||||
keine Links auf fremde Domains erzeugen kann. Die `.env` sollte trotzdem stimmen.
|
||||
BIN
dev/2026-08-28/sponsoren-logos/Arminia_Club_1905.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCBWH_Logo.jpg
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCH.jpg
Normal file
|
After Width: | Height: | Size: 171 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCH.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCH_Logo.jpg
Normal file
|
After Width: | Height: | Size: 246 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCH_Logo.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
dev/2026-08-28/sponsoren-logos/TCH_Logo_Year.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
338
dev/2026-08-28/umsetzung-inhalte.md
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
# B2in Interior – Umsetzungsdokument Inhalte
|
||||
|
||||
**Arbeitsdokument für die Umsetzung.** Für jede Sektion: aktueller Stand → neuer Inhalt.
|
||||
Schreibweisen verbindlich: **Interior** (nicht Interieur), **Febrü**, **Rotpunkt Küchen**, **CABINET** (Versalien).
|
||||
|
||||
Platzhalter sind mit `[PH]` markiert – dort fehlt Zulieferung von Marcel.
|
||||
|
||||
---
|
||||
|
||||
## 0. Globale Änderungen
|
||||
|
||||
### Meta / SEO
|
||||
|
||||
| | Alt | Neu |
|
||||
|---|---|---|
|
||||
| **Title** | B2IN - Connecting Design and Property | B2in Interior – Premium-Einrichtung & Maßanfertigung \| CABINET, Rotpunkt, Febrü |
|
||||
| **Description** | B2in verbindet exklusive Immobilien in Dubai mit europäischem Einrichtungsdesign. Ihr Partner für Investment & Interior. | B2in Interior verbindet starke Einrichtungsmarken mit persönlicher Beratung – von der Maßanfertigung bis zur vollständigen Ausstattung für Zuhause und Projekte. |
|
||||
| **OG-Title** | wie Title | wie neuer Title |
|
||||
| **OG-Description** | wie Description | wie neue Description |
|
||||
| **OG-Image** | b2in-og-default.jpg (Investment-Optik) | `[PH]` Interior-Motiv – vorerst bestehendes Hero-Bild verwenden |
|
||||
|
||||
### Logo
|
||||
|
||||
- Wortmarke **B2in** bleibt, Zusatz **Interior** in leichterer Schriftstärke darunter oder rechts daneben.
|
||||
- Betrifft: `b2in-logo-positive.svg` (Header) und `b2in-logo-negative.svg` (Footer).
|
||||
- `[PH]` Falls Marcel keine Datei liefert: Zusatz typografisch mit vorhandener Schrift ergänzen, sauber ausgerichtet.
|
||||
|
||||
### Navigation
|
||||
|
||||
| Alt | Neu |
|
||||
|---|---|
|
||||
| Home · Immobilien · Netzwerk · Magazin · FAQ · Über B2in | Home · **Marken** · **Referenzen** · Magazin · Immobilien · Über B2in |
|
||||
|
||||
- **Marken** = neue Kernmarken-Seite (Anker auf Startseite oder eigene Seite)
|
||||
- **Referenzen** = die selbst pflegbare Rubrik (Web-Display)
|
||||
- **Netzwerk** entfällt aus der Hauptnavigation (Inhalt geht in Marken/Über B2in auf), Seite bleibt erreichbar
|
||||
- **FAQ** in den Footer verschieben oder unter „Über B2in" einhängen
|
||||
- **Immobilien** rutscht nach hinten, bleibt aber in der Navigation
|
||||
|
||||
---
|
||||
|
||||
## 1. Ankündigungsleiste
|
||||
|
||||
**Alt:**
|
||||
> NEW LAUNCH Azizi Creek Views 4 – Exklusives Off-Market-Projekt in Dubai ab 1.125.000 AED (ca. 283.000 EUR / 306.000 USD) → Exposé ansehen
|
||||
|
||||
**Neu (Startbelegung):**
|
||||
> **NEU** Rotpunkt Küchen jetzt bei B2in Interior – jetzt Beratungstermin sichern → Termin anfragen
|
||||
|
||||
**Alternative, falls Rotpunkt-Studio noch nicht startklar:**
|
||||
> **NEU** CABINET Einbauschränke nach Maß – Showroom Bielefeld → Termin anfragen
|
||||
|
||||
*Hinweis: Leiste bleibt technisch wie sie ist, nur Inhalt und Ziel-Link ändern sich. Dubai-Launches können dort später wieder erscheinen, aber nicht als Dauerzustand.*
|
||||
|
||||
---
|
||||
|
||||
## 2. Hero
|
||||
|
||||
**Alt:**
|
||||
> # B2in – Wo exklusive Immobilien-Investments auf smartes Interior treffen.
|
||||
> Ihr Partner für renditestarke internationale Immobilien und globales Supply-Chain-Management im Interior-Bereich.
|
||||
> [Zu den Immobilien-Projekten] [Unser Netzwerk]
|
||||
> Internationale Immobilien · Exklusive Einrichtung · Persönliche Beratung
|
||||
|
||||
**Neu:**
|
||||
|
||||
> # B2in Interior – Premium-Einrichtung von starken Marken. Für Ihr Zuhause. Für Ihr Projekt.
|
||||
>
|
||||
> Von der einzelnen Maßanfertigung bis zur vollständigen Ausstattung – mit CABINET, Rotpunkt Küchen, Febrü und einem Netzwerk regionaler Fachexperten.
|
||||
|
||||
**Buttons:**
|
||||
- Primär (dunkel): **Unsere Marken entdecken** → `#marken`
|
||||
- Sekundär (hell): **Termin anfragen** → öffnet Anfrage-Widget
|
||||
|
||||
**Checkmarks:**
|
||||
- Premium-Marken
|
||||
- Maßgefertigte Lösungen
|
||||
- Persönliche Beratung
|
||||
|
||||
**Hero-Bild:** `[PH]` Interior-Motiv (Einbaumöbel oder Küche, warmes Licht). Bis zur Zulieferung bestehendes Bild belassen.
|
||||
|
||||
**Bild-Badge (unten rechts über dem Bild):**
|
||||
|
||||
| Alt | Neu |
|
||||
|---|---|
|
||||
| B2in / Connecting Design and Property | B2in Interior / Einrichtung, die bleibt. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Marcel-Badge (kleiner Einschub unter dem Hero)
|
||||
|
||||
**Alt:**
|
||||
> B2in by Marcel Scheibe – Ihr persönlicher Partner für internationale Immobilien und exklusive Einrichtungskonzepte.
|
||||
> Marcel Scheibe · Gründer & CEO, B2in
|
||||
|
||||
**Neu:**
|
||||
> B2in by Marcel Scheibe – Ihr persönlicher Partner für hochwertige Einrichtung und starke Marken.
|
||||
> Marcel Scheibe · Gründer & CEO, B2in
|
||||
|
||||
---
|
||||
|
||||
## 4. Weiche Privat / Geschäft
|
||||
|
||||
**Ersetzt vollständig die Sektion „Zwei Welten. Ein Netzwerk."**
|
||||
|
||||
**Alt:**
|
||||
> ## Zwei Welten. Ein Netzwerk.
|
||||
> Wir verbinden den Immobilienkauf mit der perfekten Einrichtung. **Immobilien-Investoren** profitieren von unserem exklusiven Möbel-Netzwerk – **Projektentwickler** von unserer deutschen Vertragssicherheit im Supply-Chain-Management.
|
||||
|
||||
**Neu:**
|
||||
|
||||
> ## Für Ihr Zuhause. Für Ihr Projekt.
|
||||
>
|
||||
> Ob einzelnes Möbelstück oder komplette Ausstattung – wir begleiten Sie mit denselben Marken, demselben Anspruch und einem persönlichen Ansprechpartner.
|
||||
|
||||
**Karte 1**
|
||||
|
||||
> ### Einrichtung für Ihr Zuhause
|
||||
>
|
||||
> Einzelne Möbelstücke, maßgefertigte Einbaulösungen oder die komplette Einrichtung: Unsere Kernmarken und unser Fachhandels-Netzwerk begleiten Sie von der ersten Idee bis zur Montage. Besuchen Sie unsere Showrooms oder vereinbaren Sie eine persönliche Beratung.
|
||||
>
|
||||
> **Button:** Beratung anfragen
|
||||
|
||||
**Karte 2**
|
||||
|
||||
> ### Ausstattung für Ihr Projekt
|
||||
>
|
||||
> Vollständige Einrichtung für Objekte, Büros und Projektentwicklungen – koordiniert aus einer Hand, von der Küche bis zur letzten Blume. Mit deutscher Vertragssicherheit und einem eingespielten Herstellernetzwerk.
|
||||
>
|
||||
> **Button:** Projekt besprechen
|
||||
|
||||
*Bild „Das B2in-Ökosystem" aus der alten Sektion entfällt hier – kann bei „Über B2in" weiterverwendet werden.*
|
||||
|
||||
---
|
||||
|
||||
## 5. Kernmarken (neues CMS-Modul) — `#marken`
|
||||
|
||||
> ## Unsere Kernmarken
|
||||
>
|
||||
> Wir arbeiten nicht mit beliebigen Katalogen, sondern mit ausgewählten Herstellern, hinter denen wir stehen – jede Marke ein Spezialist auf ihrem Gebiet.
|
||||
|
||||
### Kachel 1 – CABINET
|
||||
|
||||
> ### CABINET
|
||||
> **Einbauschränke nach Maß.**
|
||||
>
|
||||
> Maßgefertigte Schranklösungen, geplant bis auf den Millimeter – gefertigt für Räume, in denen Standard nicht genügt. Erleben Sie die Möglichkeiten in unserem Showroom in Bielefeld.
|
||||
>
|
||||
> *Mehr zu CABINET →*
|
||||
|
||||
### Kachel 2 – Rotpunkt Küchen
|
||||
|
||||
> ### Rotpunkt Küchen
|
||||
> **Küchen, die Haltung zeigen.**
|
||||
>
|
||||
> Premium-Küchen aus deutscher Fertigung – individuell geplant, nachhaltig gedacht und gebaut für den Mittelpunkt Ihres Zuhauses. Beratung und Planung in unserem Küchenstudio.
|
||||
>
|
||||
> *Mehr zu Rotpunkt →*
|
||||
|
||||
### Kachel 3 – Febrü
|
||||
|
||||
> ### Febrü
|
||||
> **Arbeiten, wo man gerne ist.**
|
||||
>
|
||||
> Möbel für konzentriertes Arbeiten – vom durchdachten Home-Office bis zur kompletten Büroeinrichtung. Ergonomie und Design für Zuhause und fürs Unternehmen.
|
||||
>
|
||||
> *Mehr zu Febrü →*
|
||||
|
||||
### Detailseiten (Vorlage-Struktur je Marke)
|
||||
|
||||
Jede Marke bekommt eine Detailseite mit:
|
||||
1. Header (Logo + Claim + Stimmungsbild)
|
||||
2. Einleitungstext (3–5 Sätze)
|
||||
3. Leistungen / Besonderheiten (3–4 Punkte)
|
||||
4. Bildergalerie
|
||||
5. CTA-Block: „Termin anfragen" + „Per WhatsApp schreiben"
|
||||
|
||||
`[PH]` Logos und Basis-Infos zu Rotpunkt und Febrü fehlen – Detailseiten vorerst mit obigen Kacheltexten plus Platzhalter-Galerie anlegen, damit die Struktur steht.
|
||||
|
||||
---
|
||||
|
||||
## 6. Über Marcel / Vertrauen
|
||||
|
||||
**Alt:**
|
||||
> ## Gebaut auf Expertise und Vertrauen
|
||||
> **B2in (Bridges2international)** verbindet zwei Welten: internationale Immobilien und exklusive Einrichtungskonzepte. Als Ihr persönlicher Partner navigiere ich Sie durch beide Bereiche – mit Expertise, Netzwerk und dem Anspruch, dass jede Entscheidung auf Vertrauen basiert.
|
||||
> Ob ein **Investment in Dubai**, eine Villa in Lissabon oder die **maßgeschneiderte Einrichtung** Ihres neuen Zuhauses durch lokale Fachexperten – bei B2in laufen alle Fäden zusammen.
|
||||
> **Regional verwurzelt, international vernetzt** – das ist B2in.
|
||||
|
||||
**Neu:**
|
||||
|
||||
> ## Gebaut auf Expertise und Vertrauen
|
||||
>
|
||||
> **B2in** stand ursprünglich für *Bridges to International*. Heute steht es ebenso für *Bridges to Interior*: hochwertige Einrichtung mit persönlicher Handschrift. Als Ihr Ansprechpartner verbinde ich ausgewählte Hersteller, regionale Fachexperten und ein verlässliches Netzwerk – damit aus Räumen Orte werden, die bleiben.
|
||||
>
|
||||
> Ob **maßgefertigter Einbauschrank**, neue **Küche** oder die **vollständige Ausstattung** eines Objekts: Bei B2in laufen alle Fäden zusammen. Und wer über die Einrichtung hinausdenkt, findet bei uns auch den Zugang zu internationalen Immobilien.
|
||||
>
|
||||
> **Regional verwurzelt, international vernetzt** – das ist B2in.
|
||||
|
||||
*Hier ist die Markenstory verankert, die Marcel selbst vorgeschlagen hat. Immobilien bewusst als vorletzter Satz.*
|
||||
|
||||
---
|
||||
|
||||
## 7. Engagement / Sponsoring
|
||||
|
||||
**Neue Sektion, direkt nach „Über Marcel" – schlanke Logo-Leiste.**
|
||||
|
||||
> ## Regional verbunden
|
||||
>
|
||||
> Wir unterstützen Vereine und Organisationen aus der Region – weil Verwurzelung mehr ist als eine Adresse.
|
||||
|
||||
**Logos:** 3 gelieferte Sponsoring-Logos in einer ruhigen, gleich großen Reihe (Graustufen oder gedeckt, damit sie den Markenauftritt nicht überstrahlen).
|
||||
|
||||
`[PH]` Weitere Logos ergänzen, sobald geliefert.
|
||||
|
||||
---
|
||||
|
||||
## 8. Aktuelles / Referenzen (Web-Display)
|
||||
|
||||
**Ersetzt die Sektion „Ein Ökosystem, drei Säulen" komplett.**
|
||||
|
||||
**Alt (entfällt):**
|
||||
> ## Ein Ökosystem, drei Säulen
|
||||
> Immobilien & Investments / Local-for-Local Marktplatz / Supply-Chain-Management
|
||||
|
||||
*Begründung: Zwei von drei Säulen sind interne Konzeptsprache, die Besucher nicht verstehen, und die dahinterliegenden Systeme sind pausiert.*
|
||||
|
||||
**Neu – Startseiten-Teaser:**
|
||||
|
||||
> ## Aktuelles aus unseren Showrooms
|
||||
>
|
||||
> Projekte, Neuheiten und Einblicke – laufend aktualisiert.
|
||||
>
|
||||
> **Button:** Alle Referenzen ansehen →
|
||||
|
||||
**Neue Unterseite `/referenzen`:**
|
||||
|
||||
> # Referenzen
|
||||
>
|
||||
> Realisierte Projekte aus unseren Showrooms und von unseren Kunden. Jedes Projekt maßgefertigt, jedes anders.
|
||||
|
||||
Inhalte kommen aus dem Web-Display im Display-CMS (Bild, Text, optional YouTube-Video), von Marcel selbst pflegbar.
|
||||
|
||||
`[PH]` Startbelegung mit CABINET-Projekten durch Marcel. Bis dahin 2–3 Platzhalter-Einträge anlegen, damit der Bereich nicht leer wirkt.
|
||||
|
||||
**Wichtig:** Unter „Referenzen" ausschließlich realisierte Projekte. Visualisierungen und Entwürfe gehören in die Kernmarken-Detailseiten, nicht hierher.
|
||||
|
||||
---
|
||||
|
||||
## 9. Immobilien-Teaser
|
||||
|
||||
**Neu, klein und dezent, kurz vor dem Abschluss-CTA:**
|
||||
|
||||
> ## Außerdem: Internationale Immobilien
|
||||
>
|
||||
> Neben der Einrichtung begleiten wir ausgewählte internationale Immobilienprojekte – persönlich kuratiert und mit klarem Blick auf Substanz.
|
||||
>
|
||||
> **Link (dezent):** Zu den Immobilien →
|
||||
|
||||
*Keine Preise, keine Renditeversprechen, kein Dubai im Teasertext. Wer gezielt sucht, findet den Weg.*
|
||||
|
||||
---
|
||||
|
||||
## 10. Abschluss-CTA
|
||||
|
||||
**Alt:**
|
||||
> ## Ihr nächster Schritt
|
||||
> Ob Immobilien-Investment, Supply-Chain-Partnerschaft oder Einrichtungs-Netzwerk – sprechen Sie direkt mit uns.
|
||||
> [Kontakt aufnehmen]
|
||||
|
||||
**Neu:**
|
||||
|
||||
> ## Ihr nächster Schritt
|
||||
>
|
||||
> Ob einzelnes Möbelstück, komplette Einrichtung oder Projektausstattung – sprechen Sie mit uns. Persönlich, unkompliziert, verbindlich.
|
||||
>
|
||||
> **Button 1:** Termin anfragen (öffnet Widget)
|
||||
> **Button 2:** Per WhatsApp schreiben (`wa.me`-Link)
|
||||
|
||||
---
|
||||
|
||||
## 11. Footer
|
||||
|
||||
| | Alt | Neu |
|
||||
|---|---|---|
|
||||
| **Claim unter Logo** | Connecting Design and Property | Premium-Einrichtung. Persönlich gemacht. |
|
||||
| **Zeile darunter** | Marcel Scheibe – Gründer & CEO | bleibt |
|
||||
|
||||
*Falls Marcel „Bridges to Interior" als Claim bevorzugt, wird stattdessen das eingesetzt.*
|
||||
|
||||
---
|
||||
|
||||
## 12. Terminanfrage-Widget
|
||||
|
||||
Schwebendes Element unten rechts, auf allen Seiten.
|
||||
|
||||
**Öffnet mit:**
|
||||
> **Termin anfragen**
|
||||
> Kurz Ihre Daten, wir melden uns persönlich zurück.
|
||||
|
||||
**Felder:**
|
||||
- Name *(Pflicht)*
|
||||
- E-Mail *(Pflicht)*
|
||||
- Telefon *(optional)*
|
||||
- Anliegen / Marke *(Auswahl: CABINET · Rotpunkt Küchen · Febrü · Projektausstattung · Sonstiges)*
|
||||
- Wunschtermin *(optional)*
|
||||
- Nachricht *(optional)*
|
||||
|
||||
**Button:** Anfrage senden
|
||||
**Bestätigung:** Danke für Ihre Anfrage – wir melden uns zeitnah bei Ihnen.
|
||||
|
||||
**Zweiter Button daneben:** WhatsApp → öffnet Chat direkt.
|
||||
|
||||
---
|
||||
|
||||
## Arbeitsreihenfolge (Vorschlag)
|
||||
|
||||
1. **Globales zuerst:** Logo-Zusatz, Meta/SEO, Navigation, Footer-Claim
|
||||
2. **Startseite von oben nach unten:** Ankündigungsleiste → Hero → Weiche → Kernmarken → Über Marcel → Sponsoring → Aktuelles → Immobilien-Teaser → Abschluss
|
||||
3. **Kernmarken-Modul im CMS** anlegen und mit den drei Marken befüllen
|
||||
4. **Referenzen-Rubrik** (Web-Display) anlegen, 2–3 Platzhalter einstellen
|
||||
5. **Terminanfrage-Widget + WhatsApp-Button**
|
||||
6. **Durchgang auf Alt-Begriffe:** „Supply-Chain", „Local-for-Local", „Ökosystem", „Investment" auf Unterseiten prüfen und bereinigen (auch /netzwerk, /about, /faq)
|
||||
|
||||
---
|
||||
|
||||
## Offene Zulieferungen von Marcel
|
||||
|
||||
| Was | Status |
|
||||
|---|---|
|
||||
| Sponsoring-Logos | ✅ 3 Stück erhalten |
|
||||
| Logo mit Zusatz „Interior" | ❌ offen – ggf. selbst ergänzen |
|
||||
| Rotpunkt: Logo + Basis-Infos | ❌ offen – Platzhalter |
|
||||
| Febrü: Logo + Basis-Infos | ❌ offen – Platzhalter |
|
||||
| Hero-Bildmotiv (Interior) | ❌ offen – Bestandsbild belassen |
|
||||
| Bilder Kernmarken-Kacheln | ❌ offen – Platzhalter |
|
||||
| CABINET-Referenzprojekte | ❌ offen – Platzhalter-Einträge |
|
||||
| WhatsApp-Nummer für Button | ❌ klären: Mobil +49 151 51002992? |
|
||||
120
dev/2026-08-28/umsetzungliste.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# B2in Interior – Umsetzungsliste
|
||||
|
||||
**Freigegebener Rahmen: ca. 37–39 Std.** (30 Basis + 3 Display-Spiegelung + 4–6 Rubrik-Seite)
|
||||
Schreibweisen: **Interior**, **Febrü**, **Rotpunkt Küchen**, **CABINET**
|
||||
|
||||
Legende: ✅ freigegeben · 🟡 mitnehmen, wenn ohne Mehraufwand machbar · ⏸ später, separat zu beziffern
|
||||
|
||||
---
|
||||
|
||||
## 1. Website-Umstrukturierung & Umtextung ✅ *(ca. 18 Std.)*
|
||||
|
||||
- Meta-Title und Description auf Interior-Ausrichtung umstellen
|
||||
- OG-Title / OG-Description anpassen
|
||||
- Navigation umbauen: „Marken" und „Referenzen" rein, „Immobilien" nach hinten, „Netzwerk" raus aus der Hauptnavi (Seite bleibt erreichbar), FAQ in den Footer
|
||||
- Ankündigungsleiste neu belegen (Interior-Thema statt Dubai-Launch)
|
||||
- Hero: neue Headline, Subline, Buttons, Checkmarks, Bild-Badge
|
||||
- Marcel-Badge unter dem Hero umtexten
|
||||
- Sektion „Zwei Welten. Ein Netzwerk." ersetzen durch **Weiche Privat / Geschäft** (zwei Karten)
|
||||
- Sektion „Über Marcel / Vertrauen" umtexten – inkl. Markenstory *Bridges to International / Bridges to Interior*
|
||||
- Sektion „Ein Ökosystem, drei Säulen" entfernen (Fläche übernimmt Aktuelles/Referenzen)
|
||||
- Immobilien-Teaser neu anlegen: klein, dezent, kurz vor dem Abschluss
|
||||
- Abschluss-CTA umtexten, zwei Kontakt-Buttons
|
||||
- Footer-Claim ersetzen („Connecting Design and Property" → neuer Claim)
|
||||
- Durchgang auf Alt-Begriffe: „Supply-Chain", „Local-for-Local", „Ökosystem", „Investment" – auch auf /netzwerk, /about, /faq
|
||||
|
||||
*🟡 Logo-Zusatz „Interior": Wenn Marcel keine Datei liefert, typografisch mit vorhandener Schrift ergänzen – kleiner Aufwand, versuche ich mitzunehmen.*
|
||||
|
||||
---
|
||||
|
||||
## 2. Kernmarken-Modul im CMS ✅ *(ca. 8 Std.)*
|
||||
|
||||
- CMS-Struktur anlegen (adaptiert vom Magazin-Muster: Übersicht + Detailseite)
|
||||
- Von Marcel selbst erweiterbar, weitere Marken ohne Codeänderung ergänzbar
|
||||
- Kachel-Übersicht auf der Startseite (`#marken`)
|
||||
- Drei Marken anlegen: CABINET, Rotpunkt Küchen, Febrü
|
||||
- Detailseiten-Vorlage: Header, Einleitung, Leistungen, Galerie, CTA-Block
|
||||
|
||||
*Platzhalter, solange Logos und Infos zu Rotpunkt und Febrü fehlen.*
|
||||
|
||||
---
|
||||
|
||||
## 3. Terminanfrage-Widget ✅ *(ca. 4 Std.)*
|
||||
|
||||
- Schwebendes Element unten rechts, auf allen Seiten
|
||||
- Felder: Name, E-Mail, Telefon (optional), Anliegen/Marke (Auswahl), Wunschtermin (optional), Nachricht
|
||||
- Versand per Mail an Marcel, Bestätigungstext für den Absender
|
||||
- **WhatsApp-Button** daneben: Klick-to-Chat, öffnet direkt den Chat (Handy: App, Desktop: WhatsApp Web)
|
||||
- *Kein Buchungskalender – bewusst schlank*
|
||||
|
||||
*Offen: WhatsApp-Nummer bestätigen lassen.*
|
||||
|
||||
---
|
||||
|
||||
## 4. Display-Spiegelung auf der Website ✅ *(ca. 3 Std.)*
|
||||
|
||||
- Bestehende Display-Inhalte (9:16) werden auf der Website ausgespielt
|
||||
- Nutzt die vorhandene Display-/Player-API als Datenquelle
|
||||
- Keine doppelte Pflege: Marcel pflegt weiterhin nur im Display-CMS
|
||||
|
||||
*⏸ 16:9-Modul wurde zurückgestellt.*
|
||||
|
||||
---
|
||||
|
||||
## 5. Rubrik-Seite „Referenzen" (Web-Display) ✅ *(ca. 4–6 Std.)*
|
||||
|
||||
- Zweites, separates Display im Display-CMS anlegen
|
||||
- Eigene Unterseite `/referenzen`, die diese Inhalte ausspielt
|
||||
- Von Marcel selbst pflegbar: Bilder, Texte, YouTube-Verlinkungen
|
||||
- Teaser-Sektion auf der Startseite mit Verlinkung
|
||||
- Aufnahme in die Navigation
|
||||
- 2–3 Platzhalter-Einträge, damit der Bereich nicht leer wirkt
|
||||
|
||||
*Inhaltliche Regel: Unter „Referenzen" nur realisierte Projekte. Visualisierungen und Entwürfe gehören in die Kernmarken-Detailseiten.*
|
||||
|
||||
---
|
||||
|
||||
## 6. Engagement / Sponsoring 🟡 *(Versuch ohne Mehraufwand)*
|
||||
|
||||
- Schlanke Sektion „Regional verbunden" nach der Marcel-Sektion
|
||||
- Drei gelieferte Logos in ruhiger Reihe, gedeckt oder Graustufen
|
||||
- Ein Satz Einleitungstext
|
||||
|
||||
*Wird mitgenommen, solange es bei Logo-Leiste plus Satz bleibt. Eigene Unterseite oder Text je Verein wäre ein Zusatz.*
|
||||
|
||||
---
|
||||
|
||||
## Später separat zu beziffern ⏸
|
||||
|
||||
| Thema | Warum nicht jetzt |
|
||||
|---|---|
|
||||
| **Referenzbereich voll ausgebaut** | Eigene Projektseiten, Kategorien, Galerien – eigenes Modul. Die schlanke Rubrik (Punkt 5) reicht für den Start. |
|
||||
| **16:9-Display-Modul** | Von Marcel selbst zurückgestellt. Braucht zusätzlich querformat-taugliches Bildmaterial. |
|
||||
| **Immobilien-CMS** | Immobilien bleiben statisch, rücken nur in der Gewichtung nach hinten. Separater Kostenplan liegt vor. |
|
||||
| **Dubai-Map** | Interaktive Karte – eigenes Paket, setzt das Immobilien-CMS voraus. |
|
||||
| **Markenrichtlinie Fahrzeug / Print** | Kombinationsregeln B2in + Kernmarken für Fahrzeugbeschriftung, Visitenkarten, Social Media. Eigene Design-Aufgabe, sinnvoll nach dem Website-Livegang. |
|
||||
| **Weitere frei anlegbare Rubriken** | Jede zusätzliche Rubrik ist ein eigener kleiner Baustein. |
|
||||
| **Eigene Videolösung / Player** | Nicht nötig – Videos laufen über YouTube-Einbindung. |
|
||||
|
||||
---
|
||||
|
||||
## Spielregeln
|
||||
|
||||
- **Eine Korrekturschleife je Bereich** ist enthalten (Abstände, Positionen, Farben, Gewichtungen)
|
||||
- Weitere Runden oder neue Anforderungen: vorher kurz melden, Mehraufwand nennen, erst nach Freigabe umsetzen
|
||||
- **Deadline Ende August** – abhängig von rechtzeitigen Zulieferungen
|
||||
|
||||
---
|
||||
|
||||
## Offene Zulieferungen
|
||||
|
||||
| Was | Status |
|
||||
|---|---|
|
||||
| Sponsoring-Logos | ✅ 3 Stück erhalten |
|
||||
| Logo mit Zusatz „Interior" | offen – ggf. selbst ergänzen |
|
||||
| Rotpunkt: Logo + Basis-Infos | offen – Platzhalter |
|
||||
| Febrü: Logo + Basis-Infos | offen – Platzhalter |
|
||||
| Hero-Bildmotiv (Interior) | offen – Bestandsbild belassen |
|
||||
| Bilder Kernmarken-Kacheln | offen – Platzhalter |
|
||||
| CABINET-Referenzprojekte | offen – Platzhalter-Einträge |
|
||||
| WhatsApp-Nummer | offen – bestätigen lassen |
|
||||
130
dev/2026-08-28/unterseite_marke.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# B2in Interior – Unterseite `/marken`
|
||||
|
||||
Vollständige Texte zur Umsetzung. Schreibweisen: **Interior**, **Febrü**, **Rotpunkt Küchen**, **CABINET**.
|
||||
Platzhalter: `[PH]`
|
||||
|
||||
---
|
||||
|
||||
## Meta / SEO
|
||||
|
||||
| Feld | Inhalt |
|
||||
|---|---|
|
||||
| **Title** | Unsere Marken – CABINET, Rotpunkt Küchen & Febrü \| B2in Interior |
|
||||
| **Description** | Ausgewählte Hersteller statt beliebiger Kataloge: maßgefertigte Einbauschränke, Premium-Küchen und Möbel fürs Arbeiten – mit persönlicher Beratung in der Region. |
|
||||
| **URL** | `/marken` |
|
||||
| **Breadcrumb** | Home → Marken |
|
||||
|
||||
---
|
||||
|
||||
## 1. Seitenkopf
|
||||
|
||||
> # Unsere Marken
|
||||
>
|
||||
> Wir arbeiten nicht mit beliebigen Katalogen, sondern mit ausgewählten Herstellern, hinter denen wir stehen. Jede Marke ist Spezialist auf ihrem Gebiet – und jede bringt mit, was gute Einrichtung ausmacht: Qualität, die man sieht, und Beratung, die zuhört.
|
||||
|
||||
**Bild:** `[PH]` Ruhiges Interior-Motiv oder Showroom-Aufnahme. Alternativ ohne Headerbild, dafür großzügiger Weißraum.
|
||||
|
||||
---
|
||||
|
||||
## 2. Kernmarken
|
||||
|
||||
*Reihenfolge wie auf der Startseite. Pro Marke: Logo, Bild, Claim, Beschreibung, Merkmale, Link zur Detailseite.*
|
||||
|
||||
### CABINET
|
||||
|
||||
> ### CABINET
|
||||
> **Einbauschränke nach Maß.**
|
||||
>
|
||||
> Wo Standardmaße an ihre Grenzen kommen, fängt CABINET an. Schranklösungen, die exakt in Ihren Raum geplant werden – von der Dachschräge über die Nische bis zur raumhohen Front. Gefertigt in der Qualität, die man erst beim zweiten Hinschauen ganz erfasst.
|
||||
>
|
||||
> Erleben Sie die Möglichkeiten in unserem Showroom in Bielefeld.
|
||||
>
|
||||
> - Millimetergenaue Planung
|
||||
> - Individuelle Fronten und Innenausstattung
|
||||
> - Persönliche Beratung vor Ort
|
||||
>
|
||||
> **Mehr zu CABINET →**
|
||||
|
||||
### Rotpunkt Küchen
|
||||
|
||||
> ### Rotpunkt Küchen
|
||||
> **Küchen, die Haltung zeigen.**
|
||||
>
|
||||
> Premium-Küchen aus deutscher Fertigung – individuell geplant und gebaut für den Raum, in dem am meisten passiert. Rotpunkt steht für durchdachte Funktion, langlebige Materialien und einen Anspruch an Nachhaltigkeit, der über das Marketing hinausgeht.
|
||||
>
|
||||
> Beratung und Planung in unserem Küchenstudio.
|
||||
>
|
||||
> - Fertigung in Deutschland
|
||||
> - Individuelle Planung nach Ihrem Grundriss
|
||||
> - Nachhaltige Materialien
|
||||
>
|
||||
> **Mehr zu Rotpunkt →**
|
||||
|
||||
### Febrü
|
||||
|
||||
> ### Febrü
|
||||
> **Arbeiten, wo man gerne ist.**
|
||||
>
|
||||
> Ob Home-Office oder ganze Büroetage: Febrü macht Möbel für konzentriertes Arbeiten. Höhenverstellbare Tische, durchdachte Stauraumlösungen und Sitzmöbel, die auch nach acht Stunden noch überzeugen – mit einem Design, das ins Zuhause genauso passt wie ins Unternehmen.
|
||||
>
|
||||
> - Ergonomie, die man merkt
|
||||
> - Vom einzelnen Arbeitsplatz bis zur Bürofläche
|
||||
> - Für Zuhause und fürs Unternehmen
|
||||
>
|
||||
> **Mehr zu Febrü →**
|
||||
|
||||
`[PH]` Logos und Bildmaterial zu Rotpunkt und Febrü fehlen – Platzhalter setzen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Partnernetzwerk
|
||||
|
||||
*Nimmt den Netzwerk-Gedanken der alten Seite auf, in kundenverständlicher Sprache.*
|
||||
|
||||
> ## Mehr als Marken: unser Netzwerk
|
||||
>
|
||||
> Gute Einrichtung endet nicht beim Möbelstück. Deshalb arbeiten wir mit Fachbetrieben und Handwerkern aus der Region zusammen – von der Aufmaß-Erstellung über die Montage bis zu angrenzenden Gewerken.
|
||||
>
|
||||
> Für Sie bedeutet das: ein Ansprechpartner, der die Fäden zusammenhält, statt vieler Einzelgespräche. Und Partner, die wir kennen und für deren Arbeit wir geradestehen.
|
||||
|
||||
**Optionale drei Punkte darunter:**
|
||||
|
||||
> **Aufmaß & Planung**
|
||||
> Wir kommen zu Ihnen, nehmen Maß und planen mit Ihnen gemeinsam.
|
||||
>
|
||||
> **Montage durch Fachbetriebe**
|
||||
> Handwerker aus der Region, die wir persönlich kennen.
|
||||
>
|
||||
> **Ein Ansprechpartner**
|
||||
> Von der ersten Idee bis zur Übergabe koordiniert aus einer Hand.
|
||||
|
||||
---
|
||||
|
||||
## 4. Marken werden ergänzt
|
||||
|
||||
*Kurzer Block, der die Erweiterbarkeit signalisiert. Optional – nur einbauen, wenn die Seite sonst zu kurz wirkt.*
|
||||
|
||||
> ## Unsere Markenwelt wächst
|
||||
>
|
||||
> Wir erweitern unser Portfolio laufend um Hersteller, die zu unserem Anspruch passen. Sie vermissen eine bestimmte Marke oder haben einen konkreten Wunsch? Sprechen Sie uns an – oft finden wir über unser Netzwerk genau das Richtige.
|
||||
|
||||
---
|
||||
|
||||
## 5. Abschluss-CTA
|
||||
|
||||
> ## Lernen Sie unsere Marken kennen
|
||||
>
|
||||
> Am besten dort, wo Sie sie anfassen können: in unseren Showrooms. Vereinbaren Sie einen unverbindlichen Beratungstermin – wir nehmen uns Zeit.
|
||||
>
|
||||
> **Button 1:** Termin anfragen
|
||||
> **Button 2:** Per WhatsApp schreiben
|
||||
|
||||
---
|
||||
|
||||
## 6. Umsetzungshinweise
|
||||
|
||||
- **Startseiten-Sektion bleibt** als Teaser mit verkürzten Texten. Kacheln verlinken direkt auf die jeweilige Detailseite, darunter ein Button **„Alle Marken ansehen"** → `/marken`.
|
||||
- **Navigation:** „Marken" verlinkt auf `/marken`, nicht mehr per Anker auf die Startseite.
|
||||
- **Detailseiten** hängen unter `/marken/cabinet`, `/marken/rotpunkt`, `/marken/februe` – dadurch saubere Hierarchie und funktionierender Rückweg.
|
||||
- **Alte `/netzwerk`-Seite:** Inhalt geht in Abschnitt 3 auf. Seite entfernen und per 301 auf `/marken` weiterleiten, damit bestehende Links und Rankings nicht ins Leere laufen.
|
||||
- **Reihenfolge der Marken** über das CMS steuerbar halten, damit Marcel sie später selbst ändern kann.
|
||||