From 918ece5f2c351895c83653fb71d3065e2d2992a0 Mon Sep 17 00:00:00 2001
From: it-fixcomart <it@fixcomart.co.id>
Date: Tue, 24 Jun 2025 14:34:49 +0700
Subject: <hafid> dragable banner

---
 src/lib/home/components/PopupBannerPromotion.jsx | 108 ++++++++++++++++-------
 1 file changed, 76 insertions(+), 32 deletions(-)

(limited to 'src/lib/home/components/PopupBannerPromotion.jsx')

diff --git a/src/lib/home/components/PopupBannerPromotion.jsx b/src/lib/home/components/PopupBannerPromotion.jsx
index c5466009..347617d6 100644
--- a/src/lib/home/components/PopupBannerPromotion.jsx
+++ b/src/lib/home/components/PopupBannerPromotion.jsx
@@ -18,6 +18,9 @@ const PagePopupInformation = () => {
   const [position, setPosition] = useState({ x: 20, y: window.innerHeight - 170 });
   const dragStartPos = useRef({ x: 0, y: 0 });
   const isDragging = useRef(false);
+  const isTouching = useRef(false);
+
+  const [isSnapping, setIsSnapping] = useState(false); // 🔥 Penanda kapan transisi diaktifkan
 
   useEffect(() => {
     const getData = async () => {
@@ -41,10 +44,62 @@ const PagePopupInformation = () => {
     }
   }, [isHomePage, auth]);
 
+  useEffect(() => {
+    const handleGlobalTouchMove = (e) => {
+      if (isTouching.current) {
+        e.preventDefault();
+        isDragging.current = true;
+        setIsSnapping(false); // 🔥 Matikan transisi saat drag
+
+        let newX = e.touches[0].clientX - dragStartPos.current.x;
+        let newY = e.touches[0].clientY - dragStartPos.current.y;
+
+        const popupWidth = popupRef.current?.offsetWidth || 0;
+        const popupHeight = popupRef.current?.offsetHeight || 0;
+        const maxX = window.innerWidth - popupWidth - 20;
+        const maxY = window.innerHeight - popupHeight - 20;
+
+        newX = Math.max(0, Math.min(newX, maxX));
+        newY = Math.max(0, Math.min(newY, maxY));
+
+        setPosition({ x: newX, y: newY });
+      }
+    };
+
+    const handleGlobalTouchEnd = () => {
+      if (isDragging.current) {
+        const popupWidth = popupRef.current?.offsetWidth || 0;
+        const screenMiddle = window.innerWidth / 2;
+
+        setIsSnapping(true); // 🔥 Aktifkan transisi saat snap
+
+        if (position.x + popupWidth / 2 < screenMiddle) {
+          // Snap ke kiri
+          setPosition({ x: 20, y: position.y });
+        } else {
+          // Snap ke kanan
+          setPosition({ x: window.innerWidth - popupWidth - 20, y: position.y });
+        }
+      }
+
+      isTouching.current = false;
+      isDragging.current = false;
+    };
+
+    window.addEventListener('touchmove', handleGlobalTouchMove, { passive: false });
+    window.addEventListener('touchend', handleGlobalTouchEnd);
+
+    return () => {
+      window.removeEventListener('touchmove', handleGlobalTouchMove);
+      window.removeEventListener('touchend', handleGlobalTouchEnd);
+    };
+  }, [position]);
+
   const handleMouseDown = (e) => {
     e.preventDefault();
     dragStartPos.current = { x: e.clientX - position.x, y: e.clientY - position.y };
     isDragging.current = false;
+    setIsSnapping(false); // 🔥 Matikan transisi saat drag
 
     window.addEventListener('mousemove', handleMouseMove);
     window.addEventListener('mouseup', handleMouseUp);
@@ -68,47 +123,36 @@ const PagePopupInformation = () => {
   };
 
   const handleMouseUp = () => {
+    if (isDragging.current) {
+      const popupWidth = popupRef.current?.offsetWidth || 0;
+      const screenMiddle = window.innerWidth / 2;
+
+      setIsSnapping(true); // 🔥 Aktifkan transisi saat snap
+
+      if (position.x + popupWidth / 2 < screenMiddle) {
+        // Snap ke kiri
+        setPosition({ x: 20, y: position.y });
+      } else {
+        // Snap ke kanan
+        setPosition({ x: window.innerWidth - popupWidth - 20, y: position.y });
+      }
+    }
+
     window.removeEventListener('mousemove', handleMouseMove);
     window.removeEventListener('mouseup', handleMouseUp);
+
+    isDragging.current = false;
   };
 
-  // Touch Events (Mobile)
   const handleTouchStart = (e) => {
     if (e.touches.length === 1) {
-      const touch = e.touches[0];
-      dragStartPos.current = { x: touch.clientX - position.x, y: touch.clientY - position.y };
+      dragStartPos.current = { x: e.touches[0].clientX - position.x, y: e.touches[0].clientY - position.y };
       isDragging.current = false;
-
-      window.addEventListener('touchmove', handleTouchMove, { passive: false });
-      window.addEventListener('touchend', handleTouchEnd);
-    }
-  };
-
-  const handleTouchMove = (e) => {
-    if (e.touches.length === 1) {
-      e.preventDefault();
-      isDragging.current = true;
-
-      let newX = e.touches[0].clientX - dragStartPos.current.x;
-      let newY = e.touches[0].clientY - dragStartPos.current.y;
-
-      const popupWidth = popupRef.current?.offsetWidth || 0;
-      const popupHeight = popupRef.current?.offsetHeight || 0;
-      const maxX = window.innerWidth - popupWidth - 20;
-      const maxY = window.innerHeight - popupHeight - 20;
-
-      newX = Math.max(0, Math.min(newX, maxX));
-      newY = Math.max(0, Math.min(newY, maxY));
-
-      setPosition({ x: newX, y: newY });
+      isTouching.current = true;
+      setIsSnapping(false); // 🔥 Matikan transisi saat drag
     }
   };
 
-  const handleTouchEnd = () => {
-    window.removeEventListener('touchmove', handleTouchMove);
-    window.removeEventListener('touchend', handleTouchEnd);
-  };
-
   if (!active || !data || loading || !Array.isArray(data) || !data[0]?.image) return null;
 
   const banner = data[0];
@@ -117,7 +161,7 @@ const PagePopupInformation = () => {
     <div className="fixed inset-0 z-[9999] pointer-events-none">
       <div
         ref={popupRef}
-        className="absolute pointer-events-auto"
+        className={`absolute pointer-events-auto ${isSnapping ? 'transition-transform duration-300 ease-out' : ''}`}
         style={{
           transform: `translate(${position.x}px, ${position.y}px)`,
           cursor: 'grab',
-- 
cgit v1.2.3

