|
|
@@ -0,0 +1,304 @@
|
|
|
+"use client";
|
|
|
+import { useState, useEffect, useMemo } from "react";
|
|
|
+import { useParams } from "next/navigation";
|
|
|
+import Link from "next/link";
|
|
|
+import { clientFetch } from "@/lib/restApiClient";
|
|
|
+import Select from "@/components/theme/ui/Select";
|
|
|
+import { useForm, FormProvider, Controller } from "react-hook-form";
|
|
|
+import CustomerAddressPhone from "../../new/_components/CustomerAddressPhone";
|
|
|
+const CustomerAddressEditPage = () => {
|
|
|
+ // 定义表单类型(严格对齐你要的字段)
|
|
|
+ interface AddressFormData {
|
|
|
+ first_name: string;
|
|
|
+ last_name: string;
|
|
|
+ email: string;
|
|
|
+ phone: string;
|
|
|
+ address: string[];
|
|
|
+ country: string;
|
|
|
+ state: string;
|
|
|
+ city: string;
|
|
|
+ postcode: string;
|
|
|
+ default_address: number;
|
|
|
+ }
|
|
|
+ const { id } = useParams();
|
|
|
+ // const [form, setForm] = useState({});
|
|
|
+ // 1. 根据ID获取地址详情
|
|
|
+ console.log("addressid:", id);
|
|
|
+ const COUNTRIES = [
|
|
|
+ { id: 1, code: "AF", name: "Afghanistan" },
|
|
|
+ { id: 2, code: "AX", name: "Åland Islands" },
|
|
|
+ { id: 3, code: "AL", name: "Albania" },
|
|
|
+ { id: 4, code: "DZ", name: "Algeria" },
|
|
|
+ { id: 49, code: "CN", name: "China" },
|
|
|
+ { id: 244, code: "US", name: "United States" },
|
|
|
+ ];
|
|
|
+ const countriesOptions = useMemo(() => {
|
|
|
+ return COUNTRIES.map((country) => ({
|
|
|
+ value: country.code,
|
|
|
+ label: country.name,
|
|
|
+ id: String(country.id),
|
|
|
+ }));
|
|
|
+ }, [COUNTRIES]);
|
|
|
+ const [actionType, setActionType] = useState<"save" | "delete">("save");
|
|
|
+ // 修改地址到接口
|
|
|
+ const UpdataAddress = async (formData: AddressFormData) => {
|
|
|
+ const res = await clientFetch(`/api/customer/token/address?id=${id}`, {
|
|
|
+ method: "PUT",
|
|
|
+ headers: {
|
|
|
+ "Content-Type": "application/json",
|
|
|
+ },
|
|
|
+ body: JSON.stringify(formData),
|
|
|
+ });
|
|
|
+ const json = await res;
|
|
|
+ console.log("提交成功,返回结果:", json);
|
|
|
+ if(json?.data?.success){
|
|
|
+ window.location.reload();
|
|
|
+ }else{
|
|
|
+ alert("error");
|
|
|
+ }
|
|
|
+ return json;
|
|
|
+ };
|
|
|
+ // 删除地址接口
|
|
|
+ const DeleteAddress =async ()=>{
|
|
|
+ const res = await clientFetch(`/api/customer/token/address?id=${id}`, {
|
|
|
+ method: "DELETE",
|
|
|
+ headers: {
|
|
|
+ "Content-Type": "application/json",
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const json = await res;
|
|
|
+ console.log("删除成功,返回结果:", json);
|
|
|
+ }
|
|
|
+ // 表单提交
|
|
|
+ const addressFormOnSubmit = async (formData: AddressFormData) => {
|
|
|
+ console.log("actionType",actionType);
|
|
|
+
|
|
|
+ if (actionType === "save") {
|
|
|
+ UpdataAddress(formData);
|
|
|
+ } else {
|
|
|
+ DeleteAddress();
|
|
|
+ console.log("执行删除");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 表单实例(严格对齐你需要的字段)
|
|
|
+ const addressForm = useForm<AddressFormData>({
|
|
|
+ mode: "onBlur",
|
|
|
+ reValidateMode: "onChange",
|
|
|
+ defaultValues: {
|
|
|
+ first_name: "",
|
|
|
+ last_name: "",
|
|
|
+ email: "",
|
|
|
+ phone: "",
|
|
|
+ address: ["", ""], // 数组格式
|
|
|
+ country: "",
|
|
|
+ state: "",
|
|
|
+ city: "",
|
|
|
+ postcode: "",
|
|
|
+ default_address: 0,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ const {
|
|
|
+ reset,
|
|
|
+ register,
|
|
|
+ handleSubmit,
|
|
|
+ formState: { errors, isValid },
|
|
|
+ } = addressForm;
|
|
|
+ useEffect(() => {
|
|
|
+ if (!id) return;
|
|
|
+ const load = async () => {
|
|
|
+ const resp = await clientFetch(`/api/customer/token/address?id=${id}`);
|
|
|
+ console.log("【完整接口响应】", resp);
|
|
|
+
|
|
|
+ // 自动兼容后端 99% 的返回格式
|
|
|
+ const formData = resp.data?.data || resp.data || {};
|
|
|
+ console.log("✅ 回填数据:", formData);
|
|
|
+
|
|
|
+ reset(formData);
|
|
|
+ };
|
|
|
+ load();
|
|
|
+ }, [id, reset]);
|
|
|
+ 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/address"}
|
|
|
+ // onClick={() => window.history.back()}
|
|
|
+ className="absolute left-2.5 text-2xl inline-block top-1/2 -translate-y-1/2"
|
|
|
+ >
|
|
|
+ <svg
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ width="24"
|
|
|
+ height="24"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ fill="none"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ stroke="rgba(0, 0, 0, 1)"
|
|
|
+ stroke-width="1.2"
|
|
|
+ stroke-linejoin="round"
|
|
|
+ stroke-linecap="round"
|
|
|
+ d="M15 18L9 12L15 6"
|
|
|
+ ></path>
|
|
|
+ </svg>
|
|
|
+ </Link>
|
|
|
+ <span className="vipReturnTitles">ADDRESS EDIT</span>
|
|
|
+ </div>
|
|
|
+ <div className="max-w-md mx-auto bg-[#f8f8f8]">
|
|
|
+ <FormProvider {...addressForm}>
|
|
|
+ <form
|
|
|
+ className="overflow-hidden"
|
|
|
+ onSubmit={handleSubmit(addressFormOnSubmit)}
|
|
|
+ >
|
|
|
+ <div className="bg-[#f8f8f8] p-[20px_10px]">
|
|
|
+ {/* 姓名 */}
|
|
|
+ <div className="text-start">*Name</div>
|
|
|
+ <div className="flex justify-between items-center gap-3">
|
|
|
+ {/* firstname */}
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="firstname"
|
|
|
+ {...register("first_name", {
|
|
|
+ required: "First name is required",
|
|
|
+ })}
|
|
|
+ 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"
|
|
|
+ />
|
|
|
+ {/* lastname */}
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="last_name"
|
|
|
+ {...register("last_name", {
|
|
|
+ required: "Last name is required",
|
|
|
+ })}
|
|
|
+ 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]"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ {errors.first_name && (
|
|
|
+ <p className="text-red-500 text-sm mt-1">
|
|
|
+ {errors.first_name.message}
|
|
|
+ </p>
|
|
|
+ )}
|
|
|
+ {errors.last_name && (
|
|
|
+ <p className="text-red-500 text-sm mt-1">
|
|
|
+ {errors.last_name.message}
|
|
|
+ </p>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* 手机号 */}
|
|
|
+ <CustomerAddressPhone />
|
|
|
+ <Controller
|
|
|
+ control={addressForm.control}
|
|
|
+ name="country"
|
|
|
+ rules={{ required: "Country is required" }}
|
|
|
+ render={({ field }) => {
|
|
|
+ return (
|
|
|
+ <Select
|
|
|
+ placeholder="Country/Region"
|
|
|
+ defaultValue={field.value}
|
|
|
+ onChange={field.onChange}
|
|
|
+ onBlur={field.onBlur}
|
|
|
+ name={field.name}
|
|
|
+ options={countriesOptions}
|
|
|
+ error={errors.country?.message as string}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ {/* <input {...register("country")} /> */}
|
|
|
+ {/* 邮箱 */}
|
|
|
+ <div className="mt-4">
|
|
|
+ <label>Email Address*</label>
|
|
|
+ <input
|
|
|
+ type="email"
|
|
|
+ placeholder="Email"
|
|
|
+ {...register("email", {
|
|
|
+ required: "Email is required",
|
|
|
+ pattern: {
|
|
|
+ value: /^\S+@\S+\.\S+$/,
|
|
|
+ message: "Invalid email",
|
|
|
+ },
|
|
|
+ })}
|
|
|
+ className="w-full h-11 rounded-sm border border-[rgba(102,102,102,1)] indent-4 text-base mt-1"
|
|
|
+ />
|
|
|
+ {errors.email && (
|
|
|
+ <p className="text-red-500 text-sm mt-1">
|
|
|
+ {errors.email.message}
|
|
|
+ </p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 邮编 */}
|
|
|
+ <div className="mt-4">
|
|
|
+ <label>Zip/Postal Code</label>
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="Postcode"
|
|
|
+ {...register("postcode")}
|
|
|
+ className="w-full h-11 rounded-sm border border-[rgba(102,102,102,1)] indent-4 text-base mt-1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 省/州 */}
|
|
|
+ <div className="mt-4">
|
|
|
+ <label>State / Province</label>
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="State"
|
|
|
+ {...register("state")}
|
|
|
+ className="w-full h-11 rounded-sm border border-[rgba(102,102,102,1)] indent-4 text-base mt-1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 城市 */}
|
|
|
+ <div className="mt-4">
|
|
|
+ <label>City</label>
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="City"
|
|
|
+ {...register("city")}
|
|
|
+ className="w-full h-11 rounded-sm border border-[rgba(102,102,102,1)] indent-4 text-base mt-1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 默认地址 */}
|
|
|
+ <label className="flex items-center gap-2 cursor-pointer mt-4">
|
|
|
+ <input
|
|
|
+ type="checkbox"
|
|
|
+ {...register("default_address", { valueAsNumber: true })}
|
|
|
+ className="w-5 h-5"
|
|
|
+ />
|
|
|
+ <span>Use as my default address</span>
|
|
|
+ </label>
|
|
|
+
|
|
|
+ {/* 提交按钮 */}
|
|
|
+ <button
|
|
|
+ className="w-full h-11 leading-11 bg-[#1bbc9b] text-white text-center mt-6 rounded"
|
|
|
+ type="button"
|
|
|
+ onClick={() => {
|
|
|
+ setActionType("save");
|
|
|
+ document.getElementById("realSubmit")?.click();
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ Save Address
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ className="w-full h-11 leading-11 bg-[#1bbc9b] text-white text-center mt-6 rounded"
|
|
|
+ type="button"
|
|
|
+ onClick={() => {
|
|
|
+ if (!confirm("确定删除该地址?")) return;
|
|
|
+ setActionType("delete");
|
|
|
+ document.getElementById("realSubmit")?.click();
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ Delete Address
|
|
|
+ </button>
|
|
|
+ <button id="realSubmit" type="submit" hidden />
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </FormProvider>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+export default CustomerAddressEditPage;
|