{data.title}
diff --git a/components/homes/home-15/Hero.jsx b/components/homes/home-15/Hero/HeroUI.jsx
similarity index 89%
rename from components/homes/home-15/Hero.jsx
rename to components/homes/home-15/Hero/HeroUI.jsx
index c491545..fcc52cb 100644
--- a/components/homes/home-15/Hero.jsx
+++ b/components/homes/home-15/Hero/HeroUI.jsx
@@ -1,37 +1,12 @@
"use client";
-import React, { useEffect, useState } from "react";
import Image from "next/image";
import AnimatedText from "@/components/common/AnimatedText";
import Link from "next/link";
-import axios from "axios";
-export default function Hero() {
- const [data, setData] = useState(null);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
-
- useEffect(() => {
- async function fetchData() {
- try {
- setLoading(true);
- const res = await axios.get("/api/get-component-data", {
- params: { component_name: "Hero" },
- });
- setData(res.data.data);
- } catch (err) {
- setError("获取Features数据失败");
- } finally {
- setLoading(false);
- }
- }
- fetchData();
- }, []);
-
- if (loading) return
加载中...
;
- if (error) return null;
+export default function HeroUI({ data }) {
if (!data) return null;
- const bgImage = data.bg_image || "/assets/img/photos/blurry.png";
+ const bgImage = data.image || "/assets/img/photos/blurry.png";
const title = data.title || "";
const subtitle = data.subtitle || "";
const buttonText = data.button_text || "MORE";
@@ -39,7 +14,6 @@ export default function Hero() {
const buttonText2 = data.button_2_text || "MORE";
const buttonLink2 = data.button_2_link || "#";
-
return (
);
-}
+}
\ No newline at end of file
diff --git a/components/homes/home-15/Hero/index.jsx b/components/homes/home-15/Hero/index.jsx
new file mode 100644
index 0000000..cbdef0d
--- /dev/null
+++ b/components/homes/home-15/Hero/index.jsx
@@ -0,0 +1,13 @@
+import { fetchComponentData } from "@/utils/data";
+import HeroUI from "./HeroUI";
+
+export default async function Hero() {
+ const result = await fetchComponentData("Hero");
+
+ if (result.error || !result.data) {
+ if(result.error) console.error("Failed to fetch Hero data:", result.error);
+ return null;
+ }
+
+ return
;
+}
\ No newline at end of file
diff --git a/components/sidebar/Category.jsx b/components/sidebar/Category.jsx
index ed5df50..4dd76be 100644
--- a/components/sidebar/Category.jsx
+++ b/components/sidebar/Category.jsx
@@ -1,88 +1,52 @@
-"use client";
-import React, { useEffect, useState } from "react";
-import axios from "axios";
+import { fetchComponentData, fetchCategoryData } from "@/utils/data";
/**
* Product category sidebar component
* @param {string} componentName - component name
* @param {string} className - additional class names
*/
-export default function Category({
+export default async function Category({
componentName = "Category",
className = "",
}) {
- const [data, setData] = useState(null);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
- const [activeCategory, setActiveCategory] = useState(null);
+ // 1. 获取组件元数据
+ const metaRes = await fetchComponentData(componentName);
+ const metaData = metaRes.data;
- useEffect(() => {
- async function fetchData() {
- try {
- setLoading(true);
- // 1. 获取组件元数据
- const metaRes = await axios.get("/api/get-component-data", {
- params: { component_name: componentName },
- });
- const metaData = metaRes.data.data || {};
- // 2. 获取分类树
- if (metaData.p1 && metaData.p2) {
- const catRes = await axios.get("/api/get-category", {
- params: { pagetype: metaData.p1, name: metaData.p2 },
- });
- const categoryData = catRes.data.message?.data || {};
- setData({
- title: metaData.title || "Product Categories",
- subtitle: metaData.subtitle || "",
- slug: categoryData.slug,
- items: categoryData.children || [],
- });
- }
- } catch (err) {
- console.error("获取分类数据失败:", err);
- setError("Failed to fetch category data");
- } finally {
- setLoading(false);
- }
- }
- fetchData();
- }, [componentName]);
+ // 如果按 componentName 未找到组件数据,或数据未有效配置分类,则不渲染组件
+ if (!metaData || !metaData.p1 || !metaData.p2) {
+ return null;
+ }
- if (loading) return null;
- if (error) return null;
- if (!data) return null;
-
- const handleCategoryClick = (categorySlug) => {
- if (activeCategory === categorySlug) {
- setActiveCategory(null);
- } else {
- setActiveCategory(categorySlug);
- }
+ // 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 (
{items.map((item) => {
const hasChildren = Array.isArray(item.children) && item.children.length > 0;
- const isActive = activeCategory === item.slug;
const currentPath = [...parentSlugs, item.slug];
-
return (
-
-
{
- if (hasChildren) handleCategoryClick(item.slug);
- }}
- >
+
-
- {hasChildren && isActive && (
+ {hasChildren && (
{item.children.map((child) => (
@@ -99,7 +62,6 @@ export default function Category({
e.stopPropagation()}
>
{child.name}
diff --git a/public/files/banner-about.jpg b/public/files/banner-about.jpg
new file mode 100644
index 0000000..d08416e
Binary files /dev/null and b/public/files/banner-about.jpg differ
diff --git a/utils/data.js b/utils/data.js
index 28d1eff..693a3a0 100644
--- a/utils/data.js
+++ b/utils/data.js
@@ -9,7 +9,7 @@ if (!fs.existsSync(PUBLIC_FILES_DIR)) {
fs.mkdirSync(PUBLIC_FILES_DIR, { recursive: true });
}
-async function downloadToLocal(fileUrl) {
+export async function downloadToLocal(fileUrl) {
if (!fileUrl) return fileUrl;
try {
let fullUrl = fileUrl;
@@ -51,7 +51,7 @@ function extractImageUrlsFromHtml(html) {
return urls;
}
-async function processDataItem(item, downloadFiles) {
+export async function processDataItem(item, downloadFiles) {
if (!downloadFiles) return item;
if (item.image) {
@@ -174,38 +174,67 @@ export async function getAllSlugs() {
export async function fetchComponentData(componentName) {
try {
- // We use no-store to ensure data is fresh, suitable for dynamic component settings.
- // For more static data, you might adjust the cache policy.
- const res = await fetch(`${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_component_data?component_name=${componentName}`, { cache: 'no-store' });
- if (!res.ok) {
- const errorText = await res.text();
- console.error(`Failed to fetch component data for ${componentName}: ${res.statusText}`, errorText);
+ const res = await axios.get(
+ `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_component_data`,
+ {
+ params: { component_name: componentName },
+ }
+ );
+ return { data: res.data.message?.data || null };
+ } catch (error) {
+ if (
+ error.response &&
+ (error.response.status === 403 || error.response.status === 404)
+ ) {
return { data: null };
}
- const result = await res.json();
- return { data: result.message?.data || null };
- } catch (error) {
- console.error(`Error fetching component data for ${componentName}:`, error);
+ console.error(
+ `Error fetching component data for ${componentName}:`,
+ error.message
+ );
return { data: null };
}
}
export async function fetchListViewData({ pagetype, category, count }) {
try {
- const queryParams = new URLSearchParams({ pagetype });
- if (category) queryParams.append("category", category);
- if (count !== undefined && count !== null) queryParams.append("count", String(count));
-
- const res = await fetch(`${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_listview_data?${queryParams.toString()}`, { cache: 'no-store' });
- if (!res.ok) {
- const errorText = await res.text();
- console.error(`Failed to fetch list view data: ${res.statusText}`, errorText);
+ const params = { pagetype };
+ if (category) params.category = category;
+ if (count !== undefined && count !== null) params.count = String(count);
+
+ const res = await axios.get(
+ `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_listview_data`,
+ { params }
+ );
+
+ return { data: res.data.message?.data || [] };
+ } catch (error) {
+ if (
+ error.response &&
+ (error.response.status === 403 || error.response.status === 404)
+ ) {
return { data: [] };
}
- const result = await res.json();
- return { data: result.message?.data || [] };
- } catch (error) {
- console.error(`Error fetching list view data:`, error);
+ console.error(`Error fetching list view data:`, error.message);
return { data: [] };
}
+}
+
+export async function fetchCategoryData({ pagetype, name }) {
+ try {
+ const res = await axios.get(
+ `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_category`,
+ { params: { pagetype, name } }
+ );
+ return { data: res.data.message?.data || null };
+ } catch (error) {
+ if (
+ error.response &&
+ (error.response.status === 403 || error.response.status === 404)
+ ) {
+ return { data: null };
+ }
+ console.error(`Error fetching category data:`, error.message);
+ return { data: null };
+ }
}
\ No newline at end of file