Fix mobile search and update resale prices
This commit is contained in:
@@ -2416,7 +2416,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"price": 1480,
|
"price": 1480,
|
||||||
"sale": {
|
"sale": {
|
||||||
"currency": "KRW",
|
"currency": "KRW",
|
||||||
"suggestedPrice": 12000,
|
"suggestedPrice": 30000,
|
||||||
"priceRange": {
|
"priceRange": {
|
||||||
"min": 10000,
|
"min": 10000,
|
||||||
"max": 14000
|
"max": 14000
|
||||||
@@ -2426,7 +2426,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"confidence": "low",
|
"confidence": "low",
|
||||||
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
||||||
"checkedAt": "2026-05-19",
|
"checkedAt": "2026-05-19",
|
||||||
"priceVerified": false
|
"priceVerified": true
|
||||||
},
|
},
|
||||||
"itemCondition": "-",
|
"itemCondition": "-",
|
||||||
"status": "available"
|
"status": "available"
|
||||||
@@ -2606,7 +2606,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"price": 6578,
|
"price": 6578,
|
||||||
"sale": {
|
"sale": {
|
||||||
"currency": "KRW",
|
"currency": "KRW",
|
||||||
"suggestedPrice": 28000,
|
"suggestedPrice": 40000,
|
||||||
"priceRange": {
|
"priceRange": {
|
||||||
"min": 24000,
|
"min": 24000,
|
||||||
"max": 32000
|
"max": 32000
|
||||||
@@ -2616,7 +2616,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"confidence": "low",
|
"confidence": "low",
|
||||||
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
||||||
"checkedAt": "2026-05-19",
|
"checkedAt": "2026-05-19",
|
||||||
"priceVerified": false
|
"priceVerified": true
|
||||||
},
|
},
|
||||||
"itemCondition": "-",
|
"itemCondition": "-",
|
||||||
"status": "available"
|
"status": "available"
|
||||||
@@ -5456,7 +5456,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"price": 2480,
|
"price": 2480,
|
||||||
"sale": {
|
"sale": {
|
||||||
"currency": "KRW",
|
"currency": "KRW",
|
||||||
"suggestedPrice": 12000,
|
"suggestedPrice": 25000,
|
||||||
"priceRange": {
|
"priceRange": {
|
||||||
"min": 10000,
|
"min": 10000,
|
||||||
"max": 14000
|
"max": 14000
|
||||||
@@ -6710,7 +6710,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"price": 9172,
|
"price": 9172,
|
||||||
"sale": {
|
"sale": {
|
||||||
"currency": "KRW",
|
"currency": "KRW",
|
||||||
"suggestedPrice": 41000,
|
"suggestedPrice": 90000,
|
||||||
"priceRange": {
|
"priceRange": {
|
||||||
"min": 35000,
|
"min": 35000,
|
||||||
"max": 47000
|
"max": 47000
|
||||||
@@ -6720,7 +6720,7 @@ export const NSW_RESALE_DB = {
|
|||||||
"confidence": "medium-low",
|
"confidence": "medium-low",
|
||||||
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
"memo": "한국 중고가 우선, 국내 시세가 약한/없는 일본판·희소 타이틀은 일본 중고가를 원화 환산한 대략 판매가. 상태/구성품/특전/케이스 상태에 따라 조정 필요.",
|
||||||
"checkedAt": "2026-05-19",
|
"checkedAt": "2026-05-19",
|
||||||
"priceVerified": false
|
"priceVerified": true
|
||||||
},
|
},
|
||||||
"itemCondition": "-",
|
"itemCondition": "-",
|
||||||
"status": "available"
|
"status": "available"
|
||||||
|
|||||||
57
index.html
57
index.html
@@ -15,6 +15,46 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section aria-labelledby="products-heading" class="pt-6 pb-12">
|
<section aria-labelledby="products-heading" class="pt-6 pb-12">
|
||||||
|
<div id="mobileSearchForm" class="mb-4 lg:hidden">
|
||||||
|
<label
|
||||||
|
for="mobile-search-input"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900">
|
||||||
|
직접 검색
|
||||||
|
</label>
|
||||||
|
<div class="relative mt-2 flex rounded-md shadow-sm">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
|
||||||
|
게임명
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="mobile-search-input"
|
||||||
|
data-search-input
|
||||||
|
enterkeyhint="search"
|
||||||
|
autocomplete="off"
|
||||||
|
oninput="window.updateNswSearch && window.updateNswSearch(this.value)"
|
||||||
|
onchange="window.updateNswSearch && window.updateNswSearch(this.value)"
|
||||||
|
class="block w-full min-w-0 flex-1 rounded-none rounded-r-md px-2 py-2 pr-9 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||||
|
placeholder=" " />
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="absolute inset-y-0 right-0 z-10 flex items-center pr-3"
|
||||||
|
id="mobile-reset-search"
|
||||||
|
aria-label="검색어 지우기"
|
||||||
|
onclick="window.clearNswSearch && window.clearNswSearch()">
|
||||||
|
<svg
|
||||||
|
class="h-5 w-5 text-gray-400"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-x-8 gap-y-2 lg:grid-cols-4">
|
<div class="grid grid-cols-1 gap-x-8 gap-y-2 lg:grid-cols-4">
|
||||||
<!-- 필터 섹션 -->
|
<!-- 필터 섹션 -->
|
||||||
<div class="lg:block">
|
<div class="lg:block">
|
||||||
@@ -78,7 +118,7 @@
|
|||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<form id="searchForm" class="mb-4">
|
<form id="searchForm" class="mb-4" onsubmit="return false">
|
||||||
<label
|
<label
|
||||||
for="search-input"
|
for="search-input"
|
||||||
class="block text-sm font-medium leading-6 text-gray-900">
|
class="block text-sm font-medium leading-6 text-gray-900">
|
||||||
@@ -91,13 +131,18 @@
|
|||||||
</span>
|
</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="search-input"
|
|
||||||
id="search-input"
|
id="search-input"
|
||||||
class="block w-full px-2 min-w-0 flex-1 rounded-none rounded-r-md py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
data-search-input
|
||||||
|
enterkeyhint="search"
|
||||||
|
autocomplete="off"
|
||||||
|
oninput="window.updateNswSearch && window.updateNswSearch(this.value)"
|
||||||
|
onchange="window.updateNswSearch && window.updateNswSearch(this.value)"
|
||||||
|
class="block w-full px-2 min-w-0 flex-1 rounded-none rounded-r-md py-1.5 pr-9 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||||
placeholder=" " />
|
placeholder=" " />
|
||||||
<div
|
<div
|
||||||
class="cursor-pointer absolute inset-y-0 right-0 flex items-center pr-3"
|
class="cursor-pointer absolute inset-y-0 right-0 z-10 flex items-center pr-3"
|
||||||
id="reset-search">
|
id="reset-search"
|
||||||
|
onclick="window.clearNswSearch && window.clearNswSearch()">
|
||||||
<svg
|
<svg
|
||||||
class="h-5 w-5 text-gray-400"
|
class="h-5 w-5 text-gray-400"
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
@@ -497,6 +542,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="module" src="./script/nsw.js"></script>
|
<script type="module" src="./script/nsw.js?v=20260519-mobile-search"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
143
script/nsw.js
143
script/nsw.js
@@ -1,5 +1,7 @@
|
|||||||
import NSW_DB from '../db/nsw.resale.db.js';
|
import NSW_DB from '../db/nsw.resale.db.js';
|
||||||
|
|
||||||
|
window.NSW_APP_VERSION = '20260519-mobile-search';
|
||||||
|
|
||||||
const SHOW_SOLD_BY_DEFAULT = false;
|
const SHOW_SOLD_BY_DEFAULT = false;
|
||||||
const SHOW_RECOMMENDED_PRICE_RANGE_BY_DEFAULT = false;
|
const SHOW_RECOMMENDED_PRICE_RANGE_BY_DEFAULT = false;
|
||||||
|
|
||||||
@@ -816,7 +818,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
cero: [],
|
cero: [],
|
||||||
};
|
};
|
||||||
filterState.searchText = '';
|
filterState.searchText = '';
|
||||||
document.getElementById('search-input').value = '';
|
document.querySelectorAll('[data-search-input]').forEach(input => {
|
||||||
|
input.value = '';
|
||||||
|
});
|
||||||
|
|
||||||
// 게임 목록 다시 렌더링
|
// 게임 목록 다시 렌더링
|
||||||
renderGames();
|
renderGames();
|
||||||
@@ -827,25 +831,136 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// 필터 체크박스 이벤트 리스너 설정
|
// 필터 체크박스 이벤트 리스너 설정
|
||||||
function setupFilterListeners() {
|
function setupFilterListeners() {
|
||||||
const searchInput = document.getElementById('search-input');
|
const searchInputs = [
|
||||||
const searchForm = document.getElementById('searchForm');
|
document.getElementById('search-input'),
|
||||||
const resetSearch = document.getElementById('reset-search');
|
document.getElementById('mobile-search-input'),
|
||||||
|
].filter(Boolean);
|
||||||
|
const searchForms = [document.getElementById('searchForm')].filter(Boolean);
|
||||||
|
const resetSearchButtons = [
|
||||||
|
document.getElementById('reset-search'),
|
||||||
|
document.getElementById('mobile-reset-search'),
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
searchForm.addEventListener('submit', event => {
|
function updateSearchText(value) {
|
||||||
event.preventDefault();
|
filterState.searchText = value.trim().toLowerCase();
|
||||||
filterState.searchText = searchInput.value.trim().toLowerCase();
|
searchInputs.forEach(input => {
|
||||||
|
if (input.value !== value) input.value = value;
|
||||||
|
});
|
||||||
renderGames();
|
renderGames();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.updateNswSearch = value => {
|
||||||
|
updateSearchText(value || '');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.clearNswSearch = () => {
|
||||||
|
updateSearchText('');
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateSearchFromInput(input, options = {}) {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
updateSearchText(input.value);
|
||||||
|
if (options.blur) input.blur();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSearchInput(target) {
|
||||||
|
return target instanceof HTMLInputElement && target.matches('[data-search-input]');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
'submit',
|
||||||
|
event => {
|
||||||
|
if (!event.target.querySelector?.('[data-search-input]')) return;
|
||||||
|
event.preventDefault();
|
||||||
|
if (event.stopImmediatePropagation) event.stopImmediatePropagation();
|
||||||
|
event.stopPropagation();
|
||||||
|
const searchInput = event.target.querySelector('[data-search-input]');
|
||||||
|
if (searchInput) updateSearchFromInput(searchInput, { blur: true });
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
'input',
|
||||||
|
event => {
|
||||||
|
if (!isSearchInput(event.target)) return;
|
||||||
|
updateSearchText(event.target.value);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
'change',
|
||||||
|
event => {
|
||||||
|
if (!isSearchInput(event.target)) return;
|
||||||
|
updateSearchFromInput(event.target);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
'focusout',
|
||||||
|
event => {
|
||||||
|
if (!isSearchInput(event.target)) return;
|
||||||
|
updateSearchFromInput(event.target);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
searchForms.forEach(form => {
|
||||||
|
form.addEventListener(
|
||||||
|
'submit',
|
||||||
|
event => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (event.stopImmediatePropagation) event.stopImmediatePropagation();
|
||||||
|
event.stopPropagation();
|
||||||
|
const searchInput = form.querySelector('[data-search-input]');
|
||||||
|
if (searchInput) updateSearchFromInput(searchInput, { blur: true });
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
searchInput.addEventListener('input', event => {
|
searchInputs.forEach(input => {
|
||||||
filterState.searchText = event.target.value.trim().toLowerCase();
|
let isComposing = false;
|
||||||
renderGames();
|
|
||||||
|
input.addEventListener('compositionstart', () => {
|
||||||
|
isComposing = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener('blur', event => {
|
||||||
|
updateSearchFromInput(event.target);
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener('compositionend', event => {
|
||||||
|
isComposing = false;
|
||||||
|
updateSearchFromInput(event.target);
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener('keydown', event => {
|
||||||
|
if (event.key !== 'Enter') return;
|
||||||
|
if (isComposing || event.isComposing || event.keyCode === 229) return;
|
||||||
|
event.preventDefault();
|
||||||
|
updateSearchFromInput(event.target, { blur: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
input.addEventListener('keyup', event => {
|
||||||
|
if (isComposing || event.isComposing || event.keyCode === 229) return;
|
||||||
|
updateSearchFromInput(event.target, { blur: event.key === 'Enter' });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
resetSearch.addEventListener('click', () => {
|
resetSearchButtons.forEach(button => {
|
||||||
filterState.searchText = '';
|
function clearSearch(event) {
|
||||||
searchInput.value = '';
|
event.preventDefault();
|
||||||
renderGames();
|
event.stopPropagation();
|
||||||
|
updateSearchText('');
|
||||||
|
}
|
||||||
|
|
||||||
|
button.addEventListener('pointerdown', clearSearch);
|
||||||
|
button.addEventListener('touchstart', clearSearch);
|
||||||
|
button.addEventListener('click', clearSearch);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 언어 필터
|
// 언어 필터
|
||||||
|
|||||||
Reference in New Issue
Block a user