[260204] 데이터 카테고리별 분리

This commit is contained in:
2026-02-04 11:25:24 +09:00
parent 6265a0b7c0
commit d4ccc616a7
6 changed files with 216 additions and 229 deletions

View File

@@ -1,4 +1,8 @@
import products from '/data.js';
// scripts/app.js 상단
import products from '../data/index.js';
// 이제 products는 모든 카테고리가 합쳐지고 날짜순으로 정렬된 상태입니다.
console.log('Total products loaded:', products.length);
const ITEMS_PER_PAGE = 20;
let currentPage = 1;
@@ -81,7 +85,6 @@ let activeStatuses = new Set(
.map(([status]) => status),
);
// openModal 함수 내부에 추가하거나 전역으로 설정
const copyBtn = document.getElementById('copy-link-btn');
const copyBtnText = document.getElementById('copy-btn-text');
@@ -89,13 +92,13 @@ const copyBtnText = document.getElementById('copy-btn-text');
copyBtn.onclick = () => {
// 현재 도메인 + 제품 ID 쿼리 조합
const shareUrl = `${window.location.origin}${window.location.pathname}?id=${product.id}`;
navigator.clipboard.writeText(shareUrl).then(() => {
copyBtnText.textContent = "링크가 복사되었습니다!";
copyBtnText.textContent = '링크가 복사되었습니다!';
copyBtn.classList.replace('bg-slate-900', 'bg-green-600');
setTimeout(() => {
copyBtnText.textContent = "상품 링크 복사하기";
copyBtnText.textContent = '상품 링크 복사하기';
copyBtn.classList.replace('bg-green-600', 'bg-slate-900');
}, 2000);
});
@@ -258,25 +261,34 @@ window.openModal = (id) => {
// --- 1. 이미지 및 UI 초기화 로직 ---
const loopImages = [images[images.length - 1], ...images, images[0]];
const mainImagesHtml = loopImages
.map(img => `
.map(
(img) => `
<div class="flex-shrink-0 w-full h-full snap-center flex items-center justify-center p-4 select-none">
<img src="${img}" draggable="false" class="max-w-full max-h-full object-contain pointer-events-none shadow-sm rounded-lg">
</div>
`).join('');
`,
)
.join('');
const thumbnailsHtml = product.images
.map((img, idx) => `
.map(
(img, idx) => `
<div onclick="scrollToImage(${idx})"
class="modal-thumb-item size-16 rounded-lg border-2 ${idx === 0 ? 'border-primary' : 'border-transparent'}
bg-cover bg-center overflow-hidden cursor-pointer ${idx === 0 ? 'opacity-100' : 'opacity-70'}
hover:opacity-100 transition-all flex-shrink-0"
style="background-image: url('${img}');"></div>
`).join('');
`,
)
.join('');
const dotsHtml = product.images
.map((_, idx) => `
.map(
(_, idx) => `
<div class="modal-dot-item ${idx === 0 ? 'w-4 bg-primary' : 'w-2 bg-gray-300 dark:bg-gray-700'} h-2 rounded-full transition-all"></div>
`).join('');
`,
)
.join('');
// --- 2. 데이터 주입 ---
document.getElementById('modal-main-carousel').innerHTML = mainImagesHtml;
@@ -313,7 +325,7 @@ window.openModal = (id) => {
// 상세 설명
const modalDesc = document.getElementById('modal-desc');
if (modalDesc) {
modalDesc.innerHTML = Array.isArray(product.fullDescription) ? product.fullDescription.join('<br>') : (product.fullDescription || '');
modalDesc.innerHTML = Array.isArray(product.fullDescription) ? product.fullDescription.join('<br>') : product.fullDescription || '';
}
// --- 3. [핵심] 링크 복사 버튼 이벤트 바인딩 ---
@@ -323,10 +335,10 @@ window.openModal = (id) => {
copyBtn.onclick = () => {
const shareUrl = `${window.location.origin}${window.location.pathname}?id=${product.id}`;
navigator.clipboard.writeText(shareUrl).then(() => {
if (copyBtnText) copyBtnText.textContent = "링크가 복사되었습니다!";
copyBtn.classList.add('!bg-green-600');
if (copyBtnText) copyBtnText.textContent = '링크가 복사되었습니다!';
copyBtn.classList.add('!bg-green-600');
setTimeout(() => {
if (copyBtnText) copyBtnText.textContent = "상품 링크 복사하기";
if (copyBtnText) copyBtnText.textContent = '상품 링크 복사하기';
copyBtn.classList.remove('!bg-green-600');
}, 2000);
});
@@ -351,7 +363,7 @@ window.openModal = (id) => {
window.closeModal = () => {
document.getElementById('product-modal').classList.add('hidden');
document.body.style.overflow = 'auto';
const cleanUrl = window.location.origin + window.location.pathname;
window.history.replaceState(null, '', cleanUrl);
};
@@ -627,15 +639,14 @@ document.addEventListener('DOMContentLoaded', () => {
checkUrlAndOpenModal();
});
function checkUrlAndOpenModal() {
const params = new URLSearchParams(window.location.search);
const productId = params.get('id'); // URL에서 가져온 ID (문자열)
if (productId) {
// 데이터의 id와 URL의 id를 모두 문자열로 변환하여 비교
const product = products.find((p) => String(p.id) === productId);
if (product) {
// DOM 렌더링 시간을 고려해 약간의 지연 후 모달 오픈
setTimeout(() => openModal(product.id), 100);
@@ -643,8 +654,7 @@ function checkUrlAndOpenModal() {
}
}
// [최종 ID 생성기] 매번 완전히 새로운 8자리 난수 출력
const newId = Math.random().toString(36).substring(2, 10);
console.log(`%c[NEW ID for data.js]: ${newId}`, "color: #137fec; font-weight: bold; border: 1px solid #137fec; padding: 2px 5px; border-radius: 4px;");
console.log(`%c[NEW ID for data.js]: ${newId}`, 'color: #137fec; font-weight: bold; border: 1px solid #137fec; padding: 2px 5px; border-radius: 4px;');