diff --git a/config/nam.3bear.design.json b/config/nam.3bear.design.json index 75406bc..eb2c9d3 100644 --- a/config/nam.3bear.design.json +++ b/config/nam.3bear.design.json @@ -474,6 +474,22 @@ } } }, + { + "VtBrand": { + "config": { + "className": "w-full py-12 bg-[#CFECD9]", + "innerClassName": "content-container flex flex-col items-center", + "title": "Trusted By", + "titleClassName": "text-[#003F31] text-[20px] font-semibold mb-8", + "brandsClassName": "flex w-full items-center justify-between gap-12", + "items": [ + { "label": "Men'sHealth", "containerClassName": "", "className": "text-[#003F31] text-[36px] font-semibold italic" }, + { "label": "GQ", "containerClassName": "", "className": "text-[#003F31] text-[44px] font-black tracking-tight" }, + { "label": "BIRCHBOX", "containerClassName": "", "className": "text-[#003F31] text-[36px] font-semibold tracking-[0.2em]" } + ] + } + } + }, { "FreeShippingPriceNudge": { "config": { diff --git a/config/nam.drsquatch.design.json b/config/nam.drsquatch.design.json index 1b01132..84a0dda 100644 --- a/config/nam.drsquatch.design.json +++ b/config/nam.drsquatch.design.json @@ -348,6 +348,22 @@ } } }, + { + "VtBrand": { + "config": { + "className": "w-full py-12 bg-[#CFECD9]", + "innerClassName": "content-container flex flex-col items-center", + "title": "", + "titleClassName": "text-[#1f3521] text-[20px] font-bold mb-8", + "brandsClassName": "flex w-full items-center justify-between gap-12", + "items": [ + { "imageSrc": "/brand-logo.png", "alt": "Men's Health", "containerClassName": "", "imageClassName": "h-[40px] object-contain" }, + { "imageSrc": "/brand-logo.png", "alt": "GQ", "containerClassName": "", "imageClassName": "h-[40px] object-contain" }, + { "imageSrc": "/brand-logo.png", "alt": "Birchbox", "containerClassName": "", "imageClassName": "h-[40px] object-contain" } + ] + } + } + }, { "CartMismatchBanner": { "config": { "show": true } } }, { "FreeShippingPriceNudge": { "config": { "variant": "popup" } } } ], diff --git a/public/brand-logo.png b/public/brand-logo.png new file mode 100644 index 0000000..f71b945 Binary files /dev/null and b/public/brand-logo.png differ diff --git a/src/modules/home/components/vt-brand/index.tsx b/src/modules/home/components/vt-brand/index.tsx new file mode 100644 index 0000000..3b7808a --- /dev/null +++ b/src/modules/home/components/vt-brand/index.tsx @@ -0,0 +1,72 @@ +import { clx } from "@medusajs/ui" +import LocalizedClientLink from "@modules/common/components/localized-client-link" +import { + LayoutComponentDefinition, + LayoutContext, +} from "@vibentec/component-map" + +export default async function VtBrand({ + nodes, + context, +}: { + nodes: LayoutComponentDefinition + context: LayoutContext +}) { + const props = nodes.config ?? {} + + const title: string = props.title ?? "Trusted By" + const items = props.items ?? [] + + const classes = { + container: props.className ?? "w-full py-12 bg-[#CFECD9]", + inner: props.innerClassName ?? "content-container flex flex-col items-center", + title: props.titleClassName ?? "text-[#1f3521] text-[20px] font-bold mb-8", + brands: props.brandsClassName ?? "flex w-full items-center justify-between gap-12", + item: props.itemClassName ?? "opacity-90", + image: props.imageClassName ?? "h-[48px] w-auto object-contain", + label: props.labelClassName ?? "text-[#1f3521] text-[36px] font-semibold", + } + + if (!items || items.length === 0) { + return null + } + + const renderItem = (brand: any, idx: number) => { + const content = brand.imageSrc ? ( + {brand.alt + ) : ( + + {brand.label ?? ""} + + ) + + return brand.href ? ( + + {content} + + ) : ( +
+ {content} +
+ ) + } + + return ( +
+
+ {title &&
{title}
} +
+ {items.map((brand: any, idx: number) => renderItem(brand, idx))} +
+
+
+ ) +} diff --git a/src/vibentec/component-map.tsx b/src/vibentec/component-map.tsx index 97bdf9c..5d1e679 100644 --- a/src/vibentec/component-map.tsx +++ b/src/vibentec/component-map.tsx @@ -27,6 +27,7 @@ import { VtCarousel } from "@modules/layout/templates/vt-carousel" import { VtCtaBanner } from "@modules/layout/templates/vt-cta-banner" import VtFeaturedProducts from "@modules/home/components/vt-featured-products" import VtCategoryHighlight from "@modules/home/components/vt-category-highlight" +import VtBrand from "@modules/home/components/vt-brand" type ComponentConfig = Record @@ -103,6 +104,7 @@ export const componentMap: Record = { ImageDisplayer: nodesContextRenderer(VtCarousel), VtFeaturedProducts: nodesContextRenderer(VtFeaturedProducts), VtCategoryHighlight: nodesContextRenderer(VtCategoryHighlight), + VtBrand: nodesContextRenderer(VtBrand), } export type ComponentName = keyof typeof componentMap diff --git a/src/vibentec/configloader.ts b/src/vibentec/configloader.ts index 1759cee..7b07466 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.namDrsquatch async function readDesignFile() { const filePath = path.join(process.cwd(), "config", fileName) @@ -10,6 +10,7 @@ async function readDesignFile() { return JSON.parse(fileData) } + export async function loadLayoutConfig() { const config = await readDesignFile() if (Array.isArray(config)) return config