refactor: remove singular component and replace with wrapper component
This commit is contained in:
parent
baaa0e9c62
commit
fe881d5aed
|
|
@ -41,11 +41,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Button": {
|
"Link": {
|
||||||
"config": {
|
"config": {
|
||||||
"label": "Mehr Info",
|
"label": "Mehr Info",
|
||||||
"href": "/",
|
"href": "/",
|
||||||
"className": "text-[13px] w-fit text-white px-3 flex items-center bg-[#112638] gap-1 "
|
"className": "text-[13px] rounded-md hover:text-white w-[80px] text-white text-center flex items-center bg-[#112638] flex justify-center h-[28px] "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
"className": "h-24 bg-[white] text-[#11314E] gap-12 pl-16",
|
"className": "h-24 bg-[white] text-[#11314E] gap-12 pl-16",
|
||||||
"left": [
|
"left": [
|
||||||
{
|
{
|
||||||
"Image": {
|
"Logo": {
|
||||||
"config": {
|
"config": {
|
||||||
"src": "/VibentecIT-logo.svg",
|
"src": "/VibentecIT-logo.svg",
|
||||||
"alt": "MyShop",
|
"alt": "MyShop",
|
||||||
|
|
@ -202,37 +202,18 @@
|
||||||
"rightClassName": "flex mt-[160px]",
|
"rightClassName": "flex mt-[160px]",
|
||||||
"left": [
|
"left": [
|
||||||
{
|
{
|
||||||
"Image": {
|
"VtFooterHero": {
|
||||||
"config": {
|
|
||||||
"src": "/VibentecIT-logo.svg",
|
|
||||||
"alt": "MyShop",
|
|
||||||
"className": "h-[100px] w-[320px]",
|
|
||||||
"objectFit": "contain"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"VtMenuItem": {
|
|
||||||
"config": {
|
"config": {
|
||||||
|
"logoClassName": "h-[100px] w-[255px]",
|
||||||
|
"logoSrc": "/VibentecIT-logo.svg",
|
||||||
|
"logoAlt": "Vibentec IT",
|
||||||
"title": "Der Wegbereiter für innovative IT-Lösungen",
|
"title": "Der Wegbereiter für innovative IT-Lösungen",
|
||||||
"className": "flex flex-col gap-y-2 ml-10 w-[320px] text-[24px] font-semibold text-[#11314E]",
|
"description": "Tauchen Sie ein in eine Welt modernster Technologien, zuverlässiger Support und proaktiver Innovation – gemeinsam gestalten wir die digitale Zukunft Ihres Unternehmens.",
|
||||||
"itemClassName": "text-ui-fg-subtle txt-small",
|
"cta": { "label": "Kontaktieren Sie uns", "href": "/" },
|
||||||
"items": [
|
"className": "",
|
||||||
{
|
"ctaClassName": "ml-8",
|
||||||
"text": "Tauchen Sie ein in eine Welt modernster Technologien, zuverlässiger Support und proaktiver Innovation – gemeinsam gestalten wir die digitale Zukunft Ihres Unternehmens.",
|
"titleClassName": "ml-8",
|
||||||
"href": "/"
|
"descriptionClassName": "ml-8 w-[320px]"
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Button": {
|
|
||||||
"config": {
|
|
||||||
"label": "Kontaktieren Sie uns",
|
|
||||||
"className": "bg-black text-white items-center flex gap-2 ml-10 px-4 mt-[24px] py-5 rounded-md w-fit text-[14px]",
|
|
||||||
"icon": "ChevronRightMini",
|
|
||||||
"iconClassName": "order-1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -342,42 +323,13 @@
|
||||||
"Footer": {
|
"Footer": {
|
||||||
"config": {
|
"config": {
|
||||||
"className": "content-container h-[128px] w-full text text-[#11314E] flex items-center justify-between px-20 mt-2",
|
"className": "content-container h-[128px] w-full text text-[#11314E] flex items-center justify-between px-20 mt-2",
|
||||||
|
"leftClassName": "w-full",
|
||||||
"left": [
|
"left": [
|
||||||
{
|
{
|
||||||
"Text": {
|
"VtFooterBottom": {
|
||||||
"config": {
|
"config": {
|
||||||
"label": "©2025 Vibentec IT. All rights reserved",
|
"text": "©2025 Vibentec IT. All rights reserved",
|
||||||
"className": "text-[14px] font-[400] pt-2"
|
"icons": ["Mastercard", "PayPal", "Visa"]
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"center": [],
|
|
||||||
"right": [
|
|
||||||
{
|
|
||||||
"Button": {
|
|
||||||
"config": {
|
|
||||||
"href": "/",
|
|
||||||
"icon": "Mastercard",
|
|
||||||
"className": "shadow-none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Button": {
|
|
||||||
"config": {
|
|
||||||
"href": "/",
|
|
||||||
"icon": "PayPal",
|
|
||||||
"className": "shadow-none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Button": {
|
|
||||||
"config": {
|
|
||||||
"href": "/",
|
|
||||||
"icon": "Visa",
|
|
||||||
"className": "shadow-none"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,21 +24,21 @@ export default async function VtFooter({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className={props?.className ?? ""}>
|
<footer className={props?.className ?? ""}>
|
||||||
|
{props?.left && (
|
||||||
<div className={clx("flex gap-x-4 h-full", props?.leftClassName)}>
|
<div className={clx("flex gap-x-4 h-full", props?.leftClassName)}>
|
||||||
{props.left && (
|
<DynamicLayoutRenderer nodes={props?.left} context={context} />
|
||||||
<DynamicLayoutRenderer nodes={props.left} context={context} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
{props?.center && (
|
||||||
<div className={clx("flex gap-x-4 h-full", props?.centerClassName)}>
|
<div className={clx("flex gap-x-4 h-full", props?.centerClassName)}>
|
||||||
{props.center && (
|
<DynamicLayoutRenderer nodes={props?.center} context={context} />
|
||||||
<DynamicLayoutRenderer nodes={props.center} context={context} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
{props?.right && (
|
||||||
<div className={clx("flex gap-x-4 h-full", props?.rightClassName)}>
|
<div className={clx("flex gap-x-4 h-full", props?.rightClassName)}>
|
||||||
{props.right && (
|
<DynamicLayoutRenderer nodes={props?.right} context={context} />
|
||||||
<DynamicLayoutRenderer nodes={props.right} context={context} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import * as MedusaIcons from "@medusajs/icons"
|
||||||
|
import { clx } from "@medusajs/ui"
|
||||||
|
import { LayoutComponentDefinition, LayoutContext } from "@vibentec/component-map"
|
||||||
|
|
||||||
|
export default function VtFooterBottom({
|
||||||
|
nodes,
|
||||||
|
context,
|
||||||
|
}: {
|
||||||
|
nodes: LayoutComponentDefinition
|
||||||
|
context: LayoutContext
|
||||||
|
}) {
|
||||||
|
const props = (nodes.config) ?? {}
|
||||||
|
|
||||||
|
const renderIcon = (name: string, idx: number) => {
|
||||||
|
const IconComp = (MedusaIcons as Record<string, any>)[name]
|
||||||
|
if (!IconComp) return null
|
||||||
|
return (
|
||||||
|
<IconComp key={`${name}-${idx}`} className="shadow-none" />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clx("flex w-full items-center justify-between", props.className)}>
|
||||||
|
<span className={clx("text-[14px] font-[400] pt-2", props.textClassName)}>{props.text}</span>
|
||||||
|
<div className={clx("flex items-center gap-2", props.iconsClassName)}>
|
||||||
|
{(props.icons ?? []).map(renderIcon)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { clx } from "@medusajs/ui"
|
||||||
|
import { ChevronRightMini } from "@medusajs/icons"
|
||||||
|
import { LayoutComponentDefinition, LayoutContext } from "@vibentec/component-map"
|
||||||
|
import LocalizedClientLink from "@modules/common/components/localized-client-link"
|
||||||
|
|
||||||
|
interface VtFooterHeroConfig {
|
||||||
|
logoSrc: string
|
||||||
|
logoAlt?: string
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
cta?: { label: string; href: string }
|
||||||
|
className?: string
|
||||||
|
logoClassName?: string
|
||||||
|
titleClassName?: string
|
||||||
|
descriptionClassName?: string
|
||||||
|
ctaClassName?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function VtFooterHero({
|
||||||
|
nodes,
|
||||||
|
context,
|
||||||
|
}: {
|
||||||
|
nodes: LayoutComponentDefinition
|
||||||
|
context: LayoutContext
|
||||||
|
}) {
|
||||||
|
const props = (nodes.config as VtFooterHeroConfig) ?? {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clx("flex flex-col items-start", props.className)}>
|
||||||
|
{props.logoSrc && (
|
||||||
|
<img
|
||||||
|
src={props.logoSrc}
|
||||||
|
alt={props.logoAlt ?? "logo"}
|
||||||
|
className={clx("object-contain", props.logoClassName)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{props.title && (
|
||||||
|
<h2 className={clx("mt-4 w-[320px] text-[24px] font-semibold text-[#11314E]", props.titleClassName)}>
|
||||||
|
{props.title}
|
||||||
|
</h2>
|
||||||
|
)}
|
||||||
|
{props.description && (
|
||||||
|
<p className={clx("mt-2 text-ui-fg-subtle txt-small", props.descriptionClassName)}>
|
||||||
|
{props.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{props.cta && (
|
||||||
|
<LocalizedClientLink
|
||||||
|
href={props.cta.href}
|
||||||
|
className={clx(
|
||||||
|
"bg-black text-white items-center flex gap-2 px-4 mt-[24px] py-2 rounded-md w-fit text-[14px]",
|
||||||
|
props.ctaClassName
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<span>{props.cta.label}</span>
|
||||||
|
<ChevronRightMini className="order-1" />
|
||||||
|
</LocalizedClientLink>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,15 +3,13 @@ import {
|
||||||
LayoutComponentDefinition,
|
LayoutComponentDefinition,
|
||||||
LayoutContext,
|
LayoutContext,
|
||||||
} from "@vibentec/component-map"
|
} from "@vibentec/component-map"
|
||||||
import Image from "next/image"
|
|
||||||
|
|
||||||
export interface VtImageConfig {
|
export interface VtImageConfig {
|
||||||
src: string
|
src: string
|
||||||
alt: string
|
alt: string
|
||||||
className?: string,
|
className?: string,
|
||||||
objectFit?: string,
|
objectFit?: string,
|
||||||
}
|
}
|
||||||
export default function VtImage({
|
export default function VtLogo({
|
||||||
nodes,
|
nodes,
|
||||||
context,
|
context,
|
||||||
}: {
|
}: {
|
||||||
|
|
@ -21,7 +19,7 @@ export default function VtImage({
|
||||||
const props = (nodes.config as VtImageConfig) ?? {}
|
const props = (nodes.config as VtImageConfig) ?? {}
|
||||||
return (
|
return (
|
||||||
<div className={clx("relative", props.className)}>
|
<div className={clx("relative", props.className)}>
|
||||||
<img src={props.src} alt={props.alt} className={clx("w-full h-full object-cover", props.objectFit)} />
|
<img src={props.src} alt={props.alt} className={clx("w-full h-full", props.objectFit)} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -12,17 +12,16 @@ import Banner from "@modules/layout/templates/vt-banner"
|
||||||
import VtMegaMenu from "@modules/layout/components/vt-mega-menu"
|
import VtMegaMenu from "@modules/layout/components/vt-mega-menu"
|
||||||
import VtLink from "@modules/layout/components/vt-linkbutton"
|
import VtLink from "@modules/layout/components/vt-linkbutton"
|
||||||
import VtSideMenu from "@modules/layout/components/vt-sidemenu"
|
import VtSideMenu from "@modules/layout/components/vt-sidemenu"
|
||||||
import VtImage from "@modules/layout/templates/vt-image"
|
|
||||||
import VtDropdown from "@modules/layout/templates/vt-dropdown"
|
import VtDropdown from "@modules/layout/templates/vt-dropdown"
|
||||||
import VtButton from "@modules/layout/templates/vt-button"
|
|
||||||
import VtSearchInput from "@modules/layout/templates/vt-search-input"
|
import VtSearchInput from "@modules/layout/templates/vt-search-input"
|
||||||
import VtSection from "@modules/layout/templates/vt-section"
|
import VtSection from "@modules/layout/templates/vt-section"
|
||||||
import VtText from "@modules/layout/templates/vt-text"
|
|
||||||
import VtInput from "@modules/layout/templates/vt-input"
|
|
||||||
import VtCurrencySelect from "@modules/layout/templates/vt-currency-select"
|
import VtCurrencySelect from "@modules/layout/templates/vt-currency-select"
|
||||||
import VtMenuItem from "@modules/layout/templates/vt-menu-item"
|
import VtMenuItem from "@modules/layout/templates/vt-menu-item"
|
||||||
import VtCountryCodeSelect from "@modules/layout/templates/vt-country-select/server"
|
import VtCountryCodeSelect from "@modules/layout/templates/vt-country-select/server"
|
||||||
import VtSocialLinks from "@modules/layout/templates/vt-social-link"
|
import VtSocialLinks from "@modules/layout/templates/vt-social-link"
|
||||||
|
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"
|
||||||
|
|
||||||
type ComponentConfig = Record<string, any>;
|
type ComponentConfig = Record<string, any>;
|
||||||
|
|
||||||
|
|
@ -63,18 +62,14 @@ export const componentMap: Record<string, ComponentRenderer> = {
|
||||||
VtSideMenu: nodesContextRenderer(VtSideMenu),
|
VtSideMenu: nodesContextRenderer(VtSideMenu),
|
||||||
Banner: nodesContextRenderer(Banner),
|
Banner: nodesContextRenderer(Banner),
|
||||||
HomeButton: nodesContextRenderer(HomeButton),
|
HomeButton: nodesContextRenderer(HomeButton),
|
||||||
|
Logo: nodesContextRenderer(VtLogo),
|
||||||
AccountButton: nodesContextRenderer(AccountButton),
|
AccountButton: nodesContextRenderer(AccountButton),
|
||||||
Button: nodesContextRenderer(VtButton),
|
|
||||||
Section: nodesContextRenderer(VtSection),
|
|
||||||
SearchInput: nodesContextRenderer(VtSearchInput),
|
SearchInput: nodesContextRenderer(VtSearchInput),
|
||||||
VtCartButton: nodesContextRenderer(VtCartButton),
|
VtCartButton: nodesContextRenderer(VtCartButton),
|
||||||
VtCurrencySelect: nodesContextRenderer(VtCurrencySelect),
|
VtCurrencySelect: nodesContextRenderer(VtCurrencySelect),
|
||||||
VtCountryCodeSelect: nodesContextRenderer(VtCountryCodeSelect),
|
VtCountryCodeSelect: nodesContextRenderer(VtCountryCodeSelect),
|
||||||
VtSocialLinks: nodesContextRenderer(VtSocialLinks),
|
VtSocialLinks: nodesContextRenderer(VtSocialLinks),
|
||||||
Link: nodesContextRenderer(VtLink),
|
Link: nodesContextRenderer(VtLink),
|
||||||
Input: nodesContextRenderer(VtInput),
|
|
||||||
Image: nodesContextRenderer(VtImage),
|
|
||||||
Text: nodesContextRenderer(VtText),
|
|
||||||
Dropdown: nodesContextRenderer(VtDropdown),
|
Dropdown: nodesContextRenderer(VtDropdown),
|
||||||
VtMenuItem: nodesContextRenderer(VtMenuItem),
|
VtMenuItem: nodesContextRenderer(VtMenuItem),
|
||||||
CartMismatchBanner: configOnly(CartMismatchBanner),
|
CartMismatchBanner: configOnly(CartMismatchBanner),
|
||||||
|
|
@ -82,6 +77,8 @@ export const componentMap: Record<string, ComponentRenderer> = {
|
||||||
PropsChildren: {
|
PropsChildren: {
|
||||||
render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children
|
render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children
|
||||||
},
|
},
|
||||||
|
VtFooterHero: nodesContextRenderer(VtFooterHero),
|
||||||
|
VtFooterBottom: nodesContextRenderer(VtFooterBottom),
|
||||||
Footer: nodesContextRenderer(VtFooter)
|
Footer: nodesContextRenderer(VtFooter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue