import { useRouter } from 'next/router'; import { useEffect, useState, useRef } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { X } from 'lucide-react'; import { getAuth } from '~/libs/auth'; import useDevice from '@/core/hooks/useDevice'; import { createPortal } from 'react-dom'; const PagePopupInformation = () => { const router = useRouter(); const isHomePage = router.pathname === '/'; const auth = getAuth(); const { isDesktop } = useDevice(); const [active, setActive] = useState(false); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const popupRef = useRef(null); 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); const [containerLeft, setContainerLeft] = useState(0); const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); useEffect(() => { if (isHomePage && !auth) { setActive(true); fetchData(); } }, [isHomePage, auth]); const fetchData = async () => { try { const res = await fetch(`/api/hero-banner?type=dragable-banner`); const { data } = await res.json(); if (Array.isArray(data) && data[0]?.image) { setData(data[0]); } else { setActive(false); } } catch (error) { console.error('Failed to fetch popup banner:', error); } finally { setLoading(false); } }; useEffect(() => { const handleResizeOrZoom = () => { if (!popupRef.current) return; const popupWidth = popupRef.current.offsetWidth || 85; const popupHeight = popupRef.current.offsetHeight || 85; setPosition({ x: 20, y: window.innerHeight - popupHeight - 20, }); }; window.addEventListener('resize', handleResizeOrZoom); return () => { window.removeEventListener('resize', handleResizeOrZoom); }; }, []); const updateContainerLeft = () => { const container = document.querySelector('.container'); if (container) { setContainerLeft(container.getBoundingClientRect().left); } }; useEffect(() => { updateContainerLeft(); window.addEventListener('resize', updateContainerLeft); window.addEventListener('scroll', updateContainerLeft); return () => { window.removeEventListener('resize', updateContainerLeft); window.removeEventListener('scroll', updateContainerLeft); }; }, []); useEffect(() => { if (isDesktop && containerLeft) { const popupWidth = popupRef.current?.offsetWidth || 85; setPosition({ x: containerLeft - popupWidth - 20, y: window.innerHeight - 130, }); } }, [isDesktop, containerLeft]); const startDrag = (clientX, clientY) => { dragStartPos.current = { x: clientX - position.x, y: clientY - position.y }; isDragging.current = false; setIsSnapping(false); }; const moveDrag = (clientX, clientY) => { isDragging.current = true; const popupWidth = popupRef.current?.offsetWidth || 85; const popupHeight = popupRef.current?.offsetHeight || 85; const maxX = window.innerWidth - popupWidth - 20; const topPadding = isDesktop ? 0 : 130; const bottomPadding = isDesktop ? 0 : 80; const maxY = window.innerHeight - popupHeight - bottomPadding; const minX = 0; let newX = clientX - dragStartPos.current.x; let newY = clientY - dragStartPos.current.y; newX = Math.max(minX, Math.min(newX, maxX)); newY = Math.max(topPadding, Math.min(newY, maxY)); setPosition({ x: newX, y: newY }); }; const endDrag = () => { if (isDragging.current) { setIsSnapping(true); if (isDesktop) { const popupWidth = popupRef.current?.offsetWidth || 85; setPosition({ x: containerLeft - popupWidth - 20, y: window.innerHeight - 130, }); } else { const popupWidth = popupRef.current?.offsetWidth || 85; const screenMiddle = window.innerWidth / 2; setPosition(pos => ({ x: pos.x + popupWidth / 2 < screenMiddle ? 20 : window.innerWidth - popupWidth - 20, y: pos.y, })); } } isDragging.current = false; isTouching.current = false; }; const handleMouseDown = e => { e.preventDefault(); startDrag(e.clientX, e.clientY); window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); }; const handleMouseMove = e => moveDrag(e.clientX, e.clientY); const handleMouseUp = () => { endDrag(); window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); }; const handleTouchStart = e => { if (e.touches.length === 1) { isTouching.current = true; startDrag(e.touches[0].clientX, e.touches[0].clientY); } }; useEffect(() => { const handleTouchMove = e => { if (isTouching.current) { e.preventDefault(); moveDrag(e.touches[0].clientX, e.touches[0].clientY); } }; const handleTouchEnd = () => endDrag(); window.addEventListener('touchmove', handleTouchMove, { passive: false }); window.addEventListener('touchend', handleTouchEnd); return () => { window.removeEventListener('touchmove', handleTouchMove); window.removeEventListener('touchend', handleTouchEnd); }; }, []); if (!active || !data || loading) return null; const popupContent = (
{ if (isDragging.current) { e.preventDefault(); isDragging.current = false; } else { setActive(false); } }} draggable="false" > {data.name
); if (isDesktop && isClient) { return createPortal(
{popupContent}
, document.body ); } return (
{popupContent}
); }; export default PagePopupInformation;