(() => {
const { EventManager, pageHelper, utils } = ShopbySkin;
const INITIAL_PAGE = 1;
const PAGE_SIZE = 20;
const PAGINATION_SIZE = 5;
const getCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
return null;
};
const memberNo = getCookie("memberNo");
const codeStatus = {
"GENERATED": "사용 가능",
"COMPLETED": "사용중",
"TRANSMITTED": "사용 완료",
"GRADING_COMPLETED": "사용 완료",
}
// 필터 상태 및 캐시
let isFilterActive = false;
let filteredCache = [];
const redirectLoginPage = () => {
const nextUrl = `${location.origin}/pages/sign-in/sign-in.html`;
location.href = `${nextUrl}?from=${encodeURIComponent(location.href)}`;
};
// 페이지 초기화
const initPage = async () => {
// 목록 불러오기
getExamCodeList({
page: INITIAL_PAGE,
size: PAGE_SIZE,
});
// 탭 버튼
// const tabs = document.getElementsByClassName("tab__button");
//
// for (let tab of tabs) {
// tab.addEventListener("click", onClickTab);
// }
// 모아보기 필터
const filter = document.getElementById("available");
if (filter) {
filter.addEventListener("change", filterAvailable);
}
// 직접 등록 버튼
const button = document.getElementById("register");
if (button) {
button.addEventListener("click", openRegisterModal);
}
// 온라인 구매 발급 버튼
const onlineButton = document.getElementById("online-register");
if (onlineButton) {
onlineButton.addEventListener("click", openExamCodeListModal);
}
// 페이지 컨트롤 버튼
const paginationButtons = document.querySelectorAll("#exam-code-pagination > .pagination__btn");
if (paginationButtons && paginationButtons.length) {
paginationButtons.forEach((button) => {
button.addEventListener("click", onClickPageControl);
})
}
}
// 모의고사 식별번호 일괄 발급 모달 오픈
const openExamCodeListModal = () => {
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'exam-code-list-form',
title: "온라인 구매 발급",
modalAddClass: 'exam-code-list-form',
isFull: false,
data: {
isModify: false,
},
onClose: (e) => {
const {state} = e;
if (!state?.result) return;
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'SUCCESS',
message: `식별번호 총 ${state?.generatedCnt}건이 발급되었습니다.`,
onClose: () => {
location.reload();
},
});
},
});
}
// 모의고사 식별번호 등록 모달 오픈
const openRegisterModal = () => {
EventManager.fire('OPEN_LAYER_MODAL', {
name: 'exam-code-register-form',
title: "직접 등록",
modalAddClass: 'exam-code-register-form',
isFull: false,
data: {
isModify: false,
},
onClose: (e) => {
const { state } = e;
if (state && state.result) {
EventManager.fire('MODAL_ALERT_OPEN', {
noticeType: 'SUCCESS',
message: '모의고사 식별번호 등록 완료',
onClose: () => {
location.reload();
},
});
}
},
});
}
// 탭 버튼 클릭 콜백
// const onClickTab = (tab) => {
// const currentTab = tab.currentTarget;
// const prevActiveTab = document.querySelector(".tab__button.is-active");
//
// if (prevActiveTab) {
// prevActiveTab.classList.remove("is-active");
// }
//
// currentTab.classList.add("is-active");
// getExamCodeList({
// page: INITIAL_PAGE,
// size: PAGE_SIZE,
// package: currentTab.id,
// });
// }
// [API] 단일 페이지 fetch
const fetchExamCodePage = async (option) => {
if( !memberNo ) return null;
let requestUrl = DSDOENV.ApiConfig.DSDO_API + `/api/v1/fo-user/mock-exam-code/${memberNo}`;
if (option) requestUrl += `?${new URLSearchParams(option)}`;
try {
const response = await fetch(requestUrl, {
method: "GET",
headers: { "Content-Type": "application/json" },
});
if (!response.ok) {
console.error("API 요청 중 오류 발생:", await response.json());
return null;
}
const { data } = await response.json();
return data;
} catch (error) {
console.error("API 요청 중 오류 발생:", error);
return null;
}
}
const getExamCodeList = async (option) => {
const response = await fetchExamCodePage(option);
if (response) updateExamCodeTable(response);
}
const fetchAllFilteredCodes = async () => {
const firstPage = await fetchExamCodePage({ page: 1, size: PAGE_SIZE });
if (!firstPage?.content) return [];
const { totalPages, content: contents } = firstPage;
let remainingContent = [];
if (totalPages > 1) {
const pageRequests = Array.from({ length: totalPages - 1 }, (_, i) =>
fetchExamCodePage({ page: i + 2, size: PAGE_SIZE })
);
const responses = await Promise.all(pageRequests);
remainingContent = responses
.filter(res => res?.content)
.flatMap(res => res.content);
}
return [...contents, ...remainingContent]
.filter(item => item?.codeStatus === "GENERATED");
};
// 클라이언트 페이지네이션 렌더링
const renderClientPage = (page) => {
const totalItems = filteredCache.length;
const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE));
const content = filteredCache.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);
updateExamCodeTable({
content,
number: page - 1,
totalPages,
first: page === 1,
last: page >= totalPages,
});
}
// 모의고사 식별번호 테이블 렌더링
const updateExamCodeTable = (data) => {
const { content } = data;
const table = document.getElementById("exam-code-table");
const tableBody = table.getElementsByClassName("body")[0];
const pagination = document.getElementById("exam-code-pagination");
const empty = table.querySelector(".empty-list");
if (!tableBody || !empty || !pagination) return;
tableBody.innerHTML = "";
if (!content.length) {
empty.classList.remove("hide");
pagination.classList.add("hide");
} else {
empty.classList.add("hide");
pagination.classList.remove("hide");
content.forEach(examCode => createRow(examCode, tableBody));
updatePagination(data, pagination);
}
}
// 모의고사 식별번호 테이블 row 렌더링
const createRow = (examCode, body) => {
const row = document.createElement("div");
row.classList.add("row");
// 식별번호 유형
const type = document.createElement("div");
type.classList.add("cell");
type.innerText = examCode.issueType || '알 수 없음';
row.appendChild(type);
// 모의고사
const name = document.createElement("div");
name.classList.add("cell");
name.innerText = examCode.mockExamName;
row.appendChild(name);
// 식별번호
const code = document.createElement("div");
code.classList.add("cell");
code.innerText = examCode.examCode;
row.appendChild(code);
// 상태
const status = document.createElement("div");
status.classList.add("cell");
const usedStatus = codeStatus[examCode.codeStatus] !== codeStatus["GENERATED"] && Number(examCode?.usedBy) !== Number(memberNo) ? "타 계정 사용 완료" : codeStatus[examCode.codeStatus];
const examAvailable = codeStatus[examCode.codeStatus] === codeStatus["GENERATED"] && examCode.examAvailable;
const link = DSDOENV.ApiConfig.EXAM_SYSTEM;
if (examAvailable) {
status.style.gap = '1rem';
status.innerHTML = `${usedStatus}응시하기`;
} else {
status.innerHTML = `
${usedStatus}
${examCode?.usedAt ? `(${formatWithoutSeconds(examCode.usedAt)})` : ''}