Ver Fonte

登录注册页;忘记密码功能 -- 缺重置密码部分;

fogwind há 6 dias atrás
pai
commit
062d5c07b7

BIN
public/image/Logo.webp


BIN
public/image/forget-password.webp


BIN
public/image/login.webp


+ 2 - 1
src/actions/index.ts

@@ -4,4 +4,5 @@ export {createGuestCartAction} from "./createGuestCartAction";
 export {switchCurrencyAction} from "./switchCurrencyAction";
 export {addProductToCartAction} from "./addProductToCartAction";
 export {deleteCartProductAction} from "./deleteCartProductAction";
-export {logoutAction} from "@/actions/logoutAction";
+export {logoutAction} from "@/actions/logoutAction";
+export {recoverPasswordAction} from "@/actions/recoverPasswordAction";

+ 47 - 0
src/actions/recoverPasswordAction.ts

@@ -0,0 +1,47 @@
+"use server";
+
+import {FORGET_PASSWORD} from "@/graphql/customer/mutations";
+import { serverGraphqlFetch } from "@utils/bagisto";
+
+interface ForgetPasswordData{
+     createForgotPassword: {
+      forgotPassword: {
+        success: boolean;
+        message: string;
+      }
+    }
+}
+
+
+export async function recoverPasswordAction(formData: {
+  email: string;
+}): Promise<{ success: boolean; msg: string;}> {
+    try {
+        const response = await serverGraphqlFetch<ForgetPasswordData,{email: string;}>({
+            query: FORGET_PASSWORD,
+            variables: {
+                email: formData.email
+            }
+        });
+        if(!response.error) {
+            const resData = response?.data?.createForgotPassword?.forgotPassword;
+
+            return {
+                success: resData?.success ?? false,
+                msg: resData?.message ?? '',
+            };
+
+        } else {
+            return {
+                success: false,
+                msg: response.error.message,
+            }
+        }
+
+    } catch(error) {
+        return {
+            success: false,
+            msg: error instanceof Error ? error.message : 'Add product to cart failed!',
+        }
+    }
+}

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

@@ -0,0 +1,138 @@
+"use client";
+import { useState } from "react";
+import { useForm, SubmitHandler } from "react-hook-form";
+import Link from "next/link";
+import {recoverPasswordAction} from "@/actions";
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
+import { EMAIL_REGEX } from '@/utils/constants';
+import InputText from "@/components/theme/ui/InputText";
+import { useCustomToast } from '@/utils/hooks/useToast';
+
+type ForgetPasswordInputs = {
+    email: string;
+};
+
+export default function ForgetPasswordForm() {
+    const { showToast } = useCustomToast();
+    const [emailValue, setEmailValue] = useState('');
+
+    const {
+        register,
+        handleSubmit,
+        formState: { errors },
+    } = useForm<ForgetPasswordInputs>({
+        mode: "onSubmit",
+        reValidateMode: "onChange",
+    });
+
+    const onSubmit: SubmitHandler<ForgetPasswordInputs> = async (data: {email: string;}) => {
+
+        overlayLoading.start();
+        const formData = new FormData();
+
+        formData.append("email", data.email);
+
+        try {
+            const result = await recoverPasswordAction({
+                email: data?.email,
+            });
+
+            // Show success/error API response
+            if (result.success) {
+                showToast(result.msg, "success");
+                setEmailValue(data.email);
+            } else {
+                showToast(result.msg, "danger");
+            }
+        } catch {
+            showToast("Something went wrong. Please try again later.", "danger");
+        } finally {
+            overlayLoading.stop();
+        }
+    };
+
+    return (<>{!emailValue ?
+
+        <div className="w-full box-border px-3">
+            <h2 className="text-center text-ly-18 font-bold">
+                Retrieve Your Password Here
+            </h2>
+            <p className="mt-6 text-center text-ly-16 leading-6">
+                Please enter your email address below. We will email you a verification code to reset your password.
+            </p>
+
+            <form
+                noValidate
+                className="w-full  mt-9"
+                onSubmit={handleSubmit(onSubmit)}
+            >
+                <label className="text-ly-12 block mb-1 font-semibold">
+                    *Email Address
+                </label>
+                <InputText
+                    type="email"
+                    placeholder="Enter your email address"
+                    {...register("email", {
+                        required: "Email is required",
+                        pattern: {
+                            value: EMAIL_REGEX,
+                            message: "Please enter a valid email address.",
+                        },
+                    })}
+                    error={errors?.email?.message ? errors.email.message : undefined}
+                />
+
+
+                <div className="w-full mt-9">
+                    <button type="submit" 
+                        title="Reset Password"
+                        className="flex items-center justify-center w-full h-12 bg-ly-middlegreen text-ly-16 text-white rounded-3xl"
+                    >
+                        Submit
+                    </button>
+                
+                    <Link className="mt-3 flex items-center justify-center w-full h-12 border-1  text-ly-16 rounded-3xl"
+                        href="/customer/login" 
+                        aria-label="Go to sign in page"
+                    >
+                        Back To Login
+                    </Link>
+                    
+                </div>
+            </form>
+        </div>
+    :
+        <div className="w-full box-border px-3 mt-6">
+
+            <h2 className="text-center text-ly-18 font-bold">
+                Password Reset
+            </h2>
+            <p className="mt-6 text-center text-ly-16 leading-6">
+                We sent an email to <br/>
+                <span className="underline text-[#00BAAD]">{emailValue}</span><br/>
+                with a link to resetyour password.<br/>
+                Please check your mailbox and follow theinstruction.
+            </p>
+            <p className="relative pl-4 mt-6 text-ly-16 leading-6">
+                <span className="absolute left-0 top-2 w-1.5 h-1.5 rounded-sm bg-[#00BAAD] mr-2.5"></span>
+                Emails may experience few-minute delays.
+            </p>
+            <p className="relative pl-4  mt-3 text-ly-16 leading-6">
+                <span className="absolute left-0 top-2 w-1.5 h-1.5 rounded-sm bg-[#00BAAD] mr-2.5"></span>
+                If you have not received an email, please check your junk and spam folders.
+            </p>
+            <p className="relative pl-4  mt-3 text-ly-16 leading-6">
+                <span className="absolute left-0 top-2 w-1.5 h-1.5 rounded-sm bg-[#00BAAD] mr-2.5"></span>
+                If you still don't receive the email after requesting a password reset, please contact our customer
+            </p>
+
+            <Link className="mt-6 flex items-center justify-center w-full h-12 bg-ly-middlegreen text-ly-16 text-white rounded-3xl"
+                href="/customer/login" 
+                aria-label="Go to sign in page"
+            >
+                Back To Login
+            </Link>
+
+        </div>
+    }</>);
+}

