summaryrefslogtreecommitdiff
path: root/src/lib/home/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/home/components')
-rw-r--r--src/lib/home/components/PopupBannerPromotion.jsx136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/lib/home/components/PopupBannerPromotion.jsx b/src/lib/home/components/PopupBannerPromotion.jsx
new file mode 100644
index 00000000..03855fbb
--- /dev/null
+++ b/src/lib/home/components/PopupBannerPromotion.jsx
@@ -0,0 +1,136 @@
+import { useRouter } from 'next/router';
+import { useEffect, useState, useRef } from 'react';
+import Image from 'next/image';
+import Link from 'next/link';
+import { getAuth } from '~/libs/auth';
+import { X } from 'lucide-react';
+
+const PagePopupInformation = () => {
+ const router = useRouter();
+ const isHomePage = router.pathname === '/';
+ const auth = getAuth();
+
+ 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);
+
+ useEffect(() => {
+ const getData = async () => {
+ 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
+ }
+ } catch (error) {
+ console.error('Failed to fetch popup banner:', error);
+ }
+ setLoading(false);
+ };
+
+ if (isHomePage && !auth) {
+ setActive(true);
+ getData();
+ }
+ }, [isHomePage, auth]);
+
+ const handleMouseDown = (e) => {
+ e.preventDefault();
+ dragStartPos.current = {
+ x: e.clientX - position.x,
+ y: e.clientY - position.y,
+ };
+ isDragging.current = false;
+
+ window.addEventListener('mousemove', handleMouseMove);
+ window.addEventListener('mouseup', handleMouseUp);
+ };
+
+ const handleMouseMove = (e) => {
+ isDragging.current = true;
+
+ let newX = e.clientX - dragStartPos.current.x;
+ let newY = e.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 handleMouseUp = () => {
+ window.removeEventListener('mousemove', handleMouseMove);
+ window.removeEventListener('mouseup', handleMouseUp);
+ };
+
+ // Jika data tidak valid, langsung return null
+ if (!active || !data || loading || !Array.isArray(data) || !data[0]?.image) return null;
+
+ const banner = data[0]; // Data sudah aman di sini
+
+ return (
+ <div className="fixed inset-0 z-[9999] pointer-events-none">
+ <div
+ ref={popupRef}
+ className="absolute pointer-events-auto"
+ style={{
+ transform: `translate(${position.x}px, ${position.y}px)`,
+ cursor: 'grab',
+ width: '150px',
+ }}
+ >
+ <div className="relative w-full h-auto">
+ <div
+ onMouseDown={handleMouseDown}
+ className="cursor-grab active:cursor-grabbing"
+ >
+ <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={150}
+ height={150}
+ className="w-full h-auto select-none"
+ draggable="false"
+ />
+ </Link>
+ </div>
+
+ <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"
+ aria-label="Close popup"
+ >
+ <X className="w-3 h-3 text-white" />
+ </button>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default PagePopupInformation;