MEC-Import (Legacy Mall-Cockpit)
Pfad im Dashboard: /dashboard/integration/mec-import.
Vorschau (Schritt 2)
Die Vorschau-API (GET /api/import/mec?sourceCenterId=…) liefert pro Bereich Stichproben, ein Feldmapping (MEC → Datenbank / themeOverrides.templateContent[<websiteTemplate>]) und eine Website-Konfigurations-Vorschau (Hero-Slides, Farbe, Footer, Navigation, Anfahrt).
API-Filter (wichtig): Center-spezifische Endpoints (/informationen, /slider, /shops, …) erwarten center_id=<id>¢er=<id>. Nur center_id liefert teils globale ACF-„options“ (falsches Center, leere Infokasten/Teaser). Der Cockpit-Client setzt beide Parameter (mec-api-client.ts: mecCenterQueryParams).
Anfahrt / Verkehrsmittel: Aus /informationen → anfahrt.<locale>.verkehrsmittel[] (Repeater mit verschachteltem textblock[]) werden Titel, Icon-URL und Textblöcke nach templateContent[<websiteTemplate>].anfahrt.verkehrsmittel[] importiert. Zusätzlich anfahrt.<locale>.footer (MEC-Accordion „Footer“: Titel, Untertitel, Button-Text) → anfahrt.footer (title, subtitle, ctaLabel, ctaPath: '/anfahrt'). ShopBox erhält zusätzlich flache anfahrt.blocks[] (heading/body). Koordinaten (lat/lng) landen in den Center-Stammdaten (aus adresse oder anfahrt.adresse). Im Dashboard bearbeiten: Reiter Anfahrt (alle MEC-Templates). Anfahrt ist Teil der Checkbox Website-Konfiguration (templateContent); im Import-Ergebnis erscheint die Anzahl importierter Verkehrsmittel-Blöcke, sofern die MEC-API Daten liefert.
Merge beim Re-Import: Navigation: bestehende Dashboard-Werte gewinnen (manuelle Anpassungen bleiben). Hero-Slides: Wenn MEC /slider nicht-leere slides liefert, überschreiben diese die lokalen Slides beim Re-Import (MEC ist Quelle der Wahrheit); andere Hero-Einstellungen im Dashboard (z. B. intervalMs, Layout) bleiben erhalten. Liefert die API keine Slides, bleiben manuell gepflegte Slides unverändert. Pro Slide werden start_date/end_date → startDate/endDate, style → mecStyle (+ Hintergrundfarbe aus bekannten slider_td_*-Klassen), Beschreibung als v3-Objekt { text, … } und imageUrl parallel als image/backgroundImage übernommen. Import-Vorschau und Ergebnis zeigen aktiv / abgelaufen / zukünftig (Laufzeitfilter wie auf der Website via filterHeroSlidesByDate). Anfahrt und Einkaufen-im-Center-Texte (Footer/welcomeGray): MEC-Daten überschreiben lokale Inhalte, sofern die API Text liefert. Center-Stammdaten ShoppingCenter.description: wird aus dem gleichen Textblock befüllt/aktualisiert (Plaintext).
Mehrsprach-Formate: Manche Center liefern Texte doppelt verschachtelt ({ lang: { de, multi } } statt { de, multi }). Der Import normalisiert diese Felder vor dem Speichern (resolveMecLocalizedString / buildMecLocaleStringMap), damit in templateContent und der Import-Vorschau keine {lang}-Objekte als React-Text landen.
Import-Ergebnis (Schritt 3): Neben Shops/News zeigt die Zusammenfassung auch Website-Konfiguration (Hero, Navigation, Footer, Primärfarbe), Anfahrt (Verkehrsmittel-Blöcke) und Center-Metadaten – auch wenn alle Datensätze „bereits vorhanden“ sind (+0 neu).
UI (Dashboard): Schritt 2 nutzt auf breiten Bildschirmen ein Zwei-Spalten-Layout (links Import-Optionen und Aktionen, rechts Vorschau & Mapping). Die Detail-Vorschau (Shops, News, Services, Jobs, Website) ist in Reiter (Tabs) gegliedert, damit du weniger scrollen musst. Die Seite nutzt die volle Arbeitsbreite bis ca. 1600px; für lange Centerlisten gibt es Suchfelder in Schritt 1.
Shops: Öffnungszeiten (oeffnungszeit / oeffnungszeiten)
- Strukturiert (bevorzugt):
oeffnungszeiten.grundzeiten[].liste[]mittage[],von,bis→Shop.openingHours.regularHours(Mo–So, mehrere Slots pro Tag möglich).oeffnungszeiten.sonderzeiten[]→Shop.openingHours.specialDays(Datum, Label, Von/Bis). - Fallback:
lang.<locale>.oeffnungszeit(oft HTML mit<br />) →Shop.openingHours.announcement(Klartext), nur wenn keine Grundzeiten vorhanden sind. - Die Öffnungszeiten-Seite (MEC
#times-main/ Shop-Balken) benötigt die strukturiertenregularHours; reiner Freitext reicht dort nicht für die Wochentags-Balken.
Center: Öffnungszeiten
-
Numerisch:
center_einstellungen.oeffnungszeiten(mo_von/mo_bis…so_von/so_bis) →ShoppingCenter.openingHours.regularHours(beim Import mit Website-Konfiguration / Center-Metadaten). -
Lang-Repeater:
center_einstellungen.lang.de.oeffnungszeiten[](titel,zeit) →ShoppingCenter.openingHours.announcement, wenn keine numerischen Zeiten gesetzt sind. -
Bearbeiten im Cockpit: Center → Bearbeiten → Reiter „Öffnungszeiten“ (nicht Webseiten-Tab).
-
Legacy in der DB: Ältere Importe oder manuelle Einträge mit
{"custom":"…"}oder reinem Freitext werden vonformatOpeningHoursund der Öffnungszeiten-Seite weiterhin angezeigt; HTML wird bei der Ausgabe bereinigt.
Neues Center: Organisation
- Beim Anlegen eines neuen Ziel-Centers im Import-Assistenten kann eine cockpitOS-Organisation zugewiesen werden (Auswahl, sofern dein Account mehrere Organisationen sieht; mit genau einer Organisation wird sie automatisch gesetzt und angezeigt).
POST /api/import/mecakzeptiert optionalnewCenter.organizationId(UUID). Super-Admins dürfen eine beliebige existierende Organisation setzen oder weglassen (keine Zuordnung). Andere Nutzer: nur die eigene Organisation; ohne abweichende Angabe wird die Organisation des Benutzerkontos verwendet, sofern vorhanden.- Der Import-POST erfordert eine angemeldete Session (
401ohne Login).
Mehrsprachigkeit (MEC lang.de / lang.en / …)
- Hauptfelder (
name,title,description, …): werden aus der Primärsprache befüllt – Reihenfolge:de,en,fr,nl,pl,it,es,da,sv,cs, sonst erste alphabetisch verfügbare Locale mit gesetztemtitel. - Alle Sprachen der API werden zusätzlich in
metadata.mecLang(Shops, News, Services, Jobs) bzw.metadata.mecPrimaryLocalegespeichert. - Shop-Branchen (
branche,displaybranche,tags): MEC liefert diese Felder oft als lokalisierte Objekte ({ lang: { de: { name, bild } } }), nicht als Plain-Strings. Der Import normalisiert sie vor dem Speichern inShop.category(String) undShop.tags/ShopLocation.tags(String-Arrays) viaresolveMecBrancheName/collectMecShopBrancheTags; die Rohstruktur bleibt inmetadata.mecLangerhalten. Fallback fürcategory:displaybranche→ erste Branche austags. - Shop-Öffnungszeiten: Strukturierte MEC-Repeater (
oeffnungszeiten.grundzeiten) →regularHours; Freitext auslang.oeffnungszeitwird beim Import inregularHoursgeparst (z. B. „Mo–Fr: 10–19 Uhr“). Modus Fehlende Daten nachziehen füllt auch Datensätze mit leerenregularHours(nurannouncement) nach. Filialen ohne eigene Zeiten erben in der öffentlichen Shops-APIchain.openingHours. - Modus „Fehlende Daten nachziehen“ (
mode: update-missing): Sucht vorhandene Shops/Filialen permetadata.mecIdoder Name (trim, case-insensitive) und füllt nur leere Felder nach. Legt keine neuen Shops oder Filialen an — verhindert Duplikate bei erneutem Import. Ausnahme: Kategorie „Allgemein“ wird korrigiert, wenn MEC eine Branche liefert. Filialen (ShopLocation): Zuordnung auch bei abweichendem Kettennamen (z. B. MEC „Apollo-Optik“ ↔ Kette „Apollo Optik“, „Adler Modemarkt“ ↔ „Adler“). Öffnungszeiten: strukturierte MEC-grundzeitenwerden nachgezogen; fehlt MEC-Eintrag, wird vorhandener Freitext (announcement) inregularHoursgeparst (Abschluss-Pass für alle Shops/Filialen des Centers). - Hero-Slides (Startseite, CPT
/slider): sichtbare Titel/Texte aus der priorisierten Slide-Locale; bei mehreren SprachenmecLangpro Slide. Pro Slide getrennt:hintergrundbild→imageUrl,lang.*.motiv→motivImage,hintergrundfarbe→backgroundColor(Template D). Unterseiten-Header (Grooss/Green/A/D, ACF „Header für Unterseiten“):/informationen→slider[](nicht der Homepage-/slider-Endpoint) mitunterseite,beschreibung(sichtbarer Text, z. B. „Wir sind für Sie da“),hintergrundbild,motiv,titel,svg→PageContent.customContent.subpageHero(Single Source of Truth; Legacy parallel:heroTitle,hero.image,subpageHeroSlides). Mappingunterseite→pageTypeinmec-subpage-header-import.ts. Medien → Bunny (subpageHero.*). Footer / „Einkaufen im Center“:einkaufen_im_center.*→footer/welcomeGray/ShoppingCenter.description. Kontakt-Externlinks:links/links_en→kontakt.externalLinks. Centermanagement:centermanagement.liste[]→CenterContact(createdBy: mec-import) +kontakt.secretariat. Infokasten: →infoTiles[]. Vermietung: →templateContent.vermietung+header.vermietung. PageContent: Gutschein, Impressionen, Impressum/Datenschutz/AGB (Freitext). Willkommen (Template A):willkommen.*→welcomeTeaser(+einkaufsgutscheineActiveausallgeinstellungen_gutschein). Hotspot:/hotspot→templateContent.hotspot(nicht ShopBox); Formular →POST /api/[slug]/hotspot/grant(Meraki). Online-Logik wie LegacyisOnline():hotspot.active+ Center-Öffnungszeiten (Europe/Berlin), Fenster optional erweitert durch Shop „real“. Dashboard: Reiter Hotspot / WLAN. Weihnachten:weihnachten_im_center.*→templateContent.weihnachten→ Route/weihnachten/[detail].
Die öffentliche mec-template-d-Website (apps/center-website/components/templates/mec-template-d):
- Seitenraster: wie
template_d_master.css/header.tpl– außen volle Breite mit Hintergrund #eae9e7, innen#containermax. 1440px zentriert (grauer Streifen links/rechts auf großen Viewports); ab ≤480px ist der Container-Hintergrund weiß wie im Original. Header/Navigation bleiben auf 1440px begrenzt und mittig. - Footer: wie
footer.tpl/template_d_master.css:footer.mec-d-footermitdiv.mainals Tabelle (display: table), Spalten#footer-row-1(Navigation, 320px, Links 16px #808080, Hover weiß),#footer-row-2(Titel uppercase / font-weight 500, Text #808080, 18px / 24px Zeile),#footer-row-3(270px, Center-Logo.grayscale, darunterpmit „Empfehlen Sie uns:“ unda.search-row-iconca. 40×40). Desktop: Höhe 250px, padding 55px 0 205px, Hintergrund #e5e5e5; ≤960px gestapelte Blöcke (footer.tsx+globals.css). - Schriften (DSGVO): Kein Google Fonts / Typekit auf der öffentlichen Site. Futura PT … selbst gehostet …
FuturaPT-Mediumist zusätzlich als CSS-Gewicht 400 eingebunden, damit.content-cms p(Master: später 18px / 24px, bei Typekit font-weight 100) auf der React-Site nicht dünner wirkt als das Live-MEC mit selbst gehostetem Light. - Desktop-Navigation: Optik wie der effektive Zustand im Live-Template (Zusammenführung von
template_d_master.cssundtemplate_d/style.css), technisch eine klare Regel inapp/globals.css(.mec-d-nav-link/.mec-d-nav-dropdown-link) – ohne die Legacy-!important-Überlagerungen nachzubauen. Arbeitsablauf für weitere Blöcke: Template-D Legacy-CSS-Checkliste. - Zeigt einen Sprachumschalter, sobald das Slice mehr als eine Locale trägt (
footer.mecFooterByLocale, Hero-mecLang, optionalkontakt.externalLinksByLocale). - URL:
?lang=en(und SessionStorage pro Center-Slugmec-template-d-lang:<slug>). - Footer-Beschreibung und Hero-Texte werden aus den importierten mehrsprachigen Feldern gewählt; Header-Navigation bleibt im Dashboard konfigurierbar (fest codiert im Original-MEC, nicht aus
linksimportiert). Die feste Footer-Linkliste bleibt deutsch (kann später angebunden werden). - Startseite – Kachel „Aktuelle Angebote“: entspricht
home.tpl/.home-infobox-angeboteintemplate_d_master.css: weiße Fläche, Überschrift visuell wie Live (Zusammenführung Master +template_d/style.css: Futura, uppercase, 30px, top 39px usw. inapp/globals.cssunter[data-template="mec-template-d"] .home-infobox-angebote-title, inkl. Breakpoints; Link „Zum Angebot“ mit bottom 65px ausstyle.css). Linkes Shop + kurzer Titel (30 Zeichen), rechts Bild, unten rechts grüner Kreis #A4C556 mit % und „Angebot“, wenn keine Preisfelder gesetzt sind (wie MEC-offer-green); sonst roter Kreis #EF4741 mit Preis/Euro. Inhalt der Kachel (Kreis, Text, Bild, Slider-Punkte) über eine Regel inglobals.css; React nutzt u. a.mec-d-angebot-val/-caption/-old-price,ul.mec-d-angebote-dotsmitli.is-active. Punkte unten #E5E5E5 / aktiv #808080, Autoplay 5s (wie Slick intemplate_green.jsfür diese Klasse). Datenquelle:highlightsvom Center (type: 'offer'), inkl.shopaus der Angebots-Verknüpfung. - Drei große Infokacheln (Öffnungszeiten / Shopping / News,
InfoBox3): wiehome.tplmithome-infobox-3plushome-infobox-oeffnungszeiten/-shopping/-news. Titel (.box-title): Futura, 30px, bold, uppercase, linksbündig; Untertitel 18px, regular. Illustrationen:forInfobox3/.mec-d-infobox3-svg. - Hero-Slider: Auf der Startseite
sliderLayout="template-d": Abschnitt.home-slidermit festen Höhen pro Breakpoint (380 / 645 / 680 px Höhe für Mobil ab <768 px, Tablet 768–1023 px, Desktop ab 1024 px); Badge wieteaser.css(.home-slider-badge); Punkte wietemplate_d/style.css(zentriert, ≤1024px links vertikal mit flexibler Höhe, ≤767px kleinere Kreise); keine seitlichen Pfeile. Titel/Beschreibung: responsive Schrift über CSS; optionallineWidth(narrow/standard/wide/full, letztere nahezu volle Textbreite inkl. Rand) pro Titel und v3-Beschreibung; optionalfontSizePx(Legacy-Desktop, gleichwertig zufontSizePxByDevice.desktop) und/oderfontSizePxByDevicemitdesktop/tablet/mobilezum Überschreiben der Stufesizepro Breakpoint. Erlaubtes HTML in Titel, Beschreibung, Badge und Legacy-Untertitel (z. B.<br>,<strong>,<a>, Absätze) wird auf der Website und in der Dashboard-Vorschau gerendert (nach denselben Regeln wie bei Shop-Texten bereinigt). Mehrzeilige Titel: Zeilenumbruch,<br>oder<p>...</p><p>...</p>im CMS. Im Dashboard (Website → Hero-Slider für Template D): Vorschau mit Breakpoint-Umschaltung. Reiter Titel / Untertitel: Schieberegler für Schrift in px jeweils für die aktive Vorschau-Ansicht (werden infontSizePxByDevicegespeichert); Reiter Feinjustierung: max. Textbreite, Pixel-Verschiebung — gespeichert unterhero.slides[].titleAdjust/subtitleAdjust/motivAdjust. - Untere vier Infokacheln (Lottie): Klassen
home-infobox-4+ Varianten; Lottie-IDs #anfahrt-animation u. a. Titel zweizeilig wie Live: erste Zeile klein/regular, zweite groß/fett (Aufteilung: erstes Wort / Rest, oder Zeilenumbruch\nim Dashboard-Titel); Untertitel klein, normale Groß-/Kleinschreibung. CSS:mec-d-infobox4-line1/line2/subinglobals.css. - Shop-Logo-Leiste über dem Footer (wie Live-Template-D /
template_grooss.jsSlick): Standard aktiv, Shop-Logos auslayoutData.shops, sofern keine abweichendetemplateContent['mec-template-d'].footer.logoSlider-Konfiguration. Abstellbar mitlogoSlider.enabled: falseoder manuellelogoSlider.logos-Liste. Optional:logoSlider.logoLinksEnabled: true→ Klick auf Shop-Detail. Technisch Embla mit gleichen Parametern wie Slick: 6 / 3 / 2 sichtbare Logos (Desktop / ≤960px / ≤480px), Autoplay 2 s, ein Logo pro Schritt, Loop; Höhe 145px, weißer Hintergrund, horizontales Padding 75px (15px mobil), Logos max. 120×120px, Graustufen mit Hover-Farbe (globals.css+footer.tsx). - Anfahrt-Seite:
#map-routerzeigt die eingebettete Karte ohne bedienbare Google-Steuerelemente und ohne Verschieben der Karte (Embed mitpointer-events: none, untere Embed-Leiste optisch beschnitten). Wegweiser-Marker und Link Route planen bleiben aktiv (pages/anfahrt.tsx,globals.css). - Unterseiten-Header: Dashboard-Reiter Unterseiten-Header (alle MEC-Templates A/D/Grooss/Green) schreibt
PageContent.customContent.subpageHeropro Seite. Template D: Bannerhöhe 360px (Desktop), SVG rechts in voller Bannerhöhe, Inhalt vertikal zentriert;.title– Futura, weiß, uppercase, 70px,translateY(-50%)+rotate(-10deg)mittransform-origin: left center; erste Zeilefont-weight: 800, Folge 300. ≤480px ohne SVG. Ohne Dashboard-/Import-Eintrag liefern statische Legacy-Defaults ausmec-d-subpage-header-defaults.ts(bzw. template-spezifische Defaults für A/Grooss/Green); gesetzte Felder überschreiben pro Property. LegacytemplateContent['mec-template-d'].subpageHeaderswird weiter gelesen, bis alle Center migriert sind. Resolver:_mec-shared/lib/resolve-mec-subpage-hero.ts, UI:components/subpage-header.tsx. - Shops/News aus dem CMS nutzen weiter die Hauptfelder der DB; dortige Übersetzungen liegen in
metadata.mecLangund werden von der Template-D-Ansicht noch nicht für Listen/Detailseiten ausgelesen. Geschäfte A–Z:ul.shop-listwird inapp/globals.csswietemplate_d_master.cssgesetzt (Buchstaben 32px #808080, Links 18px #EF4741). Service-Seite (/service): wie Live nur Icon +.titel(.service>.icon>imgheight 65 +.titel); Kacheln 24% / Float, 250px hoch (200px ≤960px),.titel#808080,font-weight: normal, 14px ≤960px; ≤480px Kachel 100% /height: auto(pages/service.tsx+globals.css).
Medien
Wenn Bunny Storage für das Center konfiguriert ist (BUNNY_STORAGE_*), werden alle MEC-Remote-Assets beim Import wie ein manueller Dashboard-Upload verarbeitet: Download von der MEC-URL (mec.mall-cockpit.de und WP-Upload-Pfade), Upload in den Bunny-Bucket des Centers, Anlage eines MediaFile-Eintrags (Scope Center, uploadedBy: 'mec-import') und Verknüpfung mit der jeweiligen Entität.
Asset-Typen (Auswahl):
| Bereich | MEC-Quelle | Speicherziel |
|---|---|---|
| Shops | bild_datei_1 (Logo), Galerie | logo, images (Re-Import migriert auch einzelne MEC-URLs in images[]) |
| News | Titelbild, Galerie, HTML eingebettete Bilder | image, gallery, content |
| Services | Icon, Cover | icon, coverImage |
| Jobs | PDF-Anhang | externalUrl (Bunny-PDF) |
| Centerzeitung | Vorschaubild, PDF | image, metadata.pdfUrl |
| Centerplan | SVG pro Ebene | MapFloor.mapImage (+ mapSvg Text) |
| Hero / Unterseiten-Header | Hintergrund, Motiv, Titel-Grafik, SVG | templateContent.hero, PageContent.subpageHero |
| Anfahrt | Verkehrsmittel-Icons | templateContent.anfahrt.verkehrsmittel[].iconUrl |
| Willkommen / Hotspot / Weihnachten | Icons, Bilder, Sponsor-Logos | templateContent.* |
| Centermanagement | Kontaktfotos | CenterContact.photoUrl |
| Impressionen | Galerie-URLs | PageContent.customContent.images |
| Rechtstexte | HTML mit eingebetteten MEC-Bildern | PageContent.pageDescription (Impressum, Datenschutz, AGB) |
Modus „Fehlende Daten nachziehen“ (update-missing): Felder werden nicht nur bei null/leer nachgefüllt, sondern bestehende Werte auf mec.mall-cockpit.de werden erneut nach Bunny migriert (Shops, News, Services, Jobs, Centerplan, Centerzeitung u. a.).
Strict-Verhalten: Auf dem Erfolgspfad werden keine MEC-CDN-URLs als Endwert gespeichert. Schlägt der Upload fehl, erscheint ein Fehler im Import-Ergebnis; das Feld bleibt leer bzw. unverändert (kein stilles Beibehalten der MEC-URL bei Hero-Slides).
News-Texte (Center-Aktionen): In der API steckt der sichtbare HTML-Text häufig nur in kurzbeschreibung, während beschreibung leer ist. Der Import füllt content mit beschreibung oder sonst kurzbeschreibung. Eingebettete MEC-Bild-URLs im HTML werden nach Bunny umgeschrieben. excerpt: wenn beide Textfelder gesetzt sind, wird kurzbeschreibung als Auszug genutzt; wenn nur kurzbeschreibung existiert, untertitel als Teaser (falls vorhanden).
Ohne gültige Bunny-Konfiguration bleiben Medienfelder leer bzw. unverändert; es werden keine neuen MEC-Remote-URLs als Zielwert geschrieben.
Siehe auch
- Template-D Legacy-CSS-Checkliste – Pixel-Treue-Workflow für ein einzelnes Template.
- Gemeinsame MEC-Bausteine (
_mec-shared/) – Helfer und Embla-Logo-Slider, die mehrere MEC-Templates teilen, ohne ihre Optik zu vereinheitlichen.
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/mec-import