'use client'; import { useState, useEffect, useCallback } from 'react'; import { Swiper, SwiperSlide } from 'swiper/react'; import { Navigation, Pagination } from 'swiper/modules'; import { PopupItem, PopupResponse } from '@/types/response/page/popup'; import { fetchApi } from '@/lib/utils/client'; import 'swiper/css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import './PopupModal.scss'; interface PopupModalProps { position: string; } // localStorage 키 생성 function getDismissKey(position: string): string { return `popup_dismiss_${position}`; } // 24시간 이내에 dismiss 했는지 확인 function isDismissed(position: string): boolean { if (typeof window === 'undefined') { return false; } const dismissed = localStorage.getItem(getDismissKey(position)); if (!dismissed) { return false; } const dismissedAt = parseInt(dismissed, 10); const now = Date.now(); const hours24 = 24 * 60 * 60 * 1000; return (now - dismissedAt) < hours24; } // 유효한 팝업인지 확인 (isActive + 날짜 범위) function isValidPopup(item: PopupItem): boolean { if (!item.isActive) { return false; } const now = new Date(); if (item.startAt && new Date(item.startAt) > now) { return false; } if (item.endAt && new Date(item.endAt) < now) { return false; } return true; } export default function PopupModal({ position }: PopupModalProps) { const [open, setOpen] = useState(false); const [items, setItems] = useState([]); const [dismissToday, setDismissToday] = useState(false); useEffect(() => { // 이미 dismiss 되었으면 fetch하지 않음 if (isDismissed(position)) { return; } fetchApi('/api/popup/popups', { method: 'POST', body: { Code: position } }).then((res) => { if (res.success && res.data) { const validItems = (res.data.list ?? []).filter(isValidPopup); if (validItems.length > 0) { setItems(validItems); setOpen(true); } } }); }, [position]); const handleClose = useCallback(() => { if (dismissToday) { localStorage.setItem(getDismissKey(position), Date.now().toString()); } setOpen(false); }, [dismissToday, position]); // 팝업이 없거나 닫혔으면 렌더링하지 않음 if (!open || items.length === 0) { return null; } return (
e.stopPropagation()}> {/* 팝업 본문 */}
{items.length === 1 ? ( // 단일 팝업 ) : ( // 다중 팝업 - Swiper 슬라이드 1} spaceBetween={0} slidesPerView={1} > {items.map((item) => ( ))} )}
{/* 하단 - 하루 동안 보지 않기 + 닫기 */}
); } // 개별 팝업 슬라이드 function PopupSlide({ item }: { item: PopupItem }) { const content = (
{item.subject && (

{item.subject}

)} {item.content && (
)}
); if (item.link) { return ( {content} ); } return content; }