feat: create highlight category component and config with json file

This commit is contained in:
Nam Doan
2025-12-26 15:47:35 +07:00
parent e0bb44b65a
commit 4327676cb4
7 changed files with 536 additions and 29 deletions
@@ -0,0 +1,86 @@
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 VtCategoryHighlight({
nodes,
context,
}: {
nodes: LayoutComponentDefinition
context: LayoutContext
}) {
const props = nodes.config ?? {}
const title: string = props.title ?? ""
const items = props.items ?? []
const classes = {
container: props.className ?? "content-container py-12",
title:
props.titleClassName ?? "text-[#003F31] text-[28px] font-semibold mb-6",
grid: props.gridClassName ?? "grid grid-cols-3 gap-6 w-full",
tile:
props.tileClassName ??
"relative rounded-2xl overflow-hidden bg-white aspect-square w-full",
label: props.labelClassName ?? "text-[#003F31] text-[18px] font-semibold",
image: props.imageClassName ?? "w-full h-full object-contain",
}
if (!items || items.length === 0) {
return null
}
const renderTile = (tile: any, idx: number) => {
const imageEl = tile.imageSrc ? (
<img
src={tile.imageSrc}
alt={tile.label ?? `category-${idx}`}
className={clx(classes.image, tile.imageClassName)}
/>
) : (
<div
className={clx(
"w-full h-full flex items-center justify-center",
tile.className
)}
>
<div className={clx(tile.headingClassName)}>{tile.headingLabel}</div>
<div className={tile.descriptionClassName}>{tile.descriptionLabel}</div>
<button className={tile.buttonClassName}>{tile.buttonLabel}</button>
</div>
)
const content = (
<div className={clx("relative w-full h-full")}>
{imageEl}
{tile.label && <span className={classes.label}>{tile.label}</span>}
</div>
)
return tile.href ? (
<LocalizedClientLink
key={`tile-${idx}`}
href={tile.href}
className={clx("w-full h-full", tile.className)}
>
{content}
</LocalizedClientLink>
) : (
<div className={clx(tile.className, "w-full h-full")} key={`tile-${idx}`}>
{content}
</div>
)
}
return (
<section className={classes.container}>
{title && <h2 className={classes.title}>{title}</h2>}
<div className={classes.grid}>
{items.map((tile: any, idx: number) => renderTile(tile, idx))}
</div>
</section>
)
}