Browse Source

合并master

zgl 2 days ago
parent
commit
b76d861dfc
100 changed files with 1400 additions and 786 deletions
  1. 0 5
      @types/graphql.d.ts
  2. 0 36
      @types/next-auth.d.ts
  3. 5 3
      package.json
  4. 474 280
      pnpm-lock.yaml
  5. 0 5
      public/favicon.svg
  6. BIN
      public/image/account/202608271600.png
  7. BIN
      public/image/account/202608271601.png
  8. BIN
      public/image/account/202609011640.png
  9. BIN
      public/image/account/202609021400.png
  10. BIN
      public/image/theme/image_flame.webp
  11. BIN
      public/image/theme/image_hot.webp
  12. 1 1
      src/actions/addProductToCartAction.ts
  13. 1 1
      src/actions/deleteCartProductAction.ts
  14. 1 1
      src/actions/logoutAction.ts
  15. 1 1
      src/actions/mergeCartAction.ts
  16. 1 1
      src/app/(checkout)/checkout/_components/CheckoutAddress/AddressResultDisplay.tsx
  17. 1 1
      src/app/(checkout)/checkout/_components/CheckoutAddress/BillingAddressCheckout.tsx
  18. 4 4
      src/app/(checkout)/checkout/_components/CheckoutAddress/CheckoutAssress.tsx
  19. 1 1
      src/app/(checkout)/checkout/_components/CheckoutAddress/ShippingAddressCheckout.tsx
  20. 1 1
      src/app/(checkout)/checkout/_components/CheckoutCoupon/CheckoutCoupon.tsx
  21. 2 2
      src/app/(checkout)/checkout/_components/CheckoutPlaceOrder.tsx
  22. 1 1
      src/app/(checkout)/checkout/_components/CheckoutProducts/CheckoutProducts.tsx
  23. 5 5
      src/app/(checkout)/checkout/_components/CheckoutWrapper.tsx
  24. 1 1
      src/app/(checkout)/checkout/_components/ContinueToPay/ContinueToPayOrderInfo.tsx
  25. 3 3
      src/app/(checkout)/checkout/_components/ContinueToPay/PaymentMethodContinueTpPay.tsx
  26. 1 1
      src/app/(checkout)/checkout/_components/ContinueToPay/ProductsModalPendingOrder.tsx
  27. 2 2
      src/app/(checkout)/checkout/_components/GiftCard/CheckoutGiftCardGate.tsx
  28. 1 1
      src/app/(checkout)/checkout/_components/LostInsurance/LostInsurance.tsx
  29. 2 2
      src/app/(checkout)/checkout/_components/PaymentButton/PaypalApplepayButton.tsx
  30. 2 2
      src/app/(checkout)/checkout/_components/PaymentMethodCheckout.tsx
  31. 1 1
      src/app/(checkout)/checkout/_components/PromotionsDetails.tsx
  32. 1 1
      src/app/(checkout)/checkout/_components/RewardPointsRedeemMoney/RewardPointsRedeemMoney.tsx
  33. 2 2
      src/app/(checkout)/checkout/_components/ShippingMethodCheckout.tsx
  34. 1 1
      src/app/(checkout)/checkout/_components/VipPlus/CheckoutVipPlus.tsx
  35. 1 1
      src/app/(checkout)/checkout/cart/_components/CartWrapper.tsx
  36. 1 1
      src/app/(checkout)/checkout/cart/_components/UnpaidOrderSection.tsx
  37. 2 2
      src/app/(checkout)/checkout/cart/page.tsx
  38. 2 2
      src/app/(checkout)/checkout/continuetopay/page.tsx
  39. 1 1
      src/app/(checkout)/checkout/page.tsx
  40. 1 1
      src/app/(checkout)/layout.tsx
  41. 0 10
      src/app/(public)/[page]/opengraph-image.tsx
  42. 1 1
      src/app/(public)/[page]/page.tsx
  43. 1 1
      src/app/(public)/_components/CategoryTabSwiper .tsx
  44. 2 2
      src/app/(public)/_components/HomeBestSellers.tsx
  45. 5 3
      src/app/(public)/_components/HomeContent.tsx
  46. 1 1
      src/app/(public)/_components/HomeMiddleBanner.tsx
  47. 2 2
      src/app/(public)/_components/HomeNewArrival.tsx
  48. 1 1
      src/app/(public)/_components/JinGangSwiper.tsx
  49. 2 2
      src/app/(public)/_components/MiddleImageSwiper.tsx
  50. 2 2
      src/app/(public)/_components/RecommendedProducts.tsx
  51. 1 1
      src/app/(public)/_components/TopImageSwiper.tsx
  52. 2 2
      src/app/(public)/_components/Trending.tsx
  53. 1 1
      src/app/(public)/category/[slug]/[id]/_components/CategoryDesc.tsx
  54. 123 64
      src/app/(public)/category/[slug]/[id]/_components/ProductListing.tsx
  55. 99 42
      src/app/(public)/category/[slug]/[id]/page.tsx
  56. 127 41
      src/app/(public)/customer/account/_components/AccountHeader.tsx
  57. 12 12
      src/app/(public)/customer/account/_components/HelpModal.tsx
  58. 219 88
      src/app/(public)/customer/account/edit/page.tsx
  59. 33 21
      src/app/(public)/customer/account/mycoupon/_components/GiftCardList.tsx
  60. 1 1
      src/app/(public)/customer/account/mypoints/_components/GetPoints.tsx
  61. 1 1
      src/app/(public)/customer/account/mypoints/_components/PointsRule.tsx
  62. 10 9
      src/app/(public)/customer/account/page.tsx
  63. 1 1
      src/app/(public)/customer/account/pointlist/page.tsx
  64. 25 13
      src/app/(public)/customer/account/pointsreceivelist/_components/RedeemGiftCard.tsx
  65. 1 1
      src/app/(public)/customer/account/pointsreceivelist/page.tsx
  66. 67 14
      src/app/(public)/customer/address/_components/DefaultAddress.tsx
  67. 1 1
      src/app/(public)/customer/address/new/_components/CustomerAddressPhone.tsx
  68. 86 26
      src/app/(public)/customer/address/page.tsx
  69. 1 1
      src/app/(public)/customer/forget-password/_components/ForgetPasswordForm.tsx
  70. 1 1
      src/app/(public)/customer/login/_components/LoginPageWrapper.tsx
  71. 1 1
      src/app/(public)/customer/reset-password/_components/ResetPasswordWrapper.tsx
  72. 1 1
      src/app/(public)/layout.tsx
  73. 1 1
      src/app/(public)/page.tsx
  74. 2 2
      src/app/(public)/paymentresult/_components/CancelOrFailure.tsx
  75. 2 2
      src/app/(public)/paymentresult/_components/OrderDetailWrapper.tsx
  76. 1 1
      src/app/(public)/paymentresult/result/page.tsx
  77. 1 1
      src/app/(public)/product/[...urlProduct]/page.tsx
  78. 1 1
      src/app/(public)/product/_components/ProductInformation.tsx
  79. 1 1
      src/app/(public)/product/_components/ProductMedia.tsx
  80. 1 1
      src/app/(public)/product/_components/SwitchButton.tsx
  81. 1 1
      src/app/(public)/product/_components/question/ComponentsQuestionModal.tsx
  82. 1 1
      src/app/(public)/product/_components/review/AddProductReview.tsx
  83. 1 1
      src/app/(public)/product/_components/review/AddRatingStar.tsx
  84. 2 2
      src/app/(public)/product/_components/review/QuestionInputModal.tsx
  85. 2 2
      src/app/(public)/product/_components/review/ReviewDetail.tsx
  86. 1 1
      src/app/(public)/product/_components/review/ReviewImageGalleryModal.tsx
  87. 1 1
      src/app/(public)/product/_components/review/ReviewImageUploader.tsx
  88. 1 1
      src/app/(public)/product/_components/review/ReviewModal.tsx
  89. 1 1
      src/app/(public)/product/_components/youmaylike/Recommend.tsx
  90. 1 1
      src/app/(public)/search/page.tsx
  91. 2 2
      src/app/(public)/track_order/_components/TrackFaqs.tsx
  92. 14 13
      src/app/(public)/track_order/page.tsx
  93. 1 1
      src/app/api/customer/check-email/route.ts
  94. 1 1
      src/app/api/customer/orders/[id]/route.ts
  95. 1 1
      src/app/api/customer/orders/route.ts
  96. 1 1
      src/app/api/customer/orders/tracking/route.ts
  97. 1 1
      src/app/api/customer/reward-points/browse-product/route.ts
  98. 1 1
      src/app/api/customer/reward-points/follow/route.ts
  99. 1 1
      src/app/api/customer/reward-points/history/route.ts
  100. 0 0
      src/app/api/customer/token/address/route.ts

+ 0 - 5
@types/graphql.d.ts

@@ -1,5 +0,0 @@
-declare module '*.graphql' {
-  import { DocumentNode } from 'graphql';
-  const Schema: DocumentNode;
-  export = Schema;
-}

+ 0 - 36
@types/next-auth.d.ts

@@ -1,36 +0,0 @@
-import { DefaultSession } from 'next-auth';
-
-declare module 'next-auth' {
-  /**
-   * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
-   */
-  interface Session {
-    user: {
-      id: string;
-      firstname?: string;
-      lastname?: string;
-      token?: string;
-      accessToken?: string;
-      apiToken?: string;
-      role?: string;
-    } & DefaultSession['user'];
-  }
-
-  interface User {
-    id: string;
-    accessToken?: string;
-    apiToken?: string;
-    role?: string;
-    tokenType?: string;
-    expiresIn?: number;
-  }
-}
-
-declare module 'next-auth/jwt' {
-  interface JWT {
-    accessToken?: string;
-    apiToken?: string;
-    role?: string;
-    id?: string;
-  }
-}

+ 5 - 3
package.json

@@ -7,7 +7,7 @@
     "build": "eslint . && next build",
     "start": "next start -p 3001",
     "lint": "eslint .",
