186 lines
7.4 KiB
JavaScript

import Banner from "@/components/banner/Banner";
import Category from "@/components/sidebar/Category";
import { getSiteSettings } from "@/utils/data";
import { notFound } from 'next/navigation';
import DynamicListPage from "@/components/common/DynamicListPage";
import { Suspense } from 'react';
import { getPageData } from "@/utils/data";
import ProductImageGallery from "@/components/products/ProductImageGallery";
const baseSlug = 'blog';
const LoadingSpinner = () => (
<div className="flex justify-center items-center p-8">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
</div>
);
export const revalidate = 3600;
export async function generateMetadata({ params }) {
const resolvedParams = await params;
const slug = resolvedParams.slug || [];
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
const { data, error, page_info } = await getPageData({ slug_list: slugArr });
const siteSettings = await getSiteSettings();
const siteTitle = siteSettings.site_title || '';
const siteName = siteSettings.site_name || '';
const siteNameInPageTitles = siteSettings.site_name_in_page_titles || 'None';
let title = '';
if (error) {
title = error.title || 'Page Error';
return {
title,
description: error.message || '',
};
}
if (Array.isArray(data) && page_info) {
title = page_info.meta_title || page_info.title || '';
if (siteName && title) {
if (siteNameInPageTitles === 'After') {
title = `${title} - ${siteName}`;
} else if (siteNameInPageTitles === 'Before') {
title = `${siteName} - ${title}`;
}
}
return {
title,
description: page_info.meta_description || '',
};
}
title = data?.meta_title || data?.title || '';
if (siteName && title) {
if (siteNameInPageTitles === 'After') {
title = `${title} - ${siteName}`;
} else if (siteNameInPageTitles === 'Before') {
title = `${siteName} - ${title}`;
}
}
return {
title,
description: data?.meta_description || '',
};
}
export default async function Page({ params, searchParams }) {
const resolvedParams = await params;
const slug = resolvedParams.slug || [];
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
const siteSettings = await getSiteSettings();
const pageSize = Number(siteSettings.page_size) || 12;
const { data, error, total } = await getPageData({
slug_list: slugArr,
page: 1,
page_size: pageSize,
downloadFiles: false,
rewriteToProxy: true,
});
if (error) {
notFound();
}
const bannerComponentName = 'Banner-' + baseSlug;
const categoryComponentName = 'Category-' + baseSlug;
if (Array.isArray(data)) {
const currentPath = '/' + slugArr.join('/');
const listColumns = 4;
return (
<>
<Banner componentName={bannerComponentName} />
<div className="wrapper !bg-[#ffffff]">
<div className="container py-[4.5rem] xl:!py-24 lg:!py-24 md:!py-24">
<div className="flex flex-col md:flex-row mx-[-15px] xl:mx-[-35px] lg:mx-[-20px]">
<Category componentName={categoryComponentName} />
<div className="flex-1 min-w-0 !px-[15px] max-w-full md:!px-[20px] lg:!px-[20px] xl:!px-[35px]">
<Suspense fallback={<LoadingSpinner />}>
<DynamicListPage
initialItems={data}
slugArr={slugArr}
basePath={currentPath}
columns={listColumns}
pageSize={pageSize}
totalItems={total}
searchParams={searchParams}
/>
</Suspense>
</div>
</div>
</div>
</div>
</>
);
} else if (data) {
return (
<>
<Banner componentName={bannerComponentName} />
<div className="wrapper !bg-[#ffffff]">
<div className="container py-[4.5rem] xl:!py-24 lg:!py-24 md:!py-24">
<div className="flex flex-col md:flex-row mx-[-15px] xl:mx-[-35px] lg:mx-[-20px]">
<Category componentName={categoryComponentName} />
<div className="flex-1 min-w-0 !px-[15px] max-w-full md:!px-[20px] lg:!px-[20px] xl:!px-[35px]">
<div className="bg-white rounded-lg shadow-md p-6 md:p-10">
{/* 图片和附加信息并排显示,响应式优化 */}
{(data.image || data.subtitle) && (
<div className="flex flex-col md:flex-row gap-4 md:gap-10 mb-6 md:mb-8 items-center md:items-start w-full max-w-full">
{/* 图片轮播区块 */}
<ProductImageGallery data={data} />
<div className="flex-1 min-w-0">
{/* 产品标题 */}
{data.title && (
<h1 className="text-2xl md:text-3xl font-bold text-gray-900 mb-10 md:mb-10 leading-tight">
{data.title}
</h1>
)}
{/* 产品副标题 */}
{data.subtitle && (
<div className="bg-gray-50 whitespace-pre-line text-gray-700 w-full max-w-full prose prose-sm pt-6">
{data.subtitle}
</div>
)}
</div>
</div>
)}
{/* Content 和 Additional Content 标签式排版 */}
<ul className="nav nav-tabs nav-tabs-basic !mt-[70px]">
<li className="nav-item">
<a className="nav-link active" data-bs-toggle="tab" href="#tab1-1">
Description
</a>
</li>
{data.additional_content && (
<li className="nav-item">
<a className="nav-link" data-bs-toggle="tab" href="#tab1-2">
Additional
</a>
</li>
)}
</ul>
{/* 标签内容 */}
<div className="tab-content !mt-0 md:!mt-5">
<div className="tab-pane fade show active" id="tab1-1">
<div className="prose max-w-none text-gray-700 px-1 md:px-0 prose-img:max-w-full prose-img:h-auto prose-table:border prose-table:border-gray-300 prose-th:border prose-th:border-gray-300 prose-td:border prose-td:border-gray-300 prose-th:bg-gray-50 prose-table:rounded-lg prose-table:overflow-hidden" dangerouslySetInnerHTML={{ __html: data.content || '' }} />
</div>
{data.additional_content && (
<div className="tab-pane fade" id="tab1-2">
<div className="prose max-w-none text-gray-700 px-1 md:px-0 prose-img:max-w-full prose-img:h-auto prose-table:border prose-table:border-gray-300 prose-th:border prose-th:border-gray-300 prose-td:border prose-td:border-gray-300 prose-th:bg-gray-50 prose-table:rounded-lg prose-table:overflow-hidden" dangerouslySetInnerHTML={{ __html: data.additional_content }} />
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
} else {
notFound();
}
}