From 776d26572e69fa9d0b57b586262e4bd86b21dd92 Mon Sep 17 00:00:00 2001
From: it-fixcomart <it@fixcomart.co.id>
Date: Mon, 8 Sep 2025 15:04:49 +0700
Subject: <hafid> validation Address

---
 src/lib/address/components/EditAddress.jsx | 223 ++++++++++++++++++++++-------
 1 file changed, 175 insertions(+), 48 deletions(-)

(limited to 'src/lib/address/components/EditAddress.jsx')

diff --git a/src/lib/address/components/EditAddress.jsx b/src/lib/address/components/EditAddress.jsx
index 6599a764..d9908726 100644
--- a/src/lib/address/components/EditAddress.jsx
+++ b/src/lib/address/components/EditAddress.jsx
@@ -44,6 +44,13 @@ const EditAddress = ({ id, defaultValues }) => {
   const [districts, setDistricts] = useState([]);
   const [subDistricts, setSubDistricts] = useState([]);
   const [tempAddress, setTempAddress] = useState(getValues('addressMap'));
+  const resetPin = useMaps((state) => state.resetPin);
+  const setSelectedPosition = useMaps((state) => state.setSelectedPosition);
+  const setAddressMaps = useMaps((state) => state.setAddressMaps);
+  const setDetailAddress = useMaps((state) => state.setDetailAddress);
+  const [showValidationPopup, setShowValidationPopup] = useState(false);
+  const [popupMessage, setPopupMessage] = useState("");
+  const [selectedCityName, setSelectedCityName] = useState("");
 
   const {
     addressMaps,
@@ -56,48 +63,65 @@ const EditAddress = ({ id, defaultValues }) => {
 
   // Helper: cek apakah benar2 sudah PIN (bukan default center & ada addressMaps)
   const isPinned = useMemo(() => {
-    if (
-      !selectedPosition ||
-      typeof selectedPosition.lat !== 'number' ||
-      typeof selectedPosition.lng !== 'number'
-    )
-      return false;
+    if (!selectedPosition) return false;
+
+    // pastikan selalu cast ke number
+    const lat = Number(selectedPosition.lat);
+    const lng = Number(selectedPosition.lng);
+
+    // kalau hasil cast bukan angka valid
+    if (isNaN(lat) || isNaN(lng)) return false;
+
     const dc =
-      typeof getDefaultCenter === 'function'
+      typeof getDefaultCenter === "function"
         ? getDefaultCenter()
         : { lat: -6.2, lng: 106.816666 };
+
     const nearDefault =
-      Math.abs(selectedPosition.lat - dc.lat) < 1e-4 &&
-      Math.abs(selectedPosition.lng - dc.lng) < 1e-4;
+      Math.abs(lat - dc.lat) < 1e-4 &&
+      Math.abs(lng - dc.lng) < 1e-4;
+
     return Boolean(addressMaps) && !nearDefault;
   }, [selectedPosition, addressMaps, getDefaultCenter]);
 
   // Hanya isi addressMap & lat/lng di form kalau SUDAH PIN
   useEffect(() => {
-    if (addressMaps && isPinned) {
-      setTempAddress(addressMaps);
-      setValue('addressMap', addressMaps);
-    }
-    if (isPinned && selectedPosition) {
-      setValue('longtitude', selectedPosition.lng);
-      setValue('latitude', selectedPosition.lat);
+    // cek kalau form punya koordinat lama
+    const lat = getValues("latitude");
+    const lng = getValues("longtitude");
+    const oldAddress = getValues("addressMap");
+
+    if (lat && lng) {
+      setTempAddress(oldAddress);
+      setValue("addressMap", oldAddress);
+
+      // kalau store punya setter untuk koordinat/alamat:
+      if (typeof setSelectedPosition === "function") {
+        setSelectedPosition({ lat: Number(lat), lng: Number(lng) });
+      }
+      if (typeof setAddressMaps === "function") {
+        setAddressMaps(oldAddress);
+      }
     }
-  }, [addressMaps, selectedPosition, isPinned, setValue]);
+  }, [setSelectedPosition, setAddressMaps, getValues, setValue]);
 
-  // Isi ZIP/Prov dari detailAddress (JANGAN isi street)
   useEffect(() => {
-    if (Object.keys(detailAddress || {}).length > 0 && isPinned) {
-      setValue('zip', detailAddress.postalCode);
-      const selectedState = states.find(
-        (state) =>
-          detailAddress?.province?.includes(state.label) ||
-          state.label?.includes(detailAddress?.province)
-      );
-      setValue('state', selectedState?.value);
-      // jangan override street:
-      // setValue('street', detailAddress?.street);
+    const addr = getValues("addressMap");
+
+    if (!addr || addr.trim() === "") {
+      resetPin();
+    } else {
+      setAddressMaps(addr);
+
+      const lat = getValues("latitude");
+      const lng = getValues("longtitude");
+      if (lat && lng) {
+        setSelectedPosition({ lat: Number(lat), lng: Number(lng) });
+      }
     }
-  }, [detailAddress, states, isPinned, setValue]);
+  }, [getValues, resetPin, setAddressMaps, setSelectedPosition]);
+
+
 
   useEffect(() => {
     const loadProfile = async () => {
@@ -109,13 +133,29 @@ const EditAddress = ({ id, defaultValues }) => {
       setValue('alamat_wajib_pajak', dataProfile.alamatWajibPajak);
       setValue('alamat_bisnis', dataProfile.alamatBisnis);
       setValue('business_name', dataProfile.name);
-      setValue('city', dataProfile.city?.id);
-      setValue('district', dataProfile.district?.id);
-      setValue('subDistrict', dataProfile.subDistrict?.id);
     };
     if (auth) loadProfile();
   }, [auth?.parentId, setValue]);
 
+  // Isi ZIP/Prov dari detailAddress (JANGAN isi street)
+  useEffect(() => {
+    const zip = getValues("zip");
+    const province = getValues("state"); 
+    if (!zip && defaultValues?.zip) {
+      setValue("zip", defaultValues.zip);
+    }
+
+    if (!getValues("state") && province) {
+      const selectedState = states.find(
+        (state) =>
+          province.includes(state.label) || state.label.includes(province)
+      );
+      if (selectedState) {
+        setValue("state", selectedState.value);
+      }
+    }
+  }, [states, setValue, getValues, defaultValues]);
+
   useEffect(() => {
     const loadStates = async () => {
       let dataStates = await stateApi({ tempo: false });
@@ -150,7 +190,11 @@ const EditAddress = ({ id, defaultValues }) => {
   }, [watchState, setValue, getValues]);
 
   useEffect(() => {
-    if (Object.keys(detailAddress || {}).length > 0 && isPinned) {
+    if (!isPinned) return;
+
+    if (getValues("city")) return;
+
+    if (Object.keys(detailAddress || {}).length > 0) {
       const selectedCities =
         cities.find(
           (city) =>
@@ -165,9 +209,12 @@ const EditAddress = ({ id, defaultValues }) => {
               .toLowerCase()
               .includes(detailAddress?.district?.toLowerCase())
         );
-      setValue('city', selectedCities?.value);
+
+      if (selectedCities) {
+        setValue("city", selectedCities.value);
+      }
     }
-  }, [cities, detailAddress, isPinned, setValue]);
+  }, [cities, detailAddress, isPinned, getValues, setValue]);
 
   const watchCity = watch('city');
   useEffect(() => {
@@ -189,7 +236,12 @@ const EditAddress = ({ id, defaultValues }) => {
   }, [watchCity, setValue, getValues]);
 
   useEffect(() => {
-    if (Object.keys(detailAddress || {}).length > 0 && isPinned) {
+    if (!isPinned) return; // skip kalau belum pin
+
+    // jangan override kalau form sudah punya nilai district
+    if (getValues("district")) return;
+
+    if (Object.keys(detailAddress || {}).length > 0) {
       const selectedDistrict = districts.find(
         (district) =>
           detailAddress?.subDistrict
@@ -199,9 +251,13 @@ const EditAddress = ({ id, defaultValues }) => {
             .toLowerCase()
             .includes(detailAddress?.subDistrict?.toLowerCase())
       );
-      setValue('district', selectedDistrict?.value);
+
+      if (selectedDistrict) {
+        setValue("district", selectedDistrict.value);
+      }
     }
-  }, [districts, detailAddress, isPinned, setValue]);
+  }, [districts, detailAddress, isPinned, getValues, setValue]);
+  
 
   const watchDistrict = watch('district');
   useEffect(() => {
@@ -227,7 +283,12 @@ const EditAddress = ({ id, defaultValues }) => {
   }, [watchDistrict, setValue, getValues]);
 
   useEffect(() => {
-    if (Object.keys(detailAddress || {}).length > 0 && isPinned) {
+    if (!isPinned) return; // skip kalau belum pin
+
+    // jangan override kalau form sudah punya nilai subDistrict
+    if (getValues("subDistrict")) return;
+
+    if (Object.keys(detailAddress || {}).length > 0) {
       const selectedSubDistrict = subDistricts.find(
         (district) =>
           detailAddress?.village
@@ -237,9 +298,12 @@ const EditAddress = ({ id, defaultValues }) => {
             .toLowerCase()
             .includes(detailAddress?.village?.toLowerCase())
       );
-      setValue('subDistrict', selectedSubDistrict?.value);
+
+      if (selectedSubDistrict) {
+        setValue("subDistrict", selectedSubDistrict.value);
+      }
     }
-  }, [subDistricts, detailAddress, isPinned, setValue]);
+  }, [subDistricts, detailAddress, isPinned, getValues, setValue]);
 
   useEffect(() => {
     if (id) {
@@ -247,7 +311,52 @@ const EditAddress = ({ id, defaultValues }) => {
     }
   }, [id, setValue]);
 
+  useEffect(() => {
+    const currentCity = cities.find((c) => c.value === watch("city"))?.label || "";
+
+    let normalized = currentCity.toLowerCase().trim();
+
+    const parts = normalized.split(" ");
+
+    if (parts.length >= 3) {
+      // hapus prefix kabupaten/kota kalau ada
+      normalized = normalized
+        .replace(/^kabupaten\s+/i, "")
+        .replace(/^kota\s+/i, "")
+        .trim();
+    }
+
+    setSelectedCityName(normalized);
+  }, [watch("city"), cities]);
+  // console.log(defaultValues);
+  
+  // console.log(selectedCityName, '=', detailAddress?.district);
   const onSubmitHandler = async (values) => {
+    if (addressMaps) {
+      if (!detailAddress){
+        if (defaultValues?.oldCity !== values.city) {
+          setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih");
+          setShowValidationPopup(true);
+          console.log(detailAddress)
+          return;
+        }
+      }
+      if(detailAddress){
+        if (selectedCityName && selectedCityName !== detailAddress?.district?.toLowerCase()) {
+          setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih");
+          setShowValidationPopup(true);
+          return;
+        }
+      }
+    }
+    // if(!addressMaps && detailAddress){
+    //   if (selectedCityName && selectedCityName !== detailAddress?.district?.toLowerCase()) {
+    //     setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih 3");
+    //     setShowValidationPopup(true);
+    //     return;
+    //   }
+    // }
+
     const data = {
       ...values,
       phone: values.mobile,
@@ -257,7 +366,7 @@ const EditAddress = ({ id, defaultValues }) => {
       sub_district_id: parseInt(values.subDistrict, 10),
     };
 
-    // kirim koordinat + address_map + use_pin HANYA jika sudah PIN
+    
     if (isPinned) {
       data.longtitude = selectedPosition?.lng;
       data.latitude = selectedPosition?.lat;
@@ -324,7 +433,7 @@ const EditAddress = ({ id, defaultValues }) => {
     const dataProfile = await addressApi({ id: auth.partnerId });
     console.log('ini adalah', dataProfile);
   };
-
+  // console.log('ini adalah', detailAddress);
   return (
     <>
       <BottomPopup
@@ -335,12 +444,30 @@ const EditAddress = ({ id, defaultValues }) => {
       >
         <div className='flex mt-4'>
           <PinPointMap
-            initialLatitude={selectedPosition?.lat}
-            initialLongitude={selectedPosition?.lng}
-            initialAddress={tempAddress}
+            initialLatitude={getValues('latitude')}
+            initialLongitude={getValues('longtitude')}
+            initialAddress={getValues('addressMap')}
           />
         </div>
       </BottomPopup>
+      <BottomPopup
+        active={showValidationPopup}
+        close={() => setShowValidationPopup(false)}
+      >
+        <div className="leading-7 text-gray_r-12/80 text-center">
+          {popupMessage}
+        </div>
+
+        <div className="flex justify-center mt-6">
+          <button
+            className="btn-solid-red w-full md:w-auto"
+            type="button"
+            onClick={() => setShowValidationPopup(false)}
+          >
+            OK
+          </button>
+        </div>
+      </BottomPopup>
       <div className='max-w-none md:container mx-auto flex p-0 md:py-10'>
         <div className='hidden md:block w-3/12 pr-4'>
           <Menu />
@@ -355,7 +482,7 @@ const EditAddress = ({ id, defaultValues }) => {
           <form onSubmit={handleSubmit(onSubmitHandler)}>
             <div className='mb-4 items-start'>
               <label className='form-label mb-2'>Koordinat Alamat</label>
-              {tempAddress ? (
+              {addressMaps ? (
                 <div className='flex gap-x-2 items-center'>
                   <button
                     type='button'
@@ -366,7 +493,7 @@ const EditAddress = ({ id, defaultValues }) => {
                       onClick={() => setPinedMaps(true)}
                     />
                   </button>
-                  <span> {tempAddress} </span>
+                  <span> {addressMaps} </span>
                 </div>
               ) : (
                 <Button
-- 
cgit v1.2.3

