From fe881d5aed63291c49b88868bd1938167da32f71 Mon Sep 17 00:00:00 2001 From: Nam Doan Date: Wed, 10 Dec 2025 14:09:46 +0700 Subject: [PATCH] refactor: remove singular component and replace with wrapper component --- config/nam.vibentec.design.json | 82 ++++--------------- .../layout/templates/vt-footer/index.tsx | 30 +++---- .../vt-footer/vt-footer-bottom/index.tsx | 31 +++++++ .../vt-footer/vt-footer-hero/index.tsx | 62 ++++++++++++++ .../templates/{vt-image => vt-logo}/index.tsx | 6 +- src/vibentec/component-map.tsx | 15 ++-- 6 files changed, 133 insertions(+), 93 deletions(-) create mode 100644 src/modules/layout/templates/vt-footer/vt-footer-bottom/index.tsx create mode 100644 src/modules/layout/templates/vt-footer/vt-footer-hero/index.tsx rename src/modules/layout/templates/{vt-image => vt-logo}/index.tsx (82%) diff --git a/config/nam.vibentec.design.json b/config/nam.vibentec.design.json index c0d23f0..22917f8 100644 --- a/config/nam.vibentec.design.json +++ b/config/nam.vibentec.design.json @@ -41,11 +41,11 @@ } }, { - "Button": { + "Link": { "config": { "label": "Mehr Info", "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", "left": [ { - "Image": { + "Logo": { "config": { "src": "/VibentecIT-logo.svg", "alt": "MyShop", @@ -202,37 +202,18 @@ "rightClassName": "flex mt-[160px]", "left": [ { - "Image": { - "config": { - "src": "/VibentecIT-logo.svg", - "alt": "MyShop", - "className": "h-[100px] w-[320px]", - "objectFit": "contain" - } - } - }, - { - "VtMenuItem": { + "VtFooterHero": { "config": { + "logoClassName": "h-[100px] w-[255px]", + "logoSrc": "/VibentecIT-logo.svg", + "logoAlt": "Vibentec IT", "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]", - "itemClassName": "text-ui-fg-subtle txt-small", - "items": [ - { - "text": "Tauchen Sie ein in eine Welt modernster Technologien, zuverlässiger Support und proaktiver Innovation – gemeinsam gestalten wir die digitale Zukunft Ihres Unternehmens.", - "href": "/" - } - ] - } - } - }, - { - "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" + "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": "/" }, + "className": "", + "ctaClassName": "ml-8", + "titleClassName": "ml-8", + "descriptionClassName": "ml-8 w-[320px]" } } } @@ -342,42 +323,13 @@ "Footer": { "config": { "className": "content-container h-[128px] w-full text text-[#11314E] flex items-center justify-between px-20 mt-2", + "leftClassName": "w-full", "left": [ { - "Text": { + "VtFooterBottom": { "config": { - "label": "©2025 Vibentec IT. All rights reserved", - "className": "text-[14px] font-[400] pt-2" - } - } - } - ], - "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" + "text": "©2025 Vibentec IT. All rights reserved", + "icons": ["Mastercard", "PayPal", "Visa"] } } } diff --git a/src/modules/layout/templates/vt-footer/index.tsx b/src/modules/layout/templates/vt-footer/index.tsx index 588b51e..67beee4 100644 --- a/src/modules/layout/templates/vt-footer/index.tsx +++ b/src/modules/layout/templates/vt-footer/index.tsx @@ -24,21 +24,21 @@ export default async function VtFooter({ return ( ) } diff --git a/src/modules/layout/templates/vt-footer/vt-footer-bottom/index.tsx b/src/modules/layout/templates/vt-footer/vt-footer-bottom/index.tsx new file mode 100644 index 0000000..4dbe26f --- /dev/null +++ b/src/modules/layout/templates/vt-footer/vt-footer-bottom/index.tsx @@ -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)[name] + if (!IconComp) return null + return ( + + ) + } + + return ( +
+ {props.text} +
+ {(props.icons ?? []).map(renderIcon)} +
+
+ ) +} + diff --git a/src/modules/layout/templates/vt-footer/vt-footer-hero/index.tsx b/src/modules/layout/templates/vt-footer/vt-footer-hero/index.tsx new file mode 100644 index 0000000..fd7ebc8 --- /dev/null +++ b/src/modules/layout/templates/vt-footer/vt-footer-hero/index.tsx @@ -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 ( +
+ {props.logoSrc && ( + {props.logoAlt + )} + {props.title && ( +

+ {props.title} +

+ )} + {props.description && ( +

+ {props.description} +

+ )} + {props.cta && ( + + {props.cta.label} + + + )} +
+ ) +} + diff --git a/src/modules/layout/templates/vt-image/index.tsx b/src/modules/layout/templates/vt-logo/index.tsx similarity index 82% rename from src/modules/layout/templates/vt-image/index.tsx rename to src/modules/layout/templates/vt-logo/index.tsx index ba09f5f..022a3dc 100644 --- a/src/modules/layout/templates/vt-image/index.tsx +++ b/src/modules/layout/templates/vt-logo/index.tsx @@ -3,15 +3,13 @@ import { LayoutComponentDefinition, LayoutContext, } from "@vibentec/component-map" -import Image from "next/image" - export interface VtImageConfig { src: string alt: string className?: string, objectFit?: string, } -export default function VtImage({ +export default function VtLogo({ nodes, context, }: { @@ -21,7 +19,7 @@ export default function VtImage({ const props = (nodes.config as VtImageConfig) ?? {} return (
- {props.alt} + {props.alt}
) } diff --git a/src/vibentec/component-map.tsx b/src/vibentec/component-map.tsx index 68256a9..96761a3 100644 --- a/src/vibentec/component-map.tsx +++ b/src/vibentec/component-map.tsx @@ -12,17 +12,16 @@ import Banner from "@modules/layout/templates/vt-banner" import VtMegaMenu from "@modules/layout/components/vt-mega-menu" import VtLink from "@modules/layout/components/vt-linkbutton" 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 VtButton from "@modules/layout/templates/vt-button" import VtSearchInput from "@modules/layout/templates/vt-search-input" 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 VtMenuItem from "@modules/layout/templates/vt-menu-item" import VtCountryCodeSelect from "@modules/layout/templates/vt-country-select/server" 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; @@ -63,18 +62,14 @@ export const componentMap: Record = { VtSideMenu: nodesContextRenderer(VtSideMenu), Banner: nodesContextRenderer(Banner), HomeButton: nodesContextRenderer(HomeButton), + Logo: nodesContextRenderer(VtLogo), AccountButton: nodesContextRenderer(AccountButton), - Button: nodesContextRenderer(VtButton), - Section: nodesContextRenderer(VtSection), SearchInput: nodesContextRenderer(VtSearchInput), VtCartButton: nodesContextRenderer(VtCartButton), VtCurrencySelect: nodesContextRenderer(VtCurrencySelect), VtCountryCodeSelect: nodesContextRenderer(VtCountryCodeSelect), VtSocialLinks: nodesContextRenderer(VtSocialLinks), Link: nodesContextRenderer(VtLink), - Input: nodesContextRenderer(VtInput), - Image: nodesContextRenderer(VtImage), - Text: nodesContextRenderer(VtText), Dropdown: nodesContextRenderer(VtDropdown), VtMenuItem: nodesContextRenderer(VtMenuItem), CartMismatchBanner: configOnly(CartMismatchBanner), @@ -82,6 +77,8 @@ export const componentMap: Record = { PropsChildren: { render: (_props, ctx) => ctx.contentChildren, // PageLayout's props.children }, + VtFooterHero: nodesContextRenderer(VtFooterHero), + VtFooterBottom: nodesContextRenderer(VtFooterBottom), Footer: nodesContextRenderer(VtFooter) }