90 lines
2.9 KiB
JavaScript
90 lines
2.9 KiB
JavaScript
import { fetchComponentData, fetchCategoryData } from "@/utils/data";
|
|
|
|
/**
|
|
* Product category sidebar component
|
|
* @param {string} componentName - component name
|
|
* @param {string} className - additional class names
|
|
*/
|
|
export default async function Category({
|
|
componentName = "Category",
|
|
className = "",
|
|
}) {
|
|
// 1. 获取组件元数据
|
|
const metaRes = await fetchComponentData(componentName);
|
|
const metaData = metaRes.data;
|
|
|
|
// 如果按 componentName 未找到组件数据,或数据未有效配置分类,则不渲染组件
|
|
if (!metaData || !metaData.p1 || !metaData.p2) {
|
|
return null;
|
|
}
|
|
|
|
// 2. 获取分类树
|
|
let data = {
|
|
title: metaData.title || "Product Categories",
|
|
subtitle: metaData.subtitle || "",
|
|
slug: "",
|
|
items: [],
|
|
};
|
|
const catRes = await fetchCategoryData({ pagetype: metaData.p1, name: metaData.p2 });
|
|
const categoryData = catRes.data || {};
|
|
data = {
|
|
...data,
|
|
slug: categoryData.slug,
|
|
items: categoryData.children || [],
|
|
};
|
|
|
|
// 渲染分类列表
|
|
const renderCategories = (items, parentSlugs = []) => {
|
|
if (!items || !items.length) return null;
|
|
return (
|
|
<ul className="pl-0 list-none">
|
|
{items.map((item) => {
|
|
const hasChildren = Array.isArray(item.children) && item.children.length > 0;
|
|
const currentPath = [...parentSlugs, item.slug];
|
|
return (
|
|
<li key={item.slug} className="nav-item">
|
|
<div className="flex items-center justify-between cursor-pointer py-2">
|
|
<a
|
|
className="!text-[#60697b] hover:!text-[#1fc76f]"
|
|
href={`/${currentPath.join('/')}`}
|
|
>
|
|
{item.name}
|
|
</a>
|
|
{hasChildren && (
|
|
<span className="ml-2 text-gray-400 hover:text-[#1fc76f]">{'>'}</span>
|
|
)}
|
|
</div>
|
|
{hasChildren && (
|
|
<div className="pl-4 sub-category">
|
|
<ul className="list-none pl-0">
|
|
{item.children.map((child) => (
|
|
<li key={child.slug} className="py-1">
|
|
<a
|
|
className="!text-[#60697b] hover:!text-[#1fc76f] text-sm"
|
|
href={`/${currentPath.join('/')}/${child.slug}`}
|
|
>
|
|
{child.name}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<aside className={`hidden md:block lg:w-3/12 xl:w-3/12 sidebar px-8 py-8 bg-white rounded-xl shadow-md ${className}`}>
|
|
<div className="widget">
|
|
<h4 className="widget-title !mb-3">{data.title}</h4>
|
|
{data.subtitle && <div className="text-xs text-gray-500 mb-2">{data.subtitle}</div>}
|
|
{renderCategories(data.items, [data.slug])}
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|