"use client"; import { useMemo, useState, useEffect, useCallback } from "react"; import { useQuery } from "@apollo/client/react"; import clsx from "clsx"; import { useFormContext, useWatch, Controller } from "react-hook-form"; import { formatFinalPhoneValue, getPhoneCodeBycountryCode } from "@/components/theme/ui/PhoneNumberInput/phoneCodeMetaData"; import { GET_COUNTRY_STATES } from "@/graphql"; import { EMAIL_REGEX, IS_VALID_INPUT, IS_VALID_PHONECODE, IS_VALID_FULL_PHONE } from "@utils/constants"; import { useCountries } from "@utils/hooks/useConfig"; 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"; import { LoadingSpinner } from "@components/common/LoadingSpinner"; import {LyDropDown} from "@/components/theme/ui/LyDropDown"; export default function BillingAddressCheckout ({ noAddress, isGuest, showFormField, onShowFormFieldChange, customerAddressList }: { noAddress: boolean; isGuest: boolean; showFormField: boolean; onShowFormFieldChange: (e: boolean) => void; customerAddressList: CustomerAddressItem[]; }) { const countries = useCountries(); const { getValues, setValue, register, clearErrors, formState: { errors }, control } = useFormContext() // retrieve all hook methods const countriesOptions = useMemo(() => { return countries.map((country) => ({ value: country.code, label: country.name, id: String(country._id), })) },[countries]); const [ billingSameAsShipping, selectedCountryCode, firstName, lastName, streetAddress, stateProvince, postCode, city, phoneNumber ] = useWatch({ control, name: [ 'billingSameAsShipping', 'billingCountry', 'billingFirstName', 'billingLastName', 'billingAddress', 'billingState', 'billingPostcode', 'billingCity', 'billingPhoneNumber' ] }); useEffect(() => { if (billingSameAsShipping) { clearErrors([ "billingEmail", "billingFirstName", "billingLastName", "billingCompanyName", "billingAddress", "billingCountry", "billingState", "billingCity", "billingPostcode", "billingPhoneNumber", ]); } }, [billingSameAsShipping, clearErrors]); /* const shippingFields = useWatch({ control, name: [ "shippingEmail", "shippingFirstName", "shippingLastName", "shippingCompanyName", "shippingAddress", "shippingCountry", "shippingState", "shippingCity", "shippingPostcode", "shippingPhoneNumber", ], }); useEffect(() => { if (!billingSameAsShipping) return; const [ shippingEmail, shippingFirstName, shippingLastName, shippingCompanyName, shippingAddress, shippingCountry, shippingState, shippingCity, shippingPostcode, shippingPhoneNumber, ] = shippingFields; setValue("billingEmail", shippingEmail); setValue("billingFirstName", shippingFirstName); setValue("billingLastName", shippingLastName); setValue("billingCompanyName", shippingCompanyName); setValue("billingAddress", shippingAddress); setValue("billingCountry", shippingCountry); setValue("billingCity", shippingCity); setValue("billingPostcode", shippingPostcode); setValue("billingPhoneNumber", shippingPhoneNumber); setValue("billingState", shippingState,{shouldValidate: true}); // 必须触发校验,因为使用浏览器自动填充的时候,可能导致billingState校验不通过,导致无法下单 }, [billingSameAsShipping, shippingFields, setValue]); */ const selectedCountry = useMemo(() => { return countries.find( (country) => country.code === selectedCountryCode) }, [countries, selectedCountryCode]); const { data: statesData, loading: statesLoading } = useQuery(GET_COUNTRY_STATES, { variables: { countryId: selectedCountry?._id }, skip: !selectedCountryCode, }); let statesOptions: { value: string; label: string, id: string }[] = []; if(statesData) { statesOptions = statesData.countryStates.map((state) => ({ value: state.code, label: state.defaultName, id: String(state._id), })); } const [showDropDown, setShowDropDown] = useState(false); // 是否用户手动选择过区号 const [hasUserSelectedPhoneCode, setHasUserSelectedPhoneCode] = useState(false); // 选择国家时同步电话区号 useEffect(() => { const preBillingPhoneNum = getValues('billingPhoneNumber'); const regPhoneCode = IS_VALID_PHONECODE; if(preBillingPhoneNum && !hasUserSelectedPhoneCode) { const newPhoneCode = getPhoneCodeBycountryCode(selectedCountryCode); const codePart = regPhoneCode.exec(preBillingPhoneNum); let phone = preBillingPhoneNum; if(codePart) { phone = preBillingPhoneNum.replace(codePart[0], ''); } if(codePart && newPhoneCode !== codePart[0].trim()) { return; } setValue('billingPhoneNumber',formatFinalPhoneValue(newPhoneCode, phone)) } },[selectedCountryCode,hasUserSelectedPhoneCode,getValues,setValue]); const showMyAddressList = () => { setShowDropDown(true); }; const closeMyaddressList = useCallback(() => { setShowDropDown(false); },[]); // 从地址列表选择地址 const selectAddress = (param: CustomerAddressItem | 'edit') => { if(param === 'edit') { if(!showFormField) onShowFormFieldChange(true); } else { setValue('billingFirstName',param.firstName); setValue('billingLastName',param.lastName); setValue('billingAddress',param.address); setValue('billingCountry',param.country); setValue('billingState',param.state); setValue('billingPostcode',param.postcode); setValue('billingCity',param.city); setValue('billingPhoneNumber',param.phone); } closeMyaddressList(); }; return (<>
Billing Address

Same As Shipping Address

{noAddress ?
+New Shipping Address {!isGuest && }
:

{firstName} {lastName} {phoneNumber}

{!isGuest && }
{streetAddress}, {city}, {stateProvince}, {postCode}, {selectedCountryCode}
}
{selectAddress('edit')}}> Edit Address
{customerAddressList.map((item) => { return (
selectAddress(item)}>

{item.firstName} {item.lastName}, {item.address}, {item.city}, {item.state}, {item.postcode}, {item.country}, {item.phone}

); })}
) : ( )}
{ return ( setHasUserSelectedPhoneCode(true)} /> ); }} />
); }