"use client"; import {useState, useLayoutEffect} from "react"; import { useRouter } from 'next/navigation'; import { signIn } from "next-auth/react"; import clsx from "clsx"; import { useForm, Controller } from "react-hook-form"; import { EMAIL_REGEX, IS_VALID_INPUT, IS_VALID_FULL_PHONE } from "@utils/constants"; import {mergeCartAction} from "@/actions/mergeCartAction"; import { useAppDispatch } from "@/store/hooks"; import { updateCart } from "@/store/slices/cart-slice"; import { useCustomToast } from "@/utils/hooks/useToast"; 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 CommonModal from "@/components/theme/ui/CommonModal"; import InputText from "@/components/theme/ui/InputText"; import PasswordInput from "@/components/theme/ui/PasswordInput"; import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumberInput"; 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; mergeCartSuccess: boolean; cartAfterMerge: CartDetail | null; msg: string; } export default function LoginModal({ isShow, callbackUrl, closeModal, onFinalResult = async () => {}, }: { isShow: boolean; callbackUrl?: string closeModal: (bool: boolean) => void; onFinalResult?: (param: LoginModalReult) =>void | Promise; }) { const router = useRouter(); const dispatch = useAppDispatch(); const {userRegister} = useUserRegister(); const { showToast } = useCustomToast(); const loginForm = useForm({ mode: "onChange", reValidateMode: "onChange", defaultValues: { username: '', password: '' } }); const registerForm = useForm({ mode: "onChange", reValidateMode: "onChange", defaultValues: { firstName: '', lastName: '', email: '', password: '', confirmPassword: '', phone: '', subscribedToNewsLetter: true, isAgree: true } }); const [activeTab, setActiveTab] = useState('login'); useLayoutEffect(() => { if(isShow) { loginForm.reset(); registerForm.reset(); } },[isShow]); const toggleLoginRegister = (tab: TabFlag) => { setActiveTab(tab); }; const toSignin = async (data: {username:string;password:string;flag:'login'|'register';}) => { const result = await signIn("credentials", { redirect: false, username: data.username, password: data.password, callbackUrl }); const finalRes: LoginModalReult = { loginSuccess: false, registerSuccess: data.flag === "register" ? true : false, mergeCartSuccess: false, cartAfterMerge: null, msg: '' }; if (!result?.ok) { // 登录失败 let txt = ''; if(finalRes.registerSuccess) { txt = "Register Successfully! But fail to login: " + result?.error; } else { txt = result?.error || "Fail to login."; } showToast(txt, "danger"); finalRes.msg = txt; onFinalResult(finalRes); return; } // 登录成功 finalRes.loginSuccess = true; showToast("Successfully logged in.", "success"); // 合并购物车 const mergeRes = await mergeCartAction(); finalRes.mergeCartSuccess = mergeRes.success; finalRes.cartAfterMerge = mergeRes.cartDetail; console.log('cartAfterMerge ========', mergeRes); if(mergeRes.cartDetail) { const newCartDetail = formatCartDetail(mergeRes.cartDetail); dispatch(updateCart(newCartDetail)); } await onFinalResult(finalRes); // 关闭登录弹窗 closeModal(false); if(callbackUrl){ router.push(callbackUrl); // 跳转指定页面 }else{ router.refresh(); // 当前页面重新渲染 } }; const loginSubmit = async (data:LoginFormData) => { console.log(data); overlayLoading.start(); await toSignin({ username: data.username, password: data.password, flag: 'login' }); overlayLoading.stop(); }; const registerSubmit = async (registerData: RegisterFormData) => { console.log(registerData); overlayLoading.start(); const registerRes = await userRegister({ input: { firstName: registerData.firstName, lastName: registerData.lastName, email: registerData.email, password: registerData.password, confirmPassword: registerData.confirmPassword, phone: registerData.phone, subscribedToNewsLetter: registerData.subscribedToNewsLetter } }); if(!registerRes.error) { // 注册成功,登录 await toSignin({ username: registerData.email, password: registerData.password, flag: 'register' }); overlayLoading.stop(); } else { overlayLoading.stop(); showToast("Fail to register: " + registerRes.msg, "danger"); onFinalResult({ loginSuccess: false, registerSuccess: false, mergeCartSuccess: false, cartAfterMerge: null, msg: registerRes.msg }) } }; return (<> } body={ <>
{ 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={registerForm.formState.errors.password && registerForm.formState.errors.password.message as 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.'; } if(pass !== password) { return 'The Confirm Passwords do not match the Password'; } return true; }, })} error={registerForm.formState.errors.confirmPassword && registerForm.formState.errors.confirmPassword.message as string} />
{ return ( ); }} />
{ 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={loginForm.formState.errors.password && loginForm.formState.errors.password.message as string} />
} /> ); }