992 lines
36 KiB
HTML
992 lines
36 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta
|
|
name="viewport"
|
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
/>
|
|
<title>Card List</title>
|
|
<script src="/script/navigation.js"></script>
|
|
<script type="module" src="/i18n/i18n.js"></script>
|
|
<link href="/style/navigation.css" rel="stylesheet" />
|
|
<link href="/style/style.css" rel="stylesheet" />
|
|
<link href="/style/output.css" rel="stylesheet" />
|
|
</head>
|
|
|
|
<body>
|
|
<style>
|
|
.homeview_container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.ads_coupang iframe {
|
|
max-height: 96px;
|
|
}
|
|
@media screen and (min-width: 640px) {
|
|
.ads_coupang {
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
}
|
|
.homeview_container {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
}
|
|
.ads_coupang iframe {
|
|
max-height: 128px;
|
|
}
|
|
}
|
|
#cardList {
|
|
padding-bottom: 128px;
|
|
}
|
|
</style>
|
|
<div id="app">
|
|
<!-- 로딩 -->
|
|
<div
|
|
id="loading-screen"
|
|
class="fixed top-0 left-0 w-full h-full bg-white flex justify-center items-center"
|
|
>
|
|
<div
|
|
class="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"
|
|
></div>
|
|
</div>
|
|
|
|
<div class="homeview_container max-w-6xl lg:max-w-7xl mx-auto">
|
|
<div class="sm:col-span-1">
|
|
<div
|
|
class="aside-widget w-full mx-auto max-w-2xl sm:max-w-4xl lg:max-w-5xl xl:max-w-7xl flex gap-1 justify-between px-4 xl:px-2 sm:mt-20"
|
|
>
|
|
<div class="w-full flex flex-col gap-2 transition-all">
|
|
<div class="">
|
|
<div class="relative">
|
|
<label
|
|
for="name"
|
|
class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
|
|
>Card Search</label
|
|
>
|
|
<input
|
|
type="text"
|
|
id="searchQuery"
|
|
class="block w-full rounded-md border-0 px-3 py-1.5 text-gray-900 shadow-sm 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="ex) UA04BT/IMS-1-082"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<h4 class="mt-4 font-bold text-lg">COLOR</h4>
|
|
<div class="flex flex-wrap gap-2 mt-4">
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded border"
|
|
data-color="All"
|
|
>
|
|
All
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Red"
|
|
>
|
|
Red
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Blue"
|
|
>
|
|
Blue
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Green"
|
|
>
|
|
Green
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Yellow"
|
|
>
|
|
Yellow
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Purple"
|
|
>
|
|
Purple
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="AP"
|
|
>
|
|
AP
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="color-filter-btn px-3 py-1 rounded"
|
|
data-color="Multi"
|
|
>
|
|
Multi
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col aside-accordion-widget">
|
|
<h4 class="mt-4 font-bold text-lg">TYPE</h4>
|
|
<div
|
|
class="checkbox-wrapper w-full flex flex-col gap-2 items-start py-2"
|
|
>
|
|
<div>
|
|
<input id="includeBasic" type="checkbox" checked />
|
|
<label for="includeBasic" data-i18n="includeBasic"></label>
|
|
</div>
|
|
<div>
|
|
<input id="includeAP" type="checkbox" />
|
|
<label
|
|
for="includeAP"
|
|
data-i18n="includeActionPoint"
|
|
></label>
|
|
</div>
|
|
<div>
|
|
<input id="includeParallel" type="checkbox" />
|
|
<label
|
|
for="includeParallel"
|
|
data-i18n="includeParallel"
|
|
></label>
|
|
</div>
|
|
</div>
|
|
<h4 class="mt-4 font-bold text-lg">TRIGGER</h4>
|
|
<div class="radio-wrapper w-full flex flex-col gap-2 py-2">
|
|
<div>
|
|
<input
|
|
id="includeAllTrigger"
|
|
type="radio"
|
|
name="triggerType"
|
|
value="allTrigger"
|
|
checked
|
|
/>
|
|
<label
|
|
for="includeAllTrigger"
|
|
class="ml-2"
|
|
data-i18n="includeAllTrigger"
|
|
>Include All Trigger</label
|
|
>
|
|
</div>
|
|
<div>
|
|
<input
|
|
id="includeColorTrigger"
|
|
type="radio"
|
|
name="triggerType"
|
|
value="colorTrigger"
|
|
/>
|
|
<label
|
|
for="includeColorTrigger"
|
|
class="ml-2"
|
|
data-i18n="includeColorTrigger"
|
|
>Include Color Trigger</label
|
|
>
|
|
</div>
|
|
<div>
|
|
<input
|
|
id="includeSpecialTrigger"
|
|
type="radio"
|
|
name="triggerType"
|
|
value="specialTrigger"
|
|
/>
|
|
<label
|
|
for="includeSpecialTrigger"
|
|
class="ml-2"
|
|
data-i18n="includeSpecialTrigger"
|
|
>Include Special Trigger</label
|
|
>
|
|
</div>
|
|
<div>
|
|
<input
|
|
id="includeFinalTrigger"
|
|
type="radio"
|
|
name="triggerType"
|
|
value="finalTrigger"
|
|
/>
|
|
<label
|
|
for="includeFinalTrigger"
|
|
class="ml-2"
|
|
data-i18n="includeFinalTrigger"
|
|
>Include Final Trigger</label
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="SelectedSeriesCardList col-span-3 mt-4 sm:mt-0">
|
|
<div
|
|
id="totalCount"
|
|
class="result_total_count text-center text-xl mb-8"
|
|
>
|
|
<span data-i18n="SearchResults"></span>:
|
|
<span id="SearchResultsCounter">0</span>
|
|
<span data-i18n="SearchResultsCounter"></span>
|
|
</div>
|
|
<div id="cardList">
|
|
<div
|
|
class="mx-auto max-w-2xl mb-24 px-4 sm:px-6 sm:max-w-4xl lg:max-w-5xl lg:px-8 xl:max-w-7xl"
|
|
>
|
|
<div
|
|
class="mt-6 grid grid-cols-3 gap-x-6 gap-y-6 lg:grid-cols-4 lg:gap-x-5 xl:grid-cols-5 xl:gap-x-8"
|
|
id="card-grid"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="w-full fixed bottom-0 z-50">
|
|
<!-- 프리뷰 버튼 -->
|
|
<div class="w-full go-result-page-btn rounded-t-xl">
|
|
<!-- Coupang -->
|
|
<div class="ads_coupang">
|
|
<iframe
|
|
src="https://ads-partners.coupang.com/widgets.html?id=915533&template=carousel&trackingCode=AF6561083&subId=&width=1280&height=128&tsource="
|
|
width="100%"
|
|
height="128"
|
|
frameborder="0"
|
|
scrolling="no"
|
|
referrerpolicy="unsafe-url"
|
|
browsingtopics
|
|
></iframe>
|
|
</div>
|
|
<div
|
|
id="goToResultPage"
|
|
class="w-full h-12 cursor-pointer flex justify-center items-center bg-indigo-500 px-3 py-2 font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
|
|
data-i18n="makeDeckList"
|
|
></div>
|
|
</div>
|
|
<!-- 푸터 카드 현황 -->
|
|
<div
|
|
class="bottom-line w-full bg-black text-white text-center text-sm flex gap-4 justify-around items-center z-50"
|
|
>
|
|
<div class="copyright hidden sm:block">
|
|
KEY CARD: <span id="keyCardCount">0</span>/4
|
|
</div>
|
|
<div class="flex gap-4 select-none">
|
|
<div id="colorCount">
|
|
COLOR: <span id="colorCardCount">0</span>/4
|
|
</div>
|
|
<span>|</span>
|
|
<div id="finalCount">
|
|
FINAL: <span id="finalCardCount">0</span>/4
|
|
</div>
|
|
<span>|</span>
|
|
<div id="specialCount">
|
|
SPECIAL: <span id="specialCardCount">0</span>/4
|
|
</div>
|
|
<span>|</span>
|
|
<div id="totalCardsCount">
|
|
TOTAL: <span id="totalCardCount">0</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="imageOverlay" class="overlay">
|
|
<img src="" alt="Card Preview" />
|
|
</div>
|
|
<script src="/script/loading.js"></script>
|
|
<script>
|
|
// 1. 변수 선언 및 초기화
|
|
let cardList;
|
|
let selectedCards = [];
|
|
let selectedColors = new Set(["All"]);
|
|
const colorButtons = document.querySelectorAll(".color-filter-btn");
|
|
const searchQueryInput = document.getElementById("searchQuery");
|
|
const includeBasicCheckbox = document.getElementById("includeBasic");
|
|
const includeAPCheckbox = document.getElementById("includeAP");
|
|
const includeParallelCheckbox =
|
|
document.getElementById("includeParallel");
|
|
const includeAllTriggerRadio =
|
|
document.getElementById("includeAllTrigger");
|
|
const includeSpecialTriggerRadio = document.getElementById(
|
|
"includeSpecialTrigger"
|
|
);
|
|
const includeColorTriggerRadio = document.getElementById(
|
|
"includeColorTrigger"
|
|
);
|
|
const includeFinalTriggerRadio = document.getElementById(
|
|
"includeFinalTrigger"
|
|
);
|
|
const keyCardCountElement = document.getElementById("keyCardCount");
|
|
const colorCardCountElement = document.getElementById("colorCardCount");
|
|
const finalCardCountElement = document.getElementById("finalCardCount");
|
|
const specialCardCountElement =
|
|
document.getElementById("specialCardCount");
|
|
const totalCardCountElement = document.getElementById("totalCardCount");
|
|
|
|
// 2. URL 파라미터 및 로컬 스토리지 관리
|
|
function getQueryParam(param) {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
return urlParams.get(param);
|
|
}
|
|
|
|
const seriesKey = getQueryParam("series");
|
|
const nameKey = getQueryParam("seriesName");
|
|
|
|
if (seriesKey) {
|
|
localStorage.setItem(
|
|
"selectedSeries",
|
|
JSON.stringify({ key: seriesKey, name: nameKey })
|
|
);
|
|
}
|
|
|
|
// 3. 데이터 로딩 및 초기화
|
|
async function loadCardData() {
|
|
try {
|
|
const module = await import(`./datas/${seriesKey}.js`);
|
|
cardList = module.cardList;
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const cardsParam = urlParams.get("cards");
|
|
|
|
if (cardsParam) {
|
|
const parsedCards = JSON.parse(decodeURIComponent(cardsParam));
|
|
cardList = updateCardListFromStorage(cardList, parsedCards);
|
|
selectedCards = parsedCards;
|
|
displayCardList(cardList);
|
|
updateCardList();
|
|
} else {
|
|
const savedSelectedCards = localStorage.getItem("selectedCards");
|
|
if (savedSelectedCards) {
|
|
const parsedCards = JSON.parse(
|
|
decodeURIComponent(savedSelectedCards)
|
|
);
|
|
cardList = updateCardListFromStorage(cardList, parsedCards);
|
|
selectedCards = parsedCards;
|
|
displayCardList(cardList);
|
|
updateCardList();
|
|
} else {
|
|
applyInitialFilter();
|
|
}
|
|
}
|
|
|
|
const loadingScreen = document.getElementById("loading-screen");
|
|
if (loadingScreen) {
|
|
loadingScreen.style.display = "none";
|
|
}
|
|
|
|
updateCounters();
|
|
} catch (error) {
|
|
console.error("Failed to load card data:", error);
|
|
}
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", async () => {
|
|
const loadingScreen = document.getElementById("loading-screen");
|
|
if (loadingScreen) {
|
|
loadingScreen.style.display = "flex";
|
|
}
|
|
|
|
await loadCardData();
|
|
|
|
const goToResultPage = document.getElementById("goToResultPage");
|
|
if (goToResultPage) {
|
|
goToResultPage.addEventListener("click", () => {
|
|
const queryParams = encodeURIComponent(
|
|
JSON.stringify(selectedCards)
|
|
);
|
|
const seriesKey = getQueryParam("series");
|
|
const nameKey = getQueryParam("seriesName");
|
|
localStorage.setItem("selectedCards", queryParams);
|
|
localStorage.setItem(
|
|
"selectedSeries",
|
|
JSON.stringify({ key: seriesKey, name: nameKey })
|
|
);
|
|
window.location.href = `/result.html?series=${seriesKey}&seriesName=${nameKey}&cards=${queryParams}`;
|
|
});
|
|
}
|
|
});
|
|
|
|
function applyInitialFilter() {
|
|
const filteredList = cardList.filter(
|
|
(card) => card.color !== "AP" && !card.parallel
|
|
);
|
|
document.getElementById("includeBasic").checked = true;
|
|
document.getElementById("includeAP").checked = false;
|
|
document.getElementById("includeParallel").checked = false;
|
|
displayCardList(filteredList);
|
|
}
|
|
|
|
function updateCardListFromStorage(cardList, savedSelectedCards) {
|
|
const cardMap = new Map(cardList.map((card) => [card.imgSrc, card]));
|
|
|
|
savedSelectedCards.forEach((savedCard) => {
|
|
const uniqueKey = savedCard.imgSrc;
|
|
const existingCard = cardMap.get(uniqueKey);
|
|
if (existingCard) {
|
|
existingCard.count = savedCard.count;
|
|
existingCard.key = savedCard.key;
|
|
}
|
|
});
|
|
|
|
return Array.from(cardMap.values());
|
|
}
|
|
|
|
const RARITY_STYLE_RULES = [
|
|
{
|
|
// 🌈 레인보우: 별표 포함 or UR
|
|
match: (r) => r.includes("★") || ["UR"].includes(r),
|
|
background:
|
|
"linear-gradient(45deg, rgba(204, 75, 149, 0.8) 10%, rgba(102, 148, 210, 0.8), rgba(113, 194, 228, 0.8), rgba(129, 197, 101, 0.8), rgba(240, 219, 76, 0.8))",
|
|
},
|
|
{
|
|
// ⚙ 메탈: SP / PcC / PcU / PcR
|
|
match: (r) => ["SP", "PcC", "PcU", "PcR"].includes(r),
|
|
background:
|
|
"linear-gradient(90deg, rgba(139,155,175,0.85), rgba(231,239,247,0.9) 50%, rgba(139,155,175,0.85))",
|
|
},
|
|
{
|
|
// 🟡 SR 계열
|
|
match: (r) => ["SR", "PcSR"].includes(r),
|
|
background: "#F2F320",
|
|
},
|
|
];
|
|
|
|
function applyRarityStyle(rarityDiv, rarity) {
|
|
// 기본 배경
|
|
rarityDiv.style.backgroundColor = "rgba(255, 255, 255, 0.8)";
|
|
|
|
for (const rule of RARITY_STYLE_RULES) {
|
|
if (rule.match(rarity)) {
|
|
rarityDiv.style.background = rule.background;
|
|
break; // 첫 매칭 규칙만 적용
|
|
}
|
|
}
|
|
}
|
|
|
|
// 4. 카드 목록 표시 및 업데이트
|
|
function displayCardList(cardList) {
|
|
const cardGrid = document.getElementById("card-grid");
|
|
cardGrid.innerHTML = "";
|
|
|
|
// 광고 배너 추가
|
|
// const totalCards = cardList.length;
|
|
// let adCount = 0;
|
|
// if (totalCards >= 50) {
|
|
// adCount = Math.floor(totalCards / 150) + 1;
|
|
// }
|
|
// const adIndices = [];
|
|
// if (adCount > 0) {
|
|
// const segmentSize = Math.floor(totalCards / adCount);
|
|
// for (let i = 0; i < adCount; i++) {
|
|
// const start = i * segmentSize;
|
|
// const end = (i === adCount - 1) ? totalCards - 1 : (i + 1) * segmentSize - 1;
|
|
// const randIndex = Math.floor(Math.random() * (end - start + 1)) + start;
|
|
// adIndices.push(randIndex);
|
|
// }
|
|
// }
|
|
|
|
cardList.forEach((card, index) => {
|
|
const cardContainer = document.createElement("div");
|
|
cardContainer.className =
|
|
"cardContainer group relative z-10 hover:z-40 select-none flex flex-col";
|
|
cardContainer.setAttribute("data-imgsrc", card.imgSrc);
|
|
|
|
const imgSrc = `images/${seriesKey}/${card.imgSrc.split("/").pop()}`;
|
|
const img = document.createElement("img");
|
|
img.src = imgSrc;
|
|
img.alt = "";
|
|
img.className =
|
|
"h-full w-full object-contain object-center transition-opacity lg:h-full lg:w-full";
|
|
img.onerror = () => handleImageError(card, img);
|
|
|
|
const imageContainer = document.createElement("div");
|
|
imageContainer.className =
|
|
"card_image cursor-pointer aspect-w-1 w-full mb-2 lg:mb-3 xl:mb-4 rounded-md lg:aspect-none";
|
|
imageContainer.appendChild(img);
|
|
|
|
imageContainer.addEventListener("click", () => {
|
|
showOverlay(card, index, cardList);
|
|
});
|
|
|
|
const countDiv = document.createElement("div");
|
|
countDiv.className = "absolute top-0 right-0";
|
|
|
|
const infoDiv = document.createElement("div");
|
|
infoDiv.className = "flex justify-between";
|
|
|
|
if (card.rarity) {
|
|
const rarityDiv = document.createElement("div");
|
|
rarityDiv.className =
|
|
"card-rarity font-bold inline-flex items-center rounded-full px-2 text-xs ring-1 ring-inset ring-gray-500/10";
|
|
rarityDiv.textContent = card.rarity;
|
|
|
|
applyRarityStyle(rarityDiv, card.rarity.trim());
|
|
|
|
infoDiv.appendChild(rarityDiv);
|
|
}
|
|
|
|
const numberDiv = document.createElement("div");
|
|
numberDiv.className = "flex items-center text-xs";
|
|
numberDiv.textContent =
|
|
card.color === "AP" ? "ACTION POINT" : card.Number.slice(-5);
|
|
infoDiv.appendChild(numberDiv);
|
|
|
|
const countControlDiv = document.createElement("div");
|
|
countControlDiv.className = "pt-1 flex justify-between z-10";
|
|
|
|
const decrementButton = document.createElement("button");
|
|
decrementButton.textContent = "-";
|
|
decrementButton.className =
|
|
"decrementButton cursor-pointer rounded-lg bg-black w-8 h-8 text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:z-10 disabled:opacity-0 disabled:cursor-not-allowed touch-manipulation";
|
|
if (card.count == 0) {
|
|
decrementButton.classList.add("opacity-0", "cursor-not-allowed");
|
|
}
|
|
decrementButton.addEventListener("click", (event) =>
|
|
decrementCount(card, event)
|
|
);
|
|
countControlDiv.appendChild(decrementButton);
|
|
|
|
const countSpan = document.createElement("span");
|
|
countSpan.textContent = card.count;
|
|
countSpan.className = "mx-1 w-8 text-center pt-1";
|
|
countControlDiv.appendChild(countSpan);
|
|
|
|
const incrementButton = document.createElement("button");
|
|
incrementButton.textContent = "+";
|
|
incrementButton.className =
|
|
"incrementButton cursor-pointer rounded-lg bg-black w-8 h-8 text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:opacity-0 disabled:cursor-not-allowed touch-manipulation";
|
|
if (card.count == 4) {
|
|
incrementButton.classList.add("opacity-0", "cursor-not-allowed");
|
|
}
|
|
incrementButton.addEventListener("click", (event) =>
|
|
incrementCount(card, event)
|
|
);
|
|
countControlDiv.appendChild(incrementButton);
|
|
|
|
const keyCardButton = document.createElement("button");
|
|
keyCardButton.textContent = "KEY CARD";
|
|
keyCardButton.className =
|
|
"keyCardButton cursor-pointer rounded-lg bg-white w-full px-2 py-1 mt-1 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50";
|
|
if (card.key) {
|
|
keyCardButton.classList.add("opacity-100");
|
|
keyCardButton.classList.remove("opacity-50");
|
|
} else {
|
|
keyCardButton.classList.add("opacity-50");
|
|
keyCardButton.classList.remove("opacity-100");
|
|
}
|
|
keyCardButton.addEventListener("click", (event) =>
|
|
toggleKeyCard(card, event)
|
|
);
|
|
|
|
cardContainer.appendChild(imageContainer);
|
|
cardContainer.appendChild(countDiv);
|
|
cardContainer.appendChild(infoDiv);
|
|
cardContainer.appendChild(countControlDiv);
|
|
cardContainer.appendChild(keyCardButton);
|
|
|
|
cardGrid.appendChild(cardContainer);
|
|
|
|
// 광고 프레임
|
|
// const adFrames = [
|
|
// `<iframe src="https://ads-partners.coupang.com/widgets.html?id=915488&template=carousel&trackingCode=AF6561083&subId=&width=200&height=360&tsource=" class="absolute top-0 left-0 w-full h-full" frameborder="0" scrolling="no" referrerpolicy="unsafe-url" browsingtopics></iframe>`,
|
|
// `<iframe src="https://ads-partners.coupang.com/widgets.html?id=915505&template=carousel&trackingCode=AF6561083&subId=&width=200&height=360&tsource=" class="absolute top-0 left-0 w-full h-full" frameborder="0" scrolling="no" referrerpolicy="unsafe-url" browsingtopics></iframe>`,
|
|
// `<iframe src="https://ads-partners.coupang.com/widgets.html?id=915509&template=carousel&trackingCode=AF6561083&subId=&width=200&height=360&tsource=" class="absolute top-0 left-0 w-full h-full" frameborder="0" scrolling="no" referrerpolicy="unsafe-url" browsingtopics></iframe>`,
|
|
// `<iframe src="https://ads-partners.coupang.com/widgets.html?id=915510&template=carousel&trackingCode=AF6561083&subId=&width=200&height=360&tsource=" class="absolute top-0 left-0 w-full h-full" frameborder="0" scrolling="no" referrerpolicy="unsafe-url" browsingtopics></iframe>`,
|
|
// `<iframe src="https://ads-partners.coupang.com/widgets.html?id=915514&template=carousel&trackingCode=AF6561083&subId=&width=200&height=360&tsource=" class="absolute top-0 left-0 w-full h-full" frameborder="0" scrolling="no" referrerpolicy="unsafe-url" browsingtopics></iframe>`
|
|
// ];
|
|
|
|
// if (adIndices.includes(index)) {
|
|
// console.log("coupang:", index);
|
|
|
|
// const bannerContainer = document.createElement("div");
|
|
// bannerContainer.className = "relative w-full h-full flex flex-col my-2";
|
|
|
|
// const adIndex = adIndices.indexOf(index) % adFrames.length;
|
|
// bannerContainer.innerHTML = adFrames[adIndex];
|
|
|
|
// cardGrid.appendChild(bannerContainer);
|
|
// }
|
|
});
|
|
|
|
function showOverlay(card, index, cardList) {
|
|
console.log(card, index, cardList);
|
|
const overlay = document.getElementById("imageOverlay");
|
|
const img = overlay.querySelector("img");
|
|
const imgSrc = `images/${seriesKey}/${card.imgSrc.split("/").pop()}`;
|
|
|
|
let imageLoaded = false;
|
|
|
|
img.onload = () => {
|
|
imageLoaded = true;
|
|
};
|
|
|
|
img.onerror = () => {
|
|
handleOverlayImageError(img);
|
|
imageLoaded = true;
|
|
};
|
|
|
|
img.src = imgSrc;
|
|
overlay.style.display = "flex";
|
|
|
|
const handleKeyDown = (event) => {
|
|
if (event.key === "ArrowLeft" && imageLoaded) {
|
|
index = (index - 1 + cardList.length) % cardList.length;
|
|
imageLoaded = false;
|
|
showOverlay(cardList[index], index, cardList);
|
|
event.preventDefault();
|
|
} else if (event.key === "ArrowRight" && imageLoaded) {
|
|
index = (index + 1) % cardList.length;
|
|
imageLoaded = false;
|
|
showOverlay(cardList[index], index, cardList);
|
|
event.preventDefault();
|
|
}
|
|
};
|
|
document.addEventListener("keydown", handleKeyDown);
|
|
|
|
overlay.onclick = (event) => {
|
|
if (event.target === overlay) {
|
|
overlay.style.display = "none";
|
|
document.removeEventListener("keydown", handleKeyDown);
|
|
}
|
|
};
|
|
}
|
|
|
|
function handleOverlayImageError(img) {
|
|
img.src = "/images/uapr/comingsoon.png";
|
|
img.onerror = null;
|
|
}
|
|
|
|
const SearchResultsCounter = document.getElementById(
|
|
"SearchResultsCounter"
|
|
);
|
|
SearchResultsCounter.textContent = cardList.length;
|
|
|
|
colorButtons.forEach((btn) => {
|
|
const color = btn.dataset.color;
|
|
if (selectedColors.has(color)) {
|
|
btn.style.opacity = 1;
|
|
} else {
|
|
btn.style.opacity = 0.5;
|
|
}
|
|
|
|
if (selectedColors.size === 0) {
|
|
colorButtons[0].style.opacity = 1;
|
|
}
|
|
});
|
|
}
|
|
|
|
function handleImageError(card, img) {
|
|
img.src = "/images/uapr/comingsoon.png";
|
|
img.onerror = null;
|
|
}
|
|
|
|
// 5. 카드 개수 조절 및 키 카드 관리
|
|
function decrementCount(card, event) {
|
|
if (card.count > 0) {
|
|
event.stopPropagation();
|
|
card.count--;
|
|
if (card.count === 0) {
|
|
card.key = false;
|
|
}
|
|
updateCardDisplay(card, document.activeElement);
|
|
updateCardCount(card, card.count);
|
|
updateLocalStorage();
|
|
updateQueryParameters();
|
|
}
|
|
}
|
|
|
|
function incrementCount(card, event) {
|
|
const maxCount = card.maxCount || 4;
|
|
|
|
const sameNumberCards = cardList.filter(
|
|
(c) => c.Number === card.Number
|
|
);
|
|
const totalCount = sameNumberCards.reduce((sum, c) => sum + c.count, 0);
|
|
|
|
if (totalCount < maxCount) {
|
|
event.stopPropagation();
|
|
card.count++;
|
|
updateCardDisplay(card, document.activeElement);
|
|
updateCardCount(card, card.count);
|
|
updateLocalStorage();
|
|
updateQueryParameters();
|
|
}
|
|
}
|
|
|
|
function updateCardDisplay(card, element) {
|
|
const cardContainers = document.querySelectorAll(
|
|
`.cardContainer[data-imgsrc="${card.imgSrc}"]`
|
|
);
|
|
let targetContainer = null;
|
|
|
|
cardContainers.forEach((container) => {
|
|
targetContainer = container;
|
|
});
|
|
|
|
if (targetContainer) {
|
|
const countSpan = targetContainer.querySelector(
|
|
"span.mx-1.w-8.text-center.pt-1"
|
|
);
|
|
if (countSpan) {
|
|
countSpan.textContent = card.count;
|
|
}
|
|
|
|
updateButtonState(targetContainer, card);
|
|
}
|
|
|
|
updateLocalStorage();
|
|
updateCounters();
|
|
}
|
|
|
|
function updateButtonState(container, card) {
|
|
const decrementButton = container.querySelector(
|
|
"button.decrementButton"
|
|
);
|
|
const incrementButton = container.querySelector(
|
|
"button.incrementButton"
|
|
);
|
|
const keyCardButton = container.querySelector("button.keyCardButton");
|
|
|
|
// 같은 Number를 가진 카드들의 총 개수 계산
|
|
const sameNumberCards = cardList.filter(
|
|
(c) => c.Number === card.Number
|
|
);
|
|
const totalCount = sameNumberCards.reduce((sum, c) => sum + c.count, 0);
|
|
const maxCount = card.maxCount || 4;
|
|
|
|
if (decrementButton) {
|
|
decrementButton.classList.toggle("opacity-0", card.count === 0);
|
|
decrementButton.classList.toggle(
|
|
"cursor-not-allowed",
|
|
card.count === 0
|
|
);
|
|
}
|
|
|
|
if (incrementButton) {
|
|
incrementButton.classList.toggle("opacity-0", totalCount >= maxCount);
|
|
incrementButton.classList.toggle(
|
|
"cursor-not-allowed",
|
|
totalCount >= maxCount
|
|
);
|
|
}
|
|
|
|
if (keyCardButton) {
|
|
keyCardButton.disabled = card.count === 0;
|
|
if (card.count === 0) {
|
|
card.key = false;
|
|
}
|
|
keyCardButton.classList.toggle(
|
|
"opacity-100",
|
|
card.key && card.count > 0
|
|
);
|
|
keyCardButton.classList.toggle(
|
|
"opacity-50",
|
|
!card.key || card.count === 0
|
|
);
|
|
}
|
|
|
|
// 같은 Number를 가진 모든 카드의 + 버튼 상태 업데이트
|
|
sameNumberCards.forEach((sameCard) => {
|
|
if (sameCard !== card) {
|
|
const otherContainer = document.querySelector(
|
|
`.cardContainer[data-imgsrc="${sameCard.imgSrc}"]`
|
|
);
|
|
if (otherContainer) {
|
|
const otherIncrementButton = otherContainer.querySelector(
|
|
"button.incrementButton"
|
|
);
|
|
if (otherIncrementButton) {
|
|
otherIncrementButton.classList.toggle(
|
|
"opacity-0",
|
|
totalCount >= maxCount
|
|
);
|
|
otherIncrementButton.classList.toggle(
|
|
"cursor-not-allowed",
|
|
totalCount >= maxCount
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateCounters() {
|
|
let keyCount = 0;
|
|
let colorCount = 0;
|
|
let finalCount = 0;
|
|
let specialCount = 0;
|
|
let totalCount = 0;
|
|
|
|
cardList.forEach((card) => {
|
|
if (card.key && card.count > 0) {
|
|
keyCount++;
|
|
}
|
|
if (card.trigger === "COLOR" && card.count > 0) {
|
|
colorCount += card.count;
|
|
}
|
|
if (card.trigger === "FINAL" && card.count > 0) {
|
|
finalCount += card.count;
|
|
}
|
|
if (card.trigger === "SPECIAL" && card.count > 0) {
|
|
specialCount += card.count;
|
|
}
|
|
totalCount += card.count;
|
|
});
|
|
|
|
keyCardCountElement.textContent = keyCount;
|
|
colorCardCountElement.textContent = colorCount;
|
|
finalCardCountElement.textContent = finalCount;
|
|
specialCardCountElement.textContent = specialCount;
|
|
totalCardCountElement.textContent = totalCount;
|
|
}
|
|
|
|
function toggleKeyCard(card, event) {
|
|
event.stopPropagation();
|
|
|
|
if (card.count === 0) {
|
|
return;
|
|
}
|
|
|
|
const maxKeyCards = 4;
|
|
const currentKeyCards = cardList.filter(
|
|
(c) => c.key && c.count > 0
|
|
).length;
|
|
|
|
if (card.key) {
|
|
card.key = false;
|
|
} else if (currentKeyCards < maxKeyCards) {
|
|
card.key = true;
|
|
}
|
|
|
|
updateCardDisplay(card, document.activeElement);
|
|
updateLocalStorage();
|
|
updateQueryParameters();
|
|
}
|
|
|
|
function updateSelectedCards() {
|
|
selectedCards = cardList.filter((card) => card.count > 0);
|
|
}
|
|
|
|
function updateCardCount(card, count) {
|
|
card.count = count;
|
|
updateSelectedCards();
|
|
updateLocalStorage();
|
|
}
|
|
|
|
// 6. 로컬 스토리지 업데이트 및 결과 페이지 이동
|
|
function updateLocalStorage() {
|
|
const queryParams = encodeURIComponent(JSON.stringify(selectedCards));
|
|
localStorage.setItem("selectedCards", queryParams);
|
|
}
|
|
|
|
// 7. 검색 및 필터링 기능
|
|
searchQueryInput.addEventListener("input", updateCardList);
|
|
|
|
colorButtons.forEach((button) => {
|
|
button.addEventListener("click", () => {
|
|
const color = button.dataset.color;
|
|
|
|
if (color === "All") {
|
|
selectedColors.clear();
|
|
selectedColors.add("All");
|
|
} else {
|
|
selectedColors.delete("All");
|
|
|
|
if (selectedColors.has(color)) {
|
|
selectedColors.delete(color);
|
|
} else {
|
|
selectedColors.add(color);
|
|
}
|
|
}
|
|
|
|
if (selectedColors.size === 0) {
|
|
selectedColors.add("All");
|
|
}
|
|
|
|
updateCardList();
|
|
});
|
|
});
|
|
|
|
function updateCardList() {
|
|
const includeBasic = includeBasicCheckbox.checked;
|
|
const includeAP = includeAPCheckbox.checked;
|
|
const includeParallel = includeParallelCheckbox.checked;
|
|
console.log(
|
|
`TYPE FILTER - [Basic: ${includeBasic}], [AP: ${includeAP}], [Parallel: ${includeParallel}]`
|
|
);
|
|
|
|
let filteredCardList = cardList;
|
|
|
|
filteredCardList = filteredCardList.filter((card) => {
|
|
if (includeBasic && card.color !== "AP" && !card.parallel)
|
|
return true;
|
|
if (includeAP && card.color === "AP") return true;
|
|
if (includeParallel && card.parallel) return true;
|
|
return false;
|
|
});
|
|
|
|
if (!selectedColors.has("All")) {
|
|
filteredCardList = filteredCardList.filter((card) => {
|
|
if (card.color === "Multi") {
|
|
return selectedColors.has("ALL COLOR");
|
|
} else {
|
|
return selectedColors.has(card.color);
|
|
}
|
|
});
|
|
}
|
|
|
|
const selectedTrigger = document.querySelector(
|
|
'input[name="triggerType"]:checked'
|
|
).value;
|
|
switch (selectedTrigger) {
|
|
case "specialTrigger":
|
|
filteredCardList = filteredCardList.filter(
|
|
(card) => card.trigger === "SPECIAL"
|
|
);
|
|
break;
|
|
case "colorTrigger":
|
|
filteredCardList = filteredCardList.filter(
|
|
(card) => card.trigger === "COLOR"
|
|
);
|
|
break;
|
|
case "finalTrigger":
|
|
filteredCardList = filteredCardList.filter(
|
|
(card) => card.trigger === "FINAL"
|
|
);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
const searchQuery = searchQueryInput.value.toLowerCase();
|
|
if (searchQuery) {
|
|
filteredCardList = filteredCardList.filter((card) => {
|
|
return card.Number.toLowerCase().includes(searchQuery);
|
|
});
|
|
}
|
|
|
|
displayCardList(filteredCardList);
|
|
}
|
|
|
|
includeBasicCheckbox.addEventListener("change", updateCardList);
|
|
includeAPCheckbox.addEventListener("change", updateCardList);
|
|
includeParallelCheckbox.addEventListener("change", updateCardList);
|
|
|
|
includeAllTriggerRadio.addEventListener("change", updateCardList);
|
|
includeSpecialTriggerRadio.addEventListener("change", updateCardList);
|
|
includeColorTriggerRadio.addEventListener("change", updateCardList);
|
|
includeFinalTriggerRadio.addEventListener("change", updateCardList);
|
|
|
|
function updateQueryParameters() {
|
|
const queryParams = encodeURIComponent(JSON.stringify(selectedCards));
|
|
const seriesKey = getQueryParam("series");
|
|
const nameKey = getQueryParam("seriesName");
|
|
|
|
const newUrl = new URL(window.location.href);
|
|
newUrl.searchParams.set("cards", queryParams);
|
|
window.history.replaceState({}, "", newUrl);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|