diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-06-24 06:46:07 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-06-24 06:46:07 +0000 |
| commit | 4577ee97cf54e9f9d6424c5307d281112ea76943 (patch) | |
| tree | f89afc51e4eb273b4df9b41c130b1ec799ff4965 /src/lib | |
| parent | f7afa3b368dcbf8ce44f8a9665b9d5ec2e6d46af (diff) | |
| parent | 57fa96f28d768a0c0a4940330f76cd3badf819f0 (diff) | |
Merged in top-banner-mobile (pull request #425)
<hafid> dragable banner
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/home/components/PopupBannerPromotion.jsx | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/lib/home/components/PopupBannerPromotion.jsx b/src/lib/home/components/PopupBannerPromotion.jsx index 03855fbb..c5466009 100644 --- a/src/lib/home/components/PopupBannerPromotion.jsx +++ b/src/lib/home/components/PopupBannerPromotion.jsx @@ -24,11 +24,10 @@ const PagePopupInformation = () => { try { const res = await fetch(`/api/hero-banner?type=dragable-banner`); const { data } = await res.json(); - // Cek apakah data array dan ada image-nya if (Array.isArray(data) && data.length > 0 && data[0]?.image) { setData(data); } else { - setActive(false); // Tidak tampil jika tidak valid + setActive(false); } } catch (error) { console.error('Failed to fetch popup banner:', error); @@ -44,10 +43,7 @@ const PagePopupInformation = () => { const handleMouseDown = (e) => { e.preventDefault(); - dragStartPos.current = { - x: e.clientX - position.x, - y: e.clientY - position.y, - }; + dragStartPos.current = { x: e.clientX - position.x, y: e.clientY - position.y }; isDragging.current = false; window.addEventListener('mousemove', handleMouseMove); @@ -76,10 +72,46 @@ const PagePopupInformation = () => { window.removeEventListener('mouseup', handleMouseUp); }; - // Jika data tidak valid, langsung return null + // 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 }; + 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 }); + } + }; + + 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]; // Data sudah aman di sini + const banner = data[0]; return ( <div className="fixed inset-0 z-[9999] pointer-events-none"> @@ -89,12 +121,13 @@ const PagePopupInformation = () => { style={{ transform: `translate(${position.x}px, ${position.y}px)`, cursor: 'grab', - width: '150px', + width: '85px', }} > <div className="relative w-full h-auto"> <div onMouseDown={handleMouseDown} + onTouchStart={handleTouchStart} className="cursor-grab active:cursor-grabbing" > <Link @@ -112,8 +145,8 @@ const PagePopupInformation = () => { <Image src={banner.image} alt={banner.name || 'popup'} - width={150} - height={150} + width={85} + height={85} className="w-full h-auto select-none" draggable="false" /> |
