(() => {
const API_BASE = DSDOENV.ApiConfig.DSDO_API + "/api/v1/fo-user/mock-exam-attempt";
const SIZE = 1000;
const UNIVERSITY = "university";
const DEPARTMENT = "department";
let currentUniv = null; // { universityCode, universityName }
let selected = null; // { universityCode, universityName, departmentCode, departmentName }
const fetchJson = async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`학교/학과 코드 요청 실패 (${response.status})`);
return response.json();
};
// 대학 검색 응답은 학과별 row가 배열로 오므로 universityCode 기준으로 중복 제거
const searchUniversities = async (universityName) => {
const rows = await fetchJson(
`${API_BASE}/search?universityName=${encodeURIComponent(universityName)}&size=${SIZE}`
);
const seen = new Map();
(rows.content ?? []).forEach((row) => {
if (!seen.has(row.universityCode)) {
seen.set(row.universityCode, { universityCode: row.universityCode, universityName: row.universityName });
}
});
return Array.from(seen.values());
};
const searchDepartments = async (universityCode, departmentName) => {
const rows = await fetchJson(
`${API_BASE}/${universityCode}?size=${SIZE}&departmentName=${encodeURIComponent(departmentName ?? "")}`
);
return rows.content ?? [];
};
const renderEmpty = (isEmpty, message) => {
const el = document.getElementById("result-empty-msg");
el.hidden = !isEmpty;
if (message) el.textContent = message;
};
const renderUniversityCards = (universities) => {
const listEl = document.getElementById("result-card-list");
listEl.innerHTML = universities
.map(
(u) => `
${u.universityName}
대학코드
${u.universityCode}
`
)
.join("");
renderEmpty(universities.length === 0, "검색 결과가 없습니다.");
};
const renderDepartmentCards = (departments) => {
const listEl = document.getElementById("result-card-list");
listEl.innerHTML = (departments ?? [])
.map((d) => {
const isSelected = selected && selected.departmentCode === d.departmentCode && selected.universityCode === d.universityCode;
return `
${d.departmentName}
대학코드
${d.departmentCode}
`;
})
.join("");
renderEmpty((departments ?? []).length === 0, "검색 결과가 없습니다.");
};
const updateSummary = () => {
const placeholderEl = document.getElementById("summary-placeholder");
const rowEl = document.getElementById("summary-row");
if (!currentUniv) {
placeholderEl.hidden = false;
rowEl.hidden = true;
return;
}
placeholderEl.hidden = true;
rowEl.hidden = false;
document.getElementById("summary-univ-dept-label").textContent = selected ? "선택된 대학/학과" : "선택된 대학";
document.getElementById("summary-univ-dept-name").textContent = selected
? `${selected.universityName} ${selected.departmentName}`
: currentUniv.universityName;
document.getElementById("summary-univ-code").textContent = currentUniv.universityCode;
const deptCodeEl = document.getElementById("summary-dept-code");
deptCodeEl.textContent = selected ? selected.departmentCode : "학과 코드를 선택해 주세요.";
deptCodeEl.classList.toggle("univ-dept-search__pill--empty", !selected);
};
// 대학 검색 단계 <-> 학과 검색 단계 전환
const setPhase = (phase) => {
document.getElementById("univ-search-row").hidden = phase !== UNIVERSITY;
document.getElementById("univ-selected-row").hidden = phase !== DEPARTMENT;
document.getElementById("dept-row-divider").hidden = phase !== DEPARTMENT;
document.getElementById("dept-search-row").hidden = phase !== DEPARTMENT;
};
const onUnivInputChange = () => {
const hasValue = document.getElementById("univ-search-input").value.length > 0;
document.getElementById("univ-clear-btn").hidden = !hasValue;
document.getElementById("univ-search-icon").hidden = hasValue;
};
const onUnivClear = () => {
const input = document.getElementById("univ-search-input");
input.value = "";
input.focus();
onUnivInputChange();
document.getElementById("result-card-list").innerHTML = "";
renderEmpty(true, "대학을 검색해주세요.");
};
const onUnivSearch = async () => {
const keyword = document.getElementById("univ-search-input").value.trim();
if (!keyword) return;
try {
const universities = await searchUniversities(keyword);
renderUniversityCards(universities);
} catch (error) {
console.error("대학 검색 중 오류 발생:", error);
}
};
const loadDepartments = async (departmentName) => {
if (!currentUniv) return;
try {
const departments = await searchDepartments(currentUniv.universityCode, departmentName);
renderDepartmentCards(departments);
} catch (error) {
console.error("학과 검색 중 오류 발생:", error);
}
};
const onResultCardClick = async (event) => {
const card = event.target.closest(".univ-dept-search__card");
if (!card) return;
if (card.dataset.departmentCode) {
selected = {
universityCode: card.dataset.universityCode,
universityName: currentUniv.universityName,
departmentCode: card.dataset.departmentCode,
departmentName: card.dataset.departmentName,
};
updateSummary();
await loadDepartments(document.getElementById("dept-search-input").value.trim());
return;
}
currentUniv = { universityCode: card.dataset.universityCode, universityName: card.dataset.universityName };
selected = null;
document.getElementById("univ-display").value = `${currentUniv.universityName} (${currentUniv.universityCode})`;
document.getElementById("dept-search-input").value = "";
onDeptInputChange();
setPhase(DEPARTMENT);
updateSummary();
await loadDepartments("");
};
const onChangeUniv = () => {
currentUniv = null;
selected = null;
const univInput = document.getElementById("univ-search-input");
univInput.value = "";
onUnivInputChange();
setPhase(UNIVERSITY);
document.getElementById("result-card-list").innerHTML = "";
renderEmpty(false);
updateSummary();
univInput.focus();
};
const onDeptInputChange = () => {
const hasValue = document.getElementById("dept-search-input").value.length > 0;
document.getElementById("dept-clear-btn").hidden = !hasValue;
document.getElementById("dept-search-icon").hidden = hasValue;
};
const onDeptClear = () => {
const input = document.getElementById("dept-search-input");
input.value = "";
input.focus();
onDeptInputChange();
loadDepartments("");
};
const onDeptSearch = () => {
loadDepartments(document.getElementById("dept-search-input").value.trim());
};
const onReselect = () => {
selected = null;
updateSummary();
loadDepartments(document.getElementById("dept-search-input").value.trim());
};
const initPage = () => {
setPhase(UNIVERSITY);
updateSummary();
document.getElementById("univ-search-input").addEventListener("input", onUnivInputChange);
document.getElementById("univ-search-input").addEventListener("keydown", (event) => {
if (event.key === "Enter") onUnivSearch();
});
document.getElementById("univ-search-btn").addEventListener("click", onUnivSearch);
document.getElementById("univ-clear-btn").addEventListener("click", onUnivClear);
document.getElementById("change-univ-btn").addEventListener("click", onChangeUniv);
document.getElementById("result-card-list").addEventListener("click", onResultCardClick);
document.getElementById("dept-search-btn").addEventListener("click", onDeptSearch);
document.getElementById("dept-search-input").addEventListener("input", onDeptInputChange);
document.getElementById("dept-search-input").addEventListener("keydown", (event) => {
if (event.key === "Enter") onDeptSearch();
});
document.getElementById("dept-clear-btn").addEventListener("click", onDeptClear);
document.getElementById("reselect-btn").addEventListener("click", onReselect);
};
window.addEventListener("load", initPage);
})();