오류 수정

This commit is contained in:
2026-02-11 02:35:33 +09:00
parent f3e0e08c6b
commit 66d4f54e98
7 changed files with 165 additions and 73 deletions

View File

@@ -1,7 +1,19 @@
/** 상품 그리드·페이지네이션 렌더링 */
import { state } from './state.js';
import { state, saveSelection } from './state.js';
import { ITEMS_PER_PAGE, STATUS_META, STATUS_COLOR, PRODUCT_CONDITIONS } from './config.js';
import { updateSummary } from './main.js';
import { openModal } from './modal.js';
// 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');
@@ -59,11 +71,9 @@ export function renderProducts(page = 1) {
grid.innerHTML = '';
pagedProducts.forEach((product) => {
const isSold = STATUS_META[product.status]?.soldOut === true;
grid.insertAdjacentHTML(
'beforeend',
`
grid.insertAdjacentHTML('beforeend', `
<div class="group flex flex-col gap-4 cursor-pointer" onclick="openModal('${product.id}')">
<div class="relative w-full aspect-card bg-slate-50 dark:bg-slate-800 rounded-xl overflow-hidden shadow-sm group-hover:shadow-md transition-shadow">
<div class="relative w-full aspect-card bg-slate-50 dark:bg-slate-800 rounded-xl overflow-hidden shadow-sm transition-shadow">
<div class="w-full h-full bg-center bg-no-repeat bg-cover transform ${isSold ? 'grayscale opacity-80' : 'group-hover:scale-105'} transition-transform duration-500"
style="background-image: url('${product.images[0]}')"></div>
<div class="absolute top-3 left-3">
@@ -80,46 +90,58 @@ export function renderProducts(page = 1) {
<p class="text-slate-500 dark:text-slate-400 text-sm font-normal line-clamp-1">${product.description}</p>
</div>
</div>
`,
);
`);
});
} else {
// 테이블 렌더링 (이전과 동일, 가격 포함)
// [테이블 렌더링: 스타일 & 체크박스 제어 추가]
tableBody.innerHTML = pagedProducts
.map((product) => {
const isSelectable = STATUS_META[product.status]?.selectable !== false;
const meta = STATUS_META[product.status];
const isSold = meta?.soldOut === true;
const isSelectable = meta?.selectable !== false;
// 1. 상태(Condition) 설정 로직
const conditionKey = product.specs.condition;
const conditionConfig = PRODUCT_CONDITIONS[conditionKey];
let conditionDisplay = '';
let conditionClass = 'text-slate-500';
if (conditionConfig) {
// 1. 정의된 Key인 경우 (추천 방식)
conditionDisplay = conditionConfig.label;
conditionClass = conditionConfig.color;
} else if (conditionKey && conditionKey.trim() !== '') {
// 2. 정의되지 않았지만 텍스트가 있는 경우 (기존 수기 입력 데이터)
conditionDisplay = conditionKey;
} else {
// 3. 데이터가 비어있는 경우
conditionDisplay = '상세 설명 참고 ';
conditionClass = 'text-indigo-500 italic';
}
// 2. 행 전체 스타일 및 제목 스타일
const rowClass = isSold ? 'opacity-50 grayscale-[0.5]' : '';
const titleClass = isSold ? 'line-through text-slate-400' : 'text-slate-900 dark:text-white';
return `
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors cursor-pointer" onclick="if(event.target.type !== 'checkbox') openModal('${product.id}')">
<td class="py-4 px-4 text-center" onclick="event.stopPropagation()">
<input type="checkbox" ...>
</td>
<td class="py-4 px-4 font-semibold text-slate-900 dark:text-white">${product.title}</td>
<td class="py-4 px-4 text-xs break-keep ${conditionClass}">${conditionDisplay}</td>
<td class="py-4 px-4 text-right font-bold text-slate-900 dark:text-white">₩${product.price.toLocaleString()}</td>
<td class="hidden lg:block py-4 px-4 text-center">
<span class="px-2 py-0.5 rounded text-[10px] font-bold border ${STATUS_COLOR[product.status]}">${product.status}</span>
</td>
</tr>`;
})
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors ${isSold ? 'opacity-50 grayscale cursor-not-allowed' : 'cursor-pointer'}"
onclick="if(event.target.type !== 'checkbox') {
${isSold ? "alert('판매 완료된 상품은 상세 정보를 볼 수 없습니다.');" : `openModal('${product.id}')`}
}">
<td class="py-4 px-4 text-center" onclick="event.stopPropagation()">
<input type="checkbox"
class="product-check rounded border-slate-300 w-4 h-4 ${isSelectable ? 'cursor-pointer text-primary' : 'opacity-20 cursor-not-allowed'}"
${state.selectedIds.has(product.id) ? 'checked' : ''}
${isSelectable ? '' : 'disabled'}
onchange="window.toggleSelectItem('${product.id}')">
</td>
<td class="py-4 px-4 font-semibold ${isSold ? 'line-through text-slate-400' : 'text-slate-900 dark:text-white'}">${product.title}</td>
<td class="py-4 px-4 text-xs break-keep ${conditionClass}">${conditionDisplay}</td>
<td class="py-4 px-4 text-right font-bold text-slate-900 dark:text-white">
${product.price.toLocaleString()}
</td>
<td class="hidden lg:table-cell py-4 px-4 text-center">
<span class="px-2 py-0.5 rounded text-[10px] font-bold border ${STATUS_COLOR[product.status]}">${product.status}</span>
</td>
</tr>`;
})
.join('');
}