|
@@ -1,362 +0,0 @@
|
|
|
-import { type Metadata } from "next";
|
|
|
|
|
-import { notFound } from "next/navigation";
|
|
|
|
|
-// import { isArray } from "@/utils/type-guards";
|
|
|
|
|
-// import FilterList from "@components/theme/filters/FilterList";
|
|
|
|
|
-// import Pagination from "@components/catalog/Pagination";
|
|
|
|
|
-import Image from "next/image";
|
|
|
|
|
-import ProductListing from "./_components/ProductListing";
|
|
|
|
|
-import type{
|
|
|
|
|
- // ProductsResponse,
|
|
|
|
|
- GetCategoryAttrFiltersResult,
|
|
|
|
|
- CategoryProductsResult,
|
|
|
|
|
-} from "@components/catalog/type";
|
|
|
|
|
-import {
|
|
|
|
|
- // GET_FILTER_PRODUCTS,
|
|
|
|
|
- // GET_TREE_CATEGORIES,
|
|
|
|
|
- GET_CATEHORY_BY_ID,
|
|
|
|
|
- GET_CATEGORY_ATTR_FILTERS,
|
|
|
|
|
- CATEGORY_PRODUCTS,
|
|
|
|
|
-} from "@/graphql";
|
|
|
|
|
-
|
|
|
|
|
-import { newSortByFields } from "@utils/constants";
|
|
|
|
|
-// import { CategoryDetail } from "@components/theme/search/CategoryDetail";
|
|
|
|
|
-import CategoryDesc from "./_components/CategoryDesc";
|
|
|
|
|
-import FaqList, { type FaqItem } from "./_components/FaqList";
|
|
|
|
|
-// import { TreeCategoriesResponse } from "@/types/theme/category-tree";
|
|
|
|
|
-// import { MobileSearchBar } from "@components/layout/navbar/MobileSearch";
|
|
|
|
|
-import {
|
|
|
|
|
- // extractNumericId,
|
|
|
|
|
- // findCategoryBySlug,
|
|
|
|
|
- newBuildProductFilters,
|
|
|
|
|
- transformFiltersForApi,
|
|
|
|
|
-} from "@utils/helper";
|
|
|
|
|
-import { serverGraphqlFetch } from "@/utils/bagisto/index";
|
|
|
|
|
-import type {
|
|
|
|
|
- // CategoryNode,
|
|
|
|
|
- CategorySingleResponse,
|
|
|
|
|
-} from "@/types/theme/category-tree";
|
|
|
|
|
-
|
|
|
|
|
-/**列表页 */
|
|
|
|
|
-export async function generateMetadata({
|
|
|
|
|
- params,
|
|
|
|
|
-}: {
|
|
|
|
|
- params: Promise<{ slug: string; id: string }>;
|
|
|
|
|
-}): Promise<Metadata> {
|
|
|
|
|
- const { slug: _categorySlug, id: categoryId } = await params;
|
|
|
|
|
- const { data: categoryData } = await serverGraphqlFetch<
|
|
|
|
|
- CategorySingleResponse,
|
|
|
|
|
- { id: number }
|
|
|
|
|
- >({
|
|
|
|
|
- query: GET_CATEHORY_BY_ID,
|
|
|
|
|
- variables: {
|
|
|
|
|
- id: Number(categoryId),
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // const {data:treeData} = await cachedGraphQLRequest<TreeCategoriesResponse>(
|
|
|
|
|
- // "category",
|
|
|
|
|
- // GET_TREE_CATEGORIES,
|
|
|
|
|
- // { parentId: 1 }
|
|
|
|
|
- // );
|
|
|
|
|
-
|
|
|
|
|
- // const categories = treeData?.treeCategories || [];
|
|
|
|
|
- // const categoryItem = findCategoryBySlug(categories, categorySlug);
|
|
|
|
|
- const categoryItem = categoryData?.category;
|
|
|
|
|
- if (!categoryItem) return notFound();
|
|
|
|
|
-
|
|
|
|
|
- const translation = categoryItem.translation;
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- title: translation?.metaTitle || translation?.name,
|
|
|
|
|
- description: translation?.description || `${translation?.name} products`,
|
|
|
|
|
- };
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-export default async function CategoryPage({
|
|
|
|
|
- searchParams,
|
|
|
|
|
- params,
|
|
|
|
|
-}: {
|
|
|
|
|
- params: Promise<{ slug: string; id: string }>;
|
|
|
|
|
- searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
|
|
|
|
|
-}) {
|
|
|
|
|
- // const { collection: categorySlug } = await params;
|
|
|
|
|
- const { slug: _categorySlug, id: categoryId } = await params;
|
|
|
|
|
- const resolvedParams = await searchParams;
|
|
|
|
|
- function getSearchParam(
|
|
|
|
|
- value: string | string[] | undefined,
|
|
|
|
|
- ): string | undefined {
|
|
|
|
|
- return Array.isArray(value) ? value[0] : value;
|
|
|
|
|
- }
|
|
|
|
|
- /*
|
|
|
|
|
- const [{data:treeData}, filterAttributes] = await Promise.all([
|
|
|
|
|
- cachedGraphQLRequest<TreeCategoriesResponse>(
|
|
|
|
|
- "category",
|
|
|
|
|
- GET_TREE_CATEGORIES,
|
|
|
|
|
- { parentId: 1 }
|
|
|
|
|
- ),
|
|
|
|
|
- getFilterAttributes(), // 这个不能用
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- const categories = treeData?.treeCategories || [];
|
|
|
|
|
- const categoryItem = findCategoryBySlug(categories, categorySlug);
|
|
|
|
|
- */
|
|
|
|
|
- //const filterAttributes = await getFilterAttributes(); // 这个不能用
|
|
|
|
|
- const filterAttributesRes = await serverGraphqlFetch<
|
|
|
|
|
- GetCategoryAttrFiltersResult,
|
|
|
|
|
- { slug: string; first: number }
|
|
|
|
|
- >({
|
|
|
|
|
- query: GET_CATEGORY_ATTR_FILTERS,
|
|
|
|
|
- variables: {
|
|
|
|
|
- slug: _categorySlug || "Ready To Go Wig",
|
|
|
|
|
- first: 50,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 错误判断
|
|
|
|
|
- if (filterAttributesRes.error) {
|
|
|
|
|
- console.error("获取分类筛选属性失败", filterAttributesRes.error);
|
|
|
|
|
- throw new Error(filterAttributesRes.error.message);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- console.log(
|
|
|
|
|
- "filterAttributesRes---------------AAA",
|
|
|
|
|
- filterAttributesRes.data?.categoryAttributeFilters,
|
|
|
|
|
- );
|
|
|
|
|
- console.log("filterAttributes---------------:", resolvedParams);
|
|
|
|
|
- const { data: categoryData } = await serverGraphqlFetch<
|
|
|
|
|
- CategorySingleResponse,
|
|
|
|
|
- { id: number }
|
|
|
|
|
- >({
|
|
|
|
|
- query: GET_CATEHORY_BY_ID,
|
|
|
|
|
- variables: {
|
|
|
|
|
- id: Number(categoryId),
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- const categoryItem = categoryData?.category;
|
|
|
|
|
- if (!categoryItem) return notFound();
|
|
|
|
|
-
|
|
|
|
|
- console.log("categoryItem +++++++++++", categoryItem);
|
|
|
|
|
- // const numericId = extractNumericId(categoryItem.id);
|
|
|
|
|
- const numericId = String(categoryItem._id);
|
|
|
|
|
-
|
|
|
|
|
- // const {
|
|
|
|
|
- // q: searchValue,
|
|
|
|
|
- // page,
|
|
|
|
|
- // cursor,
|
|
|
|
|
- // before,
|
|
|
|
|
- // } = (resolvedParams || {}) as {
|
|
|
|
|
- // [key: string]: string;
|
|
|
|
|
- // };
|
|
|
|
|
- const searchValue = resolvedParams?.q ?? "";
|
|
|
|
|
-
|
|
|
|
|
- // const page = getSearchParam(resolvedParams?.page);
|
|
|
|
|
-
|
|
|
|
|
- const cursor = getSearchParam(resolvedParams?.cursor);
|
|
|
|
|
-
|
|
|
|
|
- const before = getSearchParam(resolvedParams?.before);
|
|
|
|
|
- const itemsPerPage = 15;
|
|
|
|
|
- // const currentPage = page ? parseInt(page) - 1 : 0;
|
|
|
|
|
- const sortValue = getSearchParam(resolvedParams?.sort) ?? "name-asc";
|
|
|
|
|
- const selectedSort =
|
|
|
|
|
- newSortByFields.find((s) => s.key === sortValue) || newSortByFields[0];
|
|
|
|
|
-
|
|
|
|
|
- const { filterObject: baseFilterObject } = newBuildProductFilters(
|
|
|
|
|
- resolvedParams || {},
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- const filterObject: Record<string, string> = {
|
|
|
|
|
- ...baseFilterObject,
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- if (numericId) {
|
|
|
|
|
- filterObject.category_id = numericId;
|
|
|
|
|
- }
|
|
|
|
|
- const finalFilterObj =transformFiltersForApi(filterObject);
|
|
|
|
|
- const filterInput = JSON.stringify(finalFilterObj);
|
|
|
|
|
- // 默认获取产品数据接口:
|
|
|
|
|
- const { data: categoryProductDatas } = await serverGraphqlFetch<
|
|
|
|
|
- CategoryProductsResult,
|
|
|
|
|
- any
|
|
|
|
|
- >({
|
|
|
|
|
- query: CATEGORY_PRODUCTS,
|
|
|
|
|
- variables: {
|
|
|
|
|
- slug: _categorySlug || "Ready To Go Wig",
|
|
|
|
|
- filter: filterInput,
|
|
|
|
|
- id: Number(categoryId),
|
|
|
|
|
- ...(before
|
|
|
|
|
- ? {
|
|
|
|
|
- last: itemsPerPage,
|
|
|
|
|
- before,
|
|
|
|
|
- }
|
|
|
|
|
- : {
|
|
|
|
|
- first: itemsPerPage,
|
|
|
|
|
- after: cursor || null,
|
|
|
|
|
- }),
|
|
|
|
|
- sortKey: selectedSort.sortKey,
|
|
|
|
|
- reverse: selectedSort.reverse,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- console.log("categoryProductDatas-----------:",categoryProductDatas,selectedSort);
|
|
|
|
|
-
|
|
|
|
|
- // 这个也改成 serverGraphqlFetch
|
|
|
|
|
- // const productVariables = {
|
|
|
|
|
- // query: searchValue || "",
|
|
|
|
|
- // filter: filterInput,
|
|
|
|
|
- // ...(before
|
|
|
|
|
- // ? {
|
|
|
|
|
- // last: itemsPerPage,
|
|
|
|
|
- // before,
|
|
|
|
|
- // }
|
|
|
|
|
- // : {
|
|
|
|
|
- // first: itemsPerPage,
|
|
|
|
|
- // after: cursor || null,
|
|
|
|
|
- // }),
|
|
|
|
|
- // sortKey: selectedSort.sortKey,
|
|
|
|
|
- // reverse: selectedSort.reverse,
|
|
|
|
|
- // };
|
|
|
|
|
- // const { data } = await serverGraphqlFetch<
|
|
|
|
|
- // ProductsResponse,
|
|
|
|
|
- // typeof productVariables
|
|
|
|
|
- // >({
|
|
|
|
|
- // query: GET_FILTER_PRODUCTS,
|
|
|
|
|
- // variables: productVariables,
|
|
|
|
|
- // });
|
|
|
|
|
- // const [{ data }] = await Promise.all([
|
|
|
|
|
- // cachedCategoryRequest<ProductsResponse>(categorySlug, GET_FILTER_PRODUCTS, {
|
|
|
|
|
- // query: searchValue || "",
|
|
|
|
|
- // filter: filterInput,
|
|
|
|
|
- // ...(before
|
|
|
|
|
- // ? { last: itemsPerPage, before: before }
|
|
|
|
|
- // : { first: itemsPerPage, after: cursor }),
|
|
|
|
|
- // sortKey: selectedSort.sortKey,
|
|
|
|
|
- // reverse: selectedSort.reverse,
|
|
|
|
|
- // }),
|
|
|
|
|
- // ]);
|
|
|
|
|
- console.log(
|
|
|
|
|
- "GET_FILTER_PRODUCTS ----- ",
|
|
|
|
|
- searchValue,
|
|
|
|
|
- filterInput,
|
|
|
|
|
- itemsPerPage,
|
|
|
|
|
- before,
|
|
|
|
|
- cursor,
|
|
|
|
|
- selectedSort,
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- const products = categoryProductDatas?.categoryProducts?.products?.map((e) => e.node) || [];
|
|
|
|
|
- const pageInfo = categoryProductDatas?.categoryProducts?.pageInfo||{endCursor:'',hasNextPage:false};
|
|
|
|
|
- const totalCount = categoryProductDatas?.categoryProducts?.totalCount || 0;
|
|
|
|
|
- const translation = categoryItem.translation;
|
|
|
|
|
- console.log("initialQuery------------", {
|
|
|
|
|
- search: searchValue,
|
|
|
|
|
- sort: sortValue,
|
|
|
|
|
- sortKey: selectedSort.sortKey,
|
|
|
|
|
- reverse: selectedSort.reverse,
|
|
|
|
|
- filters: baseFilterObject,
|
|
|
|
|
- });
|
|
|
|
|
- // 模拟FAQ假数据
|
|
|
|
|
- const mockFaqData: FaqItem[] = [
|
|
|
|
|
- {
|
|
|
|
|
- id: "1",
|
|
|
|
|
- question: "How long is the delivery time for human hair wigs?",
|
|
|
|
|
- answer:
|
|
|
|
|
- "Standard shipping takes 7-12 working days, expedited shipping supports 3-5 days delivery worldwide.",
|
|
|
|
|
- likeCount: 248,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: "2",
|
|
|
|
|
- question: "Is the HD lace wig invisible on all skin tones?",
|
|
|
|
|
- answer:
|
|
|
|
|
- "Our HD transparent lace matches all skin tones, melts perfectly without foundation.",
|
|
|
|
|
- likeCount: 186,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: "3",
|
|
|
|
|
- question: "Can I dye and bleach the hair extensions?",
|
|
|
|
|
- answer:
|
|
|
|
|
- "100% human hair can be dyed darker or bleached lighter, we recommend professional hairdresser operation.",
|
|
|
|
|
- likeCount: 312,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: "4",
|
|
|
|
|
- question: "What payment methods do you support?",
|
|
|
|
|
- answer:
|
|
|
|
|
- "Credit card, PayPal, Apple Pay, Google Pay and bank transfer are all available.",
|
|
|
|
|
- likeCount: 97,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: "5",
|
|
|
|
|
- question: "How to return or exchange products?",
|
|
|
|
|
- answer:
|
|
|
|
|
- "Contact our customer service within 30 days after receiving the package for free exchange.",
|
|
|
|
|
- likeCount: 154,
|
|
|
|
|
- },
|
|
|
|
|
- ];
|
|
|
|
|
- return (
|
|
|
|
|
- <>
|
|
|
|
|
- {/* <MobileSearchBar /> */}
|
|
|
|
|
- <section>
|
|
|
|
|
-
|
|
|
|
|
- {/* <CategoryDetail
|
|
|
|
|
- categoryItem={{
|
|
|
|
|
- description: translation?.description ?? "",
|
|
|
|
|
- name: translation?.name ?? "",
|
|
|
|
|
- }}
|
|
|
|
|
- /> */}
|
|
|
|
|
- <div className="flex justify-center">
|
|
|
|
|
- <Image
|
|
|
|
|
- src={categoryProductDatas? categoryProductDatas.categoryProducts.banner: ''}
|
|
|
|
|
- alt={'categoryBanner'}
|
|
|
|
|
- width={358}
|
|
|
|
|
- height={176}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- <CategoryDesc
|
|
|
|
|
- title={translation?.name ?? ""}
|
|
|
|
|
- description={
|
|
|
|
|
- categoryProductDatas? categoryProductDatas.categoryProducts.description: ''
|
|
|
|
|
- } //translation?.description ?? ""}
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- {/* <div className="my-10 hidden gap-4 md:flex md:items-baseline md:justify-between w-full max-w-screen-2xl mx-auto px-4">
|
|
|
|
|
- <FilterList filterAttributes={filterAttributes} />
|
|
|
|
|
- <SortOrder sortOrders={SortByFields} title="Sort by" />
|
|
|
|
|
- </div> */}
|
|
|
|
|
- <ProductListing
|
|
|
|
|
- categoryId={numericId}
|
|
|
|
|
- slug={_categorySlug}
|
|
|
|
|
- filterAttributes={
|
|
|
|
|
- filterAttributesRes.data? filterAttributesRes.data.categoryAttributeFilters.edges:[]
|
|
|
|
|
- }
|
|
|
|
|
- initialProducts={products}
|
|
|
|
|
- initialPageInfo={pageInfo}
|
|
|
|
|
- initialTotal={totalCount}
|
|
|
|
|
- initialQuery={{
|
|
|
|
|
- // search: searchValue,
|
|
|
|
|
- sortValue: sortValue,
|
|
|
|
|
- sortKey: selectedSort.sortKey,
|
|
|
|
|
- reverse: selectedSort.reverse,
|
|
|
|
|
- filters: baseFilterObject,
|
|
|
|
|
- cursor,
|
|
|
|
|
- }}
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- {/* {isArray(products) &&
|
|
|
|
|
- (totalCount > itemsPerPage || pageInfo?.hasNextPage) && (
|
|
|
|
|
- <nav
|
|
|
|
|
- aria-label="Collection pagination"
|
|
|
|
|
- className="my-10 block items-center sm:flex"
|
|
|
|
|
- >
|
|
|
|
|
- <Pagination
|
|
|
|
|
- itemsPerPage={itemsPerPage}
|
|
|
|
|
- itemsTotal={totalCount || 0}
|
|
|
|
|
- currentPage={currentPage}
|
|
|
|
|
- nextCursor={pageInfo?.endCursor}
|
|
|
|
|
- prevCursor={pageInfo?.startCursor}
|
|
|
|
|
- />
|
|
|
|
|
- </nav>
|
|
|
|
|
- )} */}
|
|
|
|
|
- <FaqList faqList={mockFaqData} />
|
|
|
|
|
- </section>
|
|
|
|
|
- </>
|
|
|
|
|
- );
|
|
|
|
|
-}
|
|
|