+ 5 - 9
src/app/(public)/customer/forget-password/page.tsx

@@ -1,9 +1,6 @@
-import dynamic from "next/dynamic";
 import { generateMetadataForPage } from "@utils/helper";
 import { staticSeo } from "@utils/metadata";
-import { Suspense } from "react";
-import ForgetSkeleton from "@components/common/skeleton/ForgetSkeleton";
-const ForgetPasswordForm = dynamic(() => import("@components/customer/ForgetPassword"));
+import ForgetPasswordForm from "./_components/ForgetPasswordForm";
 
 export const revalidate = 3600;
 export async function generateMetadata() {
@@ -11,9 +8,8 @@ export async function generateMetadata() {
 }
 
 export default function ForgetPasswordPage() {
-  return (
-    <Suspense fallback={<ForgetSkeleton />}>
-      <ForgetPasswordForm />
-    </Suspense>
-  );
+    return (<div className="w-full mt-6 box-border">
+        <ForgetPasswordForm />
+
+    </div>);
 }

Diff do ficheiro suprimidas por serem muito extensas
+ 422 - 0
src/app/(public)/customer/login/_components/LoginPageWrapper.tsx


+ 12 - 9
src/app/(public)/customer/login/page.tsx

@@ -1,18 +1,21 @@
-import LoginForm from "@components/customer/LoginForm";
 import { generateMetadataForPage } from "@utils/helper";
 import { staticSeo } from "@utils/metadata";
-
-
-export const revalidate = 60;
+import {LoginPageWrapper} from "./_components/LoginPageWrapper";
 
 export async function generateMetadata() {
   return generateMetadataForPage("", staticSeo.login);
 }
 
-export default async function LoginPage() {
-  return (
-
-      <LoginForm />
+export default async function LoginPage({
+  searchParams
+}:{
+  searchParams: Promise<{
+      callbackUrl?: string;
+  }>;
+}) {
+  const { callbackUrl } = await searchParams;
+  return (<>
+      <LoginPageWrapper callbackUrl={callbackUrl || '/'} />
 
-  );
+  </>);
 }

+ 0 - 13
src/app/(public)/customer/register/page.tsx

@@ -1,13 +0,0 @@
-import RegistrationForm from "@components/customer/RegistrationForm";
-import { generateMetadataForPage } from "@utils/helper";
-import { staticSeo } from "@utils/metadata";
-
- export const revalidate = 60;
-
-export async function generateMetadata() {
-  return generateMetadataForPage("", staticSeo.register);
-}
-
-export default async function Register() {
-  return <RegistrationForm />;
-}

+ 26 - 0
src/app/(public)/customer/reset-password/[token]/page.tsx

@@ -0,0 +1,26 @@
+import ResetPasswordWrapper from "../_components/ResetPasswordWrapper";
+
+export default async function ResetPasswordPage({
+  searchParams,
+  params,
+}: {
+  params: Promise<{ token: string; }>;
+  searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
+}) {
+    const { token } = await params;
+    const resolvedParams = await searchParams;
+    //   const { page = '1', sort = 'asc', query = '' } = await searchParams
+
+
+
+
+
+
+  return (
+    <>
+        <ResetPasswordWrapper />
+        {token}
+        <p>{resolvedParams ? JSON.stringify(resolvedParams) : resolvedParams}</p>
+    </>
+  );
+}

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

@@ -0,0 +1,128 @@
+"use client";
+
+import { useForm, SubmitHandler } from "react-hook-form";
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
+import PasswordInput from "@/components/theme/ui/PasswordInput";
+
+type ResetPasswordFormData= {
+    password: string;
+    password_confirmation: string;
+};
+
+export default function ResetPasswordWrapper() {
+    // const { showToast } = useCustomToast();
+    // const [emailValue, setEmailValue] = useState('');
+
+    const {
+        register,
+        handleSubmit,
+        formState: { errors },
+    } = useForm<ResetPasswordFormData>({
+        mode: "onSubmit",
+        reValidateMode: "onChange",
+        defaultValues: {
+            "password": '',
+            "password_confirmation": ''
+        }
+    });
+
+    const onSubmit: SubmitHandler<ResetPasswordFormData> = async (data: ResetPasswordFormData) => {
+
+        overlayLoading.start();
+        console.log(data);
+
+        // try {
+        //     const result = await recoverPasswordAction({
+        //         password: data.password,
+        //         password_confirmation: data.password_confirmation
+        //     });
+
+        //     // Show success/error API response
+        //     if (result.success) {
+        //         showToast(result.msg, "success");
+        //         setEmailValue(data.email);
+        //     } else {
+        //         showToast(result.msg, "danger");
+        //     }
+        // } catch {
+        //     showToast("Something went wrong. Please try again later.", "danger");
+        // } finally {
+        //     overlayLoading.stop();
+        // }
+    };
+
+    return (
+
+        <div className="w-full box-border px-3 mt-6">
+            <h2 className="text-center text-ly-18 font-bold">
+                Change Password
+            </h2>
+
+            <form className="w-full mt-6" onSubmit={handleSubmit(onSubmit)}>
+                <div className="w-full">
+                    <label className="text-ly-12 block mb-1 font-semibold">
+                        *New Password
+                    </label>
+                    <PasswordInput
+                        placeholder="New password"
+                        {...register("password", {
+                            required: "Password is required",
+                            minLength: {
+                                value: 6,
+                                message: "Be at least 6 characters long",
+                            },
+                            validate: (value: string) => {
+                                const pass=value.trim(); /*strip leading and trailing spaces*/
+                                const res = pass.length>0 && pass.length < 6;
+                                if(res) {
+                                    return 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.';
+                                } 
+                                return true;
+                            },
+                        })}
+                        error={errors.password_confirmation && errors.password_confirmation.message}
+                    />
+                </div>
+                <div className="w-full mt-4">
+                    <label className="text-ly-12 block mb-1 font-semibold">
+                        *Confirm Password
+                    </label>
+
+                    <PasswordInput
+                        placeholder="Confirm password"
+                        {...register("password_confirmation", {
+                            required: "Confirm Password is required",
+                            minLength: {
+                                value: 6,
+                                message: "Be at least 6 characters long",
+                            },
+                            validate: (value: string, {password}) => {
+                                const pass = value.trim(); /*strip leading and trailing spaces*/
+                                const res = pass.length>0 && pass.length < 6;
+                                if(res) {
+                                    return 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.';
+                                } 
+                                if(pass !== password) {
+                                    return 'The Confirm Passwords do not match the Password';
+                                }
+                                return true;
+                            },
+                        })}
+                        error={errors.password_confirmation && errors.password_confirmation.message}
+                    />
+                </div>
+
+
+                <div className="w-full mt-9">
+                    <button type="submit" 
+                        title="Reset Password"
+                        className="flex items-center justify-center w-full h-12 bg-ly-middlegreen text-ly-16 text-white rounded-3xl"
+                    >
+                        Submit
+                    </button>
+                    
+                </div>
+            </form>
+        </div>
+    );
+}

+ 42 - 1
src/app/api/revalidate/route.ts

@@ -1,5 +1,46 @@
-import { revalidate } from "@/utils/bagisto";
 import { NextRequest, NextResponse } from "next/server";
+import { headers } from "next/headers";
+import { revalidatePath } from "next/cache";
+
+
+async function revalidate(req: NextRequest): Promise<NextResponse> {
+  const collectionWebhooks = [
+    "collections/create",
+    "collections/delete",
+    "collections/update",
+  ];
+  const productWebhooks = [
+    "products/create",
+    "products/delete",
+    "products/update",
+  ];
+  const topic = (await headers()).get("x-bagisto-topic") || "unknown";
+  const secret = req.nextUrl.searchParams.get("secret");
+  const isCollectionUpdate = collectionWebhooks.includes(topic);
+  const isProductUpdate = productWebhooks.includes(topic);
+
+  if (!secret || secret !== process.env.BAGISTO_REVALIDATION_SECRET) {
+    return NextResponse.json({ status: 200 });
+  }
+
+  if (!isCollectionUpdate && !isProductUpdate) {
+    return NextResponse.json({ status: 200, message: "No action needed" });
+  }
+
+  if (isProductUpdate) {
+    revalidatePath("/", "layout");
+  } else if (isCollectionUpdate) {
+    revalidatePath("/", "layout");
+  }
+
+  return NextResponse.json({
+    status: 200,
+    revalidated: true,
+    topic,
+    now: Date.now(),
+  });
+}
+
 
 export async function POST(req: NextRequest): Promise<NextResponse> {
   return revalidate(req);

+ 1 - 14
src/components/common/LoginModal/LoginModal.tsx

@@ -14,6 +14,7 @@ import { useUserRegister } from "@/utils/hooks/useUserRegister";
 import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
 import { formatCartDetail } from "@/utils/cartDetailTools";
 import {CartDetail} from "@/types/cart/type";
+import {LoginFormData, RegisterFormData} from "@/types/customer/type";
 import CommonModal from "@/components/theme/ui/CommonModal";
 import InputText from "@/components/theme/ui/InputText";
 import PasswordInput from "@/components/theme/ui/PasswordInput";
@@ -21,20 +22,6 @@ import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumber
 
 type TabFlag = "login"|"register";
 
-interface LoginFormData {
-    username:string;
-    password:string;
-}
-interface RegisterFormData {
-    firstName: string;
-    lastName: string;
-    email: string;
-    password: string;
-    confirmPassword: string;
-    phone: string;
-    subscribedToNewsLetter: boolean;
-    isAgree: boolean;
-}
 export interface LoginModalReult {
     loginSuccess: boolean;
     registerSuccess: boolean;

+ 0 - 116
src/components/common/form/Input.tsx

@@ -1,116 +0,0 @@
-import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
-import clsx from "clsx";
-import { forwardRef } from "react";
-import { isArray } from '@/utils/type-guards';
-interface InputTextProps
-  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
-  className?: string;
-  label: string;
-  name: string;
-  errorMsg?: string | string[] | Record<string, unknown>;
-  defaultValue?: string;
-  typeName?: string;
-  placeholder?: string;
-  size?: "sm" | "md" | "lg";
-  labelPlacement?: "inside" | "outside" | "outside-left";
-  rounded?: "sm" | "md" | "lg";
-  showAsterisk?: boolean; // Show asterisk if true
-}
-
-const sizeClasses = {
-  sm: "text-sm px-2 py-1",
-  md: "text-base px-3 py-2",
-  lg: "text-lg px-4 py-3",
-};
-
-const roundedClasses = {
-  sm: "rounded-sm",
-  md: "rounded-md",
-  lg: "rounded-lg",
-};
-
-const InputText = forwardRef<HTMLInputElement, InputTextProps>(
-  (
-    {
-      className,
-      label,
-      name,
-      errorMsg,
-      defaultValue,
-      typeName = "text",
-      placeholder,
-      size = "sm",
-      labelPlacement = "inside",
-      rounded = "sm",
-      required,
-      showAsterisk = true,
-      ...rest
-    },
-    ref
-  ) => {
-    const hasError = Boolean(errorMsg);
-
-    const borderColorClass = hasError
-      ? "border-red-500"
-      : "border-gray-300 dark:border-gray-500";
-
-    return (
-      <div className={clsx("max-w-full mb-2.5", className)}>
-        {labelPlacement !== "inside" && (
-          <label
-            className={clsx(
-              "px-1 mb-1 block font-medium text-black dark:text-white"
-            )}
-            htmlFor={name}
-          >
-            {label} {showAsterisk && <span className="text-red-500">*</span>}
-          </label>
-        )}
-        <div className="relative">
-          <input
-            ref={ref}
-            className={clsx(
-              "w-full !rounded-[0.62rem] border bg-transparent text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:text-white",
-              borderColorClass,
-              sizeClasses[size],
-              roundedClasses[rounded],
-              labelPlacement === "inside"
-                ? "placeholder-input-color dark:placeholder-selected-color-dark"
-                : ""
-            )}
-            defaultValue={defaultValue}
-            id={name}
-            name={name}
-            placeholder={labelPlacement === "inside" ? label : placeholder}
-            type={typeName}
-            required={required}
-            {...rest}
-          />
-          {hasError && (
-            <ul className="absolute -bottom-8 py-2 text-sm text-red-500">
-              {isArray(errorMsg) ? (
-                (errorMsg as string[]).map((msg, index) => (
-                  <li key={index} className="flex items-center gap-1">
-                    <ExclamationCircleIcon className="h-5 w-5" />
-                    {msg}
-                  </li>
-                ))
-              ) : (
-                <li className="flex items-center gap-1 text-xs sm:text-sm">
-                  <ExclamationCircleIcon className="size-[18px]" />
-                  {typeof errorMsg === "string"
-                    ? errorMsg
-                    : JSON.stringify(errorMsg)}
-                </li>
-              )}
-            </ul>
-          )}
-        </div>
-      </div>
-    );
-  }
-);
-
-InputText.displayName = "InputText";
-
-export default InputText;

+ 0 - 32
src/components/common/skeleton/CategoryCarouselSkeleton.tsx

@@ -1,32 +0,0 @@
-export const CategoryCarouselSkeleton = () => {
-    return (
-        <section className="pt-8 sm:pt-12 lg:pt-20">
-            <div className="md:max-w-4.5xl mx-auto mb-10 w-auto text-center md:px-36">
-                {/* Heading skeleton */}
-                <div className="mb-2 mx-auto h-8 w-64 animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900 md:h-10 md:w-80" />
-
-                {/* Description skeleton */}
-                <div className="mx-auto mt-3 h-4 w-full max-w-2xl animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900 md:h-5" />
-                <div className="mx-auto mt-2 h-4 w-3/4 max-w-xl animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900 md:h-5" />
-            </div>
-
-            <div className="w-full overflow-x-auto overflow-y-hidden">
-                <ul className="m-0 grid grid-cols-1 gap-7 p-0 xss:grid-cols-2 sm:grid-cols-3">
-                    {[1, 2, 3].map((index) => (
-                        <li
-                            key={index}
-                            className="relative aspect-498/665 h-full w-full max-w-[498px] flex-none overflow-hidden rounded-[18px]"
-                        >
-                            <div className="relative h-full w-full animate-pulse rounded-[18px] bg-neutral-100 dark:bg-neutral-900">
-                                {/* Category label skeleton */}
-                                <div className="absolute bottom-0 left-0 right-0 p-6">
-                                    <div className="h-6 w-32 animate-pulse rounded-md bg-neutral-200 dark:bg-neutral-800" />
-                                </div>
-                            </div>
-                        </li>
-                    ))}
-                </ul>
-            </div>
-        </section>
-    );
-};

+ 0 - 137
src/components/customer/ForgetPassword.tsx

@@ -1,137 +0,0 @@
-"use client";
-import { useState } from "react";
-import { useForm, SubmitHandler } from "react-hook-form";
-import clsx from "clsx";
-import Image from "next/image";
-import Link from "next/link";
-
-import { recoverPassword } from "@utils/actions";
-
-import { Button } from "@components/common/button/Button";
-
-import { EMAIL_REGEX, FORGET_PASSWORD_IMG } from '@/utils/constants';
-import InputText from '@components/common/form/Input';
-import { useCustomToast } from '@/utils/hooks/useToast';
-
-type ForgetPasswordInputs = {
-  email: string;
-};
-
-export default function ForgetPasswordForm() {
-  const { showToast } = useCustomToast();
-  const [loading, setLoading] = useState(false);
-
-  const {
-    register,
-    handleSubmit,
-    formState: { errors, isSubmitting },
-  } = useForm<ForgetPasswordInputs>({
-    mode: "onSubmit",
-    reValidateMode: "onChange",
-  });
-
-  const onSubmit: SubmitHandler<ForgetPasswordInputs> = async (data: {
-    email: string;
-  }) => {
-    setLoading(true);
-
-    const formData = new FormData();
-
-    formData.append("email", data.email);
-
-    try {
-      const result = await recoverPassword({
-        email: data?.email,
-      });
-
-      // Show success/error API response
-      if (result.success) {
-        showToast(result.success.msg, "success");
-      } else if (result.errors?.apiRes) {
-        showToast(result.errors.apiRes?.msg, "danger");
-      }
-
-      // Field-specific errors
-      if (result.errors?.email) {
-        showToast(
-          Array.isArray(result.errors.email)
-            ? result.errors.email[0]
-            : result.errors.email,
-          "danger"
-        );
-      }
-    } catch {
-      showToast("Something went wrong. Please try again later.", "danger");
-    } finally {
-      setLoading(false);
-    }
-  };
-
-  return (
-    <div className="my-8 flex w-full items-center w-full max-w-screen-2xl mx-auto px-4 xss:px-7.5 justify-between gap-4 lg:my-16 xl:my-32">
-      <div className="flex w-full flex-col gap-y-4 lg:max-w-[583px] lg:gap-y-12">
-        <div className="font-outfit">
-          <h2 className="py-1 text-2xl font-semibold sm:text-4xl">
-            Recover Password
-          </h2>
-          <p className="mt-2 text-base md:text-lg font-normal text-black/60 dark:text-neutral-400">
-            If you forgot your password, recover it by entering your email
-            address.
-          </p>
-        </div>
-
-        <form
-          noValidate
-          className="flex flex-col gap-y-5 md:gap-y-10"
-          onSubmit={handleSubmit(onSubmit)}
-        >
-          <InputText
-            {...register("email", {
-              required: "Email is required",
-              pattern: {
-                value: EMAIL_REGEX,
-                message: "Please enter a valid email address.",
-              },
-            })}
-            errorMsg={errors?.email?.message ? [errors.email.message] : undefined}
-            label="Enter Your Email Address"
-            labelPlacement="outside"
-            name="email"
-            placeholder="Enter email address"
-            size="lg"
-            typeName="email"
-          />
-
-          <div className="flex flex-col gap-y-3 md:gap-y-2">
-            <Button
-              disabled={loading || isSubmitting}
-              loading={loading || isSubmitting}
-              title="Reset Password"
-              type="submit"
-            />
-            <span className="px-1 mx-auto md:mx-0 font-outfit">
-              Back to sign in?{" "}
-              <Link className="text-blue-600 underline" href="/customer/login" aria-label="Go to sign in page">
-                Sign In
-              </Link>
-            </span>
-          </div>
-        </form>
-      </div>
-
-      <div className="relative hidden aspect-[1] max-h-[692px] w-full max-w-[790px] sm:block md:aspect-[1.14]">
-        <Image
-          fill
-          priority
-          alt="Forget Password Illustration"
-          className={clsx(
-            "relative h-full w-full object-fill",
-            "transition duration-300 ease-in-out group-hover:scale-105"
-          )}
-          sizes={"(min-width: 768px) 66vw, 100vw"}
-          src={FORGET_PASSWORD_IMG}
-        />
-      </div>
-    </div>
-  );
-}

+ 0 - 183
src/components/customer/LoginForm.tsx

@@ -1,183 +0,0 @@
-"use client";
-
-import clsx from "clsx";
-import { signIn } from "next-auth/react";
-import Image from "next/image";
-import Link from "next/link";
-import { useRouter } from "next/navigation";
-import { SubmitHandler, useForm } from "react-hook-form";
-import { Button } from "@components/common/button/Button";
-import { EMAIL_REGEX, SIGNIN_IMG } from "@/utils/constants";
-import InputText from "@components/common/form/Input";
-import { useCustomToast } from "@/utils/hooks/useToast";
-import { mergeCartAction, deleteGuestCookieAction } from "@/actions";
-import { useAppSelector } from "@/store/hooks";
-import { useCartDetail } from "@utils/hooks/useCartDetail";
-
-type LoginFormInputs = {
-  username: string;
-  password: string;
-};
-
-export default function LoginForm() {
-  const router = useRouter();
-  const { showToast } = useCustomToast();
-  const { getCartDetail } = useCartDetail()
-
-  const cart = useAppSelector((state) => state.cartDetail.cart);
-  const {
-    register,
-    handleSubmit,
-    formState: { errors, isSubmitting },
-  } = useForm<LoginFormInputs>({
-    mode: "onSubmit",
-    reValidateMode: "onChange",
-  });
-
-  const onSubmit: SubmitHandler<LoginFormInputs> = async (data) => {
-    try {
-
-      const result = await signIn("credentials", {
-        redirect: false,
-        ...data,
-        callbackUrl: "/", // The callbackUrl specifies to which URL the user will be redirected after signing in. Defaults to the page URL the sign-in is initiated from.
-      });
-      console.log('result --- ',result);
-
-      if (!result?.ok) {
-        showToast(result?.error || "Invalid login credentials.", "warning");
-        return;
-      }
-      showToast("Welcome! Successfully logged in.", "success");
-
-
-        if(cart) {
-          await mergeCartAction();
-        } else {
-          await deleteGuestCookieAction(false);
-          await getCartDetail();
-        }
-
-        setTimeout(() => {
-          router.push("/");
-          router.refresh();
-        }, 100);
-
-
-    } catch (error) {
-      console.error(error);
-      showToast("Something went wrong. Please try again.", "danger");
-    }
-  };
-
-  return (
-    <div className="flex w-full items-center max-w-screen-2xl mx-auto px-4  xss:px-7.5 justify-between gap-4 lg:my-16 xl:my-28">
-      <div className="flex w-full max-w-[583px] flex-col gap-y-4 lg:gap-y-12">
-        <div className="font-outfit">
-          <h2 className="py-1 text-2xl font-semibold sm:text-4xl">
-            Sign in to your account
-          </h2>
-          <p className="mt-2  text-base md:text-lg font-normal text-black/60 dark:text-neutral-400">
-            If you have an account, sign in with your email address.
-          </p>
-        </div>
-
-        <form
-          noValidate
-          className="flex flex-col gap-y-4 lg:gap-y-12"
-          onSubmit={handleSubmit(onSubmit)}
-        >
-          <div className="flex flex-col gap-y-2.5 lg:gap-4">
-            <InputText
-              {...register("username", {
-                required: "Email is required",
-                pattern: {
-                  value: EMAIL_REGEX,
-                  message: "Please enter a valid email.",
-                },
-              })}
-              errorMsg={
-                errors.username?.message ? [errors.username.message] : undefined
-              }
-              label="Enter Your Email Address"
-              labelPlacement="outside"
-              name="username"
-              placeholder="Enter your email address"
-              rounded="md"
-              size="lg"
-              typeName="email"
-            />
-
-            <InputText
-              {...register("password", {
-                required: "Password is required",
-                minLength: {
-                  value: 2,
-                  message: "Be at least 2 characters long",
-                },
-                validate: (value) => {
-                  if (!/[0-2]/.test(value))
-                    return "Contain at least one number.";
-
-                  return true;
-                },
-              })}
-              errorMsg={
-                errors.password?.message ? [errors.password.message] : undefined
-              }
-              label="Enter Password"
-              labelPlacement="outside"
-              name="password"
-              placeholder="Enter your password"
-              rounded="md"
-              size="lg"
-              typeName="password"
-            />
-
-            <Link
-              className="text-end text-sm font-medium text-blue-600 underline hover:text-blue-500 underline"
-              href="/customer/forget-password"
-              aria-label="Go to forgot password page"
-            >
-              Forgot your password ?
-            </Link>
-          </div>
-
-          <div className="flex flex-col gap-2 lg:gap-y-3">
-            <Button
-              className="cursor-pointer"
-              disabled={isSubmitting}
-              loading={isSubmitting}
-              title="Sign In"
-              type="submit"
-            />
-            <span className="mx-auto font-outfit sm:mx-0">
-              New customer?{" "}
-              <Link
-                className="font-medium text-blue-600 hover:text-blue-500 underline"
-                href="/customer/register"
-                aria-label="Go to create account page"
-              >
-                Create your account
-              </Link>
-            </span>
-          </div>
-        </form>
-      </div>
-
-      <div className="relative hidden aspect-[0.9] max-h-[692px] w-full max-w-[790px] sm:block md:aspect-[1.14]">
-        <Image
-          fill
-          priority
-          alt="Sign In Image"
-          className={clsx(
-            "relative h-full w-full object-fill",
-            "transition duration-300 ease-in-out group-hover:scale-105"
-          )}
-          sizes={"(min-width: 768px) 66vw, 100vw"}
-          src={SIGNIN_IMG}
-        />
-      </div>
-    </div>
-  );
-}

+ 0 - 214
src/components/customer/RegistrationForm.tsx

@@ -1,214 +0,0 @@
-"use client";
-
-import Image from "next/image";
-import Link from "next/link";
-import { SubmitHandler, useForm } from "react-hook-form";
-import InputText from "@components/common/form/Input";
-import { useCustomToast } from "@/utils/hooks/useToast";
-import { useRouter } from "next/navigation";
-import { EMAIL_REGEX, SIGNUP_IMG, IS_VALID_INPUT } from "@utils/constants";
-import { createUser } from "@utils/actions";
-import { Button } from "@components/common/button/Button";
-
-export type RegisterInputs = {
-  firstName: string;
-  lastName: string;
-  email: string;
-  password: string;
-  passwordConfirmation: string;
-};
-
-export default function RegistrationForm() {
-  const router = useRouter();
-
-  const {
-    register,
-    handleSubmit,
-    formState: { errors, isSubmitting },
-  } = useForm<RegisterInputs>({
-    mode: "onSubmit",
-    reValidateMode: "onChange",
-  });
-
-  const { showToast } = useCustomToast();
-
-  /**
-   * 
-   * 浏览器端 RegistrationForm.onSubmit
-      → 调用 createUser(data)  ← 这是一个 Server Action
-        → 发送 POST 请求到当前页面路由(或者由框架生成的端点)
-          → 服务端执行 createUser 函数(访问 cookies、session、数据库等)
-            → 返回结果给浏览器 
-   */
-  const onSubmit: SubmitHandler<RegisterInputs> = async (data) => {
-    console.log('register run where?--------');
-    if (data.password !== data.passwordConfirmation) {
-      showToast("The Passwords do not match.", "warning");
-      return;
-    }
-
-    await createUser(data)
-      .then((res) => {
-        if (res?.success) {
-          showToast("User created successfully", "success");
-          router.replace("/customer/login");
-        } else {
-          showToast(res?.error?.message || "Failed to create user", "warning");
-        }
-      })
-      .catch((error) => {
-        showToast(error.message || "An error occurred", "warning");
-      });
-  };
-
-  return (
-    <div className="mt-5 md:my-8 md:mt-0 flex w-full items-center w-full max-w-screen-2xl mx-auto px-4 xss:px-7.5 justify-between gap-0 md:gap-4 lg:my-16 xl:my-28">
-      <div className="relative flex w-full max-w-[583px] flex-col gap-y-4 lg:gap-y-12">
-        <div className="font-outfit">
-          <h2 className="py-1 text-2xl font-semibold sm:text-4xl">
-            Become User
-          </h2>
-          <p className="mt-2 text-base md:text-lg font-normal text-black/[60%] dark:text-neutral-400 sm:mt-2">
-            You are new to our store, we are glad to have you as a member.
-          </p>
-        </div>
-
-        <form
-          noValidate
-          className="flex flex-col gap-y-5 lg:gap-y-12"
-          onSubmit={handleSubmit(onSubmit)}
-        >
-          <div className="flex flex-col gap-y-2.5 lg:gap-[18px]">
-            <div className="flex w-full gap-2.5 lg:gap-[18px]">
-              <InputText
-                {...register("firstName", {
-                  required: "First name is required",
-                  pattern: {
-                    value: IS_VALID_INPUT,
-                    message: "Invalid First Name",
-                  },
-                })}
-                className="w-full"
-                errorMsg={
-                  errors.firstName?.message
-                    ? [errors.firstName.message]
-                    : undefined
-                }
-                label="First Name"
-                labelPlacement="outside"
-                name="firstName"
-                placeholder="Enter first name"
-                size="lg"
-              />
-              <InputText
-                {...register("lastName",
-                  {
-                    required: "Last name is required",
-                    pattern: {
-                      value: IS_VALID_INPUT,
-                      message: "Invalid Last Name",
-                    },
-                  })}
-                className="w-full"
-                errorMsg={
-                  errors.lastName?.message
-                    ? [errors.lastName.message]
-                    : undefined
-                }
-                label="Last Name"
-                labelPlacement="outside"
-                name="lastName"
-                placeholder="Enter last name"
-                size="lg"
-              />
-            </div>
-
-            <InputText
-              {...register("email", {
-                required: "Email is required",
-                pattern: {
-                  value: EMAIL_REGEX,
-                  message: "Please enter a valid email.",
-                },
-              })}
-              errorMsg={errors.email?.message}
-              label="Email"
-              labelPlacement="outside"
-              name="email"
-              placeholder="Enter email address"
-              size="lg"
-            />
-
-            <InputText
-              {...register("password", {
-                required: "Password is required",
-                minLength: {
-                  value: 8,
-                  message: "Must be at least 8 characters",
-                },
-                validate: (val) => {
-                  if (!/[A-Z]/.test(val))
-                    return "Must contain at least one uppercase letter";
-                  if (!/[a-z]/.test(val))
-                    return "Must contain at least one lowercase letter";
-                  if (!/[0-9]/.test(val))
-                    return "Must contain at least one number";
-                  if (/\s/.test(val)) return "Cannot contain spaces";
-
-                  return true;
-                },
-              })}
-              label="Password"
-              labelPlacement="outside"
-              name="password"
-              placeholder="Enter password"
-              typeName="password"
-              size="lg"
-              errorMsg={
-                errors.password?.message ? [errors.password.message] : undefined
-              }
-            />
-
-            <InputText
-              {...register("passwordConfirmation", {
-                required: "Please confirm your password",
-              })}
-              label="Confirm Password"
-              labelPlacement="outside"
-              name="passwordConfirmation"
-              placeholder="Enter confirm password"
-              size="lg"
-              typeName="password"
-            />
-          </div>
-
-          <div className="flex flex-col gap-y-3 mb-8 lg:mb-0">
-            <Button
-              disabled={isSubmitting}
-              loading={isSubmitting}
-              title="Sign Up"
-              type="submit"
-            />
-            <span className="mx-auto md:mx-0 font-outfit">
-              Already have an account?{" "}
-              <Link className="text-blue-600 underline" href="/customer/login" aria-label="Go to sign in page">
-                Sign In
-              </Link>
-            </span>
-          </div>
-        </form>
-      </div>
-
-      <div className="relative hidden aspect-[0.9] max-h-[692px] w-full max-w-[790px] sm:block md:aspect-[1.14]">
-        <Image
-          fill
-          priority
-          alt="Sign Up Image"
-          className="h-full w-full object-cover transition duration-300 ease-in-out group-hover:scale-105"
-          sizes="(min-width: 768px) 66vw, 100vw"
-          src={SIGNUP_IMG}
-        />
-      </div>
-    </div>
-  );
-}

+ 0 - 161
src/components/home/CategoryCarousel.tsx

@@ -1,161 +0,0 @@
-import { FC } from "react";
-import Link from "next/link";
-import clsx from "clsx";
-import { cachedGraphQLRequest } from "@/utils/hooks/useCache";
-import { GridTileImage } from "../theme/ui/grid/Tile";
-import { NOT_IMAGE } from "@/utils/constants";
-import { GET_HOME_CATEGORIES } from "@/graphql";
-import { CategoriesResponse } from "@/types/category/type";
-
-interface CategoryCarouselProps {
-  options: {
-    filters: Record<string, string | number | boolean | undefined>;
-  };
-}
-
-interface MobileCategoryItemProps {
-  category: any;
-  size: "full" | "half";
-  priority?: boolean;
-}
-
-const MobileCategoryItem: FC<MobileCategoryItemProps> = ({
-  category,
-  size,
-  priority,
-}) => {
-  return (
-    <div
-      className={
-        size === 'full' ? 'col-span-1 xxs:col-span-2 order-2' : 'col-span-1'
-      }
-    >
-      <Link
-        aria-label={`Shop ${category.translation.name} category`}
-        className={clsx(
-          "relative block h-full w-full aspect-[380/280]",
-          size === "half" && "xxs:aspect-[182/280]"
-        )}
-        href={`/category/${category.translation.slug}`}
-      >
-        <GridTileImage
-          fill
-          alt={`${category.translation.name} category image`}
-          className="relative h-full w-full object-cover transition duration-300 ease-in-out group-hover:scale-105"
-          label={{
-            position: "center",
-            title: category.translation.name || "",
-            page: "category",
-            amount: "0",
-            currencyCode: "USD",
-          }}
-          priority={priority}
-          sizes={
-            size === "full"
-              ? "100vw"
-              : "(min-width: 480px) 50vw, 100vw"
-          }
-          src={category.logoUrl || NOT_IMAGE}
-        />
-      </Link>
-    </div>
-  );
-};
-
-interface CategoryCarouselProps {
-  options: {
-    filters: Record<string, string | number | boolean | undefined>;
-  };
-}
-
-const CategoryCarousel: FC<CategoryCarouselProps> = async ({
-  options: _options,
-}) => {
-  
-    const {data} = await cachedGraphQLRequest<CategoriesResponse>(
-      "home",
-      GET_HOME_CATEGORIES,
-      {}
-    );
-
-    const categories =
-      data?.categories?.edges?.map((edge) => edge.node) || [];
-
-    const topCategories = categories
-      .filter((category) => category.id !== "1")
-      .sort((a, b) => (a.position || 0) - (b.position || 0))
-      .slice(1, 4);
-
-    if (!topCategories.length) return null;
-
-    return (
-      <section className="pt-8 sm:pt-12 lg:pt-20">
-        <div className="md:max-w-4.5xl mx-auto mb-10 w-auto text-center md:px-36">
-          <h2 className="mb-2 text-xl md:text-4xl  font-semibold">
-            Shop by Category
-          </h2>
-          <p className="text-sm md:text-base font-normal text-black/60 dark:text-neutral-300">
-            Discover the latest trends! Fresh products just added—shop new
-            styles, tech, and essentials before they&apos;re gone.
-          </p>
-        </div>
-        <div className="w-full overflow-x-auto overflow-y-hidden">
-          <div className="grid gap-4 grid-cols-1 xxs:grid-cols-2 lg:max-h-[calc(100vh-200px)] sm:hidden">
-            {topCategories.length > 0 && (
-              <MobileCategoryItem
-                category={topCategories[0]}
-                size="half"
-                priority={true}
-              />
-            )}
-            {topCategories.length > 1 && (
-              <MobileCategoryItem
-                category={topCategories[1]}
-                size="full"
-                priority={true}
-              />
-            )}
-            {topCategories.length > 2 && (
-              <MobileCategoryItem
-                category={topCategories[2]}
-                size="half"
-              />
-            )}
-          </div>
-
-          <ul className="m-0 hidden grid-cols-1 gap-7 p-0 xxs:grid-cols-2 sm:grid sm:grid-cols-3">
-            {topCategories.map((category) => (
-              <li
-                key={category.id}
-                className="relative aspect-498/665 h-full w-full max-w-[498px] flex-none overflow-hidden rounded-[18px]"
-              >
-                <Link
-                  className="relative h-full w-full"
-                  href={`/category/${category.translation.slug}`}
-                  aria-label={`Shop ${category.translation.name} category`}
-                >
-                  <GridTileImage
-                    fill
-                    alt={`${category.translation.name} category image`}
-                    className={
-                      "relative rounded-[18px] overflow-hidden object-cover transition duration-300 ease-in-out group-hover:scale-105"
-                    }
-                    label={{
-                      title: category.translation.name || "",
-                      page: "category",
-                      amount: "0",
-                      currencyCode: "USD",
-                    }}
-                    src={category.logoUrl || NOT_IMAGE}
-                  />
-                </Link>
-              </li>
-            ))}
-          </ul>
-        </div>
-      </section>
-    );
-
-};
-
-export default CategoryCarousel;

+ 15 - 0
src/types/customer/type.ts

@@ -10,6 +10,21 @@ export type {
     OrderAddressType
 } from "./order";
 
+export interface LoginFormData {
+    username:string;
+    password:string;
+}
+export interface RegisterFormData {
+    firstName: string;
+    lastName: string;
+    email: string;
+    password: string;
+    confirmPassword: string;
+    phone: string;
+    subscribedToNewsLetter: boolean;
+    isAgree: boolean;
+}
+
 export interface CustomerLoginData{
     id: string;
     apiToken: string;

+ 1 - 4
src/types/types.ts

@@ -410,10 +410,7 @@ export type BagistoUser = {
   name: string;
 };
 
-export type BagistoCreateUserOperation = {
-  data: CreateUserResponse;
-  variables: CreateUserVariables;
-};
+
 
 export type SuperAttribute = {
   attributeId: number;

+ 1 - 64
src/utils/actions.ts

@@ -2,12 +2,9 @@
 // 文件顶部的 "use server" 是所有导出的异步函数自动成为 Server Action 的标志。
 import { redirect } from "next/navigation";
 import {
-  createUserToLogin,
-  recoverUserLogin,
   subscribeUser,
 } from '@/utils/bagisto';
-import { isObject } from "@utils/type-guards";
-import { RegisterInputs } from "@components/customer/RegistrationForm";
+
 import { RecoverPasswordFormState } from "@components/customer/types";
 
 export type RegisterFormState = {
@@ -28,66 +25,6 @@ export async function redirectToCheckout(formData: FormData) {
 }
 
 
-export async function createUser(formData: RegisterInputs) {
-  try {
-    const { firstName, lastName, email, password, passwordConfirmation } =
-      formData;
-
-    const user = await createUserToLogin({
-      firstName,
-      lastName,
-      email,
-      password,
-      passwordConfirmation,
-    });
-
-    return {
-      error: {},
-      success: true,
-      customer: user,
-    };
-  } catch (err: any) {
-    return {
-      error: { message: err?.message || "An error occurred" },
-      success: false,
-      customer: null,
-    };
-  }
-}
-
-
-export async function recoverPassword(formData: {
-  email: string;
-}): Promise<RecoverPasswordFormState> {
-
-  const result = await recoverUserLogin({ email: formData.email }) as any;
-
-  if (isObject(result?.error)) {
-    const error = result.error as Record<string, unknown>;
-    return {
-      errors: {
-        apiRes: {
-          status: false,
-          msg: (error?.message as string) ?? "Something went wrong",
-        },
-      },
-    };
-  }
-
-  const body = result?.body;
-  const createForgotPassword = body?.data?.createForgotPassword;
-  const forgotPassword = createForgotPassword?.forgotPassword;
-
-  return {
-    success: {
-      status: forgotPassword?.success ?? false,
-      msg: "Recovery email sent successfully.",
-    },
-  };
-}
-
-
-
 
 export async function userSubscribe(
   _prevState: RecoverPasswordFormState,

+ 1 - 98
src/utils/bagisto/index.ts

@@ -1,16 +1,5 @@
-import { cookies, headers } from "next/headers";
-import { revalidatePath } from "next/cache";
-import { NextRequest, NextResponse } from "next/server";
-import {
-  BagistoCreateUserOperation,
-  BagistoUser,
-} from "@/types/types";
+import { cookies } from "next/headers";
 import { auth } from "@/utils/auth/auth-helper";
-// import { getToken,decode } from "next-auth/jwt";
-import {
-  CUSTOMER_REGISTRATION,
-  FORGET_PASSWORD,
-} from "@/graphql/customer/mutations";
 import { print, DocumentNode } from "graphql";
 import { 
   GRAPHQL_URL, 
@@ -28,7 +17,6 @@ import {
 } from "@/graphql";
 import { SUBSCRIBE_TO_NEWSLETTER } from "@/graphql/theme/mutations";
 import { cachedGraphQLRequest } from "@/utils/hooks/useCache";
-import { RegisterInputs } from "@components/customer/RegistrationForm";
 import {
   GetFooterResponse,
   ThemeCustomizationResult,
@@ -358,53 +346,6 @@ export async function bagistoFetch<T>({
 }
 
 
-export async function createUserToLogin(
-  input: RegisterInputs,
-): Promise<BagistoUser> {
-  try {
-    const { passwordConfirmation, ...userInput } = input;
-    const res = await bagistoFetch<BagistoCreateUserOperation>({
-      query: CUSTOMER_REGISTRATION,
-      variables: {
-        input: {
-          ...userInput,
-          confirmPassword: passwordConfirmation,
-          status: "1",
-          isVerified: "1",
-          isSuspended: "0",
-          subscribedToNewsLetter: true,
-        },
-      },
-      cache: "no-store",
-      revalidate: 3600,
-    });
-
-    return res.body.data.createCustomer.customer;
-  } catch (error: any) {
-    throw new Error(error?.message || "Registration failed");
-  }
-}
-
-
-export async function recoverUserLogin(
-  input: Record<string, unknown>,
-): Promise<unknown> {
-  try {
-    return await bagistoFetch<{
-      data: unknown;
-      variables: Record<string, unknown>;
-    }>({
-      query: FORGET_PASSWORD,
-      variables: {
-        ...input,
-      },
-      cache: "no-store",
-      revalidate: 3600,
-    });
-  } catch (error) {
-    return error;
-  }
-}
 
 export async function subscribeUser(
   input: Record<string, unknown>,
@@ -450,44 +391,6 @@ export async function getThemeCustomization(): Promise<ThemeCustomizationResult>
   };
 }
 
-export async function revalidate(req: NextRequest): Promise<NextResponse> {
-  const collectionWebhooks = [
-    "collections/create",
-    "collections/delete",
-    "collections/update",
-  ];
-  const productWebhooks = [
-    "products/create",
-    "products/delete",
-    "products/update",
-  ];
-  const topic = (await headers()).get("x-bagisto-topic") || "unknown";
-  const secret = req.nextUrl.searchParams.get("secret");
-  const isCollectionUpdate = collectionWebhooks.includes(topic);
-  const isProductUpdate = productWebhooks.includes(topic);
-
-  if (!secret || secret !== process.env.BAGISTO_REVALIDATION_SECRET) {
-    return NextResponse.json({ status: 200 });
-  }
-
-  if (!isCollectionUpdate && !isProductUpdate) {
-    return NextResponse.json({ status: 200, message: "No action needed" });
-  }
-
-  if (isProductUpdate) {
-    revalidatePath("/", "layout");
-  } else if (isCollectionUpdate) {
-    revalidatePath("/", "layout");
-  }
-
-  return NextResponse.json({
-    status: 200,
-    revalidated: true,
-    topic,
-    now: Date.now(),
-  });
-}
-
 
 export async function getPage(input: { urlKey: string }): Promise<PageData[]> {
   const res = await bagistoFetch<{

+ 0 - 3
src/utils/constants.ts

@@ -29,9 +29,6 @@ export const SORT = "sort";
 /**
  * Placeholder Images
  */
-export const SIGNUP_IMG = "/image/sign-in.webp";
-export const SIGNIN_IMG = "/image/login.webp";
-export const FORGET_PASSWORD_IMG = "/image/forget-password.webp";
 export const NOT_IMAGE = "/image/placeholder.webp";
 export const LOGO_IMG = "/image/logo.png";
 

+ 7 - 13
src/utils/metadata.ts

@@ -1,27 +1,21 @@
 
 export const staticSeo = {
   default: {
-    title: "Bagisto Headless",
-    description: "Headless eCommerce with Bagisto",
-    image: "/Logo.webp",
+    title: "Aateria Hair",
+    description: "Aateria Hair",
+    image: "/logo.png",
     canonical: "/",
   },
-  register : {
-    title: "Register",
-    description: "Register to Bagisto Headless",
-    image: "/Logo.webp",
-    canonical: "/customer/register",
-  },
   login: {
-    title: "Login",
-    description: "Login to Bagisto Headless",
-    image: "/Logo.webp",
+    title: "Login or Register",
+    description: "Login or Register to Aateria",
+    image: "/logo.png",
     canonical: "/customer/login",
   },
   forget:{
     title: "Forget Password",
   description: "Recover your account by resetting your password.",
-  image: "/Logo.webp",
+  image: "/logo.png",
   canonical: "/customer/forget-password",
   }
 };