Skip to main content

MEC-Import (Legacy Mall-Cockpit)

Path in the Dashboard: /dashboard/integration/mec-import.

Preview (Step 2)

The preview API (GET /api/import/mec?sourceCenterId=…) provides samples per area, a field mapping (MEC → database / themeOverrides.templateContent[<websiteTemplate>]), and a website configuration preview (hero slides, color, footer, navigation, directions).

Directions / Transportation: From /informationenanfahrt.<locale>.verkehrsmittel[] (repeater with nested textblock[]), title, icon URL, and text blocks are imported to templateContent[<websiteTemplate>].anfahrt.verkehrsmittel[]. ShopBox additionally receives flat anfahrt.blocks[] (heading/body). Coordinates (lat/lng) end up in the center master data (from adresse or anfahrt.adresse). Edit in the Dashboard: Tab Directions (all MEC templates). Directions are part of the Website Configuration checkbox (templateContent); in the import result, the number of imported transportation blocks is shown, provided the MEC API returns data.

Merge on Re-import: Navigation: existing dashboard values prevail (manual adjustments remain). Hero slides: If MEC /slider returns non-empty slides, they overwrite local slides on re-import (MEC is the source of truth); other hero-level dashboard settings (e.g. intervalMs, layout) are preserved. If the API returns no slides, manually maintained slides remain unchanged. Per slide: start_date/end_datestartDate/endDate, stylemecStyle (+ background color from known slider_td_* classes), description as v3 object { text, … }, and imageUrl also as image/backgroundImage for the dashboard repeater. Preview and import result show active / expired / future (same runtime filter as the website via filterHeroSlidesByDate). Directions and Shopping-in-Center texts (footer/welcomeGray): MEC data overwrite local content if the API provides text. Center master data ShoppingCenter.description: is filled/updated from the same text block (plaintext).

Import Result (Step 3): In addition to shops/news, the summary also shows Website Configuration (Hero, Navigation, Footer, Primary Color), Directions (Transportation blocks), and Center Metadata – even if all records are "already present" (+0 new).

UI (Dashboard): Step 2 uses a two-column layout on wide screens (import options and actions on the left, preview & mapping on the right). The detailed preview (shops, news, services, jobs, website) is organized in tabs to reduce scrolling. The page utilizes the full working width up to approximately 1600px; for long center lists, there are search fields in step 1.

