366 lines
13 KiB
JavaScript
366 lines
13 KiB
JavaScript
import NSW_DB from '../db/nsw.resale.db.js';
|
|
|
|
const SHOW_RECOMMENDED_PRICE_RANGE_BY_DEFAULT = false;
|
|
|
|
/** @type {string} 가격 확인 완료 표시 */
|
|
const VERIFIED_PRICE_MARK = '⭐';
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// URL에서 게임 번호 가져오기
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const gameNo = parseInt(urlParams.get('no'));
|
|
|
|
// 게임 데이터 찾기
|
|
const game = NSW_DB.find(g => g.no === gameNo);
|
|
if (!game) {
|
|
alert('게임을 찾을 수 없습니다.');
|
|
window.location.href = 'index.html';
|
|
return;
|
|
}
|
|
|
|
// 언어 설정
|
|
const language = localStorage.getItem('language') || 'ko';
|
|
const texts = {
|
|
ko: {
|
|
infoTitle: '게임 정보',
|
|
purchaseTitle: '판매 정보',
|
|
requiredCapacity: '필요한 용량',
|
|
playMode: '플레이 모드',
|
|
playUser: '플레이 인원',
|
|
localPlayUser: '로컬 통신',
|
|
onlinePlayUser: '인터넷 통신',
|
|
compatibleController: '대응 컨트롤러',
|
|
onlineDataSave: '세이브 데이터 보관',
|
|
maker: '메이커',
|
|
language: '지원 언어',
|
|
cero: '심의 등급',
|
|
iarc: '심의 등급',
|
|
releaseDate: '출시일',
|
|
suggestedPrice: '판매가',
|
|
pricePending: '-',
|
|
priceRange: '판매가 범위',
|
|
pricingBasis: '가격 참고 기준',
|
|
checkedAt: '기준일',
|
|
itemCondition: '제품 상태',
|
|
priceVerified: '가격 확인',
|
|
extension: '추가 콘텐츠',
|
|
none: '없음',
|
|
supported: '대응',
|
|
notSupported: '비대응',
|
|
},
|
|
ja: {
|
|
infoTitle: 'Infomation',
|
|
purchaseTitle: '販売情報',
|
|
requiredCapacity: '必要な容量',
|
|
playMode: 'プレイモード',
|
|
playUser: 'プレイ人数',
|
|
localPlayUser: 'ローカル通信',
|
|
onlinePlayUser: 'インターネット通信',
|
|
compatibleController: '対応コントローラー',
|
|
onlineDataSave: 'セーブデータお預かり',
|
|
maker: 'メーカー',
|
|
language: '対応言語',
|
|
cero: 'CERO',
|
|
iarc: 'IARC',
|
|
releaseDate: '配信日',
|
|
suggestedPrice: '推奨販売価格',
|
|
pricePending: '-',
|
|
priceRange: '価格帯',
|
|
pricingBasis: '価格参考基準',
|
|
checkedAt: '確認日',
|
|
itemCondition: '商品状態',
|
|
priceVerified: '価格確認',
|
|
extension: '追加コンテンツ',
|
|
none: 'なし',
|
|
supported: '対応',
|
|
notSupported: '非対応',
|
|
},
|
|
};
|
|
|
|
const currentTexts = texts[language];
|
|
|
|
function formatKRW(value) {
|
|
if (typeof value !== 'number') return currentTexts.pricePending;
|
|
return `${value.toLocaleString('ko-KR')}원`;
|
|
}
|
|
|
|
function formatPricingBasis(pricingBasis) {
|
|
const labels = {
|
|
ko: {
|
|
KR_USED_REFERENCE_ESTIMATE: '국내 중고 시세 참고',
|
|
JP_USED_REFERENCE_CONVERTED_TO_KRW_ESTIMATE: '일본 중고 시세 환산',
|
|
MANUAL: '직접 입력가',
|
|
SOLD_HISTORY: '판매 이력 기준',
|
|
},
|
|
ja: {
|
|
KR_USED_REFERENCE_ESTIMATE: '韓国中古相場参考',
|
|
JP_USED_REFERENCE_CONVERTED_TO_KRW_ESTIMATE: '日本中古相場換算',
|
|
MANUAL: '手入力価格',
|
|
SOLD_HISTORY: '販売履歴基準',
|
|
},
|
|
};
|
|
|
|
return labels[language][pricingBasis] || '';
|
|
}
|
|
|
|
function formatItemCondition(itemCondition) {
|
|
if (!itemCondition || itemCondition === '-') return '';
|
|
|
|
const labels = {
|
|
ko: {
|
|
SEALED: '미개봉',
|
|
OPENED: '개봉',
|
|
},
|
|
ja: {
|
|
SEALED: '未開封',
|
|
OPENED: '開封済',
|
|
},
|
|
};
|
|
|
|
return labels[language][itemCondition] || itemCondition;
|
|
}
|
|
|
|
function formatPriceVerified(priceVerified) {
|
|
if (!priceVerified) return '';
|
|
return language === 'ko' ? '실제 시세 확인 완료' : '実勢価格確認済み';
|
|
}
|
|
|
|
function convertLanguage(value) {
|
|
if (!value || language !== 'ko') return value;
|
|
|
|
const labels = {
|
|
日本語: '일본어',
|
|
英語: '영어',
|
|
韓国語: '한국어',
|
|
フランス語: '프랑스어',
|
|
ドイツ語: '독일어',
|
|
イタリア語: '이탈리아어',
|
|
スペイン語: '스페인어',
|
|
ロシア語: '러시아어',
|
|
オランダ語: '네덜란드어',
|
|
ポルトガル語: '포르투갈어',
|
|
'中国語 (簡体字)': '중국어 (간체)',
|
|
'中国語 (繁体字)': '중국어 (번체)',
|
|
};
|
|
|
|
return value
|
|
.split(',')
|
|
.map(item => labels[item.trim()] || item.trim())
|
|
.join(', ');
|
|
}
|
|
|
|
function convertMaker(value) {
|
|
if (!value || language !== 'ko') return value;
|
|
|
|
const labels = {
|
|
任天堂: '닌텐도',
|
|
スクウェア・エニックス: '스퀘어 에닉스',
|
|
コーエーテクモゲームス: '코에이 테크모 게임스',
|
|
ポケモン: '포켓몬',
|
|
バンダイナムコエンターテインメント: '반다이 남코 엔터테인먼트',
|
|
アトラス: '아틀러스',
|
|
セガ: '세가',
|
|
マーベラス: '마블러스 엔터테인먼트',
|
|
カプコン: '캡콤',
|
|
ユービーアイソフト: '유비소프트',
|
|
日本一ソフトウェア: '니폰이치 소프트웨어',
|
|
アークシステムワークス: '아크 시스템 웍스',
|
|
日本ファルコム: '일본 팔콤',
|
|
};
|
|
|
|
return value
|
|
.split(',')
|
|
.map(item => labels[item.trim()] || item.trim())
|
|
.join(', ');
|
|
}
|
|
|
|
function convertTags(value) {
|
|
if (!value || language !== 'ko') return value;
|
|
|
|
const labels = {
|
|
アクション: '액션',
|
|
アドベンチャー: '어드벤처',
|
|
テキストアドベンチャー: '텍스트 어드벤처',
|
|
ロールプレイング: '롤플레잉',
|
|
シューティング: '슈팅',
|
|
シミュレーション: '시뮬레이션',
|
|
ストラテジー: '전략',
|
|
パズル: '퍼즐',
|
|
レース: '레이스',
|
|
スポーツ: '스포츠',
|
|
格闘: '격투',
|
|
音楽ゲーム: '음악 게임',
|
|
恋愛: '연애',
|
|
難易度が選べる: '난이도 선택 가능',
|
|
戦うたびに強くなる: '싸울수록 성장',
|
|
キャラクターボイス: '캐릭터 음성',
|
|
オンラインで対戦: '온라인 대전',
|
|
オンラインで協力: '온라인 협력',
|
|
オンラインでフレンドと: '친구와 온라인으로',
|
|
キャラクターカスタマイズ: '캐릭터 커스터마이즈',
|
|
'3人称視点': '3인칭 시점',
|
|
'1台の本体でいっしょにあそべる': '한 대의 본체에서 함께 플레이',
|
|
ともだちや家族と集まって: '친구와 가족과 함께',
|
|
オンラインランキング: '온라인 랭킹',
|
|
本体を持ちよってあそべる: '게임기를 들고 플레이',
|
|
世界を自由にかけ回る: '세계를 자유롭게 탐험',
|
|
目的はあなた次第: '목적은 자유롭게 선택',
|
|
};
|
|
|
|
return value
|
|
.split(',')
|
|
.map(item => labels[item.trim()] || item.trim())
|
|
.join(', ');
|
|
}
|
|
|
|
function convertReleaseDate(value) {
|
|
if (!value || language !== 'ko') return value;
|
|
|
|
const date = new Date(value.replace(/年|月/g, '/').replace('日', ''));
|
|
if (Number.isNaN(date.getTime())) return value;
|
|
|
|
return `${date.getFullYear()}년 ${date.getMonth() + 1}월 ${date.getDate()}일`;
|
|
}
|
|
|
|
function convertSupportValue(value) {
|
|
if (!value || language !== 'ko') return value;
|
|
|
|
return value.replaceAll('対応', '대응').replaceAll('非対応', '비대응');
|
|
}
|
|
|
|
function getGameInfoValue(key) {
|
|
switch (key) {
|
|
case 'maker':
|
|
return convertMaker(game[key]);
|
|
case 'language':
|
|
return convertLanguage(game[key]);
|
|
case 'release':
|
|
return convertReleaseDate(game[key]);
|
|
case 'onlineDataSave':
|
|
return convertSupportValue(game[key]);
|
|
default:
|
|
return game[key];
|
|
}
|
|
}
|
|
|
|
// 기본 정보 설정
|
|
document.getElementById('gameImage').src = window.innerWidth < 640 ? game.thumbnail : game.image;
|
|
const displayTitle = language === 'ko' ? game.koTitle || game.title : game.title;
|
|
const gameTitleEl = document.getElementById('gameTitle');
|
|
gameTitleEl.className =
|
|
'text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl flex items-center justify-center gap-2';
|
|
gameTitleEl.innerHTML = `${game.sale?.priceVerified ? `${VERIFIED_PRICE_MARK} ` : ''}<span>${displayTitle}</span>`;
|
|
document.getElementById('gameTags').textContent = convertTags(game.tags);
|
|
document.getElementById('infoTitle').textContent = currentTexts.infoTitle;
|
|
document.getElementById('purchaseTitle').textContent = currentTexts.purchaseTitle;
|
|
document.getElementById('purchaseGameTitle').textContent =
|
|
language === 'ko' ? game.koTitle || game.title : game.title;
|
|
|
|
// 게임 상태 설정
|
|
const statusClass = {
|
|
available: 'bg-green-100 text-green-800',
|
|
download: 'bg-yellow-100 text-yellow-800',
|
|
expansion: 'bg-blue-100 text-blue-800',
|
|
sold: 'bg-red-100 text-red-800',
|
|
}[game.status];
|
|
document.getElementById(
|
|
'gameStatus',
|
|
).className = `inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${statusClass}`;
|
|
document.getElementById('gameStatus').textContent =
|
|
language === 'ko'
|
|
? { available: '판매중', sold: '판매완료' }[game.status] || game.status
|
|
: { available: '販売中', sold: '販売済み' }[game.status] || game.status;
|
|
|
|
// 국가 설정
|
|
const countryClass =
|
|
game.country === 'JPN'
|
|
? 'text-red-600 hover:text-red-900'
|
|
: 'text-indigo-600 hover:text-indigo-900';
|
|
document.getElementById('gameCountry').className = `text-center ${countryClass}`;
|
|
document.getElementById('gameCountry').textContent =
|
|
language === 'ko'
|
|
? game.country === 'JPN'
|
|
? '🇯🇵 일본판'
|
|
: '🇰🇷 한국 정발판'
|
|
: game.country === 'JPN'
|
|
? '🇯🇵 日本版'
|
|
: '🇰🇷 韓国版';
|
|
|
|
// 게임 정보 설정
|
|
const gameInfo = document.getElementById('gameInfo');
|
|
const infoItems = [
|
|
{ key: 'requiredCapacity', label: currentTexts.requiredCapacity },
|
|
{ key: 'playMode', label: currentTexts.playMode },
|
|
{ key: 'playUser', label: currentTexts.playUser },
|
|
{ key: 'compatibleController', label: currentTexts.compatibleController },
|
|
{ key: 'onlineDataSave', label: currentTexts.onlineDataSave },
|
|
{ key: 'maker', label: currentTexts.maker },
|
|
{ key: 'language', label: currentTexts.language },
|
|
{ key: 'cero', label: currentTexts.cero },
|
|
{ key: 'iarc', label: currentTexts.iarc },
|
|
{ key: 'release', label: currentTexts.releaseDate },
|
|
];
|
|
|
|
infoItems.forEach(item => {
|
|
const value = getGameInfoValue(item.key);
|
|
|
|
if (value) {
|
|
const div = document.createElement('div');
|
|
div.className = 'border-t border-gray-200 pt-4';
|
|
div.innerHTML = `
|
|
<dt class="font-medium text-gray-900">${item.label}</dt>
|
|
<dd class="mt-2 text-sm text-gray-500">${value}</dd>
|
|
`;
|
|
gameInfo.appendChild(div);
|
|
}
|
|
});
|
|
|
|
// 판매 정보 설정
|
|
const purchaseInfo = document.getElementById('purchaseInfo');
|
|
if (game.sale) {
|
|
const priceRange =
|
|
game.sale.priceRange?.min && game.sale.priceRange?.max
|
|
? `${formatKRW(game.sale.priceRange.min)} ~ ${formatKRW(game.sale.priceRange.max)}`
|
|
: '';
|
|
const saleItems = [
|
|
{ value: formatKRW(game.sale.suggestedPrice), label: currentTexts.suggestedPrice },
|
|
...(SHOW_RECOMMENDED_PRICE_RANGE_BY_DEFAULT
|
|
? [{ value: priceRange, label: currentTexts.priceRange }]
|
|
: []),
|
|
{ value: formatPricingBasis(game.sale.pricingBasis), label: currentTexts.pricingBasis },
|
|
{ value: formatItemCondition(game.itemCondition), label: currentTexts.itemCondition },
|
|
{ value: formatPriceVerified(game.sale.priceVerified), label: currentTexts.priceVerified },
|
|
{ value: game.sale.checkedAt, label: currentTexts.checkedAt },
|
|
];
|
|
|
|
const dl = document.createElement('dl');
|
|
dl.className = 'grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2';
|
|
|
|
saleItems.forEach(item => {
|
|
if (item.value) {
|
|
const div = document.createElement('div');
|
|
div.className = 'sm:col-span-1';
|
|
div.innerHTML = `
|
|
<dt class="text-sm font-medium text-gray-500">${item.label}</dt>
|
|
<dd class="mt-1 text-sm text-gray-900">${item.value}</dd>
|
|
`;
|
|
dl.appendChild(div);
|
|
}
|
|
});
|
|
|
|
if (game.extension) {
|
|
const div = document.createElement('div');
|
|
div.className = 'sm:col-span-2';
|
|
div.innerHTML = `
|
|
<dt class="text-sm font-medium text-gray-500">${currentTexts.extension}</dt>
|
|
<dd class="mt-1 text-sm text-gray-900">
|
|
${game.extension.map(ext => `<div>${ext}</div>`).join('')}
|
|
</dd>
|
|
`;
|
|
dl.appendChild(div);
|
|
}
|
|
|
|
purchaseInfo.appendChild(dl);
|
|
}
|
|
});
|