[260204] 샘플 파일 적용

This commit is contained in:
2026-02-04 01:43:58 +09:00
parent b0e5fec03e
commit c185fd1cef
7 changed files with 609 additions and 511 deletions

View File

@@ -1,6 +1,6 @@
import products from '/data.js';
const ITEMS_PER_PAGE = 8;
const ITEMS_PER_PAGE = 20;
let currentPage = 1;
let activeCategories = new Set(['All']);
let visibleProducts = products;
@@ -8,12 +8,12 @@ let searchKeyword = '';
const VISIBILITY_CONFIG = {
showUnlisted: false, // 🔥 미판매 노출 여부
showSold: true,
showSold: true, // 🔥 판매완료 노출 여부
};
const STATUS_META = {
미판매: {
selectable: false, // 기본 필터에 안 뜸
selectable: false,
defaultVisible: false,
soldOut: false,
},
@@ -242,7 +242,7 @@ window.openModal = (id) => {
.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">
<img src="${img}" draggable="false" class="max-w-full max-h-full object-contain pointer-events-none shadow-sm rounded-lg">
</div>
`,
)
@@ -270,11 +270,112 @@ window.openModal = (id) => {
)
.join('');
const customTagElement = document.getElementById('modal-custom-tag');
const tagText = product.customTag;
if (tagText && tagText.trim() !== '') {
customTagElement.textContent = tagText;
customTagElement.classList.remove('hidden');
// 키워드별 색상 스타일 정의
const tagStyles = {
완전생산한정판: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400',
특전포함: 'bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-400',
미개봉: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',
무료배송: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
};
// 기본 스타일 (정의되지 않은 텍스트일 경우)
const defaultStyle = 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400';
// 기존 스타일 클래스 초기화 후 적용
customTagElement.className = `px-2.5 py-1 rounded-lg text-xs font-bold uppercase tracking-wider ${tagStyles[tagText] || defaultStyle}`;
} else {
customTagElement.classList.add('hidden');
}
const modalCategory = document.getElementById('modal-category');
if (modalCategory) {
modalCategory.textContent = product.category;
}
// 2. 상태값 업데이트 (상태에 따른 디자인 변경 포함)
const modalStatus = document.getElementById('modal-status');
if (modalStatus) {
modalStatus.textContent = product.status;
// 상태별 스타일 정의 (배경색, 글자색)
const statusStyles = {
판매중: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
판매예정: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
판매완료: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',
미판매: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400',
};
// 기존 클래스 제거 후 해당 상태의 스타일 추가
modalStatus.className = 'px-2.5 py-1 rounded-lg text-xs font-bold uppercase tracking-wider ' + (statusStyles[product.status] || statusStyles['미판매']);
}
// HTML 주입
document.getElementById('modal-main-carousel').innerHTML = mainImagesHtml;
document.getElementById('modal-thumbnails').innerHTML = thumbnailsHtml;
document.getElementById('modal-dots').innerHTML = dotsHtml;
// 1. 제품 상태 (specs.condition) 업데이트
const conditionText = product.specs?.condition;
const isVerified = product.specs?.isVerified;
const conditionRow = document.getElementById('modal-condition-row');
const conditionValue = document.getElementById('modal-condition');
const verifiedIcon = document.getElementById('modal-verified-icon');
// 1. 그레이드(condition) 값이 있는지 체크하여 라인 노출 결정
if (conditionText && conditionText.trim() !== '') {
conditionValue.textContent = conditionText;
conditionRow.classList.remove('hidden');
conditionRow.classList.add('flex');
// 2. 인증 여부에 따라 SVG 아이콘 노출 결정
if (isVerified) {
verifiedIcon.classList.remove('hidden');
} else {
verifiedIcon.classList.add('hidden');
}
} else {
// 값이 없으면 라인 전체 숨김
conditionRow.classList.add('hidden');
conditionRow.classList.remove('flex');
}
// 2. 제품 설명 (fullDescription) 업데이트
const modalDesc = document.getElementById('modal-desc');
if (modalDesc) {
const descData = product.fullDescription;
if (Array.isArray(descData)) {
// 배열을 <br> 태그로 합쳐서 HTML로 주입
modalDesc.innerHTML = descData.join('<br>');
} else {
modalDesc.textContent = descData || '';
}
}
// 구매일자 처리 (경로 수정: product.specs?.purchaseDate)
const modalDate = document.getElementById('modal-date');
const modalDateRow = document.getElementById('modal-date-row');
// specs 객체 안의 purchaseDate를 가져옴
const pDate = product.specs?.purchaseDate;
if (pDate && pDate.trim() !== '' && pDate !== 'null') {
modalDate.textContent = pDate;
modalDateRow.classList.remove('hidden');
modalDateRow.classList.add('flex');
} else {
modalDateRow.classList.add('hidden');
modalDateRow.classList.remove('flex');
}
// 텍스트 정보 주입 (ID들 맞춰주세요)
document.getElementById('modal-title').textContent = product.title;
document.getElementById('modal-price').textContent = `${product.currency}${product.price.toLocaleString()}`;
@@ -485,52 +586,48 @@ function getCategories(products) {
}
function renderCategoryChips(products) {
const container = document.getElementById('filter-chips');
if (!container) return;
const container = document.getElementById('filter-chips');
if (!container) return;
const categories = ['All', ...new Set(products.map((p) => p.category))];
const categories = ['All', ...new Set(products.map((p) => p.category))];
container.innerHTML = '';
container.innerHTML = '';
categories.forEach((cat) => {
const isActive = activeCategories.has(cat);
categories.forEach((cat) => {
const isActive = activeCategories.has(cat);
const chip = document.createElement('button');
chip.className = `
const chip = document.createElement('button');
chip.className = `
filter-chip px-4 py-2 rounded-full text-sm font-medium transition
border
${isActive
? 'bg-primary text-white border-primary'
: 'bg-slate-50 text-slate-600 border-slate-200'}
${isActive ? 'bg-primary text-white border-primary' : 'bg-slate-50 text-slate-600 border-slate-200'}
`;
chip.textContent = cat;
chip.dataset.category = cat;
chip.textContent = cat;
chip.dataset.category = cat;
chip.onclick = () => {
toggleCategory(cat);
};
chip.onclick = () => {
toggleCategory(cat);
};
container.appendChild(chip);
});
container.appendChild(chip);
});
}
function toggleCategory(category) {
if (category === 'All') {
activeCategories.clear();
activeCategories.add('All');
} else {
activeCategories.delete('All');
activeCategories.has(category)
? activeCategories.delete(category)
: activeCategories.add(category);
if (category === 'All') {
activeCategories.clear();
activeCategories.add('All');
} else {
activeCategories.delete('All');
activeCategories.has(category) ? activeCategories.delete(category) : activeCategories.add(category);
if (activeCategories.size === 0) {
activeCategories.add('All');
if (activeCategories.size === 0) {
activeCategories.add('All');
}
}
}
renderCategoryChips(products);
applyFilters();
renderCategoryChips(products);
applyFilters();
}
function bindCategoryFilter(products) {
@@ -563,7 +660,6 @@ function bindCategoryFilter(products) {
});
}
// 카테고리 필터
renderCategoryChips(products);
bindCategoryFilter(products);