Shops: Opening Hours (oeffnungszeit / oeffnungszeiten)

  • Structured (preferred): oeffnungszeiten.grundzeiten[].liste[] with tage[], von, bisShop.openingHours.regularHours (Mon–Sun, multiple slots per day possible). oeffnungszeiten.sonderzeiten[]Shop.openingHours.specialDays (date, label, From/To).
  • Fallback: lang.<locale>.oeffnungszeit (often HTML with <br />) → Shop.openingHours.announcement (plaintext), only if no regular hours are available.
  • The Opening Hours page (MEC #times-main / shop bar) requires the structured regularHours; plain text is insufficient for the weekday bars.

Center: Opening Hours

  • Numerical: center_einstellungen.oeffnungszeiten (mo_von/mo_bisso_von/so_bis) → ShoppingCenter.openingHours.regularHours (on import with website configuration / center metadata).

  • Long Repeater: center_einstellungen.lang.de.oeffnungszeiten[] (titel, zeit) → ShoppingCenter.openingHours.announcement, if no numerical times are set.

  • Edit in the cockpit: Center → Edit → Tab "Opening Hours" (not the website tab).

  • Legacy in the DB: Older imports or manual entries with {"custom":"…"} or plain text will still be displayed by formatOpeningHours and the opening hours page; HTML will be cleaned upon output.

New Center: Organization

  • When creating a new target center in the import assistant, a cockpitOS organization can be assigned (selection occurs if your account sees multiple organizations; if there is exactly one organization, it is set and displayed automatically).
  • POST /api/import/mec optionally accepts newCenter.organizationId (UUID). Super admins can set or omit any existing organization (no assignment). Other users: only their own organization; without any deviation provided, the user account's organization will be used if available.
  • The import POST requires an authenticated session (401 without login).

Multilingualism (MEC lang.de / lang.en / …)

  • Main fields (name, title, description, …): are filled from the primary language – order: de, en, fr, nl, pl, it, es, da, sv, cs, otherwise the first alphabetically available locale with set titel.
  • All languages of the API are additionally stored in metadata.mecLang (shops, news, services, jobs) or metadata.mecPrimaryLocale.
  • Shop categories (branche, displaybranche, tags): MEC often returns these as localized objects ({ lang: { de: { name, bild } } }), not plain strings. The import normalizes them before saving to Shop.category (string) and Shop.tags / ShopLocation.tags (string arrays) via resolveMecBrancheName / collectMecShopBrancheTags; the raw structure remains in metadata.mecLang. Category fallback: displaybranche → first branch from tags.
  • Shop opening hours: Structured MEC repeaters (oeffnungszeiten.grundzeiten) → regularHours; free text from lang.oeffnungszeit is parsed into regularHours on import (e.g. “Mon–Fri: 10–19”). Update missing mode also backfills records with empty regularHours (announcement only). Locations without their own hours inherit chain.openingHours in the public shops API.
  • “Update missing” mode (mode: update-missing): Finds existing shops/locations by metadata.mecId or name (trim, case-insensitive) and only fills empty fields. Does not create new shops or locations — prevents duplicates on re-import. Exception: category “Allgemein” is corrected when MEC provides a branch. Locations: fuzzy chain-name match (e.g. MEC Apollo-Optik ↔ chain Apollo Optik). Opening hours: MEC grundzeiten are backfilled; if the MEC row is missing, existing announcement text is parsed into regularHours (final pass for all center shops/locations).
  • Hero Slides: visible titles/texts from the prioritized slide locale; in the case of multiple languages, mecLang per slide. Each slide separately: hintergrundbildimageUrl, lang.*.motivmotivImage, hintergrundfarbebackgroundColor (Template D). Footer / “Shopping in Center”: einkaufen_im_center.*footer / welcomeGray / ShoppingCenter.description. Contact External Links: links / links_enkontakt.externalLinks. Center Management: centermanagement.liste[]CenterContact (createdBy: mec-import) + kontakt.secretariat. Info Box:infoTiles[]. Rental:templateContent.vermietung + header.vermietung. PageContent: Coupons, impressions, imprint/data protection/AGB (plain text). Welcome (Template A): willkommen.*welcomeTeaser (+ einkaufsgutscheineActive from allgeinstellungen_gutschein). Hotspot: /hotspottemplateContent.hotspot (not ShopBox); Form → POST /api/[slug]/hotspot/grant (Meraki). Online Logic like legacy isOnline(): hotspot.active + center opening hours (Europe/Berlin), window optionally extended by shop "real". Dashboard: Tab Hotspot / WLAN. Christmas: weihnachten_im_center.*templateContent.weihnachten → Route /weihnachten/[detail].

The public mec-template-d website (apps/center-website/components/templates/mec-template-d):

  • Page Grid: like template_d_master.css / header.tpl – outside full width with background #eae9e7, inside #container max. 1440px centered (gray stripe left/right on large viewports); from ≤480px the container background is white like in the original. Header/navigation remain limited to 1440px and centered.
  • Footer: like footer.tpl / template_d_master.css: footer.mec-d-footer with div.main as table (display: table), columns #footer-row-1 (Navigation, 320px, Links 16px #808080, Hover white), #footer-row-2 (title uppercase / font-weight 500, text #808080, 18px / 24px line), #footer-row-3 (270px, Center logo .grayscale, below p with “Recommend us:” and a.search-row-icon approx. 40×40). Desktop: Height 250px, padding 55px 0 205px, background #e5e5e5; ≤960px stacked blocks (footer.tsx + globals.css).
  • Fonts (GDPR): No Google Fonts / Typekit on the public site. Futura PTself-hostedFuturaPT-Medium is also included as CSS weight 400 so that .content-cms p (Master: later 18px / 24px, with Typekit font-weight 100) does not appear thinner than the live MEC with self-hosted Light.
  • Desktop Navigation: Appearance like the effective condition in the live template (merging template_d_master.css and template_d/style.css), technically one clear rule in app/globals.css (.mec-d-nav-link / .mec-d-nav-dropdown-link) – without recreating the legacy !important overlays. Workflow for further blocks: Template-D Legacy CSS Checklist.
  • Shows a language switcher as soon as the slice contains more than one locale (footer.mecFooterByLocale, Hero-mecLang, optionally kontakt.externalLinksByLocale).
  • URL: ?lang=en (and SessionStorage per Center-Slug mec-template-d-lang:<slug>).
  • Footer Description and Hero Texts are selected from the imported multilingual fields; Header Navigation remains configurable in the Dashboard (hardcoded in the original MEC, not imported from links). The fixed footer link list remains in German (can be connected later).
  • Homepage – Tile "Current Offers": corresponds to home.tpl / .home-infobox-angebote in template_d_master.css: white area, heading visually like live (merging Master + template_d/style.css: Futura, uppercase, 30px, top 39px etc. in app/globals.css under [data-template="mec-template-d"] .home-infobox-angebote-title, including breakpoints; link “To the offer” with bottom 65px from style.css). Left Shop + short title (30 characters), right image, bottom right green circle #A4C556 with % and “Offer” when no price fields are set (like MEC-offer-green); otherwise, red circle #EF4741 with price/Euro. Content of the tile (circle, text, image, slider points) via one rule in globals.css; React uses, among others, mec-d-angebot-val / -caption / -old-price, ul.mec-d-angebote-dots with li.is-active. Points below #E5E5E5 / active #808080, Autoplay 5s (like Slick in template_green.js for this class). Data source: highlights from the center (type: 'offer'), including shop from the offer linkage.
  • Three large info boxes (Opening Hours / Shopping / News, InfoBox3): like home.tpl with home-infobox-3 plus home-infobox-oeffnungszeiten / -shopping / -news. Title (.box-title): Futura, 30px, bold, uppercase, left-aligned; Subtitle 18px, regular. Illustrations: forInfobox3 / .mec-d-infobox3-svg.
  • Hero Slider: On the homepage sliderLayout="template-d": section .home-slider with fixed heights per breakpoint (380 / 645 / 680 px height for mobile < 768 px, tablet 768–1023 px, desktop from 1024 px); Badge like teaser.css (.home-slider-badge); points like template_d/style.css (centered, ≤1024px left vertically with flexible height, ≤767px smaller circles); no side arrows. Title/Description: responsive font via CSS; optionally lineWidth (narrow / standard / wide / full, the latter nearly full text width including margin) per title and v3 description; optionally fontSizePx (legacy desktop, equivalent to fontSizePxByDevice.desktop) and/or fontSizePxByDevice with desktop / tablet / mobile to override the level size per breakpoint. Allowed HTML in title, description, badge, and legacy subtitle (e.g., <br>, <strong>, <a>, paragraphs) is rendered on the website and in the dashboard preview (cleaned according to the same rules as shop texts). Multi-line titles: line break, <br> or <p>...</p><p>...</p> in CMS. In the Dashboard (WebsiteHero-Slider for Template D): Preview with breakpoint switch. Tab Title / Subtitle: slider for font in px for the active preview view (stored in fontSizePxByDevice); Tab Fine-Tuning: max. text width, pixel shift — stored under hero.slides[].titleAdjust / subtitleAdjust / motivAdjust.
  • Lower four info boxes (Lottie): Classes home-infobox-4 + variants; Lottie IDs #anfahrt-animation among others. Title two lines like live: first line small/regular, second large/bold (split: first word / rest, or line break \n in the dashboard title); Subtitle small, normal capitalization. CSS: mec-d-infobox4-line1 / line2 / sub in globals.css.
  • Shop Logo Bar above the Footer (like Live Template-D / template_grooss.js Slick): standard active, Shop logos from layoutData.shops, unless a different templateContent['mec-template-d'].footer.logoSlider configuration exists. Can be turned off with logoSlider.enabled: false or manual logoSlider.logos list. Optionally: logoSlider.logoLinksEnabled: true → Click on shop details. Technically Embla with the same parameters as Slick: 6 / 3 / 2 visible logos (Desktop / ≤960px / ≤480px), Autoplay 2 s, one logo per step, Loop; Height 145px, white background, horizontal padding 75px (15px mobile), logos max. 120×120px, grayscale with hover color (globals.css + footer.tsx).
  • Directions Page: #map-router shows the embedded map without operable Google controls and without moving the map (Embed with pointer-events: none, lower embed bar visually trimmed). Guide marker and link Plan route remain active (pages/anfahrt.tsx, globals.css).
  • Subpage Header (subpageHeaders under templateContent['mec-template-d']): Banner height 360px (Desktop), SVG on the right at full banner height, content vertically centered; .titleFutura, white, uppercase, 70px, translateY(-50%) + rotate(-10deg) with transform-origin: left center; first line font-weight: 800, following 300. ≤480px without SVG. Desktop Nav: Search in the Flex next to the links (#navigation-wrapper), input width clamp, no overlap. Without dashboard entry, static legacy defaults (colors/texts/SVG URLs like in the original MEC) are delivered from mec-d-subpage-header-defaults.ts; set CMS fields overwrite per property. components/subpage-header.tsx, components/header.tsx.
  • Shops/News from the CMS continue to use the main fields of the DB; translations there are in metadata.mecLang and are not yet read for lists/detail pages in the Template-D view. Shops A–Z: ul.shop-list is set in app/globals.css like template_d_master.css (letters 32px #808080, links 18px #EF4741). Service Page (/service): like live only icon + .titel (.service > .icon > img height 65 + .titel); Tiles 24% / float, 250px high (200px ≤960px), .titel #808080, font-weight: normal, 14px ≤960px; ≤480px tile 100% / height: auto (pages/service.tsx + globals.css).

Media

If Bunny Storage is configured for the center (BUNNY_STORAGE_*), MEC image URLs will be processed during import like a manual Dashboard upload: download from the MEC URL, upload to the Bunny bucket, create a MediaFile entry (Scope Center, uploadedBy: 'mec-import') and link it with the respective entity.

  • Shops: bild_datei_1logo (logo), bild_datei_2/bild_datei_3 as well as URLs from galerieimages (gallery).
  • News: bild_datei_1 → main image (image), bild_datei_4 → first gallery image (gallery[0]), if set.
  • Services: bild_datei_1icon (icon).
  • Hero (Website Configuration): After building the slides from the MEC API, background image, motif, and title graphic (if HTTP URL) are subsequently uploaded to Bunny; hero.slides[].imageUrl, motivImage, and titleImage then contain the Bunny CDN URLs.
  • Welcome / Hotspot / Christmas: Service icons (willkommen.featured_services), hotspot images (person_image, slogan_image_*, …) and Christmas sponsor logos will also be uploaded to Bunny if storage is configured.

News Texts (Center Actions): In the API, the visible HTML text often only exists in kurzbeschreibung, while beschreibung is empty. The import fills content with beschreibung or otherwise kurzbeschreibung. excerpt: if both text fields are set, kurzbeschreibung is used as the excerpt; if only kurzbeschreibung exists, untertitel as teaser (if available).

Without a valid Bunny configuration, shop/news/service media remains empty or unchanged; Hero slides can still only work with external URLs until storage is available.

See also

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/mec-import