-    "lint:fix": "next lint --fix",
+    "lint:fix": "eslint . --fix",
     "package-version": "npx npm-check-updates"
   },
   "dependencies": {
@@ -26,12 +26,14 @@
     "@heroui/popover": "^2.3.32",
     "@heroui/radio": "^2.3.32",
     "@heroui/select": "^2.4.29",
+    "@heroui/slider": "^2.4.29",
     "@heroui/switch": "^2.2.27",
     "@heroui/system": "^2.4.28",
     "@heroui/theme": "^2.4.26",
     "@heroui/tooltip": "^2.2.29",
     "@heroui/use-disclosure": "^2.2.19",
     "@internationalized/date": "3.12.0",
+    "@livechat/widget-react": "^1.4.1",
     "@paypal/react-paypal-js": "^10.1.2",
     "@react-aria/visually-hidden": "^3.8.31",
     "@react-types/shared": "^3.33.1",
@@ -42,7 +44,7 @@
     "graphql": "^16.12.0",
     "libphonenumber-js": "^1.13.4",
     "lucide-react": "^0.563.0",
-    "next": "16.2.6",
+    "next": "16.3.4",
     "next-auth": "^4.24.13",
     "react": "19.2.5",
     "react-dom": "19.2.5",
@@ -59,7 +61,7 @@
     "@types/react-dom": "19.2.3",
     "cross-env": "^10.1.0",
     "eslint": "^9",
-    "eslint-config-next": "16.2.3",
+    "eslint-config-next": "16.3.4",
     "tailwindcss": "^4",
     "ts-node": "^10.9.2",
     "typescript": "^5"

File diff suppressed because it is too large
+ 474 - 280
pnpm-lock.yaml


File diff suppressed because it is too large
+ 0 - 5
public/favicon.svg


BIN
public/image/account/202608271600.png


BIN
public/image/account/202608271601.png


BIN
public/image/account/202609011640.png


BIN
public/image/account/202609021400.png


BIN
public/image/theme/image_flame.webp


BIN
public/image/theme/image_hot.webp


+ 1 - 1
src/actions/addProductToCartAction.ts

@@ -6,7 +6,7 @@ import { CREATE_ADD_PRODUCT_IN_CART } from "@/graphql";
 import { auth } from "@/utils/auth/auth-helper";
 import { serverGraphqlFetch } from "@utils/bagisto";
 import {createGuestCartToken,setGuestCookie} from "@/server-service/guestCartTokenService";
-import { AddToCartData,AddToCartVariables } from "@/types/cart/type";
+import type { AddToCartData,AddToCartVariables } from "@/types/cart/type";
 
 
 export async function addProductToCartAction(param:AddToCartVariables) {

+ 1 - 1
src/actions/deleteCartProductAction.ts

@@ -4,7 +4,7 @@
 import { REMOVE_CART_ITEM } from "@/graphql";
 import { serverGraphqlFetch } from "@utils/bagisto";
 import {deleteGuestCookie} from "@/server-service/guestCartTokenService";
-import { RemoveCartItemData } from "@/types/cart/type";
+import type { RemoveCartItemData } from "@/types/cart/type";
 
 
 export async function deleteCartProductAction(cartItemId:number) {

+ 1 - 1
src/actions/logoutAction.ts

@@ -4,7 +4,7 @@ import {cookies} from "next/headers";
 import { IS_GUEST } from "@/utils/constants";
 import { serverGraphqlFetch } from "@utils/bagisto";
 import {CUSTOMER_LOGOUT} from "@/graphql/customer/mutations";
-import { LogoutData } from "@/types/types";
+import type { LogoutData } from "@/types/types";
 
 export async function logoutAction() {
 

+ 1 - 1
src/actions/mergeCartAction.ts

@@ -5,7 +5,7 @@ import {cookies} from "next/headers";
 import { GUEST_CART_ID, GUEST_CART_TOKEN, IS_GUEST } from "@/utils/constants";
 import { serverGraphqlFetch } from "@utils/bagisto";
 import { CREATE_MERGE_CART } from "@/graphql";
-import { CreateMergeCartData } from "@/types/cart/type";
+import type { CreateMergeCartData } from "@/types/cart/type";
 
 export async function mergeCartAction(){
 

+ 1 - 1
src/app/(checkout)/checkout/_components/CheckoutAddress/AddressResultDisplay.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import {CartAddress} from "@/types/cart/type";
+import type {CartAddress} from "@/types/cart/type";
 
 function isAddressAvailable(address: CartAddress | null): boolean {
     if(address && 

+ 1 - 1
src/app/(checkout)/checkout/_components/CheckoutAddress/BillingAddressCheckout.tsx

@@ -20,7 +20,7 @@ import {
     IS_VALID_FULL_PHONE 
 } from "@utils/constants";
 import { useConfig } from "@utils/hooks/useConfig";
-import { CustomerAddressItem } from "@/types/customer/type";
+import type { CustomerAddressItem } from "@/types/customer/type";
 import InputText from "@/components/theme/ui/InputText";
 import Select from "@/components/theme/ui/Select";
 import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumberInput";

+ 4 - 4
src/app/(checkout)/checkout/_components/CheckoutAddress/CheckoutAssress.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import {Ref, useState, useEffect, useCallback, useImperativeHandle, useMemo } from "react";
+import {type Ref, useState, useEffect, useCallback, useImperativeHandle, useMemo } from "react";
 import { useRouter } from 'next/navigation';
 import { useForm, FormProvider } from "react-hook-form";
 import { useCustomToast } from "@/utils/hooks/useToast";
@@ -8,13 +8,13 @@ import {useCheckoutAddress} from "@/utils/hooks/useCheckoutAddress"
 import {useLoginModal} from "@/providers/LoginModalProvider";
 import { useGetCustomerAddress } from "@utils/hooks/useGetCustomerAddress";
 import { EMAIL_REGEX } from "@utils/constants";
-import { 
+import type { 
     ShipAddressFormData,
     FullAddressFormData,
     CreateCheckoutAddressVariables,
 } from "@/types/checkout/type";
-import { CustomerAddressItem,CheckEmailRegisteredData } from "@/types/customer/type";
-import { CartDetail,CartAddress } from "@/types/cart/type";
+import type { CustomerAddressItem,CheckEmailRegisteredData } from "@/types/customer/type";
+import type { CartDetail,CartAddress } from "@/types/cart/type";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import {clientFetch} from "@/lib/restApiClient";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";

+ 1 - 1
src/app/(checkout)/checkout/_components/CheckoutAddress/ShippingAddressCheckout.tsx

@@ -14,7 +14,7 @@ import {
 } from "@/components/theme/ui/PhoneNumberInput/phoneCodeMetaData";
 import { GET_COUNTRY_STATES } from "@/graphql";
 import { EMAIL_REGEX, IS_VALID_INPUT, IS_VALID_FULL_PHONE, IS_VALID_PHONECODE } from "@utils/constants";
-import { CustomerAddressItem } from "@/types/customer/type";
+import type { CustomerAddressItem } from "@/types/customer/type";
 import { useConfig } from "@utils/hooks/useConfig";
 import InputText from "@/components/theme/ui/InputText";
 import Select from "@/components/theme/ui/Select";

+ 1 - 1
src/app/(checkout)/checkout/_components/CheckoutCoupon/CheckoutCoupon.tsx

@@ -5,7 +5,7 @@ import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
 import { useCustomToast } from "@/utils/hooks/useToast";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { formatCartDetail } from "@/utils/cartDetailTools";
-import {CartDetail} from "@/types/cart/type";
+import type {CartDetail} from "@/types/cart/type";
 
 
 

+ 2 - 2
src/app/(checkout)/checkout/_components/CheckoutPlaceOrder.tsx

@@ -2,10 +2,10 @@
 
 import clsx from 'clsx';
 import { useRouter } from 'next/navigation';
-import {AirwallexCartNumberElementType} from "@/lib/Airwallex/airwallexInit";
+import type {AirwallexCartNumberElementType} from "@/lib/Airwallex/airwallexInit";
 import PaypalButton from "./PaymentButton/PaypalButton";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
-import { PlaceOrderFunction,KlarnaOtherData } from "@/types/checkout/type";
+import type { PlaceOrderFunction,KlarnaOtherData } from "@/types/checkout/type";
 import { useCustomToast } from "@/utils/hooks/useToast";
 import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";

+ 1 - 1
src/app/(checkout)/checkout/_components/CheckoutProducts/CheckoutProducts.tsx

@@ -3,7 +3,7 @@
 import {useState} from "react";
 import { useRouter } from 'next/navigation';
 import Image from "next/image";
-import {CartDetail, CartItem} from "@/types/cart/type";
+import type {CartDetail, CartItem} from "@/types/cart/type";
 import { useAddProduct } from "@utils/hooks/useAddToCart";
 import { useCustomToast } from "@/utils/hooks/useToast";
 import {useConfig} from "@/utils/hooks/useConfig";

+ 5 - 5
src/app/(checkout)/checkout/_components/CheckoutWrapper.tsx

@@ -11,19 +11,19 @@ import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
 import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import {usePaymentSDKContext} from "@/providers/PaymentSDKProvider";
 import {airwallexManager} from "@/lib/Airwallex/useAirwallexCard";
-import { 
+import type { 
     PlaceOrderResult,
     PlaceOrderFunction,
     CreatePaymentInitiateVariables
 } from "@/types/checkout/type";
-import { CartDetail,CartAddress } from "@/types/cart/type";
+import type { CartDetail,CartAddress } from "@/types/cart/type";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
-import {ShippingMethodCheckout,RefShippingMethodsHandle} from "./ShippingMethodCheckout";
-import {PaymentMethodCheckout,RefPaymentMethodsHandle} from "./PaymentMethodCheckout";
+import {ShippingMethodCheckout, type RefShippingMethodsHandle} from "./ShippingMethodCheckout";
+import {PaymentMethodCheckout,type RefPaymentMethodsHandle} from "./PaymentMethodCheckout";
 import LoadingPaymentMethod from "./LoadingPaymentMethod";
-import {CheckoutAddress, RefCheckoutAddressHandle} from "./CheckoutAddress/CheckoutAssress";
+import {CheckoutAddress, type RefCheckoutAddressHandle} from "./CheckoutAddress/CheckoutAssress";
 import LoadingCheckoutPlaceOrder from "./LoadingCheckoutPlaceOrder";
 import CheckoutPlaceOrder from "./CheckoutPlaceOrder";
 import PaypalApplepayButton from "./PaymentButton/PaypalApplepayButton";

+ 1 - 1
src/app/(checkout)/checkout/_components/ContinueToPay/ContinueToPayOrderInfo.tsx

@@ -4,7 +4,7 @@ import { useState } from "react";
 import Image from "next/image";
 import { useRouter } from 'next/navigation';
 import {useConfig} from "@/utils/hooks/useConfig";
-import { OrderDetails } from "@/types/customer/type";
+import type { OrderDetails } from "@/types/customer/type";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
 import ProductsModalPendingOrder from "./ProductsModalPendingOrder";
 import dynamic from "next/dynamic";

+ 3 - 3
src/app/(checkout)/checkout/_components/ContinueToPay/PaymentMethodContinueTpPay.tsx

@@ -12,9 +12,9 @@ import {
     useAirwallexCardState
 } from "@/lib/Airwallex/useAirwallexCard";
 import {getPaymentMethodLogo,getPaymentDescription} from "@/utils/paymentTools";
-import {RepayOrderPaymentMethodsData} from "@/types/checkout/type";
-import { OrderDetails } from "@/types/customer/type";
-import {FetchGraphqlResult} from "@/types/graphqlFetch/type";
+import type {RepayOrderPaymentMethodsData} from "@/types/checkout/type";
+import type { OrderDetails } from "@/types/customer/type";
+import type {FetchGraphqlResult} from "@/types/graphqlFetch/type";
 import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import PaypalButton from "../PaymentButton/PaypalButton";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";

+ 1 - 1
src/app/(checkout)/checkout/_components/ContinueToPay/ProductsModalPendingOrder.tsx

@@ -2,7 +2,7 @@
 
 import Image from "next/image";
 import CommonModal from "@/components/theme/ui/CommonModal";
-import {ProductsInOrderDetails, ProductItemAdditional} from "@/types/customer/type";
+import type {ProductsInOrderDetails, ProductItemAdditional} from "@/types/customer/type";
 
 
 // 根据products 计算总价和总个数

+ 2 - 2
src/app/(checkout)/checkout/_components/GiftCard/CheckoutGiftCardGate.tsx

@@ -2,13 +2,13 @@
 
 import {useState, useRef, useEffect, useCallback} from "react";
 import clsx from "clsx";
-import {CartDetail} from "@/types/cart/type";
+import type {CartDetail} from "@/types/cart/type";
 import {clientFetch} from "@/lib/restApiClient";
 import { useCustomToast } from "@/utils/hooks/useToast";
 import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
-import {GiftCardItem, GiftCardRespBody} from "@/types/api/gift/my-gift-cards";
+import type {GiftCardItem, GiftCardRespBody} from "@/types/api/gift/my-gift-cards";
 import CommonModal from "@/components/theme/ui/CommonModal";
 import { LoadingSpinner } from "@components/common/LoadingSpinner";
 

+ 1 - 1
src/app/(checkout)/checkout/_components/LostInsurance/LostInsurance.tsx

@@ -6,7 +6,7 @@ import { useCustomToast } from "@/utils/hooks/useToast";
 import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
-import {CartDetail} from "@/types/cart/type";
+import type {CartDetail} from "@/types/cart/type";
 
 /**
  * 先通过 shippingInsuranceEnabled 判断网站是否开通丢件险功能

+ 2 - 2
src/app/(checkout)/checkout/_components/PaymentButton/PaypalApplepayButton.tsx

@@ -14,9 +14,9 @@ import {
 } from "@paypal/react-paypal-js/sdk-v6";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
-import { CartAddress } from "@/types/cart/type";
+import type { CartAddress } from "@/types/cart/type";
 import { useConfig } from "@/utils/hooks/useConfig";
-import {ApplePayAddressContact} from "@/lib/Applepay/type";
+import type {ApplePayAddressContact} from "@/lib/Applepay/type";
 // import {getPaypalApplePayConfig, type PaypalApplePaySession} from "@/lib/Applepay/applepay";
 
 export default function PaypalApplepayButton({

+ 2 - 2
src/app/(checkout)/checkout/_components/PaymentMethodCheckout.tsx

@@ -1,11 +1,11 @@
 "use client";
 
 import Image from "next/image";
-import { Ref, useEffect, useImperativeHandle } from "react";
+import { type Ref, useEffect, useImperativeHandle } from "react";
 import { useForm, get } from "react-hook-form";
 import {useConfig} from "@/utils/hooks/useConfig";
 import {getPaymentMethodLogo,getPaymentDescription} from "@/utils/paymentTools";
-import { CheckoutPaymentMethod } from "@/types/checkout/type";
+import type { CheckoutPaymentMethod } from "@/types/checkout/type";
 import AirwallexCardInput from "./PaymentMethodAdditional/AirwallexCardInput";
 import {useAirwallexCardState} from "@/lib/Airwallex/useAirwallexCard";
 

+ 1 - 1
src/app/(checkout)/checkout/_components/PromotionsDetails.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import { CartDetail } from "@/types/cart/type";
+import type { CartDetail } from "@/types/cart/type";
 
 
 // 金额明细

+ 1 - 1
src/app/(checkout)/checkout/_components/RewardPointsRedeemMoney/RewardPointsRedeemMoney.tsx

@@ -8,7 +8,7 @@ import {useLoginModal} from "@/providers/LoginModalProvider";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
-import {CartDetail} from "@/types/cart/type";
+import type {CartDetail} from "@/types/cart/type";
 
 // earnableRewardPoints 判断是否开启下单送积分
 

+ 2 - 2
src/app/(checkout)/checkout/_components/ShippingMethodCheckout.tsx

@@ -1,10 +1,10 @@
 "use client";
 
 import clsx from "clsx";
-import { useEffect, useImperativeHandle, Ref  } from "react";
+import { useEffect, useImperativeHandle, type Ref  } from "react";
 import { useForm, get } from "react-hook-form";
 
-import {CheckoutShippingRate} from "@/types/checkout/type";
+import type {CheckoutShippingRate} from "@/types/checkout/type";
 import CheckoutShippingMethodLoading from "./CheckoutShippingMethodLoading";
 
 

+ 1 - 1
src/app/(checkout)/checkout/_components/VipPlus/CheckoutVipPlus.tsx

@@ -2,7 +2,7 @@
 
 import {useState} from "react";
 import { useRouter } from 'next/navigation';
-import {CartDetail} from "@/types/cart/type";
+import type {CartDetail} from "@/types/cart/type";
 import { useCustomToast } from "@/utils/hooks/useToast";
 import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
 import { formatCartDetail } from "@/utils/cartDetailTools";

+ 1 - 1
src/app/(checkout)/checkout/cart/_components/CartWrapper.tsx

@@ -11,7 +11,7 @@ import { useAddProduct } from "@utils/hooks/useAddToCart";
 import { updateCart, clearCart } from "@/store/slices/cart-slice";
 import {useConfig} from "@/utils/hooks/useConfig";
 import {useLoginModal} from "@/providers/LoginModalProvider";
-import { CartDetail, CartItem } from "@/types/cart/type";
+import type { CartDetail, CartItem } from "@/types/cart/type";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";

+ 1 - 1
src/app/(checkout)/checkout/cart/_components/UnpaidOrderSection.tsx

@@ -9,7 +9,7 @@ import { useCustomToast } from "@/utils/hooks/useToast";
 import {useConfig} from "@/utils/hooks/useConfig";
 import { confirmDialog } from "@/components/theme/ui/kernel/confirm/api";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
-import { OrderDetails, ProductsInOrderDetails } from "@/types/customer/type";
+import type { OrderDetails, ProductsInOrderDetails } from "@/types/customer/type";
 import CommonModal from "@/components/theme/ui/CommonModal";
 const CountDown = dynamic(() => import("@/components/common/CountDown"), {
   ssr: false,

+ 2 - 2
src/app/(checkout)/checkout/cart/page.tsx

@@ -2,8 +2,8 @@ import { createHash } from "crypto";
 import {serverGraphqlFetch} from "@utils/bagisto/index";
 import { GET_CART_ITEM, GET_CUSTOMER_ORDERS } from "@/graphql";
 import { auth } from "@/utils/auth/auth-helper";
-import { GetCartItemData } from "@/types/cart/type";
-import { OrderListData, OrderListDataVariables, OrderDetails } from "@/types/customer/type";
+import type { GetCartItemData } from "@/types/cart/type";
+import type { OrderListData, OrderListDataVariables, OrderDetails } from "@/types/customer/type";
 import TitleHeader from "@components/layout/navbar/TitleHeader";
 import { EmptyCart } from "./_components/EmptyCart";
 import { PromiseInCart } from "./_components/PromiseInCart";

+ 2 - 2
src/app/(checkout)/checkout/continuetopay/page.tsx

@@ -6,8 +6,8 @@ import {serverGraphqlFetch} from "@utils/bagisto/index";
 import ContinueToPayOrderInfo from "../_components/ContinueToPay/ContinueToPayOrderInfo";
 import { GET_ORDER_DETAILS, GET_REPAYORDER_PAYMENT_METHODS } from "@/graphql";
 // import { Country } from "@/types/checkout/type";
-import { OrderDetailsData } from "@/types/customer/type";
-import { RepayOrderPaymentMethodsData } from "@/types/checkout/type";
+import type { OrderDetailsData } from "@/types/customer/type";
+import type { RepayOrderPaymentMethodsData } from "@/types/checkout/type";
 import {PaymentMethodContinueTpPay} from "../_components/ContinueToPay/PaymentMethodContinueTpPay";
 import LoadingPaymentMethod from "../_components/LoadingPaymentMethod";
 import TitleHeader from "@components/layout/navbar/TitleHeader";

+ 1 - 1
src/app/(checkout)/checkout/page.tsx

@@ -4,7 +4,7 @@ import {serverGraphqlFetch} from "@utils/bagisto/index";
 import CheckoutWrapper from "./_components/CheckoutWrapper";
 import { GET_CART_ITEM } from "@/graphql";
 import { auth } from "@/utils/auth/auth-helper";
-import { GetCartItemData } from "@/types/cart/type";
+import type { GetCartItemData } from "@/types/cart/type";
 import TitleHeader from "@components/layout/navbar/TitleHeader";
 
 /**

+ 1 - 1
src/app/(checkout)/layout.tsx

@@ -1,5 +1,5 @@
 
-import { ReactNode } from "react";
+import { type ReactNode } from "react";
 export default async function CheckoutLayout({
   children,
 }: {

+ 0 - 10
src/app/(public)/[page]/opengraph-image.tsx

@@ -1,10 +0,0 @@
-import OpenGraphImage from "@components/common/OpenGraphImage";
-import { getPage } from "@utils/bagisto";
-
-export default async function Image({ params }: { params: { page: string } }) {
-  const page = await getPage({ urlKey: params.page }) as { translation?: { metaTitle?: string; pageTitle?: string } }[];
-  const pageData = page && page.length > 0 ? page[0].translation : undefined;
-  const title = pageData?.metaTitle || pageData?.pageTitle;
-
-  return await OpenGraphImage({ title });
-}

+ 1 - 1
src/app/(public)/[page]/page.tsx

@@ -1,7 +1,7 @@
 import { notFound } from "next/navigation";
 import Prose from "@components/theme/search/Prose";
 import { getPage } from "@utils/bagisto";
-import { PageData } from "@/types/theme/theme-customization";
+import type { PageData } from "@/types/theme/theme-customization";
 
 
 export default async function Page({

+ 1 - 1
src/app/(public)/_components/CategoryTabSwiper .tsx

@@ -1,5 +1,5 @@
 "use client";
-import React from "react";
+
 import Link from "next/link";
 import { Swiper, SwiperSlide } from "swiper/react";
 import { FreeMode } from "swiper/modules";

+ 2 - 2
src/app/(public)/_components/HomeBestSellers.tsx

@@ -1,11 +1,11 @@
-import React from "react";
+
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Navigation, Pagination } from "swiper/modules";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
 // 导入Swiper基础样式
 import "swiper/css";
 import "swiper/css/navigation";
-import { HomeProduct } from "@/types/home/type";
+import type { HomeProduct } from "@/types/home/type";
 import Link from "next/link";
 interface HomeBestSellersProps {
   bestSellers: HomeProduct[];

+ 5 - 3
src/app/(public)/_components/HomeContent.tsx

@@ -12,7 +12,8 @@ import RecommendedProducts from "./RecommendedProducts";
 import CategoryTabSwiper  from "./CategoryTabSwiper ";
 import "swiper/css";
 import "swiper/css/navigation";
-import {HomeApiData,HomeProduct } from "@/types/home/type"
+import type {HomeApiData,HomeProduct } from "@/types/home/type"
+import {CustomerService} from "@/components/common/CustomerService/CustomerService";
 // 定义组件入参类型
 interface HomeContentProps {
   homeData: HomeApiData;
@@ -125,7 +126,7 @@ export default function HomeContent({ homeData }: HomeContentProps) {
    // 4. Recommended
   const recommendedSection = sections.find(sec => sec.name === "Recommended_For_You");
   const recommended: HomeProduct[] = recommendedSection?.products ?? [];
-  return (
+  return (<>
     <div className="min-h-screen bg-white font-sans">
       {/* 顶部Banner */}
       <div className="w-full relative">
@@ -152,5 +153,6 @@ export default function HomeContent({ homeData }: HomeContentProps) {
       <RecommendedProducts recommended={recommended} />
       <CategoryTabSwiper />
     </div>
-  );
+    <CustomerService />
+  </>);
 }

+ 1 - 1
src/app/(public)/_components/HomeMiddleBanner.tsx

@@ -5,7 +5,7 @@ import { Navigation } from "swiper/modules";
 import "swiper/css";
 import "swiper/css/navigation";
 import Image from "next/image";
-import { HomeSectionImage } from "@/types/home/type";
+import type { HomeSectionImage } from "@/types/home/type";
 interface middleBannerProps {
   middleBanner: HomeSectionImage[];
 }

+ 2 - 2
src/app/(public)/_components/HomeNewArrival.tsx

@@ -1,11 +1,11 @@
-import React from "react";
+
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Navigation, Pagination } from "swiper/modules";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
 // 导入Swiper基础样式
 import "swiper/css";
 import "swiper/css/navigation";
-import {HomeProduct} from "@/types/home/type"
+import type {HomeProduct} from "@/types/home/type"
 interface NewArrivalProps {
   newArrival: HomeProduct[];
 }

+ 1 - 1
src/app/(public)/_components/JinGangSwiper.tsx

@@ -6,7 +6,7 @@ import { Navigation } from "swiper/modules";
 import "swiper/css";
 import "swiper/css/navigation";
 import Image from "next/image";
-import { HomeSectionImage } from "@/types/home/type";
+import type { HomeSectionImage } from "@/types/home/type";
 interface jinGangProps {
   jinGang: HomeSectionImage[];
 }

+ 2 - 2
src/app/(public)/_components/MiddleImageSwiper.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+
 import { Swiper, SwiperSlide } from "swiper/react";
 import {  Pagination  } from "swiper/modules";
 import "swiper/css";
@@ -6,7 +6,7 @@ import "swiper/css/pagination";
 import "swiper/css/navigation";
 import "./css/swiper-custom.css";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
-import {HomeProduct,HomeSectionImage} from "@/types/home/type"
+import type {HomeProduct,HomeSectionImage} from "@/types/home/type"
 interface zeroWearProps {
   zeroWear: HomeProduct[];
   zeroWearImage:HomeSectionImage[]

+ 2 - 2
src/app/(public)/_components/RecommendedProducts.tsx

@@ -1,8 +1,8 @@
 "use client";
-import React, { useState, useEffect, useCallback } from "react";
+import { useState, useEffect, useCallback } from "react";
 import Image from "next/image";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
-import {HomeProduct} from "@/types/home/type"
+import type {HomeProduct} from "@/types/home/type"
 interface recommendedProps {
   recommended: HomeProduct[];
 }

+ 1 - 1
src/app/(public)/_components/TopImageSwiper.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+
 import { Swiper, SwiperSlide } from 'swiper/react';
 import 'swiper/css';
 // import { Navigation, Pagination, Mousewheel, Keyboard } from 'swiper/modules';

+ 2 - 2
src/app/(public)/_components/Trending.tsx

@@ -1,4 +1,4 @@
-import React, { useState, useRef, useEffect } from "react";
+import { useState, useRef, useEffect } from "react";
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Scrollbar, Navigation } from "swiper/modules";
 import "swiper/css";
@@ -6,7 +6,7 @@ import "swiper/css/scrollbar";
 import "swiper/css/navigation";
 import Image from "next/image";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
-import {HomeProduct} from "@/types/home/type"
+import type {HomeProduct} from "@/types/home/type"
 interface trendingProps {
   trending: HomeProduct[];
 }

+ 1 - 1
src/app/(public)/category/[slug]/[id]/_components/CategoryDesc.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import { FC, useState, useEffect, useRef } from "react";
+import { type FC, useState, useEffect, useRef } from "react";
 
 interface CategoryDescProps {
   title: string;

+ 123 - 64
src/app/(public)/category/[slug]/[id]/_components/ProductListing.tsx

@@ -7,26 +7,31 @@ import ProductGridItems from "@components/catalog/product/ProductGridItems";
 import NewMobileFilter from "@components/theme/filters/NewMobileFilter";
 import NewSortOrder from "@components/theme/filters/NewSortOrder";
 
-import { SortByFields } from "@utils/constants";
+import { newSortByFields } from "@utils/constants";
 import { isArray } from "@/utils/type-guards";
 import { useRouter, usePathname } from "next/navigation";
+import {  useApolloClient } from "@apollo/client/react";
+import type{ CategoryProductsResult,PageInfo,CategoryProductNode,CategoryAttrFilterItem } from "@components/catalog/type";
+import {CATEGORY_PRODUCTS} from "@/graphql";
 interface QueryState {
-  search: string;
-
-  sort: string;
+  // search: string;
 
+  sortValue: string;
+  sortKey: string;
   filters: Record<string, string>;
 
   cursor?: string;
+  reverse?:boolean,
 }
 interface ProductListingProps {
+  slug:string;
   categoryId: string;
 
-  filterAttributes: any[];
+  filterAttributes:Array<{ node: CategoryAttrFilterItem }>;
 
-  initialProducts: any[];
+  initialProducts: CategoryProductNode[];
 
-  initialPageInfo: any;
+  initialPageInfo: PageInfo;
 
   initialTotal: number;
 
@@ -34,6 +39,7 @@ interface ProductListingProps {
 }
 
 export default function ProductListing({
+  slug,
   categoryId,
   filterAttributes,
   initialProducts,
@@ -44,6 +50,9 @@ export default function ProductListing({
   // 新增:页面刷新初始化源头打印
   console.log("【页面刷新初始initialQuery】", initialQuery);
   console.log("【刷新初始filters(传给筛选器的源头)】", initialQuery.filters);
+  const CategoryId =categoryId;
+  console.log(CategoryId);
+  
   const [query, setQuery] = useState(initialQuery);
 
   const [products, setProducts] = useState(initialProducts);
@@ -52,38 +61,63 @@ export default function ProductListing({
 
   const [_total, setTotal] = useState(initialTotal);
   const firstRender = useRef(true);
+  const apolloClient = useApolloClient();
+
   const fetchProducts = async (currentQuery: QueryState) => {
     try {
-      const res = await fetch("/api/products", {
-        method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-        },
-        body: JSON.stringify({
-          categoryId,
-
-          search: currentQuery.search,
-
-          sort: currentQuery.sort,
-
-          filters: currentQuery.filters,
-
-          first: 12,
+      const res = await apolloClient.query<CategoryProductsResult>({
+        query: CATEGORY_PRODUCTS,
+        variables: 
+        // {
+        
+        //   filter: JSON.stringify({
+        //   }),
+        //   first: 15,
+        //   after: null,
+        // }
+        {
+          slug: slug ||"ready-to-go-wig",
+        
+          sortKey: currentQuery.sortKey,
+          reverse: currentQuery.reverse,
+          filter:JSON.stringify( currentQuery.filters),
+
+          first: 15,
 
           after: null,
-        }),
+        },
       });
+      console.log("res----------------------------------:",res,currentQuery);
+      
+      // const res = await fetch("/api/products", {
+      //   method: "POST",
+      //   headers: {
+      //     "Content-Type": "application/json",
+      //   },
+      //   body: JSON.stringify({
+      //     categoryId,
+
+      //     sort: currentQuery.sort,
+
+      //     filters: currentQuery.filters,
+
+      //     first: 12,
+
+      //     after: null,
+      //   }),
+      // });
+      //  search: currentQuery.search,
       console.log("筛选排序触发调接口");
-      const result = await res.json();
+      // const result = await res.json();
 
       const newProducts =
-        result.data?.products?.edges?.map((e: any) => e.node) || [];
+        res.data?.categoryProducts?.products.map((e: any) => e.node) || [];
 
       setProducts(newProducts);
-
-      setPageInfo(result.data?.products?.pageInfo);
-
-      setTotal(result.data?.products?.totalCount || 0);
+      if(res.data?.categoryProducts?.pageInfo){
+      setPageInfo(res.data.categoryProducts.pageInfo);
+      }
+      setTotal(res.data?.categoryProducts?.totalCount || 0);
     } catch (error) {
       console.error("fetch products error", error);
     }
@@ -95,9 +129,11 @@ export default function ProductListing({
 
       return;
     }
+    console.log("query-----------------------------22222:",query);
     fetchProducts(query);
-  }, [query.filters, query.sort, query.search]);
-
+    
+  }, [query.filters, query.sortValue]);
+  //query.search
   const router = useRouter();
   const pathname = usePathname();
   console.log("query-----:", query);
@@ -110,8 +146,8 @@ export default function ProductListing({
       params.set("q", nextQuery.search);
     }
 
-    if (nextQuery.sort) {
-      params.set("sort", nextQuery.sort);
+    if (nextQuery.sortValue) {
+      params.set("sort", nextQuery.sortValue);
     }
 
     Object.entries(nextQuery.filters).forEach(([key, value]) => {
@@ -126,36 +162,59 @@ export default function ProductListing({
   };
   //   view more 逻辑
   const loadMore = async () => {
-    const res = await fetch("/api/products", {
-      method: "POST",
-
-      headers: {
-        "Content-Type": "application/json",
-      },
-
-      body: JSON.stringify({
-        categoryId,
-
-        search: query.search,
-
-        sort: query.sort,
-
-        filters: query.filters,
-
-        first: 15,
-
-        after: pageInfo.endCursor,
-      }),
-    });
+    // const res = await fetch("/api/products", {
+    //   method: "POST",
+
+    //   headers: {
+    //     "Content-Type": "application/json",
+    //   },
+
+    //   body: JSON.stringify({
+    //     categoryId,
+    //     sort: query.sort,
+
+    //     filters: query.filters,
+
+    //     first: 15,
+
+    //     after: pageInfo.endCursor,
+    //   }),
+    // });
+     const res = await apolloClient.query<CategoryProductsResult>({
+        query: CATEGORY_PRODUCTS,
+        variables: 
+        // {
+        
+        //   filter: JSON.stringify({
+        //   }),
+        //   first: 15,
+        //   after: null,
+        // }
+        {
+          slug: slug ||"ready-to-go-wig",
+        
+          // sort: query.sort,
+          sortKey: query.sortKey,
+          reverse: query.reverse,
+          filter:JSON.stringify(query.filters),
+
+          first: 15,
+
+          after: pageInfo.endCursor,
+        },
+      });
+    //search: query.search,
     console.log("触发view more调接口");
-    const result = await res.json();
+    console.log("res----------------------------------:",res,query);
+    // const result = await res.json();
 
     const moreProducts =
-      result.data?.products?.edges?.map((e: any) => e.node) || [];
+       res.data?.categoryProducts?.products.map((e: any) => e.node) || [];
 
     setProducts((prev) => [...prev, ...moreProducts]);
-
-    setPageInfo(result.data.products.pageInfo);
+     if(res.data?.categoryProducts?.pageInfo){
+      setPageInfo(res.data?.categoryProducts?.pageInfo);
+      }
   };
   return (
     <>
@@ -174,15 +233,15 @@ export default function ProductListing({
           }}
         />
         <NewSortOrder
-          sortOrders={SortByFields}
+          sortOrders={newSortByFields}
           title="Sort by"
-          value={query.sort}
-          onChange={(sort) => {
+          value={query.sortValue}
+          onChange={(sortValue,sortKey,reverse) => {
             updateQuery({
               ...query,
-
-              sort,
-
+              sortValue,
+              sortKey,
+              reverse:reverse,
               cursor: undefined,
             });
           }}

+ 99 - 42
src/app/(public)/category/[slug]/[id]/page.tsx

@@ -1,24 +1,30 @@
-import { Metadata } from "next";
+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 ProductListing from "./_components/ProductListing";
-import { ProductsResponse } from "@components/catalog/type";
+import type{
+  // ProductsResponse,
+  GetCategoryAttrFiltersResult,
+  CategoryProductsResult,
+} from "@components/catalog/type";
 import {
-  GET_FILTER_PRODUCTS,
+  // GET_FILTER_PRODUCTS,
   // GET_TREE_CATEGORIES,
   GET_CATEHORY_BY_ID,
+  GET_CATEGORY_ATTR_FILTERS,
+  CATEGORY_PRODUCTS,
 } from "@/graphql";
 import {
   // cachedGraphQLRequest,
   // cachedCategoryRequest,
-  getFilterAttributes,
+  // getFilterAttributes,
 } from "@/utils/hooks/useCache";
-import { SortByFields } from "@utils/constants";
+import { newSortByFields } from "@utils/constants";
 // import { CategoryDetail } from "@components/theme/search/CategoryDetail";
 import CategoryDesc from "./_components/CategoryDesc";
-import FaqList, { FaqItem } from "./_components/FaqList";
+import FaqList, { type FaqItem } from "./_components/FaqList";
 import { Suspense } from "react";
 import FilterListSkeleton from "@components/common/skeleton/FilterSkeleton";
 // import { TreeCategoriesResponse } from "@/types/theme/category-tree";
@@ -26,10 +32,10 @@ import FilterListSkeleton from "@components/common/skeleton/FilterSkeleton";
 import {
   // extractNumericId,
   // findCategoryBySlug,
-  buildProductFilters,
+  newBuildProductFilters,
 } from "@utils/helper";
 import { serverGraphqlFetch } from "@/utils/bagisto/index";
-import {
+import type {
   // CategoryNode,
   CategorySingleResponse,
 } from "@/types/theme/category-tree";
@@ -98,9 +104,29 @@ export default async function CategoryPage({
   const categories = treeData?.treeCategories || [];
   const categoryItem = findCategoryBySlug(categories, categorySlug);
   */
-  const filterAttributes = await getFilterAttributes(); // 这个不能用
+  //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,
+    },
+  });
 
-  console.log("filterAttributes---------------:", filterAttributes);
+  // 错误判断
+  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 }
@@ -125,20 +151,20 @@ export default async function CategoryPage({
   // } = (resolvedParams || {}) as {
   //   [key: string]: string;
   // };
-  const searchValue = getSearchParam(resolvedParams?.q) ?? "";
+  const searchValue = resolvedParams?.q ?? "";
 
   // const page = getSearchParam(resolvedParams?.page);
 
   const cursor = getSearchParam(resolvedParams?.cursor);
 
   const before = getSearchParam(resolvedParams?.before);
-  const itemsPerPage = 12;
+  const itemsPerPage = 15;
   // const currentPage = page ? parseInt(page) - 1 : 0;
   const sortValue = getSearchParam(resolvedParams?.sort) ?? "name-asc";
   const selectedSort =
-    SortByFields.find((s) => s.key === sortValue) || SortByFields[0];
+    newSortByFields.find((s) => s.key === sortValue) || newSortByFields[0];
 
-  const { filterObject: baseFilterObject } = buildProductFilters(
+  const { filterObject: baseFilterObject } = newBuildProductFilters(
     resolvedParams || {},
   );
 
@@ -151,30 +177,54 @@ export default async function CategoryPage({
   }
 
   const filterInput = JSON.stringify(filterObject);
-
-  // 这个也改成 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
+  // 默认获取产品数据接口:
+  const { data: categoryProductDatas } = await serverGraphqlFetch<
+    CategoryProductsResult,
+    any
   >({
-    query: GET_FILTER_PRODUCTS,
-    variables: productVariables,
+    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 || "",
@@ -196,13 +246,15 @@ export default async function CategoryPage({
     selectedSort,
   );
 
-  const products = data?.products?.edges?.map((e) => e.node) || [];
-  const pageInfo = data?.products?.pageInfo;
-  const totalCount = data?.products?.totalCount || 0;
+  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假数据
@@ -267,13 +319,18 @@ export default async function CategoryPage({
         </div> */}
         <ProductListing
           categoryId={numericId}
-          filterAttributes={filterAttributes}
+          slug={_categorySlug} 
+          filterAttributes={
+          filterAttributesRes.data?  filterAttributesRes.data.categoryAttributeFilters.edges:[]
+          }
           initialProducts={products}
           initialPageInfo={pageInfo}
           initialTotal={totalCount}
           initialQuery={{
-            search: searchValue,
-            sort: sortValue,
+            // search: searchValue,
+            sortValue: sortValue,
+            sortKey: selectedSort.sortKey,
+            reverse: selectedSort.reverse,
             filters: baseFilterObject,
             cursor,
           }}

File diff suppressed because it is too large
+ 127 - 41
src/app/(public)/customer/account/_components/AccountHeader.tsx


+ 12 - 12
src/app/(public)/customer/account/_components/HelpModal.tsx

@@ -14,12 +14,12 @@ export default function HelpModal({
       <div className="absolute bottom-0 rounded-none left-0 right-0 w-full h-full bg-white  overflow-auto">
         <div className="flex flex-col">
           {/* 顶部导航 */}
-          <header className="bg-black text-white py-4 px-4 flex items-center">
+          <header className=" text-black py-4 px-4 flex items-center border-b border-[#F9F9F9FF]">
             <button onClick={helponClose} className="mr-4">
               <svg
                 xmlns="http://www.w3.org/2000/svg"
                 className="h-6 w-6"
-                fill="none"
+                fill="#000"
                 viewBox="0 0 24 24"
                 stroke="currentColor"
               >
@@ -27,20 +27,23 @@ export default function HelpModal({
                   strokeLinecap="round"
                   strokeLinejoin="round"
                   strokeWidth={2}
+                  fill="none"
                   d="M15 19l-7-7 7-7"
                 />
               </svg>
             </button>
-            <h1 className="text-lg font-medium">HELP & SUPPORT</h1>
+            <h1 className="text-lg w-full text-center  font-normal">
+              Help & Support
+            </h1>
           </header>
           {/* 菜单列表 */}
           <div className="px-4 py-2">
             {/* Information */}
+
             <Link
               href={"/help-faqs"}
-              className="py-4 border-b border-gray-100 flex justify-between items-center"
+              className="py-4 border-b border-gray-100 flex justify-between items-center bg-[#F9F9F9FF] mb-4  px-3"
             >
-              {/* <div > */}
               <span className="text-black font-medium">Help & FAQ</span>
               <svg
                 xmlns="http://www.w3.org/2000/svg"
@@ -56,14 +59,13 @@ export default function HelpModal({
                   d="M9 5l7 7-7 7"
                 />
               </svg>
-              {/* </div> */}
             </Link>
             {/* Address */}
+
             <Link
               href={"/track_order"}
-              className="py-4 border-b border-gray-100 flex justify-between items-center"
+              className="py-4 border-b border-gray-100 flex justify-between items-center bg-[#F9F9F9FF] mb-4  px-3"
             >
-              {/* <div > */}
               <span className="text-black font-medium">Track Order</span>
               <svg
                 xmlns="http://www.w3.org/2000/svg"
@@ -79,14 +81,13 @@ export default function HelpModal({
                   d="M9 5l7 7-7 7"
                 />
               </svg>
-              {/* </div> */}
             </Link>
             {/* help & Support */}
+
             <Link
               href={"/hair-care-tips"}
-              className="py-4 border-b border-gray-100 flex justify-between items-center"
+              className="py-4 border-b border-gray-100 flex justify-between items-center bg-[#F9F9F9FF] mb-4  px-3"
             >
-              {/* <div > */}
               <span className="text-black font-medium">Hair Care Tips</span>
               <svg
                 xmlns="http://www.w3.org/2000/svg"
@@ -102,7 +103,6 @@ export default function HelpModal({
                   d="M9 5l7 7-7 7"
                 />
               </svg>
-              {/* </div> */}
             </Link>
           </div>
         </div>

+ 219 - 88
src/app/(public)/customer/account/edit/page.tsx

@@ -5,50 +5,129 @@ import { useEffect } from "react";
 import {
   parseDate,
   CalendarDate,
-  DateValue
+  type DateValue
 } from "@internationalized/date";
 import Link from "next/link";
 import { DatePicker } from "@heroui/date-picker";
+import CustomerAddressPhone from "../../address/new/_components/CustomerAddressPhone";
+import { useForm, FormProvider,Controller } from "react-hook-form";
+import { useMutation, useApolloClient } from "@apollo/client/react";
+import type{ CustomerProfileResult } from "@/types/customer/information/information";
+import {GET_CUSTOMER_PROFILE,UPDATE_CUSTOMER_PROFILE} from "@/graphql";
+import type{ UpdateCustomerProfileVars } from "@/types/customer/information/information";
+import { useCustomToast } from "@/utils/hooks/useToast";
 const AccountEditPage = () => {
   interface UserForm {
-  firstname: string;
-  lastname: string;
-  date: CalendarDate  | string;
-  email: string;
-  current_password: string;
-  password: string;
-}
-  // 统一表单对象
-  const [form, setForm] = useState<UserForm>({
-    firstname: "",
-    lastname: "",
-    date: parseDate("2026-05-12"),
-    email: "",
-    current_password: "",
-    password: "",
+    firstname: string;
+    lastname: string;
+    date: CalendarDate | string |null;
+    email: string;
+    current_password: string;
+    password: string;
+    phone: string;
+  }
+
+  const { showToast } = useCustomToast();
+  const addressForm = useForm<UserForm>({
+    mode: "onBlur",
+    reValidateMode: "onChange",
+    defaultValues: {
+      firstname: "",
+      lastname: "",
+      date: parseDate("2026-05-12"),
+      email: "",
+      current_password: "",
+      password: "",
+      phone: "",
+    },
   });
+  const [hasBirthDate, setHasBirthDate] = useState(false);
+  const { reset,setValue } = addressForm;
+  const apolloClient = useApolloClient();
+  const fetchProducts = async () => {
+      try {
+        const res = await apolloClient.query<CustomerProfileResult>({
+          query: GET_CUSTOMER_PROFILE,
+        });
+       // 空值判断
+    if (!res.data) {
+      console.warn("没有返回用户数据");
+      return;
+    }
+
+    const profile = res.data.readCustomerProfile;
+    return profile;
+      //接口数据映射到表单,reset回填
+      reset({
+        firstname: profile.firstName,
+        lastname: profile.lastName,
+        email: profile.email,
+        phone: profile.phone,
+        date: profile.dateOfBirth||null,
+        current_password: "",
+        password: "",
+      });
+       if(profile.dateOfBirth){
+         setHasBirthDate(true);
+       }else{
+         setHasBirthDate(false);
+       }
+      } catch (error) {
+        console.error("fetch products error", error);
+      }
+    };
+ useEffect(() => {
+  let mounted = true;
+
+  const loadProducts = async () => {
+    const profile = await fetchProducts();
+    // 组件已经卸载,直接放弃执行状态更新
+    if (!mounted) return;
+
+    reset({
+      firstname: profile?.firstName,
+      lastname: profile?.lastName,
+      email: profile?.email,
+      phone: profile?.phone,
+      date: profile?.dateOfBirth || null,
+      current_password: "",
+      password: "",
+    });
+
+    setHasBirthDate(!!profile?.dateOfBirth);
+  };
 
-  // 统一处理所有input变化
-  const handleChange = (e:any) => {
-    const { name, value } = e.target;
-    setForm((prev) => ({
-      ...prev,
-      [name]: value,
-    }));
+  loadProducts();
+
+  return () => {
+    mounted = false;
   };
+}, []);
+  const [updateProfileMutate] = useMutation(UPDATE_CUSTOMER_PROFILE, {
+  onCompleted: (res) => {
+    console.log("更新结果", res);
+    const result = res.createCustomerProfileUpdate.customerProfileUpdate;
+    if (result.success) {
+      // 更新成功后的逻辑,提示、刷新表单等
+      showToast(result.message, "success");
+    }
+  },
+  onError: (err) => {
+    console.error("更新用户资料失败:", err);
+     showToast(err.message, "danger");
+  },
+});
+ 
   // 1. 定义状态:控制修改密码显示隐藏
   const [showContent, setShowContent] = useState(false);
   //   日期选择方法
-  const handleDateChange = (dateValue: DateValue  | null) => {
+  const handleDateChange = (dateValue: DateValue | null) => {
     if (!dateValue) return;
 
     // 把 CalendarDate 转成 标准字符串:YYYY-MM-DD
     const formattedDate = `${dateValue.year}-${String(dateValue.month).padStart(2, "0")}-${String(dateValue.day).padStart(2, "0")}`;
-
-    setForm((prev) => ({
-      ...prev,
-      date: formattedDate, // 现在是正常字符串了
-    }));
+    return formattedDate
+ 
   };
   // 勾选框改变时:隐藏时 → 清空密码
   const handleCheckChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -57,88 +136,135 @@ const AccountEditPage = () => {
 
     // ✅ 关键:不勾选时清空密码字段
     if (!isChecked) {
-      setForm((prev) => ({
-        ...prev,
-        current_password: "",
-        password: "",
-      }));
+     setValue("current_password", "");
+    setValue("password", "");
     }
   };
-  // 统一提交
-  const handleSubmit = (e:any) => {
-    e.preventDefault();
-    // 直接拿form所有数据
-    console.log("表单数据:", form);
-  };
-  useEffect(() => {
-    // console.log("form 已更新 →", form);
-  }, [form]);
+ 
+  
+    // 表单提交
+    const addressFormOnSubmit = async (formData: UserForm) => {
+      console.log("最终提交给后端的数据:", formData);
+      const inputPayload: UpdateCustomerProfileVars["input"] = {
+        firstName: formData.firstname,
+        lastName: formData.lastname,
+        email: formData.email,
+        phone: formData.phone || null,
+        dateOfBirth: formData.date || null,
+      };
+      // 勾选修改密码时附加密码字段
+      if (showContent) {
+        inputPayload.current_password = formData.current_password;
+        inputPayload.password = formData.password;
+      }
+      await updateProfileMutate({
+        variables: {
+        input: inputPayload,
+        },
+      });
+   
+    };
+ 
+   const {
+    register,
+    handleSubmit,
+    control,
+    formState: {  },
+  } = addressForm;
   return (
     <div className="w-full h-full">
-      <form className="overflow-hidden" onSubmit={handleSubmit}>
-        <div className="bg-[#fff] pr-2.5 pl-2.5 w-full text-center text-base h-11 leading-11 font-semibold relative text-[#0b0b0b]">
-           <Link
-              className="absolute left-2.5 text-2xl inline-block top-1/2  -translate-y-1/2"
-              href="/customer/account"
-              aria-label="Go to customer account page"
-            >
+      <FormProvider {...addressForm}>
+      <form className="overflow-hidden"  onSubmit={handleSubmit(addressFormOnSubmit)} >
+        <div className=" text-black py-4 px-4 flex items-center border-b border-[#F9F9F9FF]">
+          <Link
+            className="mr-4"
+            href="/customer/account"
+            aria-label="Go to customer account page"
+          >
             <svg
               xmlns="http://www.w3.org/2000/svg"
-              width="24"
-              height="24"
+              className="h-6 w-6"
+              fill="#000"
               viewBox="0 0 24 24"
-              fill="none"
+              stroke="currentColor"
             >
               <path
-                stroke="rgba(0, 0, 0, 1)"
-                stroke-width="1.2"
-                stroke-linejoin="round"
-                stroke-linecap="round"
-                d="M15 18L9 12L15 6"
-              ></path>
+                strokeLinecap="round"
+                strokeLinejoin="round"
+                strokeWidth={2}
+                fill="none"
+                d="M15 19l-7-7 7-7"
+              />
             </svg>
           </Link>
-          <span className="vipReturnTitles">Account Information</span>
+          <h1 className="text-lg w-full text-center  font-normal">
+            Information
+          </h1>
         </div>
         <input name="form_key" type="hidden" value="kW7wucXHATeeem75"></input>
-        <div className="bg-[#f8f8f8] p-[20px_10px]">
-          <div className="text-start">*Name</div>
+        <div className=" p-[20px_10px]">
+          <div className="text-start mb-3">*Name</div>
           <div className="flex justify-between items-center">
             <input
-              name="firstname" // 必须和state字段对应
-              value={form.firstname}
-              onChange={handleChange}
+              // name="firstname" // 必须和state字段对应
+             
+              {...register("firstname", {
+                  required: "First name is required",
+                })}
               placeholder="firstname"
-              className="w-43 h-11 rounded-sm border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal"
+              className="w-43 h-11 rounded-lg border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal"
             />
             <input
-              name="lastname" // 必须和state字段对应
-              value={form.lastname}
-              onChange={handleChange}
+              // name="lastname" // 必须和state字段对应
+              
+                {...register("lastname", {
+                  required: "Last name is required",
+                })}
               placeholder="lastname"
-              className="w-43 h-11 rounded-sm border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
+              className="w-43 h-11 rounded-lg border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
             />
           </div>
           <div className="mt-7.5">
+            <Controller
+        name="date"
+        control={control}
+        rules={{
+          required: "date name is required",
+        }}
+      
+        render={({ field: { onChange } }) => (
             <DatePicker
               size="md"
-              onChange={handleDateChange}
+              label="Date Of Birth"
+              isRequired={hasBirthDate}
+              onChange={(dateValue) => {
+              // HeroUI DatePicker 返回 CalendarDate 对象,转成字符串 yyyy‑MM‑dd
+              onChange(handleDateChange(dateValue) );
+                
+           
+            }}
               radius="sm"
-              className="bg-[#fff]"
+              className="bg-white"
+              description={"This cannot be modified. Please fill in carefully."}
               labelPlacement={"outside"}
-              showMonthAndYearPickers
+              showMonthAndYearPickers={false}
               aria-label="date picker"
             />
+              )}
+      />
             {/* label={"Date of Birth"} */}
           </div>
+          <CustomerAddressPhone />
           <div className="mt-7.5">
-            <label htmlFor="email">Email Address*</label>
+            <label >Email Address*</label>
             <input
-              name="email" // 必须和state字段对应
-              value={form.email}
-              onChange={handleChange}
+              // name="email" // 必须和state字段对应
+            
+               {...register("email", {
+                  required: "email name is required",
+                })}
               placeholder="email"
-              className="w-full h-11 rounded-sm border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
+              className="w-full mt-3 h-11 rounded-lg border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
             />
           </div>
           {/* 选择框(开关)*/}
@@ -155,30 +281,35 @@ const AccountEditPage = () => {
             <div>
               <input
                 type="password"
-                name="current_password" // name对应key
-                value={form.current_password}
-                onChange={handleChange}
+                // name="current_password" // name对应key
+              
+                 {...register("current_password", {
+                  required: "Password is required",
+                })}
                 placeholder="Old password"
-                className="mt-7.5 w-full h-11 rounded-sm border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
+                className="mt-7.5 w-full h-11 rounded-lg border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
               />
               <input
                 type="password"
-                name="password" // name对应key
-                value={form.password}
-                onChange={handleChange}
+                // name="password" // name对应key
+             
+                  {...register("password", {
+                  required: "Password is required",
+                })}
                 placeholder="* New Password"
-                className=" mt-7.5 w-full h-11 rounded-sm border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
+                className=" mt-7.5 w-full h-11 rounded-lg border border-solid border-[rgba(102,102,102,1)] indent-4 text-[#a6a6a6] text-base leading-11 font-normal box-[unset]"
               />
             </div>
           )}
           <button
-            className="w-full h-11 leading-11 bg-[#1bbc9b] text-sm font-normal text-center mt-7.5"
+            className="w-full h-12 leading-12  rounded-[26px] bg-[rgba(3,97,65,1)] text-base text-white font-bold text-center mt-7.5"
             type="submit"
           >
-            Save Changes
+            Save
           </button>
         </div>
       </form>
+      </FormProvider>
     </div>
   );
 };

+ 33 - 21
src/app/(public)/customer/account/mycoupon/_components/GiftCardList.tsx

@@ -75,31 +75,43 @@ const GiftCardList: React.FC = () => {
   return (
     <div
       ref={containerRef}
-      className="h-[calc(100vh-80px)] overflow-auto px-2 py-4"
+      className="h-[calc(100vh-80px)] overflow-auto px-4 py-4"
     >
       {/* 礼品卡列表 */}
       <div className="space-y-4">
-        {giftCards.map((item,index) => (
-          <div
-            key={index}
-            className="flex items-center bg-blue-100 rounded-lg overflow-hidden"
-          >
-            {/* 礼品卡信息区 */}
-            <div className="flex-1 p-4 text-blue-600">
-              <h3 className="text-2xl font-bold">${Number(item.giftcard_amount)} OFF</h3>
-              <p className="text-sm mt-1">
-                For All Products
-              </p>
-              <p className="text-xs mt-2 text-blue-500">{item.expirationdate}</p>
-            </div>
-            {/* 分割线 */}
-            <div className="w-0.5 bg-blue-300 h-16 relative">
-              <div className="absolute top-0 left-[-4px] w-2 h-2 bg-white border border-blue-300 rounded-full"></div>
-              <div className="absolute bottom-0 left-[-4px] w-2 h-2 bg-white border border-blue-300 rounded-full"></div>
+        {giftCards.map((item) => (
+          <>
+            <div
+              key={item.id}
+              className="rounded-md p-4 pt-2 h-33.5 flex items-center justify-between text-white bg-[url('/image/account/202609021400.png')] bg-no-repeat bg-size-[100%_100%]"
+            >
+              {/* 左侧折扣+积分信息 */}
+              <div className="flex flex-col h-full py-2 justify-between">
+                    <span className="text-sm font-normal">Expire In {item.expirationdate} </span>
+                <div className="flex flex-col gap-0.5">
+                <span className="text-2xl leading-7.5 font-bold ">Gift Card</span>
+                <span className="text-sm font-normal  opacity-90">
+                  For All Products
+                </span>
+                </div>
+              </div>
+
+              {/* 右侧按钮区域 */}
+              <div className="w-[132px] h-full  text-center flex flex-col justify-between pt-1">
+                <div className="font-bold text-5xl">
+                  ${Number(item.giftcard_amount)}
+                </div>
+                {/* 按钮:已兑换显示 USED,未兑换显示 REDEEM */}
+                <button
+                  className={`w-full h-8  rounded-2xl border mx-auto bg-white text-[#01754AFF] border-white hover:bg-orange-50 transition-colors`}
+               
+                >
+                  Use Now
+                </button>
+                {/* <p className="text-xs mt-1 opacity-90">ALL Products</p> */}
+              </div>
             </div>
-            {/* 使用按钮区 */}
-            <div className="px-6 py-4 font-bold text-black">Use Now</div>
-          </div>
+            </>
         ))}
       </div>
 

+ 1 - 1
src/app/(public)/customer/account/mypoints/_components/GetPoints.tsx

@@ -1,6 +1,6 @@
 "use client";
 // import Link from "next/link";
-import React, { useState, useEffect } from "react";
+import { useState, useEffect } from "react";
 import { clientFetch } from "@/lib/restApiClient";
 
 export default function GetPoints() {

+ 1 - 1
src/app/(public)/customer/account/mypoints/_components/PointsRule.tsx

@@ -1,5 +1,5 @@
 "use client";
-import React, { useState } from "react";
+import { useState } from "react";
 import PointsRuleModal from "@/components/customer/PointsRule";
 export default function PointsRule() {
   // 控制弹窗显隐的状态

+ 10 - 9
src/app/(public)/customer/account/page.tsx

@@ -34,12 +34,12 @@ const orderNavs = [
 const MyAccountPage = () => {
   
   return (
-    <div className="min-h-screen bg-white">
+    <div className="min-h-screen bg-white pt-2 px-2">
       <AccountHeader />
       {/* 我的订单 */}
       <div className="">
         <h3 className="mt-8 ml-4 text-base">My Order</h3>
-        <div className="flex flex-wrap justify-between mt-5 pr-4 pl-4">
+        <div className="flex flex-wrap justify-between mt-5 ">
           {orderNavs.map((item, index) => (
             <a
               key={index}
@@ -59,7 +59,7 @@ const MyAccountPage = () => {
         </div>
       </div>
 
-      <div className="h-2.5 bg-[#F0F0F0]"></div>
+      <div className="h-px bg-[#F0F0F0] mt-6"></div>
 
       {/* 服务菜单 */}
       {/* <div className="">
@@ -125,14 +125,15 @@ const MyAccountPage = () => {
         </div>
       </div> */}
 
-      <div className="h-2.5 bg-[#F0F0F0]"></div>
+      {/* <div className="h-2.5 bg-[#F0F0F0]"></div> */}
       {/* 商品推荐 */}
       <div className="mb-12.5">
-        <div className="flex  justify-between items-center pt-7.5 pb-5 pl-4 pr-4">
-          <h1 className="font-bold text-base">You May Like</h1>
-          <a className="text-xs text-[#666666]" href="/flash-sale.html">
-            View More &gt;
-          </a>
+        <div className="flex  justify-between items-center pt-6 pb-5 pl-4 pr-4">
+          <h1 className="font-medium text-ly-18 leading-ly-26 text-base">Recommended For You</h1>
+          {/* <a className="text-xs text-[#666666]" href="/flash-sale.html">
+            View More  
+             &gt;
+          </a> */}
         </div>
         {/* 引入轮播组件 */}
         <AccountSwiper />

+ 1 - 1
src/app/(public)/customer/account/pointlist/page.tsx

@@ -1,5 +1,5 @@
 "use client";
-import React, { useState, useEffect, useRef, useCallback } from "react";
+import { useState, useEffect, useRef, useCallback } from "react";
 import Link from "next/link";
 import { clientFetch } from "@/lib/restApiClient";
 

+ 25 - 13
src/app/(public)/customer/account/pointsreceivelist/_components/RedeemGiftCard.tsx

@@ -3,6 +3,7 @@
 import React, { useState, useEffect } from "react";
 import { clientFetch } from "@/lib/restApiClient";
 import type { GiftItem  } from '@/types/api/gift/lists';
+import { useCustomToast } from "@/utils/hooks/useToast";
 
 const RedeemGiftCard: React.FC = () => {
   // // 模拟积分兑换数据(可根据实际接口替换)
@@ -15,7 +16,7 @@ const RedeemGiftCard: React.FC = () => {
   //   { id: 6, discount: "$85 OFF", points: 6800, isRedeemed: false },
   // ];
   const [list, setList] = useState<GiftItem[]>([]);
-  const [myPoints, setmyPoints] = useState<string>();
+  const [myPoints, setmyPoints] = useState<number>();
   useEffect(() => {
     const load = async () => {
       const resp = await clientFetch("/api/gift/lists");
@@ -28,8 +29,8 @@ const RedeemGiftCard: React.FC = () => {
 
     load();
   }, []);
-
-  const handleAdd = async (id:number) => {
+   const { showToast } = useCustomToast();
+  const handleAdd = async (id:number,points:number) => {
     const res = await clientFetch("/api/gift/add", {
       method: "POST",
       headers: {
@@ -43,6 +44,14 @@ const RedeemGiftCard: React.FC = () => {
     });
 
     const json = await res;
+    if(json.success){
+        showToast(json.data, "success");
+     
+        setmyPoints((prev) => {
+         if (prev === undefined) return prev;
+          return prev - points;
+        })
+    }
     console.log("返回结果:", json);
   };
 
@@ -112,31 +121,34 @@ const RedeemGiftCard: React.FC = () => {
           {Object.values(list).map((item) => (
             <div
               key={item.id}
-              className="bg-gradient-to-r from-orange-500 to-orange-400 rounded-md p-4 flex items-center justify-between text-white"
+              className="rounded-md p-4 pt-2 h-33.5 flex items-center justify-between text-white bg-[url('/image/account/202609021400.png')] bg-no-repeat bg-size-[100%_100%]"
             >
               {/* 左侧折扣+积分信息 */}
-              <div className="flex flex-col">
-                <span className="text-2xl font-bold">{item.amount}</span>
-                <span className="text-sm mt-1 opacity-90">
-                  SPEND POINTS {item.points}
+              <div className="flex flex-col h-full py-2 justify-between">
+                <span className="text-2xl leading-7.5 font-bold ">Gift Card</span>
+                <span className="text-sm font-normal  opacity-90">
+                  {item.points}Pts
                 </span>
               </div>
 
               {/* 右侧按钮区域 */}
-              <div className="w-[132px] h-[66px] pl-[16px] text-center flex flex-col justify-between border-l border-dashed  border-white">
+              <div className="w-[132px] h-full  text-center flex flex-col justify-between pt-1">
+                <div className="font-bold text-5xl">
+                  ${item.amount}
+                </div>
                 {/* 按钮:已兑换显示 USED,未兑换显示 REDEEM */}
                 <button
-                  onClick={() => handleAdd(item.id)}
-                  className={`w-19 h-7  rounded border mx-auto ${
+                  onClick={() => handleAdd(item.id,item.points)}
+                  className={`w-full h-8  rounded-2xl border mx-auto ${
                     !item.status
                       ? "bg-gray-300 text-gray-600 border-gray-400 cursor-not-allowed"
-                      : "bg-white text-orange-600 border-white hover:bg-orange-50 transition-colors"
+                      : "bg-white text-[#01754AFF] border-white hover:bg-orange-50 transition-colors"
                   }`}
                   disabled={!item.status}
                 >
                   {!item.num ? "USED" : "REDEEM"}
                 </button>
-                <p className="text-xs mt-1 opacity-90">ALL Products</p>
+                {/* <p className="text-xs mt-1 opacity-90">ALL Products</p> */}
               </div>
             </div>
           ))}

+ 1 - 1
src/app/(public)/customer/account/pointsreceivelist/page.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+
 import Link from "next/link";
 import RedeemGiftCard from "./_components/RedeemGiftCard"
 // 定义积分兑换项的类型

+ 67 - 14
src/app/(public)/customer/address/_components/DefaultAddress.tsx

@@ -12,8 +12,8 @@ export default function DefaultAddress() {
         `/api/customer/token/address`, ///api/shop/customer-addresses?page=${page}
       );
       console.log("完整返回:", resp.data);
-      resp.data= Array.isArray(resp.data) ? resp.data : [];
-      const sortedList = [...resp.data].sort((a, b) => {
+      resp.data.data = Array.isArray(resp.data.data) ? resp.data.data : [];
+      const sortedList = [...resp.data.data].sort((a, b) => {
         // true(1) 排在 false(0) 前面
         if (a.default_address !== b.default_address) {
           return b.default_address ? 1 : -1;
@@ -22,37 +22,90 @@ export default function DefaultAddress() {
         return 0;
       });
       setAddressDatas(sortedList);
-      console.log("aaaa",sortedList,addressDatas);
-      
+      console.log("aaaa", sortedList, addressDatas);
     };
     load();
   }, []);
   return (
     <>
-      {(addressDatas || []).map((item) => (
+      {(addressDatas || []).map((item,index) => {
+        const isLastItem = index === (addressDatas || []).length - 1;
+        return(
         <div key={item.id} className="mb-6">
           {item.default_address ? (
-            <h2 className="text-xl font-bold uppercase mb-3">
+            <h2 className="text-ly-14 leading-ly-22 font-normal mb-2">
               Default Billing Address
             </h2>
           ) : null}
-          <div className="border border-gray-200 p-4">
+          {/* <div className="border border-gray-200 p-4">
             <p className="mb-1">{item.first_name + item.last_name}</p>
             <p className="mb-1">{item.address}</p>
             <p className="mb-1">{item.city + "," + item.postcode}</p>
             <p className="mb-1">{item.country}</p>
             <p className="mb-4">T: {item.phone}</p>
-            <div className="text-right">
-              <Link
-                href={`/customer/address/eidt/${item.id}`}
-                className="text-blue-600 underline hover:text-blue-800"
+           
+          </div> */}
+          <div className="border border-gray-200 rounded-xl bg-gray-50 px-4 py-3 bg-[url('/image/account/202609011640.png')] bg-no-repeat bg-size-[100%_100%]">
+            {/* 姓名 + 手机号行 */}
+            <div className="flex items-center text-ly-13 leading-ly-21 font-normal ">
+              <span>
+                {item.first_name} {item.last_name}
+              </span>
+              <span className="mx-2">|</span>
+              <span>+1 {item.phone}</span>
+            </div>
+
+            {/* 分割线 */}
+            <hr className="border-black my-3" />
+
+            {/* SVG定位图标 + 地址行 */}
+            <div className="flex items-center gap-3 ">
+              {/* 位置图标 SVG */}
+
+              <svg
+                xmlns="http://www.w3.org/2000/svg"
+                width="24"
+                height="24"
+                viewBox="0 0 24 24"
+                fill="none"
               >
-                Change Billing Address
-              </Link>
+                <path
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                  stroke-linecap="round"
+                  d="M6.0175 15.917C4.4862 16.3764 3.53906 17.0111 3.53906 17.712C3.53906 19.1141 7.32759 20.2507 12.001 20.2507C16.6744 20.2507 20.4629 19.1141 20.4629 17.712C20.4629 17.0111 19.5157 16.3764 17.9844 15.917"
+                ></path>
+                <path
+                  d="M12.0002 16.8657C12.0002 16.8657 17.5005 13.271 17.5005 9.11522C17.5005 6.15182 15.0379 3.74951 12.0002 3.74951C8.96254 3.74951 6.5 6.15182 6.5 9.11522C6.5 13.271 12.0002 16.8657 12.0002 16.8657Z"
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                ></path>
+                <path
+                  d="M11.9983 11.3653C13.1666 11.3653 14.1138 10.4181 14.1138 9.24979C14.1138 8.08144 13.1666 7.13428 11.9983 7.13428C10.83 7.13428 9.88281 8.08144 9.88281 9.24979C9.88281 10.4181 10.83 11.3653 11.9983 11.3653Z"
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                ></path>
+              </svg>
+              <span className="text-ly-13 leading-ly-21 font-normal">
+                {item.address}, {item.city}, {item.postcode}, {item.country}
+              </span>
             </div>
           </div>
+          <div className="text-left mt-3 ">
+            <Link
+              href={`/customer/address/eidt/${item.id}`}
+              className="text-black-600 underline hover:text-blue-800"
+            >
+              Change Billing Address
+            </Link>
+          </div>
+          {!isLastItem && <hr className="border-black my-6" />}
         </div>
-      ))}
+       
+      )})}
     </>
   );
 }

+ 1 - 1
src/app/(public)/customer/address/new/_components/CustomerAddressPhone.tsx

@@ -61,7 +61,7 @@ export default function CustomerAddressPhone() {
 
   return (
     <div className="w-full mt-4">
-      <label className="text-ly-12 block mb-4 font-semibold">
+      <label className="text-ly-12 block mb-3 font-semibold">
         Phone number *
       </label>
       {/* ✅ Controller 本身写法没问题,保留即可,字段 name="phone" 和父表单一致 */}

+ 86 - 26
src/app/(public)/customer/address/page.tsx

@@ -1,31 +1,42 @@
-import React from "react";
+
 import Link from "next/link";
-import  DefaultAddress from "./_components/DefaultAddress";
+import DefaultAddress from "./_components/DefaultAddress";
 const CustomerAddressPage = async () => {
   // 模拟地址数据(可根据实际需求替换)
   const addressData = {
     billing: {
       name: "zhang xxxx",
+      first_name: "zhang",
+      last_name: "aaaaa",
       line1: "ddddd",
       line2: "aaaaaaaa",
       cityStateZip: "cscsc, Alabama, 90605",
+      address: "address",
+      city: "city",
+      postcode: "90603",
       country: "United States",
       phone: "2123165641",
     },
     shipping: {
       name: "zhang xxxx",
+      first_name: "zhang",
+      last_name: "aaaaa",
       line1: "ddddd",
       line2: "aaaaaaaa",
       cityStateZip: "cscsc, Alabama, 90605",
+      address: "address",
+      city: "city",
+      postcode: "90603",
       country: "United States",
       phone: "2123165641",
     },
   };
- 
+
   return (
     <div className="w-full h-full">
       <div className="bg-[#fff] pr-2.5 pl-2.5 w-full text-center text-base h-11 leading-11 font-semibold relative text-[#0b0b0b]">
-        <Link href={"/customer/account"}
+        <Link
+          href={"/customer/account"}
           // onClick={() => window.history.back()}
           className="absolute left-2.5 text-2xl inline-block top-1/2  -translate-y-1/2"
         >
@@ -48,36 +59,81 @@ const CustomerAddressPage = async () => {
         <span className="vipReturnTitles">SHIPPING ADDRESS</span>
       </div>
       <div className="max-w-md mx-auto p-4 bg-[#f8f8f8]">
-        <DefaultAddress  />
+        <DefaultAddress />
         {/* 账单地址模块 */}
         <div className="mb-6">
-          <h2 className="text-xl font-bold uppercase mb-3">
+          <h2 className="text-ly-14 leading-ly-22 font-normal mb-2">
             Default Billing Address
           </h2>
-          <div className="border border-gray-200 p-4">
-            <p className="mb-1">{addressData.billing.name}</p>
-            <p className="mb-1">{addressData.billing.line1}</p>
-            <p className="mb-1">{addressData.billing.line2}</p>
-            <p className="mb-1">{addressData.billing.cityStateZip}</p>
-            <p className="mb-1">{addressData.billing.country}</p>
-            <p className="mb-4">T: {addressData.billing.phone}</p>
-            <div className="text-right">
-              <a
-                href="#"
-                className="text-blue-600 underline hover:text-blue-800"
+
+          {/* 外层卡片容器,浅背景圆角 */}
+          <div className="border border-gray-200 rounded-xl bg-gray-50 px-4 py-3 bg-[url('/image/account/202609011640.png')] bg-no-repeat bg-size-[100%_100%]">
+            {/* 姓名 + 手机号行 */}
+            <div className="flex items-center text-ly-13 leading-ly-21 font-normal ">
+              <span>
+                {addressData.billing.first_name} {addressData.billing.last_name}
+              </span>
+              <span className="mx-2">|</span>
+              <span>+1 {addressData.billing.phone}</span>
+            </div>
+
+            {/* 分割线 */}
+            <hr className="border-black my-3" />
+
+            {/* SVG定位图标 + 地址行 */}
+            <div className="flex items-center gap-3 ">
+              {/* 位置图标 SVG */}
+
+              <svg
+                xmlns="http://www.w3.org/2000/svg"
+                width="24"
+                height="24"
+                viewBox="0 0 24 24"
+                fill="none"
               >
-                Change Billing Address
-              </a>
+                <path
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                  stroke-linecap="round"
+                  d="M6.0175 15.917C4.4862 16.3764 3.53906 17.0111 3.53906 17.712C3.53906 19.1141 7.32759 20.2507 12.001 20.2507C16.6744 20.2507 20.4629 19.1141 20.4629 17.712C20.4629 17.0111 19.5157 16.3764 17.9844 15.917"
+                ></path>
+                <path
+                  d="M12.0002 16.8657C12.0002 16.8657 17.5005 13.271 17.5005 9.11522C17.5005 6.15182 15.0379 3.74951 12.0002 3.74951C8.96254 3.74951 6.5 6.15182 6.5 9.11522C6.5 13.271 12.0002 16.8657 12.0002 16.8657Z"
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                ></path>
+                <path
+                  d="M11.9983 11.3653C13.1666 11.3653 14.1138 10.4181 14.1138 9.24979C14.1138 8.08144 13.1666 7.13428 11.9983 7.13428C10.83 7.13428 9.88281 8.08144 9.88281 9.24979C9.88281 10.4181 10.83 11.3653 11.9983 11.3653Z"
+                  stroke="rgba(0, 0, 0, 1)"
+                  stroke-width="1.5"
+                  stroke-linejoin="round"
+                ></path>
+              </svg>
+              <span className="text-ly-13 leading-ly-21 font-normal">
+                {addressData.billing.address}, {addressData.billing.city},{" "}
+                {addressData.billing.postcode}, {addressData.billing.country}
+              </span>
             </div>
           </div>
+
+          {/* 复选框 + Change Address */}
+          <div className="flex items-center gap-3 mt-5">
+            <input
+              type="checkbox"
+              className="w-10 h-10 border-2 border-black rounded bg-white"
+            />
+            <span className="text-2xl text-gray-500">Change Address</span>
+          </div>
         </div>
-        
+
         {/* 收货地址模块 */}
-        <div>
+        {/* <div>
           <h2 className="text-xl font-bold uppercase mb-3">
             Default Shipping Address
           </h2>
-          <div className="border border-gray-200 p-4">
+          <div className="border border-gray-200  p-4">
             <p className="mb-1">{addressData.shipping.name}</p>
             <p className="mb-1">{addressData.shipping.line1}</p>
             <p className="mb-1">{addressData.shipping.line2}</p>
@@ -93,12 +149,16 @@ const CustomerAddressPage = async () => {
               </a>
             </div>
           </div>
+        </div> */}
+        <div className="w-89.5">
+          <Link
+            href={"/customer/address/new"}
+            className="w-full h-12 leading-12 block  rounded-[26px] bg-[rgba(3,97,65,1)] text-base text-white font-bold text-center mt-7.5"
+          >
+            Add New Adress
+          </Link>
         </div>
-        <Link href={"/customer/address/new"} className="text-center bg-[#000] block text-white mt-5  width-full height-11 leading-11 text-lg" >
-          + New Address
-        </Link>
       </div>
-    
     </div>
   );
 };

+ 1 - 1
src/app/(public)/customer/forget-password/_components/ForgetPasswordForm.tsx

@@ -1,6 +1,6 @@
 "use client";
 import { useState } from "react";
-import { useForm, SubmitHandler } from "react-hook-form";
+import { useForm, type SubmitHandler } from "react-hook-form";
 import Link from "next/link";
 import {recoverPasswordAction} from "@/actions";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";

+ 1 - 1
src/app/(public)/customer/login/_components/LoginPageWrapper.tsx

@@ -15,7 +15,7 @@ import { useUserRegister } from "@/utils/hooks/useUserRegister";
 import { useCartDetail } from "@utils/hooks/useCartDetail";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { formatCartDetail } from "@/utils/cartDetailTools";
-import {LoginFormData, RegisterFormData} from "@/types/customer/type";
+import type {LoginFormData, RegisterFormData} from "@/types/customer/type";
 import InputText from "@/components/theme/ui/InputText";
 import PasswordInput from "@/components/theme/ui/PasswordInput";
 import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumberInput";

+ 1 - 1
src/app/(public)/customer/reset-password/_components/ResetPasswordWrapper.tsx

@@ -1,6 +1,6 @@
 "use client";
 
-import { useForm, SubmitHandler } from "react-hook-form";
+import { useForm, type SubmitHandler } from "react-hook-form";
 import {RESET_PASSWORD} from "@/graphql";
 import { useRouter } from "next/navigation";
 import { useApolloClient } from "@apollo/client/react";

+ 1 - 1
src/app/(public)/layout.tsx

@@ -1,4 +1,4 @@
-import { ReactNode } from "react";
+import { type ReactNode } from "react";
 import Footer from "@/components/layout/footer";
 import Navbar from "@/components/layout/navbar";
 

+ 1 - 1
src/app/(public)/page.tsx

@@ -1,6 +1,6 @@
 import HomeContent from "./_components/HomeContent";
 import { restApiFetch } from "@utils/bagisto/index";
-import {HomeApiData} from "@/types/home/type"
+import type {HomeApiData} from "@/types/home/type"
 export const revalidate = 3600;
 
 

+ 2 - 2
src/app/(public)/paymentresult/_components/CancelOrFailure.tsx

@@ -2,8 +2,8 @@
 
 import {use, useEffect, useRef} from "react";
 import Link from "next/link";
-import {FetchGraphqlResult} from "@/types/graphqlFetch/type";
-import { OrderDetailsData } from "@/types/customer/type";
+import type {FetchGraphqlResult} from "@/types/graphqlFetch/type";
+import type { OrderDetailsData } from "@/types/customer/type";
 import { usePlaceOrder } from "@/utils/hooks/usePlaceOrder";
 import Faqs from "./Faqs";
 import { useAppDispatch } from "@/store/hooks";

+ 2 - 2
src/app/(public)/paymentresult/_components/OrderDetailWrapper.tsx

@@ -4,8 +4,8 @@ import {use, useEffect} from "react";
 import { redirect, RedirectType } from 'next/navigation';
 import Link from "next/link";
 import Image from "next/image";
-import {FetchGraphqlResult} from "@/types/graphqlFetch/type";
-import { OrderDetailsData,ProductItemAdditional } from "@/types/customer/type";
+import type {FetchGraphqlResult} from "@/types/graphqlFetch/type";
+import type { OrderDetailsData,ProductItemAdditional } from "@/types/customer/type";
 import {deleteGuestCookieAction} from "@/actions";
 import { useConfig } from "@utils/hooks/useConfig";
 import {getAddressFromOrderDetailAddressList} from "@/utils/orderDetailTools";

+ 1 - 1
src/app/(public)/paymentresult/result/page.tsx

@@ -4,7 +4,7 @@ import { redirect, RedirectType } from 'next/navigation'
 import { auth } from "@/utils/auth/auth-helper";
 import {serverGraphqlFetch} from "@utils/bagisto/index";
 import {GET_ORDER_DETAILS} from "@/graphql";
-import { OrderDetailsData } from "@/types/customer/type";
+import type { OrderDetailsData } from "@/types/customer/type";
 import SuccessPageSkeleton from "../_components/SuccessPageSkeleton";
 import SkeletonCancelOrFailure from "../_components/SkeletonCancelOrFailure";
 import CancelOrFailure from "../_components/CancelOrFailure";

+ 1 - 1
src/app/(public)/product/[...urlProduct]/page.tsx

@@ -7,7 +7,7 @@ import {
 import { BASE_SCHEMA_URL, PRODUCT_TYPE } from "@/utils/constants";
 import { GET_PRODUCT_BY_URL_KEY } from "@/graphql";
 import {serverGraphqlFetch} from "@utils/bagisto/index";
-import {
+import type {
   ProductOption,
   SingleProductResponse,
   ProductMediaType,

+ 1 - 1
src/app/(public)/product/_components/ProductInformation.tsx

@@ -2,7 +2,7 @@
 
 import { useState, useMemo } from "react";
 import clsx from "clsx";
-import { ProductOption, ResolvedVariant } from "@/components/catalog/type";
+import type { ProductOption, ResolvedVariant } from "@/components/catalog/type";
 import { ProductAddToCart } from "@/app/(public)/product/_components/ProductAddToCart";
 import { useCustomToast } from "@utils/hooks/useToast";
 import { useAddProduct } from "@utils/hooks/useAddToCart";

+ 1 - 1
src/app/(public)/product/_components/ProductMedia.tsx

@@ -7,7 +7,7 @@ import { Swiper, SwiperSlide } from "swiper/react";
 import { Pagination } from "swiper/modules";
 import type { Swiper as SwiperType } from "swiper";
 import type { PaginationOptions } from "swiper/types";
-import { ProductMediaType } from "@/components/catalog/type";
+import type { ProductMediaType } from "@/components/catalog/type";
 import { baseUrl, getImageUrl } from "@/utils/constants";
 import { useState, useRef } from "react";
 

+ 1 - 1
src/app/(public)/product/_components/SwitchButton.tsx

@@ -3,7 +3,7 @@ import { useState, useMemo, useEffect, useCallback } from "react";
 import ProductReviewSection  from "@/app/(public)/product/_components/ProductReviewSection";
 import Image from "next/image";
 import ReviewAdd from "@/app/(public)/product/_components/review/ReviewAdd";
-import FaqList, { FaqItem } from "./question/FaqList";
+import FaqList, { type FaqItem } from "./question/FaqList";
 import HairPhotoGallery from "./review/HairPhotoGallery";
 import { clientFetch } from "@/lib/restApiClient";
 import { getUuId } from "@/utils/helper";

+ 1 - 1
src/app/(public)/product/_components/question/ComponentsQuestionModal.tsx

@@ -1,6 +1,6 @@
 import { useState, useEffect } from "react";
 import { X } from "lucide-react";
-import { QaItem } from "./QAModal";
+import { type QaItem } from "./QAModal";
 // interface WigAnswer {
   // id: string;
   // answer: string;

+ 1 - 1
src/app/(public)/product/_components/review/AddProductReview.tsx

@@ -8,7 +8,7 @@ import { useCustomToast } from "@utils/hooks/useToast";
 import { useProductReview } from "@utils/hooks/useProductReview";
 import Image from "next/image";
 
-import { CreateProductReviewInput } from "@/types/review";
+import type { CreateProductReviewInput } from "@/types/review";
 import { AddUploadImage } from "@components/common/icons/AddUploadImage";
 
 interface UploadImgItem {

+ 1 - 1
src/app/(public)/product/_components/review/AddRatingStar.tsx

@@ -3,7 +3,7 @@
 import { useState, useEffect } from "react";
 import clsx from "clsx";
 import { StarIcon } from "@heroicons/react/24/solid";
-import { RatingTypes } from "@/components/catalog/type";
+import type { RatingTypes } from "@/components/catalog/type";
 
 
 export const AddRatingStar = ({

+ 2 - 2
src/app/(public)/product/_components/review/QuestionInputModal.tsx

@@ -1,5 +1,5 @@
 "use client";
-import { useState } from "react";
+import { useState, type SubmitEvent } from "react";
 import { Textarea } from "@heroui/input";
 import { Button } from "@components/common/button/Button";
 
@@ -18,7 +18,7 @@ export default function QuestionInputModal({
   const [errorMsg, setErrorMsg] = useState("");
 
   // 提交处理
-  const handleSubmit = async (e: React.FormEvent) => {
+  const handleSubmit = async (e: SubmitEvent) => {
     e.preventDefault();
     setErrorMsg("");
     const trimText = content.trim();

+ 2 - 2
src/app/(public)/product/_components/review/ReviewDetail.tsx

@@ -10,8 +10,8 @@ import {
 import { isArray } from "@/utils/type-guards";
 import { Avatar } from "@heroui/avatar";
 import clsx from "clsx";
-import React, { FC, useState } from "react";
-import { ProductReviewNode } from "@/components/catalog/type";
+import React, { type FC, useState } from "react";
+import type { ProductReviewNode } from "@/components/catalog/type";
 import ReviewModal from "./ReviewModal";
 // import { ReviewTabType } from "@/types/products/review";
 import { useCustomToast } from "@utils/hooks/useToast";

+ 1 - 1
src/app/(public)/product/_components/review/ReviewImageGalleryModal.tsx

@@ -3,7 +3,7 @@ import { useRef, useState } from "react";
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Navigation } from "swiper/modules";
 import Image from "next/image";
-import { GalleryItem } from "@/types/products/review";
+import type { GalleryItem } from "@/types/products/review";
 import "swiper/css";
 import "swiper/css/navigation";
 

+ 1 - 1
src/app/(public)/product/_components/review/ReviewImageUploader.tsx

@@ -1,5 +1,5 @@
 "use client";
-// import { useState } from "react";
+import type React from "react";
 import Image from "next/image";
 import { AddUploadImage } from "@components/common/icons/AddUploadImage";
 import { useCustomToast } from "@utils/hooks/useToast";

+ 1 - 1
src/app/(public)/product/_components/review/ReviewModal.tsx

@@ -1,6 +1,6 @@
 "use client";
 import React, { useState, useRef, useEffect, useCallback } from "react";
-import {
+import type {
   ReviewTabType,
   ProductReviewList,
   GalleryItem,

+ 1 - 1
src/app/(public)/product/_components/youmaylike/Recommend.tsx

@@ -1,5 +1,5 @@
 "use client";
-import React from "react";
+
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Navigation, Pagination } from "swiper/modules";
 import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";

+ 1 - 1
src/app/(public)/search/page.tsx

@@ -12,7 +12,7 @@ import SortOrder from "@/components/theme/filters/SortOrder";
 import { SortByFields } from "@/utils/constants";
 // import MobileFilter from "@/components/theme/filters/MobileFilter";
 // import FilterList from "@/components/theme/filters/FilterList";
-import {
+import type {
   SearchProductsResponse,
   SearchProductsVariables,
 } from "@/components/catalog/type";

+ 2 - 2
src/app/(public)/track_order/_components/TrackFaqs.tsx

@@ -39,7 +39,7 @@ export default function TrackFaqs() {
           <button
             type="button"
             onClick={() => toggleFaq(idx)}
-            className="w-full flex justify-between items-center px-6 py-5 text-left text-lg"
+            className="w-full flex justify-between items-center px-0 py-5 text-left text-lg"
           >
             <span>Q:{item.question}</span>
             {/* 上下箭头图标 */}
@@ -61,7 +61,7 @@ export default function TrackFaqs() {
           </button>
           {/* 回答内容,展开/收起 */}
           <div
-            className={`px-6 overflow-hidden transition-all duration-300 ${
+            className={`px-0 overflow-hidden transition-all duration-300 ${
               activeIndex === idx ? "max-h-[800px] pb-6" : "max-h-0"
             }`}
           >

+ 14 - 13
src/app/(public)/track_order/page.tsx

@@ -1,16 +1,16 @@
 import HeadBack from "@/components/head/HeadBack";
 import TrackOrder from "./_components/TrackOrder";
 import TrackFaqs from "./_components/TrackFaqs";
-
+import AccountSwiper from "@components/customer/accountSwiper";
 export default function TrackOrderPage() {
   return (
     <>
       <HeadBack />
-      <div className="min-h-screen bg-[#f0ede4] text-black">
-        <div className="max-w-3xl mx-auto px-4 py-8">
+      <div className="  text-black">
+        <div className="max-w-3xl mx-auto  pb-3 pt-0">
           {/* 顶部 Track Order 区域 */}
-          <section className="mb-10">
-            <h1 className="text-[clamp(1.8rem,4vw,2.5rem)] font-normal mb-6">
+          <section className="mb-3 bg-[#f0ede4] px-4 pt-8 pb-6">
+            <h1 className="leading-ly-28 font-normal text-ly-20 mb-6">
               Track Order
             </h1>
             <div className="space-y-3 mb-8 text-base leading-relaxed">
@@ -25,8 +25,8 @@ export default function TrackOrderPage() {
           </section>
 
           {/* FAQ 区域 */}
-          <section className="bg-white rounded-[8px] overflow-hidden">
-            <h2 className="text-[clamp(1.5rem,3vw,2rem)] font-normal p-6 pb-4">
+          <section className="bg-white rounded-lg overflow-hidden px-4">
+            <h2 className="leading-ly-28 font-normal text-ly-20 p-6 px-0 pb-4">
               People Also Ask
             </h2>
             {/* 问答 */}
@@ -34,14 +34,15 @@ export default function TrackOrderPage() {
           </section>
 
           {/* You May Like 标题区域 */}
-          <div className="mt-10">
-            <h2 className="text-[clamp(1.4rem,3vw,1.8rem)] font-normal">
-              You May Like
-            </h2>
-            {/* 下方可自行添加商品列表 */}
-          </div>
+       
         </div>
       </div>
+         <div className="">
+            <h2 className="px-4 mb-6 leading-ly-26 font-medium text-ly-18">
+              You May Also Like 
+            </h2>
+             <AccountSwiper />
+          </div>
     </>
   );
 }

+ 1 - 1
src/app/api/customer/check-email/route.ts

@@ -1,4 +1,4 @@
-import { NextResponse, NextRequest } from "next/server";
+import { NextResponse, type NextRequest } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/orders/[id]/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/orders/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/orders/tracking/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/reward-points/browse-product/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/reward-points/follow/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 1 - 1
src/app/api/customer/reward-points/history/route.ts

@@ -1,4 +1,4 @@
-import { NextRequest, NextResponse } from "next/server";
+import { type NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 
 

+ 0 - 0
src/app/api/customer/token/address/route.ts


Some files were not shown because too many files changed in this diff