feat: create design for 3bear and drsquatch hero banner, create variants cta section
This commit is contained in:
parent
9e0f6b0071
commit
7afffb3f99
|
|
@ -177,6 +177,35 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Hero": {
|
||||||
|
"config": {
|
||||||
|
"className": "h-[35rem]",
|
||||||
|
"ImageDisplayer": {
|
||||||
|
"config": {
|
||||||
|
"duration": 0,
|
||||||
|
"images": ["./banner-hero.webp"],
|
||||||
|
"links": ["/account"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"left": [
|
||||||
|
{
|
||||||
|
"VtCtaBanner": {
|
||||||
|
"config": {
|
||||||
|
"variant": "3bear",
|
||||||
|
"className": "left-[120px] top-[80px]",
|
||||||
|
"tagText": "So einfach kann Frühstück sein – mit unseren leckeren Overnight Oats.",
|
||||||
|
"titleText": "breakfast made easy.",
|
||||||
|
"buttonText": "Jetzt entdecken"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"center": [],
|
||||||
|
"right": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"CartMismatchBanner": {
|
"CartMismatchBanner": {
|
||||||
"config": {
|
"config": {
|
||||||
|
|
@ -213,10 +242,26 @@
|
||||||
"emailInputClassName": "w-[300px] ml-8"
|
"emailInputClassName": "w-[300px] ml-8"
|
||||||
},
|
},
|
||||||
"socials": [
|
"socials": [
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
{
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
"icon": "Twitter",
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
"href": "/",
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" }
|
"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",
|
"socialsClassName": "ml-8 mt-10",
|
||||||
"className": "",
|
"className": "",
|
||||||
|
|
@ -311,15 +356,22 @@
|
||||||
"config": {
|
"config": {
|
||||||
"className": "content-container bg-[#003f31] w-full text text-[#11314E] flex items-center justify-between",
|
"className": "content-container bg-[#003f31] w-full text text-[#11314E] flex items-center justify-between",
|
||||||
"leftClassName": "w-full",
|
"leftClassName": "w-full",
|
||||||
"left": [
|
"left": [],
|
||||||
],
|
|
||||||
"center": [],
|
"center": [],
|
||||||
"right": [
|
"right": [
|
||||||
{
|
{
|
||||||
"VtFooterBottom": {
|
"VtFooterBottom": {
|
||||||
"config": {
|
"config": {
|
||||||
"className": " mr-[80px]",
|
"className": " mr-[80px]",
|
||||||
"icons": ["Mastercard", "PayPal", "Visa", "Mastercard","Mastercard","Mastercard","Mastercard"]
|
"icons": [
|
||||||
|
"Mastercard",
|
||||||
|
"PayPal",
|
||||||
|
"Visa",
|
||||||
|
"Mastercard",
|
||||||
|
"Mastercard",
|
||||||
|
"Mastercard",
|
||||||
|
"Mastercard"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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": {
|
"CartMismatchBanner": {
|
||||||
"config": {
|
"config": {
|
||||||
|
|
@ -277,10 +315,26 @@
|
||||||
"buttonClassName": "bg-[#C4622C] w-[90px]",
|
"buttonClassName": "bg-[#C4622C] w-[90px]",
|
||||||
"socialsClassName": "mt-4 gap-8",
|
"socialsClassName": "mt-4 gap-8",
|
||||||
"socials": [
|
"socials": [
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
{
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
"icon": "Twitter",
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" },
|
"href": "/",
|
||||||
{ "icon": "Twitter", "href": "/", "className": "w-5 h-5 text-white" }
|
"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"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,14 +138,7 @@
|
||||||
"Hero": {
|
"Hero": {
|
||||||
"config": {
|
"config": {
|
||||||
"variant": "default",
|
"variant": "default",
|
||||||
"className": "bg-custom-gradient",
|
"className": "bg-custom-gradient"
|
||||||
"ImageDisplayer": {
|
|
||||||
"config": {
|
|
||||||
"duration": 20,
|
|
||||||
"images": ["./banner-hero.webp", "./banner-hero.webp"],
|
|
||||||
"links": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -179,31 +179,35 @@
|
||||||
{
|
{
|
||||||
"Hero": {
|
"Hero": {
|
||||||
"config": {
|
"config": {
|
||||||
"variant": "default",
|
|
||||||
"className": "h-[35rem]",
|
"className": "h-[35rem]",
|
||||||
"ImageDisplayer": {
|
"ImageDisplayer": {
|
||||||
"config": {
|
"config": {
|
||||||
"duration": 1,
|
"duration": 0,
|
||||||
"images": [
|
"images": [
|
||||||
"./banner-hero.webp",
|
"./banner-hero.webp",
|
||||||
"./banner-hero.webp"
|
"./banner-hero-1.webp",
|
||||||
|
"./banner-hero-2.webp"
|
||||||
],
|
],
|
||||||
"links": []
|
"links": ["/", "/account", "/product"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"left":[{
|
"left": [
|
||||||
|
{
|
||||||
"VtCtaBanner": {
|
"VtCtaBanner": {
|
||||||
"config": {
|
"config": {
|
||||||
"className": "ml-[120px]",
|
"variant": "default",
|
||||||
|
"className": "left-[120px] top-[80px]",
|
||||||
|
"titleTextClassName": "leading-normal",
|
||||||
"tagText": "Besonders Aktion",
|
"tagText": "Besonders Aktion",
|
||||||
"titleText": "Willkommen in Vibentec IT Shop",
|
"titleText": "Willkommen in Vibentec IT Shop",
|
||||||
"descriptionText": "Insert the accordion description here. It would look better as two lines of text or more.",
|
"descriptionText": "Insert the accordion description here. It would look better as two lines of text or more.",
|
||||||
"buttonText": "Zum Einkaufen"
|
"buttonText": "Zum Einkaufen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
"center":[],
|
],
|
||||||
"right":[]
|
"center": [],
|
||||||
|
"right": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 403 KiB |
|
|
@ -9,14 +9,14 @@ export default function HeroDefault({ node, context }: { node: LayoutComponentDe
|
||||||
|
|
||||||
if (imageDisplayer) {
|
if (imageDisplayer) {
|
||||||
return (
|
return (
|
||||||
<div className="absolute inset-0 z-10 w-full h-full">
|
<div className="absolute inset-0 z-auto w-full h-full">
|
||||||
<VtCarousel nodes={{ config: imageDisplayer.config }} context={context} />
|
<VtCarousel nodes={{ config: imageDisplayer.config }} context={context} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute inset-0 z-10 flex flex-col justify-center items-center text-center small:p-32 gap-6">
|
<div className="absolute inset-0 z-auto flex flex-col justify-center items-center text-center small:p-32 gap-6">
|
||||||
<span>
|
<span>
|
||||||
<Heading
|
<Heading
|
||||||
level="h1"
|
level="h1"
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { Github } from "@medusajs/icons"
|
|
||||||
import { Button, clx, Heading } from "@medusajs/ui"
|
|
||||||
import {
|
|
||||||
LayoutComponentDefinition,
|
|
||||||
LayoutContext,
|
|
||||||
} from "@vibentec/component-map"
|
|
||||||
import { VtCarousel } from "../vt-carousel"
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
node: LayoutComponentDefinition
|
|
||||||
context: LayoutContext
|
|
||||||
}
|
|
||||||
const HeroVibentec = ({ node, context }: Props) => {
|
|
||||||
const props = node.config ?? {}
|
|
||||||
const imageDisplayer = props.ImageDisplayer
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={clx(props.className)}>
|
|
||||||
{imageDisplayer ? (
|
|
||||||
<VtCarousel nodes={{ config: imageDisplayer.config }} context={context} />
|
|
||||||
) : (
|
|
||||||
<VtCarousel nodes={node} context={context} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default HeroVibentec
|
|
||||||
|
|
@ -3,14 +3,9 @@ import {
|
||||||
LayoutContext,
|
LayoutContext,
|
||||||
} from "vibentec/component-map"
|
} from "vibentec/component-map"
|
||||||
import { clx } from "@medusajs/ui"
|
import { clx } from "@medusajs/ui"
|
||||||
import BannerHeroVibentec from "../hero/hero-vibentec"
|
import BannerHero from "./banner-hero"
|
||||||
import BannerHeroDefault from "../hero/hero-default"
|
|
||||||
import { DynamicLayoutRenderer } from "vibentec/renderer"
|
import { DynamicLayoutRenderer } from "vibentec/renderer"
|
||||||
|
|
||||||
interface BannerProps {
|
|
||||||
variant: "vibentec" | "default"
|
|
||||||
className?: string
|
|
||||||
}
|
|
||||||
export default async function Hero({
|
export default async function Hero({
|
||||||
nodes,
|
nodes,
|
||||||
context,
|
context,
|
||||||
|
|
@ -18,7 +13,7 @@ export default async function Hero({
|
||||||
nodes: LayoutComponentDefinition
|
nodes: LayoutComponentDefinition
|
||||||
context: LayoutContext
|
context: LayoutContext
|
||||||
}) {
|
}) {
|
||||||
const props = (nodes.config as BannerProps) ?? {}
|
const props = nodes.config ?? {}
|
||||||
const left = nodes.config?.left ?? []
|
const left = nodes.config?.left ?? []
|
||||||
const center = nodes.config?.center ?? []
|
const center = nodes.config?.center ?? []
|
||||||
const right = nodes.config?.right ?? []
|
const right = nodes.config?.right ?? []
|
||||||
|
|
@ -26,29 +21,21 @@ export default async function Hero({
|
||||||
"min-h-[30rem] w-full border-b border-ui-border-base relative",
|
"min-h-[30rem] w-full border-b border-ui-border-base relative",
|
||||||
props.className
|
props.className
|
||||||
)
|
)
|
||||||
if (!props.variant) return null
|
|
||||||
|
|
||||||
const variants = {
|
|
||||||
vibentec: BannerHeroVibentec,
|
|
||||||
default: BannerHeroDefault,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Component = variants[props.variant]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={heroClassName}>
|
<div className={heroClassName}>
|
||||||
<Component node={nodes} context={context} />
|
<BannerHero node={nodes} context={context} />
|
||||||
<div className="absolute inset-0 z-20 w-full h-full">
|
<div className="absolute z-20">
|
||||||
<nav className="content-container txt-xsmall-plus flex items-center justify-between w-full h-full text-small-regular">
|
<nav className="content-container txt-xsmall-plus flex items-center justify-between text-small-regular">
|
||||||
<div className="flex items-center gap-x-4 w-full h-full">
|
<div className="flex items-center gap-x-4">
|
||||||
{left && <DynamicLayoutRenderer nodes={left} context={context} />}
|
{left && <DynamicLayoutRenderer nodes={left} context={context} />}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-x-4 w-full h-full">
|
<div className="flex items-center gap-x-4">
|
||||||
{center && (
|
{center && (
|
||||||
<DynamicLayoutRenderer nodes={center} context={context} />
|
<DynamicLayoutRenderer nodes={center} context={context} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-x-4 w-full h-full justify-end">
|
<div className="flex items-center gap-x-4 justify-end">
|
||||||
{right && <DynamicLayoutRenderer nodes={right} context={context} />}
|
{right && <DynamicLayoutRenderer nodes={right} context={context} />}
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
|
|
@ -57,6 +58,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
.embla__button {
|
.embla__button {
|
||||||
--text-high-contrast-rgb-value: 49, 49, 49;
|
--text-high-contrast-rgb-value: 49, 49, 49;
|
||||||
|
|
@ -74,7 +76,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 3.6rem;
|
width: 3.6rem;
|
||||||
height: 3.6rem;
|
height: 3.6rem;
|
||||||
z-index: 1;
|
z-index: 1001;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
color: var(--text-body);
|
color: var(--text-body);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -98,6 +100,7 @@
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
.embla__dot {
|
.embla__dot {
|
||||||
--text-high-contrast-rgb-value: 49, 49, 49;
|
--text-high-contrast-rgb-value: 49, 49, 49;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import Autoplay from "embla-carousel-autoplay"
|
||||||
import { useMemo } from "react"
|
import { useMemo } from "react"
|
||||||
import { DotButton, useDotButton } from "./carousel-dot-button"
|
import { DotButton, useDotButton } from "./carousel-dot-button"
|
||||||
import { NextButton, PrevButton, usePrevNextButtons } from "./carousel-arrow-button"
|
import { NextButton, PrevButton, usePrevNextButtons } from "./carousel-arrow-button"
|
||||||
|
import LocalizedClientLink from "@modules/common/components/localized-client-link"
|
||||||
|
|
||||||
export function VtCarousel({
|
export function VtCarousel({
|
||||||
nodes,
|
nodes,
|
||||||
context,
|
context,
|
||||||
|
|
@ -18,13 +20,21 @@ export function VtCarousel({
|
||||||
}) {
|
}) {
|
||||||
const props = nodes.config ?? {}
|
const props = nodes.config ?? {}
|
||||||
const { options } = props as any
|
const { options } = props as any
|
||||||
const images: string[] = (props as any).images ?? (props as any).slides ?? []
|
const images: string[] = props.images ?? props.slides ?? []
|
||||||
const links: (string | undefined)[] = (props as any).links ?? []
|
const links: (string | undefined)[] = props.links ?? []
|
||||||
const durationSeconds: number = props.duration ?? 4
|
const durationSeconds: number = props.duration ?? 4
|
||||||
|
const showControls = images.length > 1
|
||||||
|
|
||||||
const plugins = useMemo(() => [
|
const plugins = useMemo(() => {
|
||||||
Autoplay({ delay: Math.max(1, durationSeconds) * 1000, stopOnInteraction: false, stopOnMouseEnter: true, })
|
if (!durationSeconds || durationSeconds <= 0) return []
|
||||||
], [durationSeconds])
|
return [
|
||||||
|
Autoplay({
|
||||||
|
delay: durationSeconds * 1000,
|
||||||
|
stopOnInteraction: false,
|
||||||
|
stopOnMouseEnter: true,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}, [durationSeconds])
|
||||||
|
|
||||||
const [emblaRef, emblaApi] = useEmblaCarousel(options, plugins)
|
const [emblaRef, emblaApi] = useEmblaCarousel(options, plugins)
|
||||||
const { selectedIndex, scrollSnaps, onDotButtonClick } =
|
const { selectedIndex, scrollSnaps, onDotButtonClick } =
|
||||||
|
|
@ -41,12 +51,12 @@ export function VtCarousel({
|
||||||
<div className={styles["embla__viewport"]} ref={emblaRef}>
|
<div className={styles["embla__viewport"]} ref={emblaRef}>
|
||||||
<div className={styles["embla__container"]}>
|
<div className={styles["embla__container"]}>
|
||||||
{images && images.map((src: string, index: number) => (
|
{images && images.map((src: string, index: number) => (
|
||||||
<div className={styles["embla__slide"]} key={index}>
|
<div className={styles["embla__slide"]} key={index + src}>
|
||||||
<div className={styles["embla__slide__number"]}>
|
<div className={styles["embla__slide__number"]}>
|
||||||
{links[index] ? (
|
{links[index] ? (
|
||||||
<a href={links[index]}>
|
<LocalizedClientLink href={links[index]}>
|
||||||
<img src={src} alt={`slide-${index + 1}`} className={styles["embla__slide__image"]} />
|
<img src={src} alt={`slide-${index + 1}`} className={styles["embla__slide__image"]} />
|
||||||
</a>
|
</LocalizedClientLink>
|
||||||
) : (
|
) : (
|
||||||
<img src={src} alt={`slide-${index + 1}`} className={styles["embla__slide__image"]} />
|
<img src={src} alt={`slide-${index + 1}`} className={styles["embla__slide__image"]} />
|
||||||
)}
|
)}
|
||||||
|
|
@ -56,6 +66,7 @@ export function VtCarousel({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{showControls && (
|
||||||
<div className={styles["embla__controls"]}>
|
<div className={styles["embla__controls"]}>
|
||||||
<div className={styles["embla__buttons"]}>
|
<div className={styles["embla__buttons"]}>
|
||||||
<PrevButton onClick={onPrevButtonClick} disabled={prevBtnDisabled} />
|
<PrevButton onClick={onPrevButtonClick} disabled={prevBtnDisabled} />
|
||||||
|
|
@ -75,6 +86,7 @@ export function VtCarousel({
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
"use client"
|
||||||
|
import { Button, clx } from "@medusajs/ui"
|
||||||
|
import {
|
||||||
|
LayoutComponentDefinition,
|
||||||
|
LayoutContext,
|
||||||
|
} from "@vibentec/component-map"
|
||||||
|
|
||||||
|
export function BearCtaBanner({
|
||||||
|
nodes,
|
||||||
|
context,
|
||||||
|
}: {
|
||||||
|
nodes: LayoutComponentDefinition
|
||||||
|
context: LayoutContext
|
||||||
|
}) {
|
||||||
|
const props = nodes.config ?? {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clx(
|
||||||
|
"relative w-full p-12 flex flex-col items-start justify-center text-left",
|
||||||
|
props.className
|
||||||
|
)}>
|
||||||
|
<p className="text-[#0D382E] text-lg font-medium mb-2">
|
||||||
|
{props.tagText ?? "So einfach kann Frühstück sein – mit unseren leckeren Overnight Oats."}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 className="text-[#0D382E] font-black leading-tight text-[64px] mb-8 tracking-tight">
|
||||||
|
{props.titleText ?? "breakfast made easy."}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<Button className="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">
|
||||||
|
{props.buttonText ?? "Jetzt entdecken"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
"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 (
|
||||||
|
<div className={clx(
|
||||||
|
"relative w-[544px] bg-white rounded-[24px] border border-[#E6EFFC] shadow-[0_12px_40px_rgba(17,49,78,0.10)] p-6",
|
||||||
|
props.className
|
||||||
|
)}>
|
||||||
|
<div className={clx(
|
||||||
|
"inline-flex items-center rounded-full bg-[#FCE9DA] text-[#E68445] px-3 py-1 text-sm font-medium",
|
||||||
|
props.tagTextClassName
|
||||||
|
)}>
|
||||||
|
{props.tagText}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className={clx(
|
||||||
|
"mt-4 text-[#11314E] font-semibold leading-normal text-[56px]",
|
||||||
|
props.titleTextClassName
|
||||||
|
)}>
|
||||||
|
{props.titleText}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className={clx(
|
||||||
|
"mt-5 text-[#285A86] text-[16px] sm:text-xl opacity-80",
|
||||||
|
props.descriptionTextClassName
|
||||||
|
)}>
|
||||||
|
{props.descriptionText}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Button className={clx(
|
||||||
|
"mt-8 inline-flex items-center gap-2 bg-[#0F2740] hover:bg-[#173551] text-white px-6 py-3 rounded-[12px] shadow-md",
|
||||||
|
props.buttonTextClassName
|
||||||
|
)}>
|
||||||
|
{props.buttonText}
|
||||||
|
<ChevronRightMini />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"use client"
|
"use client"
|
||||||
import { Button, clx } from "@medusajs/ui"
|
|
||||||
import { ChevronRightMini } from "@medusajs/icons"
|
|
||||||
import {
|
import {
|
||||||
LayoutComponentDefinition,
|
LayoutComponentDefinition,
|
||||||
LayoutContext,
|
LayoutContext,
|
||||||
} from "@vibentec/component-map"
|
} from "@vibentec/component-map"
|
||||||
|
import { DefaultCtaBanner } from "./default-cta"
|
||||||
|
import { BearCtaBanner } from "./bear-cta"
|
||||||
|
|
||||||
export function VtCtaBanner({
|
export function VtCtaBanner({
|
||||||
nodes,
|
nodes,
|
||||||
|
|
@ -14,27 +14,14 @@ export function VtCtaBanner({
|
||||||
context: LayoutContext
|
context: LayoutContext
|
||||||
}) {
|
}) {
|
||||||
const props = nodes.config ?? {}
|
const props = nodes.config ?? {}
|
||||||
return (
|
const variant = props.variant ?? "default"
|
||||||
<div className={clx(
|
|
||||||
"relative w-[544px] bg-white rounded-[24px] border border-[#E6EFFC] shadow-[0_12px_40px_rgba(17,49,78,0.10)] p-6",
|
|
||||||
props.className
|
|
||||||
)}>
|
|
||||||
<div className="inline-flex items-center rounded-full bg-[#FCE9DA] text-[#E68445] px-3 py-1 text-sm font-medium">
|
|
||||||
{props.tagText}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 className="mt-4 text-[#11314E] font-semibold leading-tight text-[56px]">
|
const variants: Record<string, any> = {
|
||||||
{props.titleText}
|
default: DefaultCtaBanner,
|
||||||
</h1>
|
"3bear": BearCtaBanner,
|
||||||
|
}
|
||||||
|
|
||||||
<p className="mt-5 text-[#285A86] text-[16px] sm:text-xl opacity-80">
|
const Component = variants[variant] || DefaultCtaBanner
|
||||||
{props.descriptionText}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Button className="mt-8 inline-flex items-center gap-2 bg-[#0F2740] hover:bg-[#173551] text-white px-6 py-3 rounded-[12px] shadow-md">
|
return <Component nodes={nodes} context={context} />
|
||||||
{props.buttonText}
|
|
||||||
<ChevronRightMini />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import fs from "fs"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { jsonFileNames } from "./devJsonFileNames";
|
import { jsonFileNames } from "./devJsonFileNames";
|
||||||
|
|
||||||
const fileName = jsonFileNames.namVibentec;
|
const fileName = jsonFileNames.namStarter;
|
||||||
|
|
||||||
export async function loadDesignConfig() {
|
export async function loadDesignConfig() {
|
||||||
const filePath = path.join(process.cwd(), "config", fileName)
|
const filePath = path.join(process.cwd(), "config", fileName)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue