Переглянути джерело

proxy.ts cookie 初始化问题修改;其他一些细节优化;

fogwind 2 тижнів тому
батько
коміт
75a056b823

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

@@ -486,7 +486,7 @@ export function PaymentMethodContinueTpPay({
             
             <div className="w-full box-border mt-4">
                 <p className="text-ly-12 text-[#666666] leading-4.75">
-                    By providing your information, you agree to Asteria's Privacy Policyand Terms of Use.
+                    By providing your information, you agree to Asteria's Privacy Policy and Terms of Use.
                 </p>
 
                 <div className="mt-6 w-full">

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

@@ -160,7 +160,7 @@ export function PaymentMethodCheckout({
                 
                 {paymentMethodError && <p className="text-red-500 text-ly-12">{paymentMethodError.message}</p>}  
             </div>
-            <p className="text-ly-12 mt-3 text-[#666666] leading-ly-20">By providing your information, you agree to Asteria's Privacy Policyand Terms of Use.</p>
+            <p className="text-ly-12 mt-3 text-[#666666] leading-ly-20">By providing your information, you agree to Asteria's Privacy Policy and Terms of Use.</p>
                 
         </form>
     </>);

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

@@ -388,9 +388,9 @@ export function LoginPageWrapper({
                         </span>
                         <span className="text-ly-12 text-[#666666]">
                             I Agree To The 
-                            Terms & Conditions
+                            <Link className="underline" href="/terms-conditions">Terms & Conditions</Link>
                             And 
-                            Privacy Policy
+                            <Link className="underline" href="/privacy-policy">Privacy Policy</Link>
                             Of  asteriahair.com
                         </span>
                         

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

@@ -214,7 +214,7 @@ export function ProductInformation({
             if(res.data) {
                 const responseData = res.data;
                 if(responseData.success) {
-                    router.push('/checkout?step=address');
+                    router.push('/checkout');
                 }
             }
         }

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

@@ -9,7 +9,7 @@ export default function ProductText({ ProductText }: { ProductText: string }) {
   // 模拟商品长标题
   const titleText =
      (ProductText ? stripHtml(ProductText) : null) ||
-    "Wiggins Hair HD Lace Frontal Wigs straight A Grade Human Hair 13x4 Transparent Lace Front Wig For Women Natural Black 18-30 Inch";
+    "Asteria Hair HD Lace Frontal Wigs straight A Grade Human Hair 13x4 Transparent Lace Front Wig For Women Natural Black 18-30 Inch";
   const [isExpand, setIsExpand] = useState(false);
 
   return (

+ 5 - 3
src/app/api/graphql/route.ts

@@ -14,7 +14,7 @@ import {
     CREATE_CHECKOUT_SHIPPING_METHODS,
     CREATE_CHECKOUT_PAYMENT_METHODS,
     CREATE_CHECKOUT_ORDER,
-    CREATE_PRODUCT_REVIEW,
+    // CREATE_PRODUCT_REVIEW,
     CREATE_PAYMENT_INITIATE,
     CREATE_SAVE_CHECKOUT_CART,
     GET_ORDER_DETAILS,
@@ -36,7 +36,7 @@ const ALLOWED_OPERATIONS: Record<string, any> = {
     CreateCheckoutShippingMethod: CREATE_CHECKOUT_SHIPPING_METHODS,
     CreateCheckoutPaymentMethod: CREATE_CHECKOUT_PAYMENT_METHODS,
     CreateCheckoutOrder: CREATE_CHECKOUT_ORDER,
-    CreateProductReview: CREATE_PRODUCT_REVIEW,
+    // CreateProductReview: CREATE_PRODUCT_REVIEW,
     CreatePaymentInitiate: CREATE_PAYMENT_INITIATE, // 创建订单
     CreateSaveCheckoutCart: CREATE_SAVE_CHECKOUT_CART,
     GetOrderDetails: GET_ORDER_DETAILS, // 获取订单详情
@@ -50,7 +50,7 @@ interface FetchOption  {
     query: string;
     variables?: Record<string, any>;
     cache?: RequestCache;
-    guestToken?: string;
+    takeAuthorization?: boolean;
     operationName?: string;
 }
 
@@ -64,6 +64,7 @@ function authorizationOperations(body: Record<string, any>): FetchOption {
         query,
         variables: finalVariables,
         cache: "no-store",
+        takeAuthorization: true
         // operationName
     }
 }
@@ -77,6 +78,7 @@ function notAuthorizationOperations(body: Record<string, any>): FetchOption {
         query,
         variables,
         cache: "no-store",
+        takeAuthorization: false
         // operationName
     }
 }

+ 8 - 15
src/app/layout.tsx

@@ -85,18 +85,11 @@ export default async function RootLayout({
   ////////eruda调试/////////
   const loadEruda = cookieStore.get('9527_LOAD_ERUDA_3345678');
   ////////eruda调试////////
-  const currentCurrency = cookieStore.get(CURRENT_CURRENCY);
-  const currentLocale = cookieStore.get(CURRENT_LOCAL);
-  const currentChannel = cookieStore.get(CURRENT_CHANNEL);
-  if(currentCurrency === undefined) {
-    throw new Error('Currency is not defined');
-  }
-  if(currentLocale === undefined) {
-    throw new Error('Local is not defined');
-  }
-  if(currentChannel === undefined) {
-    throw new Error('Channel is not defined');
-  }
+
+  const currentCurrency = cookieStore.get(CURRENT_CURRENCY)?.value ?? env.DEFAULT_CURRENCY;
+  const currentLocale = cookieStore.get(CURRENT_LOCAL)?.value ?? env.DEFAULT_LOCAL;
+  const currentChannel = cookieStore.get(CURRENT_CHANNEL)?.value ?? env.DEFAULT_CHANNEL;
+
 
   // 获取country list 和currency list
   const {data: countryResData} = await serverGraphqlFetch<{
@@ -123,9 +116,9 @@ export default async function RootLayout({
     defaultLocale: defaultLocale,
     storeName: storeName,
     // 用户当前使用值
-    currentCurrency: currentCurrency.value,
-    currentLocale: currentLocale.value,
-    currentChannel: currentChannel.value
+    currentCurrency: currentCurrency,
+    currentLocale: currentLocale,
+    currentChannel: currentChannel
   };
 
   const {data: cartDetailsRes} = await serverGraphqlFetch<GetCartItemData>({

+ 15 - 11
src/components/common/LoginModal/LoginModal.tsx

@@ -1,10 +1,11 @@
 "use client";
 
 import {useState, useLayoutEffect, useEffect} from "react";
+import Link from "next/link";
 import { useRouter } from 'next/navigation';
 import { signIn } from "next-auth/react";
 import clsx from "clsx";
-import { useForm, Controller } from "react-hook-form";
+import { useForm, Controller, type FieldErrors } from "react-hook-form";
 import { EMAIL_REGEX, IS_VALID_INPUT, IS_VALID_FULL_PHONE } from "@utils/constants";
 import {mergeCartAction} from "@/actions";
 import { useAppDispatch } from "@/store/hooks";
@@ -186,6 +187,15 @@ export default function LoginModal({
         }
 
     };
+
+    const onRegisterInvalid = (errors: FieldErrors<RegisterFormData>) => {
+        const message = errors.isAgree?.message;
+
+        if (message) {
+            showToast(message, "warning");
+        }
+    };
+
     return (<>
         <CommonModal 
             isOpen={isShow}
@@ -230,7 +240,7 @@ export default function LoginModal({
                         className={clsx("relative box-border px-6",{
                             "hidden": activeTab !== 'register'
                         })} 
-                        onSubmit={registerForm.handleSubmit(registerSubmit)}
+                        onSubmit={registerForm.handleSubmit(registerSubmit,onRegisterInvalid)}
                     >
                   
                         <div className="w-full flex justify-between">
@@ -381,13 +391,7 @@ export default function LoginModal({
                                     id="is_agree" 
                                     className="absolute opacity-0" 
                                     {...registerForm.register("isAgree", {
-                                        validate: (value: boolean) => {
-                                            if(!value) {
-                                                showToast('Please Agree To The Terms & Conditions And Privacy Policy.', "warning");
-                                                return 'Please Agree To The Terms & Conditions And Privacy Policy.';
-                                            } 
-                                            return true;
-                                        },
+                                        required: 'Please Agree To The Terms & Conditions And Privacy Policy.'
                                     })}
                                 />
                                 <span className="flex-none mr-2">
@@ -396,9 +400,9 @@ export default function LoginModal({
                                 </span>
                                 <span className="text-ly-12 text-[#666666]">
                                     I Agree To The 
-                                    Terms & Conditions
+                                    <Link className="underline" href="/terms-conditions">Terms & Conditions</Link>
                                     And 
-                                    Privacy Policy
+                                    <Link className="underline" href="/privacy-policy">Privacy Policy</Link>
                                     Of  asteriahair.com
                                 </span>
                                 

+ 1 - 1
src/components/layout/navbar/DesktopNavigation.tsx

@@ -108,7 +108,7 @@ export default function DesktopNavigation({
 
   return (
     <div
-      className="relative z-50 w-full bg-white"
+      className="relative w-full bg-white"
       onMouseLeave={() => {
         setActiveMenu(null);
       }}

+ 1 - 5
src/components/theme/toast/ToastContainer.tsx

@@ -6,11 +6,7 @@ export const ToastContainer = () => {
   const { toasts, removeToast } = useToast();
 
   return (
-    <div
-      className="fixed left-1/2 z-[999] w-[80%] -translate-x-1/2 sm:max-w-md
-        top-4 bottom-auto
-        md:bottom-4 md:top-auto"
-    >
+    <div className="fixed left-1/2 z-[999] w-[80%] -translate-x-1/2 sm:max-w-md top-4 bottom-auto">
       {toasts.map((toast) => (
         <Toast key={toast.id} toast={toast} onRemove={removeToast} />
       ))}

+ 1 - 1
src/components/theme/ui/Price.tsx

@@ -12,7 +12,7 @@ export const Price = ({
     {`${new Intl.NumberFormat(undefined, {
       style: "currency",
       currency: currencyCode,
-      currencyDisplay: "narrowSymbol",
+      // currencyDisplay: "narrowSymbol",
     }).format(parseFloat(amount))}`}
   </p>
 );

+ 31 - 26
src/proxy.ts

@@ -2,40 +2,45 @@ import { NextResponse } from 'next/server'
 import type { NextRequest } from 'next/server'
 import {handleCurrency} from "./proxy/currency";
 import {handleAuth} from "./proxy/auth";
-
-export async function proxy(
-    request:NextRequest
-){
-    let response = NextResponse.next();
-
-    /**
-     * Currency
-     */
-    response = handleCurrency(
-        request,
-        response
-    );
-
-
-
-    /**
-     * Auth
-     */
-    response = await handleAuth(
-        request,
-        response
+import { currencyCookieOptions } from "@/utils/constants/server";
+
+export async function proxy(request: NextRequest) {
+  // 找出缺失的默认 Cookie
+  const missingCookies = handleCurrency(request);
+
+  // 补齐当前请求缺失的 Cookie
+  for (const cookie of missingCookies) {
+    request.cookies.set(cookie.name, cookie.value);
+  }
+
+  // 将修改后的请求头转发给 Server Components
+  let response = NextResponse.next({
+    request: {
+      headers: request.headers,
+    },
+  });
+
+  // 将默认 Cookie 写入浏览器
+  for (const cookie of missingCookies) {
+    response.cookies.set(
+      cookie.name,
+      cookie.value,
+      currencyCookieOptions,
     );
+  }
 
+  // 处理认证与重定向
+  response = await handleAuth(request, response);
 
-
-    return response;
-
+  return response;
 }
 
 
+
 export const config = {
     matcher:[
-        "/((?!_next|api|.*\\..*).*)" // 匹配到的不经过proxy.ts处理
+        // 匹配到的不经过proxy.ts处理
+        "/((?!_next|api|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js|map|woff|woff2|ttf|eot)$).*)",
     ]
 
 };

+ 19 - 28
src/proxy/currency.ts

@@ -1,34 +1,25 @@
 import type { NextRequest } from "next/server";
-import type { NextResponse } from "next/server";
 import {CURRENT_CURRENCY,CURRENT_LOCAL,CURRENT_CHANNEL} from "@/utils/constants";
-import {currencyCookieOptions} from "@/utils/constants/server";
 import { env } from "@/env";
 
-export function handleCurrency(
-    request: NextRequest,
-    response: NextResponse
-) {
-
-    const currency = request.cookies.get(CURRENT_CURRENCY);
-    const local = request.cookies.get(CURRENT_LOCAL);
-    const channel = request.cookies.get(CURRENT_CHANNEL);
-    const defaultCurrency = env.DEFAULT_CURRENCY;
-    const defaultLocal = env.DEFAULT_LOCAL;
-    const defaultChannel = env.DEFAULT_CHANNEL;
-
-    if (!currency && defaultCurrency) {
-        
-        response.cookies.set(CURRENT_CURRENCY,defaultCurrency,currencyCookieOptions);
-    }
-    if (!local && defaultLocal) {
-        
-        response.cookies.set(CURRENT_LOCAL,defaultLocal,currencyCookieOptions);
-    }
-    if (!channel && defaultChannel) {
-        
-        response.cookies.set(CURRENT_CHANNEL,defaultChannel,currencyCookieOptions);
-    }
-
-    return response;
+// 检查请求头中是否包含对应cookie
+export function handleCurrency(request: NextRequest) {
+  const defaults = [
+    {
+      name: CURRENT_CURRENCY,
+      value: env.DEFAULT_CURRENCY,
+    },
+    {
+      name: CURRENT_LOCAL,
+      value: env.DEFAULT_LOCAL,
+    },
+    {
+      name: CURRENT_CHANNEL,
+      value: env.DEFAULT_CHANNEL,
+    },
+  ];
 
+  return defaults.filter(
+    (item) => !request.cookies.has(item.name)
+  );
 }