t10015/components/sidebar/Category.jsx
2025-08-21 15:58:23 +08:00

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>
);
}