diff --git a/config/nam.3bear.design.json b/config/nam.3bear.design.json
index e9c9da9..496fa98 100644
--- a/config/nam.3bear.design.json
+++ b/config/nam.3bear.design.json
@@ -177,6 +177,36 @@
]
}
},
+ {
+ "Hero": {
+ "config": {
+ "className": "h-[35rem]",
+ "ImageDisplayer": {
+ "config": {
+ "duration": 0,
+ "images": ["./banner-hero.webp"],
+ "links": ["/account"]
+ }
+ },
+ "left": [
+ {
+ "VtCtaBanner": {
+ "config": {
+ "className": "left-[120px] top-[80px] relative w-full p-12 flex flex-col items-start justify-center text-left bg-transperant border-none shadow-none",
+ "buttonTextClassName": "inline-flex items-center justify-center bg-[#FCEE56] hover:bg-[#FCEE56]/90 text-[#0D382E] px-8 py-3 rounded-full font-bold text-lg shadow-none border-none",
+ "tagTextClassName": "text-[#0D382E] text-lg font-medium mb-2 bg-transparent",
+ "tagText": "So einfach kann Frühstück sein – mit unseren leckeren Overnight Oats.",
+ "titleText": "breakfast made easy.",
+ "buttonText": "Jetzt entdecken"
+ }
+ }
+ }
+ ],
+ "center": [],
+ "right": []
+ }
+ }
+ },
{
"CartMismatchBanner": {
"config": {
@@ -213,10 +243,26 @@
"emailInputClassName": "w-[300px] ml-8"
},
"socials": [
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" }
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ }
],
"socialsClassName": "ml-8 mt-10",
"className": "",
@@ -311,15 +357,22 @@
"config": {
"className": "content-container bg-[#003f31] w-full text text-[#11314E] flex items-center justify-between",
"leftClassName": "w-full",
- "left": [
- ],
+ "left": [],
"center": [],
"right": [
{
"VtFooterBottom": {
"config": {
"className": " mr-[80px]",
- "icons": ["Mastercard", "PayPal", "Visa", "Mastercard","Mastercard","Mastercard","Mastercard"]
+ "icons": [
+ "Mastercard",
+ "PayPal",
+ "Visa",
+ "Mastercard",
+ "Mastercard",
+ "Mastercard",
+ "Mastercard"
+ ]
}
}
}
diff --git a/config/nam.drsquatch.design.json b/config/nam.drsquatch.design.json
index bcc4e8f..9338061 100644
--- a/config/nam.drsquatch.design.json
+++ b/config/nam.drsquatch.design.json
@@ -130,6 +130,44 @@
]
}
},
+ {
+ "Hero": {
+ "config": {
+ "className": "h-[35rem]",
+ "ImageDisplayer": {
+ "config": {
+ "duration": 0,
+ "images": [
+ "./drsquatch-banner.jpg"
+ ],
+ "links": [
+ "/account"
+ ]
+ }
+ },
+ "left": [
+ {
+ "VtCtaBanner": {
+ "config": {
+ "variant": "default",
+ "className": "left-[120px] top-[120px] bg-transparent border-none text-white text-center",
+ "tagTextClassName": "text-white bg-transparent",
+ "titleTextClassName": "text-white font-bold leading-normal text-[30px]",
+ "descriptionTextClassName": "text-white text-[1rem] w-[300px] ml-[6.6rem]",
+ "buttonTextClassName": "text-white bg-orange-500 w-[300px]",
+ "tagText": "ALL NEW!",
+ "titleText": "LUMBERJACK LODGE",
+ "descriptionText": "Step into the lodge with the warm, sweet scent of maple and vanilla.",
+ "buttonText": "SHOP NOW"
+ }
+ }
+ }
+ ],
+ "center": [],
+ "right": []
+ }
+ }
+ },
{
"CartMismatchBanner": {
"config": {
@@ -277,14 +315,30 @@
"buttonClassName": "bg-[#C4622C] w-[90px]",
"socialsClassName": "mt-4 gap-8",
"socials": [
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
- { "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" }
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ },
+ {
+ "icon": "Twitter",
+ "href": "/",
+ "className": "w-5 h-5 text-white"
+ }
]
}
}
- }
+ }
]
}
}
diff --git a/config/nam.mds-starter-design.json b/config/nam.mds-starter-design.json
index 292b7ab..9994c23 100644
--- a/config/nam.mds-starter-design.json
+++ b/config/nam.mds-starter-design.json
@@ -134,6 +134,14 @@
]
}
},
+ {
+ "Hero": {
+ "config": {
+ "variant": "default",
+ "className": "bg-custom-gradient"
+ }
+ }
+ },
{
"CartMismatchBanner": {
"config": {
diff --git a/config/nam.vibentec.design.json b/config/nam.vibentec.design.json
index 22917f8..f5b610a 100644
--- a/config/nam.vibentec.design.json
+++ b/config/nam.vibentec.design.json
@@ -176,6 +176,41 @@
]
}
},
+ {
+ "Hero": {
+ "config": {
+ "className": "h-[35rem]",
+ "ImageDisplayer": {
+ "config": {
+ "duration": 5,
+ "images": [
+ "./banner-hero.webp",
+ "./banner-hero-1.webp",
+ "./banner-hero-2.webp"
+ ],
+ "links": ["/", "/account", "/product"]
+ }
+ },
+ "left": [
+ {
+ "VtCtaBanner": {
+ "config": {
+ "variant": "default",
+ "className": "left-[120px] top-[80px]",
+ "titleTextClassName": "leading-normal",
+ "tagText": "Besonders Aktion",
+ "titleText": "Willkommen in Vibentec IT Shop",
+ "descriptionText": "Insert the accordion description here. It would look better as two lines of text or more.",
+ "buttonText": "Zum Einkaufen"
+ }
+ }
+ }
+ ],
+ "center": [],
+ "right": []
+ }
+ }
+ },
{
"CartMismatchBanner": {
"config": {
@@ -209,7 +244,10 @@
"logoAlt": "Vibentec IT",
"title": "Der Wegbereiter für innovative IT-Lösungen",
"description": "Tauchen Sie ein in eine Welt modernster Technologien, zuverlässiger Support und proaktiver Innovation – gemeinsam gestalten wir die digitale Zukunft Ihres Unternehmens.",
- "cta": { "label": "Kontaktieren Sie uns", "href": "/" },
+ "cta": {
+ "label": "Kontaktieren Sie uns",
+ "href": "/"
+ },
"className": "",
"ctaClassName": "ml-8",
"titleClassName": "ml-8",
@@ -329,7 +367,11 @@
"VtFooterBottom": {
"config": {
"text": "©2025 Vibentec IT. All rights reserved",
- "icons": ["Mastercard", "PayPal", "Visa"]
+ "icons": [
+ "Mastercard",
+ "PayPal",
+ "Visa"
+ ]
}
}
}
diff --git a/package.json b/package.json
index 8777bbc..49610ca 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,8 @@
"@radix-ui/react-accordion": "^1.2.1",
"@stripe/react-stripe-js": "^1.7.2",
"@stripe/stripe-js": "^1.29.0",
+ "embla-carousel-autoplay": "^8.6.0",
+ "embla-carousel-react": "^8.6.0",
"lodash": "^4.17.21",
"next": "^15.3.1",
"pg": "^8.11.3",
diff --git a/public/banner-hero.webp b/public/banner-hero.webp
new file mode 100644
index 0000000..d20c685
Binary files /dev/null and b/public/banner-hero.webp differ
diff --git a/public/drsquatch-banner.jpg b/public/drsquatch-banner.jpg
new file mode 100644
index 0000000..dae4892
Binary files /dev/null and b/public/drsquatch-banner.jpg differ
diff --git a/src/app/[countryCode]/(main)/page.tsx b/src/app/[countryCode]/(main)/page.tsx
index 16cc61e..7598b51 100644
--- a/src/app/[countryCode]/(main)/page.tsx
+++ b/src/app/[countryCode]/(main)/page.tsx
@@ -23,14 +23,17 @@ export default async function Home(props: {
const { collections } = await listCollections({
fields: "id, handle, title",
})
+ const res = await listCollections({
+ fields: "id, handle, title",
+ })
if (!collections || !region) {
return null
}
-
+ console.log(res, '--------------')
return (
<>
-
+ {/* */}
diff --git a/src/modules/layout/templates/hero/banner-hero.tsx b/src/modules/layout/templates/hero/banner-hero.tsx
new file mode 100644
index 0000000..cd9cc14
--- /dev/null
+++ b/src/modules/layout/templates/hero/banner-hero.tsx
@@ -0,0 +1,45 @@
+import { Github } from "@medusajs/icons"
+import { Button, Heading } from "@medusajs/ui"
+import { VtCarousel } from "../vt-carousel"
+import { LayoutComponentDefinition, LayoutContext } from "vibentec/component-map"
+
+export default function HeroDefault({ node, context }: { node: LayoutComponentDefinition; context: LayoutContext }) {
+ const props = node.config ?? {}
+ const imageDisplayer = props.ImageDisplayer
+
+ if (imageDisplayer) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+ )
+}
diff --git a/src/modules/layout/templates/hero/index.tsx b/src/modules/layout/templates/hero/index.tsx
new file mode 100644
index 0000000..3c128e6
--- /dev/null
+++ b/src/modules/layout/templates/hero/index.tsx
@@ -0,0 +1,45 @@
+import {
+ LayoutComponentDefinition,
+ LayoutContext,
+} from "vibentec/component-map"
+import { clx } from "@medusajs/ui"
+import BannerHero from "./banner-hero"
+import { DynamicLayoutRenderer } from "vibentec/renderer"
+
+export default async function Hero({
+ nodes,
+ context,
+}: {
+ nodes: LayoutComponentDefinition
+ context: LayoutContext
+}) {
+ const props = nodes.config ?? {}
+ const left = nodes.config?.left ?? []
+ const center = nodes.config?.center ?? []
+ const right = nodes.config?.right ?? []
+ const heroClassName = clx(
+ "min-h-[30rem] w-full border-b border-ui-border-base relative",
+ props.className
+ )
+
+ return (
+
+
+
+
+
+
+ )
+}
diff --git a/src/modules/layout/templates/vt-carousel/carousel-arrow-button.tsx b/src/modules/layout/templates/vt-carousel/carousel-arrow-button.tsx
new file mode 100644
index 0000000..ffb2f1f
--- /dev/null
+++ b/src/modules/layout/templates/vt-carousel/carousel-arrow-button.tsx
@@ -0,0 +1,75 @@
+import React, { useCallback, useEffect, useState } from 'react'
+import style from './index.module.css'
+export const usePrevNextButtons = (emblaApi: any) => {
+ const [prevBtnDisabled, setPrevBtnDisabled] = useState(true)
+ const [nextBtnDisabled, setNextBtnDisabled] = useState(true)
+
+ const onPrevButtonClick = useCallback(() => {
+ if (!emblaApi) return
+ emblaApi.scrollPrev()
+ }, [emblaApi])
+
+ const onNextButtonClick = useCallback(() => {
+ if (!emblaApi) return
+ emblaApi.scrollNext()
+ }, [emblaApi])
+
+ const onSelect = useCallback((emblaApi: any) => {
+ setPrevBtnDisabled(!emblaApi.canScrollPrev())
+ setNextBtnDisabled(!emblaApi.canScrollNext())
+ }, [])
+
+ useEffect(() => {
+ if (!emblaApi) return
+
+ onSelect(emblaApi)
+ emblaApi.on('reInit', onSelect).on('select', onSelect)
+ }, [emblaApi, onSelect])
+
+ return {
+ prevBtnDisabled,
+ nextBtnDisabled,
+ onPrevButtonClick,
+ onNextButtonClick
+ }
+}
+
+export const PrevButton = (props: any) => {
+ const { children, ...restProps } = props
+
+ return (
+
+ )
+}
+
+export const NextButton = (props: any) => {
+ const { children, ...restProps } = props
+
+ return (
+
+ )
+}
diff --git a/src/modules/layout/templates/vt-carousel/carousel-dot-button.tsx b/src/modules/layout/templates/vt-carousel/carousel-dot-button.tsx
new file mode 100644
index 0000000..271767e
--- /dev/null
+++ b/src/modules/layout/templates/vt-carousel/carousel-dot-button.tsx
@@ -0,0 +1,46 @@
+import React, { useCallback, useEffect, useState } from 'react'
+
+export const useDotButton = (emblaApi: any) => {
+ const [selectedIndex, setSelectedIndex] = useState(0)
+ const [scrollSnaps, setScrollSnaps] = useState([])
+
+ const onDotButtonClick = useCallback(
+ (index: number) => {
+ if (!emblaApi) return
+ emblaApi.scrollTo(index)
+ },
+ [emblaApi]
+ )
+
+ const onInit = useCallback((emblaApi: any) => {
+ setScrollSnaps(emblaApi.scrollSnapList())
+ }, [])
+
+ const onSelect = useCallback((emblaApi: any) => {
+ setSelectedIndex(emblaApi.selectedScrollSnap())
+ }, [])
+
+ useEffect(() => {
+ if (!emblaApi) return
+
+ onInit(emblaApi)
+ onSelect(emblaApi)
+ emblaApi.on('reInit', onInit).on('reInit', onSelect).on('select', onSelect)
+ }, [emblaApi, onInit, onSelect])
+
+ return {
+ selectedIndex,
+ scrollSnaps,
+ onDotButtonClick
+ }
+}
+
+export const DotButton = (props: any) => {
+ const { children, ...restProps } = props
+
+ return (
+
+ )
+}
diff --git a/src/modules/layout/templates/vt-carousel/index.module.css b/src/modules/layout/templates/vt-carousel/index.module.css
new file mode 100644
index 0000000..2dfa1ce
--- /dev/null
+++ b/src/modules/layout/templates/vt-carousel/index.module.css
@@ -0,0 +1,139 @@
+.embla {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ margin: auto;
+ --slide-height: 19rem;
+ --slide-spacing: 1rem;
+ --slide-size: 100%;
+}
+.embla__viewport {
+ height: 100%;
+ overflow: hidden;
+}
+.embla__container {
+ display: flex;
+ height: 100%;
+ touch-action: pan-y pinch-zoom;
+ margin-left: calc(var(--slide-spacing) * -1);
+ --slide-spacing: 1rem;
+}
+.embla__slide {
+ --slide-size: 100%;
+ --slide-spacing: 1rem;
+ transform: translate3d(0, 0, 0);
+ flex: 0 0 var(--slide-size);
+ min-width: 0;
+ padding-left: var(--slide-spacing);
+}
+.embla__slide__number {
+ height: 100%;
+ font-size: 4rem;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ user-select: none;
+}
+.embla__slide__image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+.embla__controls {
+ display: grid;
+ position: absolute;
+ top: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%;
+ grid-template-columns: auto 1fr;
+ justify-content: space-between;
+ gap: 1.2rem;
+}
+.embla__buttons {
+ position: absolute;
+ top: 45%;
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ z-index: 1000;
+}
+.embla__button {
+ --text-high-contrast-rgb-value: 49, 49, 49;
+ --detail-high-contrast: rgb(192, 192, 192);
+ --text-body: rgb(54, 49, 61);
+ -webkit-tap-highlight-color: rgba(var(--text-high-contrast-rgb-value), 0.5);
+ -webkit-appearance: none;
+ appearance: none;
+ background-color: transparent;
+ touch-action: manipulation;
+ text-decoration: none;
+ cursor: pointer;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 3.6rem;
+ height: 3.6rem;
+ z-index: 1001;
+ border-radius: 50%;
+ color: var(--text-body);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.embla__button:disabled {
+ --detail-high-contrast: rgb(192, 192, 192);
+ color: var(--detail-high-contrast);
+}
+.embla__button__svg {
+ width: 35%;
+ height: 35%;
+}
+.embla__dots {
+ display: flex;
+ position: absolute;
+ bottom: 0;
+ left: 48%;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+ align-items: center;
+ z-index: 1000;
+}
+.embla__dot {
+ --text-high-contrast-rgb-value: 49, 49, 49;
+ --text-body: rgb(54, 49, 61);
+ -webkit-tap-highlight-color: rgba(var(--text-high-contrast-rgb-value), 0.5);
+ -webkit-appearance: none;
+ appearance: none;
+ background-color: transparent;
+ touch-action: manipulation;
+ text-decoration: none;
+ cursor: pointer;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 1.6rem;
+ height: 1.6rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+}
+.embla__dot:after {
+ --detail-medium-contrast: rgb(234, 234, 234);
+ --detail-medium-contrast-rgb-value: 234, 234, 234;
+ box-shadow: inset 0 0 0 0.2rem var(--detail-medium-contrast);
+ width: 0.42rem;
+ height: 0.42rem;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ content: "";
+}
+.embla__dot--selected:after {
+ --text-body: black;
+ box-shadow: inset 0 0 0 0.2rem var(--text-body);
+}
diff --git a/src/modules/layout/templates/vt-carousel/index.tsx b/src/modules/layout/templates/vt-carousel/index.tsx
new file mode 100644
index 0000000..6744cc3
--- /dev/null
+++ b/src/modules/layout/templates/vt-carousel/index.tsx
@@ -0,0 +1,92 @@
+"use client"
+import {
+ LayoutComponentDefinition,
+ LayoutContext,
+} from "@vibentec/component-map"
+import styles from "./index.module.css"
+import useEmblaCarousel from "embla-carousel-react"
+import Autoplay from "embla-carousel-autoplay"
+import { useMemo } from "react"
+import { DotButton, useDotButton } from "./carousel-dot-button"
+import { NextButton, PrevButton, usePrevNextButtons } from "./carousel-arrow-button"
+import LocalizedClientLink from "@modules/common/components/localized-client-link"
+
+export function VtCarousel({
+ nodes,
+ context,
+}: {
+ nodes: LayoutComponentDefinition
+ context: LayoutContext
+}) {
+ const props = nodes.config ?? {}
+ const { options } = props as any
+ const images: string[] = props.images ?? props.slides ?? []
+ const links: (string | undefined)[] = props.links ?? []
+ const durationSeconds: number = props.duration ?? 4
+ const showControls = images.length > 1
+
+ const plugins = useMemo(() => {
+ if (!durationSeconds || durationSeconds <= 0) return []
+ return [
+ Autoplay({
+ delay: durationSeconds * 1000,
+ stopOnInteraction: false,
+ stopOnMouseEnter: true,
+ }),
+ ]
+ }, [durationSeconds])
+
+ const [emblaRef, emblaApi] = useEmblaCarousel(options, plugins)
+ const { selectedIndex, scrollSnaps, onDotButtonClick } =
+ useDotButton(emblaApi)
+
+ const {
+ prevBtnDisabled,
+ nextBtnDisabled,
+ onPrevButtonClick,
+ onNextButtonClick,
+ } = usePrevNextButtons(emblaApi)
+ return (
+
+
+
+ {images && images.map((src: string, index: number) => (
+
+
+ {links[index] ? (
+
+
+
+ ) : (
+

+ )}
+
+
+ ))}
+
+
+
+ {showControls && (
+
+
+
+
+ {scrollSnaps.map((_, index) => (
+ onDotButtonClick(index)}
+ className={[
+ styles["embla__dot"],
+ index === selectedIndex ? styles["embla__dot--selected"] : "",
+ ].filter(Boolean).join(" ")}
+ />
+ ))}
+
+
+ )}
+
+ )
+}
diff --git a/src/modules/layout/templates/vt-country-select/index.tsx b/src/modules/layout/templates/vt-country-select/index.tsx
index e492c00..625f6e6 100644
--- a/src/modules/layout/templates/vt-country-select/index.tsx
+++ b/src/modules/layout/templates/vt-country-select/index.tsx
@@ -23,7 +23,6 @@ export default function VtCountrySelectClient({
const triggerText = props?.trigger?.text
const [items, setItems] = useState<{ text: string; label?: string }[]>([])
const { countryCode } = useParams()
- console.log(regions)
useEffect(() => {
if (!regions || regions.length === 0) {
setItems([])
@@ -39,7 +38,6 @@ export default function VtCountrySelectClient({
.flat()
.filter((o) => o.text)
.sort((a, b) => (a.label ?? "").localeCompare(b.label ?? ""))
- console.log(opts)
setItems(opts)
}, [regions])
diff --git a/src/modules/layout/templates/vt-cta-banner/default-cta.tsx b/src/modules/layout/templates/vt-cta-banner/default-cta.tsx
new file mode 100644
index 0000000..34e753a
--- /dev/null
+++ b/src/modules/layout/templates/vt-cta-banner/default-cta.tsx
@@ -0,0 +1,68 @@
+"use client"
+import { Button, clx } from "@medusajs/ui"
+import { ChevronRightMini } from "@medusajs/icons"
+import {
+ LayoutComponentDefinition,
+ LayoutContext,
+} from "@vibentec/component-map"
+
+export function DefaultCtaBanner({
+ nodes,
+ context,
+}: {
+ nodes: LayoutComponentDefinition
+ context: LayoutContext
+}) {
+ const props = nodes.config ?? {}
+ return (
+
+ {props.tagText && (
+
+ {props.tagText}
+
+ )}
+
+ {props.titleText && (
+
+ {props.titleText}
+
+ )}
+
+ {props.descriptionText && (
+
+ {props.descriptionText}
+
+ )}
+
+
+
+ )
+}
diff --git a/src/modules/layout/templates/vt-cta-banner/index.tsx b/src/modules/layout/templates/vt-cta-banner/index.tsx
new file mode 100644
index 0000000..b9c78cf
--- /dev/null
+++ b/src/modules/layout/templates/vt-cta-banner/index.tsx
@@ -0,0 +1,25 @@
+"use client"
+import {
+ LayoutComponentDefinition,
+ LayoutContext,
+} from "@vibentec/component-map"
+import { DefaultCtaBanner } from "./default-cta"
+
+export function VtCtaBanner({
+ nodes,
+ context,
+}: {
+ nodes: LayoutComponentDefinition
+ context: LayoutContext
+}) {
+ const props = nodes.config ?? {}
+ const variant = props.variant ?? "default"
+
+ const variants: Record = {
+ default: DefaultCtaBanner,
+ }
+
+ const Component = variants[variant] || DefaultCtaBanner
+
+ return
+}
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 35c79e3..706603e 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -113,4 +113,4 @@
}
[data-radix-popper-content-wrapper]{
z-index: 51 !important;
-}
\ No newline at end of file
+}
diff --git a/src/vibentec/component-map.tsx b/src/vibentec/component-map.tsx
index 4ec8f7e..b1c1dcd 100644
--- a/src/vibentec/component-map.tsx
+++ b/src/vibentec/component-map.tsx
@@ -22,42 +22,56 @@ import VtFooterHero from "@modules/layout/templates/vt-footer/vt-footer-hero"
import VtFooterBottom from "@modules/layout/templates/vt-footer/vt-footer-bottom"
import VtLogo from "@modules/layout/templates/vt-logo"
import VtFooterSignUp from "@modules/layout/templates/vt-footer/vt-footer-signup"
+import Hero from "@modules/layout/templates/hero"
+import { VtCarousel } from "@modules/layout/templates/vt-carousel"
+import { VtCtaBanner } from "@modules/layout/templates/vt-cta-banner"
-type ComponentConfig = Record;
+type ComponentConfig = Record
export interface LayoutComponentDefinition {
config?: ComponentConfig
children?: LayoutComponentNode[]
}
-export interface LayoutContext {
- customer: any;
- cart: any;
- shippingOptions: any[];
- contentChildren: React.ReactNode;
+export interface LayoutContext {
+ customer: any
+ cart: any
+ shippingOptions: any[]
+ contentChildren: React.ReactNode
}
export type ComponentRenderer = {
- render: (entry: LayoutComponentDefinition, ctx: LayoutContext) => React.ReactNode
+ render: (
+ entry: LayoutComponentDefinition,
+ ctx: LayoutContext
+ ) => React.ReactNode
}
// Utility methods
-const configOnly = (Component: React.ComponentType): ComponentRenderer => ({
- render: (entry) =>
+const configOnly = (
+ Component: React.ComponentType
+): ComponentRenderer => ({
+ render: (entry) => ,
})
-const nodesContextRenderer = (Component: React.ComponentType): ComponentRenderer => ({
- render: (entry: any, ctx: LayoutContext) =>
-});
+const nodesContextRenderer = (
+ Component: React.ComponentType
+): ComponentRenderer => ({
+ render: (entry: any, ctx: LayoutContext) => (
+
+ ),
+})
const renderChildren = (entry: LayoutComponentDefinition, ctx: LayoutContext) =>
- entry.children ? : null
-
+ entry.children ? (
+
+ ) : null
// Component Map
export const componentMap: Record = {
- Header: nodesContextRenderer(VtHeader),
+ Header: nodesContextRenderer(VtHeader),
Nav: nodesContextRenderer(VtNav),
+ Hero: nodesContextRenderer(Hero),
VtMegaMenu: nodesContextRenderer(VtMegaMenu),
VtSideMenu: nodesContextRenderer(VtSideMenu),
Banner: nodesContextRenderer(Banner),
@@ -75,17 +89,20 @@ export const componentMap: Record = {
CartMismatchBanner: configOnly(CartMismatchBanner),
FreeShippingPriceNudge: configOnly(FreeShippingPriceNudge),
PropsChildren: {
- render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children
+ render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children
},
+ VtCtaBanner: nodesContextRenderer(VtCtaBanner),
VtFooterHero: nodesContextRenderer(VtFooterHero),
VtFooterBottom: nodesContextRenderer(VtFooterBottom),
VtFooterSignUp: nodesContextRenderer(VtFooterSignUp),
- Footer: nodesContextRenderer(VtFooter)
+ Footer: nodesContextRenderer(VtFooter),
+ ImageDisplayer: nodesContextRenderer(VtCarousel),
}
-
export type ComponentName = keyof typeof componentMap
// //maps key = componentName to value = props + children
// export type LayoutComponentNode = Record
-export type LayoutComponentNode = { [K in ComponentName]: LayoutComponentDefinition }[ComponentName]
\ No newline at end of file
+export type LayoutComponentNode = {
+ [K in ComponentName]: LayoutComponentDefinition
+}[ComponentName]
diff --git a/src/vibentec/configloader.ts b/src/vibentec/configloader.ts
index 1c18fc4..dd5fbef 100644
--- a/src/vibentec/configloader.ts
+++ b/src/vibentec/configloader.ts
@@ -2,7 +2,7 @@ import fs from "fs"
import path from "path"
import { jsonFileNames } from "./devJsonFileNames";
-const fileName = jsonFileNames.nam3Bear;
+const fileName = jsonFileNames.namStarter;
export async function loadDesignConfig() {
const filePath = path.join(process.cwd(), "config", fileName)