/** 상품 그리드·페이지네이션 렌더링 */ import { state, saveSelection } from './state.js'; import { ITEMS_PER_PAGE, STATUS_META, STATUS_COLOR, PRODUCT_CONDITIONS } from './config.js'; import { updateSummary } from './main.js'; // --- 터치 및 드래그 관련 전역 변수 및 핸들러 --- window.isDragging = false; let touchStartX = 0; let touchStartY = 0; // 터치 기기 여부 확인 const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; window.handleTouchStart = function (e) { window.isDragging = false; touchStartX = e.touches[0].clientX; touchStartY = e.touches[0].clientY; }; window.handleTouchMove = function (e) { const touchX = e.touches[0].clientX; const touchY = e.touches[0].clientY; // 10px 이상 움직이면 드래그(스크롤)로 간주 if (Math.abs(touchX - touchStartX) > 10 || Math.abs(touchY - touchStartY) > 10) { window.isDragging = true; } }; window.handleTouchEnd = function (e) { // 필요한 경우 추가 로직 작성 가능 (현재는 isDragging 상태 유지만으로 충분) }; // 썸네일 호버 핸들러 (PC에서만 동작하도록 수정) window.handleThumbnailHover = function (e, id) { if (isTouchDevice) return; // 모바일에서는 호버 로직 실행 안 함 const product = state.visibleProducts.find((p) => p.id === id); if (!product || !product.images || product.images.length <= 1) return; const rect = e.currentTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const sectionWidth = rect.width / product.images.length; const index = Math.floor(x / sectionWidth); const thumb = document.getElementById(`thumb-${id}`); const indicators = document.querySelector(`#indicator-${id}`)?.children; if (thumb && product.images[index]) { thumb.style.backgroundImage = `url("${product.images[index]}")`; } if (indicators) { Array.from(indicators).forEach((dot, i) => { if (i === index) { dot.classList.add('bg-white', 'scale-125'); dot.classList.remove('bg-white/40'); } else { dot.classList.remove('bg-white', 'scale-125'); dot.classList.add('bg-white/40'); } }); } }; window.handleThumbnailLeave = function (id) { if (isTouchDevice) return; const product = state.visibleProducts.find((p) => p.id === id); const thumb = document.getElementById(`thumb-${id}`); const indicators = document.querySelector(`#indicator-${id}`)?.children; if (thumb && product) { thumb.style.backgroundImage = `url("${product.images[0]}")`; } if (indicators) { Array.from(indicators).forEach((dot, i) => { if (i === 0) { dot.classList.add('bg-white', 'scale-125'); dot.classList.remove('bg-white/40'); } else { dot.classList.remove('bg-white', 'scale-125'); dot.classList.add('bg-white/40'); } }); } }; // 1. 체크박스 전역 핸들러 등록 window.toggleSelectItem = function (id) { if (state.selectedIds.has(id)) { state.selectedIds.delete(id); } else { state.selectedIds.add(id); } saveSelection(); renderProducts(state.currentPage); updateSummary(); }; export function renderProducts(page = 1) { const grid = document.getElementById('product-grid'); const tableWrapper = document.getElementById('product-table-wrapper'); const tableBody = document.getElementById('product-table-body'); const summaryBar = document.getElementById('selection-summary'); const paginationContainer = document.getElementById('pagination'); if (!grid || !tableWrapper) return; if (state.visibleProducts.length === 0) { grid.classList.remove('grid'); grid.classList.add('hidden'); tableWrapper.classList.add('hidden'); const emptyMsg = `
입력하신 검색어나 선택한 필터를 확인해 주세요.
${isNonSale ? 'Not for Sale' : `${product.currency || '₩'}${product.price.toLocaleString()}`}
${product.description}