diff options
| author | Indoteknik . <andrifebriyadiputra@gmail.com> | 2025-07-17 08:49:25 +0700 |
|---|---|---|
| committer | Indoteknik . <andrifebriyadiputra@gmail.com> | 2025-07-17 08:49:25 +0700 |
| commit | c42dfc0b052a50d43d0bf665ea9959129e87d99c (patch) | |
| tree | 5a693a2cb91c00bdcb53a74792c0fc9982a61267 | |
| parent | 39b37aa1309a4d3755678bac39e0ba4132317a74 (diff) | |
(andri) rev button close popup bottom & fix layout mobile
| -rw-r--r-- | src/lib/home/components/PopupBannerPromotion.jsx | 134 |
1 files changed, 94 insertions, 40 deletions
diff --git a/src/lib/home/components/PopupBannerPromotion.jsx b/src/lib/home/components/PopupBannerPromotion.jsx index 1463840a..1ef166f2 100644 --- a/src/lib/home/components/PopupBannerPromotion.jsx +++ b/src/lib/home/components/PopupBannerPromotion.jsx @@ -4,6 +4,7 @@ import Image from 'next/image'; import Link from 'next/link'; import { getAuth } from '~/libs/auth'; import { X } from 'lucide-react'; +import useDevice from '@/core/hooks/useDevice'; const PagePopupInformation = () => { const router = useRouter(); @@ -19,6 +20,7 @@ const PagePopupInformation = () => { const dragStartPos = useRef({ x: 0, y: 0 }); const isDragging = useRef(false); const isTouching = useRef(false); + const { isDesktop } = useDevice(); const [isSnapping, setIsSnapping] = useState(false); // 🔥 Penanda kapan transisi diaktifkan @@ -80,8 +82,9 @@ const PagePopupInformation = () => { const popupHeight = popupRef.current?.offsetHeight || 0; const maxX = window.innerWidth - popupWidth - 20; const maxY = window.innerHeight - popupHeight - 20; + const minX = -containerLeft; - newX = Math.max(0, Math.min(newX, maxX)); + newX = Math.max(minX, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); setPosition({ x: newX, y: newY }); @@ -137,8 +140,9 @@ const PagePopupInformation = () => { const popupHeight = popupRef.current?.offsetHeight || 0; const maxX = window.innerWidth - popupWidth - 20; const maxY = window.innerHeight - popupHeight - 20; + const minX = -containerLeft; - newX = Math.max(0, Math.min(newX, maxX)); + newX = Math.max(minX, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); setPosition({ x: newX, y: newY }); @@ -179,61 +183,111 @@ const PagePopupInformation = () => { const banner = data[0]; - return ( - <div className="fixed z-[9999] pointer-events-none" - style={{ - bottom: '125px', - left: `${containerLeft - 125}px`, - }}> + if (isDesktop) { + // ✅ RENDER UNTUK DESKTOP + return ( <div - ref={popupRef} - className={`absolute pointer-events-auto ${isSnapping ? 'transition-transform duration-300 ease-out' : ''}`} + className="fixed z-[9999] pointer-events-none" style={{ - transform: `translate(${position.x}px, 0px)`, - cursor: 'grab', - width: '85px', + top: '40px', + left: `${Math.max(containerLeft - 120, 0)}px` }} > - <div className="relative w-full h-auto"> - <div - onMouseDown={handleMouseDown} - onTouchStart={handleTouchStart} - className="cursor-grab active:cursor-grabbing" + <div + ref={popupRef} + className="relative pointer-events-auto" + style={{ + transform: `translate(${position.x}px, ${position.y}px)`, + cursor: 'grab', + width: '85px', + }} + onMouseDown={handleMouseDown} + onTouchStart={handleTouchStart} + > + <Link + href={typeof banner.url === 'boolean' && banner.url === false ? '/' : banner.url} + onClick={(e) => { + if (isDragging.current) { + e.preventDefault(); + isDragging.current = false; + } else { + setActive(false); + } + }} + draggable="false" > - <Link - href={typeof banner.url === 'boolean' && banner.url === false ? '/' : banner.url} - onClick={(e) => { - if (isDragging.current) { - e.preventDefault(); - isDragging.current = false; - } else { - setActive(false); - } - }} + <Image + src={banner.image} + alt={banner.name || 'popup'} + width={85} + height={85} + className="w-full h-auto select-none" draggable="false" - > - <Image - src={banner.image} - alt={banner.name || 'popup'} - width={85} - height={85} - className="w-full h-auto select-none" - draggable="false" - /> - </Link> - </div> + /> + </Link> <button onClick={() => setActive(false)} - className="absolute -top-2 -right-2 z-10 p-1 bg-gray-500 rounded-full hover:bg-gray-600 transition-colors" + className="absolute -top-2 -right-2 z-10 p-1 bg-red-500 rounded-full hover:bg-red-600 transition-colors" aria-label="Close popup" > <X className="w-3 h-3 text-white" /> </button> </div> </div> + ); + } + + // ✅ RENDER UNTUK MOBILE + return ( + <div className="fixed z-[9999] pointer-events-none" + style={{ + top: '40px', + }}> + <div + ref={popupRef} + className={`absolute pointer-events-auto ${isSnapping ? 'transition-transform duration-300 ease-out' : ''}`} + style={{ + transform: `translate(${position.x}px, ${position.y}px)`, + cursor: 'grab', + width: '85px', + }} + onMouseDown={handleMouseDown} + onTouchStart={handleTouchStart} + > + <Link + href={typeof banner.url === 'boolean' && banner.url === false ? '/' : banner.url} + onClick={(e) => { + if (isDragging.current) { + e.preventDefault(); + isDragging.current = false; + } else { + setActive(false); + } + }} + draggable="false" + > + <Image + src={banner.image} + alt={banner.name || 'popup'} + width={85} + height={85} + className="w-full h-auto select-none" + draggable="false" + /> + </Link> + + <button + onClick={() => setActive(false)} + className="absolute -top-2 -right-2 z-10 p-1 bg-red-500 rounded-full hover:bg-red-600 transition-colors" + aria-label="Close popup" + > + <X className="w-3 h-3 text-white" /> + </button> + </div> </div> ); + }; export default PagePopupInformation; |
