//////////////////////////////////////////////////////////////////////////////////////// //Global Variables //////////////////////////////////////////////////////////////////////////////////////// const tags = new Set(); let newsletterId = null; //////////////////////////////////////////////////////////////////////////////////////// //Document Ready //////////////////////////////////////////////////////////////////////////////////////// function execDocReady() { var pluginGroups = [ ["../reference/light-blue/lib/vendor/jquery.ui.widget.js", "../reference/lightblue4/docs/lib/widgster/widgster.js"], [ "../reference/lightblue4/docs/lib/bootstrap-select/dist/js/bootstrap-select.min.js", "../cover/css/newsletters.css" ] // 추가적인 플러그인 그룹들을 이곳에 추가하면 됩니다. ]; loadPluginGroupsParallelAndSequential(pluginGroups) .then(function () { console.log("모든 플러그인 로드 완료"); // setSideMenu("sidebar_menu_system", "sidebar_menu_system_provision"); $("#sidebar").hide(); $(".wrap").css("margin", 0); $(".widget").widgster(); $("#footer").load("/cover/html/template/landing-footer.html"); initNewslettersWriter(); }) .catch(function (error) { console.error("플러그인 로드 중 오류 발생"); console.error(error); }); } function initNewslettersWriter() { // 관리자 인증 newslettersAuthAdminCheck(); // 태그입력 초기화 initEditor(); newsletterId = new URL(location.href).searchParams.get("id"); if (newsletterId !== null) { loadNewsletter(newsletterId); } initTags(); initModal(); } // 유효성검사 function validateForm() { if ($("#category").val() === "") { jError("카테고리를 선택해주세요."); $("#category").focus(); return false; } if ($("#title").val().trim() === "") { jError("제목을 입력해주세요."); $("#title").focus(); return false; } if ($("#thumbnail_url").val().trim() === "") { jError("썸네일 URL을 입력해주세요."); $("#thumbnail_url").focus(); return false; } return true; } // 뉴스레터 불러오기 function loadNewsletter(id) { $.ajax({ url: "/auth-anon/api/cover/newsletter/getNewsletter/" + id, type: "GET", dataType: "json", statusCode: { 200: function (data) { $("#c_id").val(data.c_id); $("#slug").val(data.c_newsletter_slug); $("#category").val(data.c_newsletter_category); $("#title").val(data.c_newsletter_title); // $("#subtitle").val(data.c_newsletter_subtitle); // CKEDITOR.instances.contents.setData(data.c_newsletter_contents); $("#contents").val(data.c_newsletter_contents); // $("#thumbnail_url").val(data.c_newsletter_thumbnail_url); // $("#thumbnail_alt").val(data.c_newsletter_thumbnail_alt); $("#visibility").val(data.c_newsletter_visibility); $("#hiddenTags").val(data.c_newsletter_etc); // $("#desc").val(data.c_newsletter_desc); initTags(); } }, error: function (e) { console.error("Error:", e); jError("기사를 불러오는 중 오류가 발생했습니다."); } }); } function setDataToJson() { // 태그처리 $("#hiddenTags").val(Array.from(tags).join(",")); let data = { c_id: $("#c_id").val(), c_newsletter_slug: $("#slug").val(), c_newsletter_category: $("#category").val(), c_newsletter_title: $("#title").val(), // c_newsletter_subtitle: $("#subtitle").val(), c_newsletter_contents: CKEDITOR.instances["contents"].getData(), c_newsletter_thumbnail_url: $("#thumbnail_url").val(), // c_newsletter_thumbnail_alt: $("#thumbnail_alt").val(), c_newsletter_visibility: $("#visibility").val(), c_newsletter_etc: $("#hiddenTags").val(), // c_newsletter_desc: $("#desc").val(), c_newsletter_author_id: userName, c_newsletter_author_name: fullName }; return data; } // 저장버튼 function addNewsletter() { $.ajax({ url: "/auth-anon/api/cover/newsletter/addNewsletter", type: "POST", data: setDataToJson(), dataType: "json", statusCode: { 200: function () { setTimeout(function () { jSuccess("기사가 등록 되었습니다."); }, 500); window.location.href = "./template.html?page=newsletters"; } }, error: function (e) { console.error("Error:", e); jError("기사를 등록하는 중 오류가 발생했습니다."); } }); } function updateNewsletter() { $.ajax({ url: "/auth-anon/api/cover/newsletter/updateNewsletter", type: "PUT", progress: true, data: setDataToJson(), dataType: "json", statusCode: { 200: function () { jSuccess("기사가 수정 되었습니다."); window.location.href = "./template.html?page=newslettersDetail&id=" + newsletterId; } }, error: function (e) { console.error("Error:", e); jError("기사를 수정하는 중 오류가 발생했습니다."); } }); } // CKEditor 초기화 function initEditor() { var waitCKEDITOR = setInterval(function () { try { if (window.CKEDITOR) { if (window.CKEDITOR.status === "loaded") { editor = CKEDITOR.replace("contents", { contentsCss: "./css/contents.css" }); clearInterval(waitCKEDITOR); } } } catch (err) { console.log("CKEDITOR 로드가 완료되지 않아서 초기화 재시도 중..."); } }, 313 /* 네트워크 환경에 따라서 늘려야할지도 */); } function initTags(savedTags) { const tagContainer = document.getElementById("tagContainer"); const tagInput = document.getElementById("tagInput"); const inputTags = document.getElementById("inputTags"); function addTag(text) { const value = text.trim(); if (!value || tags.has(value)) return; tags.add(value); const tagEl = document.createElement("span"); tagEl.className = "mt-4 py-1 px-2 border-radius-md flex align-items-center bg-dedfe7"; tagEl.textContent = value; const btn = document.createElement("button"); btn.type = "button"; btn.className = "ml-1 border-0 bg-transparent cursor-pointer font-bold"; btn.textContent = "x"; btn.onclick = () => { tags.delete(value); tagContainer.removeChild(tagEl); }; tagEl.appendChild(btn); tagContainer.insertBefore(tagEl, inputTags); } function handleInput(value) { value.split(",").forEach(text => addTag(text)); tagInput.value = ''; } tagInput.addEventListener("keydown", e => { if (e.key === "Enter" || e.key === "," || e.key === "Tab" || e.key === " ") { e.preventDefault(); handleInput(tagInput.value); } }); tagInput.addEventListener("focusout", e => { e.preventDefault(); handleInput(tagInput.value); }); tagInput.addEventListener("paste", e => { e.preventDefault(); const text = (e.clipboardData || window.clipboardData).getData("text"); text.split(/[,\s]+/).forEach(text => addTag(text)); }); // 기존 태그 불러오기 const existingTags = document.getElementById("hiddenTags").value; if (existingTags) { existingTags.split(",").forEach(text => addTag(text)); } } function initModal() { const backdrop = document.getElementById("modalBackdrop"); const modal = backdrop.querySelector('.modal'); const modalTitleEl = document.getElementById("modalTitle"); const modalDescEl = document.getElementById("modalDesc"); const modalConfirmBtn = document.getElementById("modalConfirmBtn"); const modalCancelBtn = document.getElementById("modalCancelBtn"); let lastFocused = null; let currentOnConfirm = null; let currentOnCancel = null; function showModal({title, message, confirmText, cancelText, confirmClass="primary", onConfirm, onCancel}) { modalTitleEl.textContent = title; modalDescEl.textContent = message; modalConfirmBtn.textContent = confirmText || "확인"; modalCancelBtn.textContent = cancelText || "취소"; modalConfirmBtn.className = `btn-${confirmClass} text-5 font-color-white font-normal line-height-30px border-radius-4 px-4 py-2`; modalCancelBtn.className = `btn-default text-5 font-color-white font-normal line-height-30px border-radius-4 px-4 py-2`; lastFocused = document.activeElement; currentOnConfirm = onConfirm; currentOnCancel = onCancel; backdrop.classList.remove("hidden"); backdrop.setAttribute("aria-hidden", "false"); if (modal && typeof modal.focus() === "function") { modal.focus(); } modalConfirmBtn.onclick = () => { hideModal(); if (onConfirm) onConfirm(); }; modalCancelBtn.onclick = () => { hideModal(); if (onCancel) onCancel(); }; } function hideModal() { backdrop.classList.add("hidden"); backdrop.setAttribute("aria-hidden", "true"); if (lastFocused && typeof lastFocused.focus === "function") lastFocused.focus(); } backdrop.addEventListener("click", e => { if (e.target === backdrop) { hideModal(); if (currentOnCancel) currentOnCancel(); } }); document.addEventListener("keydown", e => { if (e.key === "Escape" && backdrop.attributes.getNamedItem("aria-hidden").value === "false") { hideModal(); if (currentOnCancel) currentOnCancel(); } }); document.getElementById("save_newsletter").addEventListener("click", e => { showModal({ title: "뉴스레터 저장", message: "뉴스레터를 저장하시겠습니까?", confirmText: "저장", cancelText: "취소", confirmClass: "primary", onConfirm: () => { setTimeout(function () { if (newsletterId === "" || newsletterId === null) { addNewsletter(); } else { updateNewsletter(); } }, 200); } }); }); document.getElementById("cancel_newsletter").addEventListener("click", e => { showModal({ title: "뉴스레터 취소", message: "뉴스레터 작성을 취소하시겠습니까? 작성 중인 내용은 저장되지 않습니다.", confirmText: "취소", cancelText: "계속 작성", confirmClass: "danger", onConfirm: () => { setTimeout(function () { window.location.href = "./template.html?page=newsletters"; }, 200); } }); }); } function newslettersAuthAdminCheck() { $.ajax({ url: "/auth-user/me", type: "GET", timeout: 7313, global: false, statusCode: { 200: function (json) { console.log("[ landing :: authUserCheck ] userName = " + json.preferred_username); console.log("[ landing :: authUserCheck ] sub = " + json.sub); console.log("[ landing :: authUserCheck ] roles = " + json.realm_access.roles); console.log("[ landing :: authUserCheck ] email = " + json.email); console.log("[ landing :: authUserCheck ] name = " + json.name); userName = json.preferred_username; permissions = json.realm_access.roles; userID = json.sub; userEmail = json.email; fullName = json.name; }, 401: function () { jError("클라이언트가 인증되지 않았거나, 유효한 인증 정보가 부족하여 요청이 거부되었습니다."); location.href = "/oauth2/authorization/middle-proxy"; return false; }, 403: function () { jError("서버가 해당 요청을 이해했지만, 권한이 없어 요청이 거부되었습니다."); return false; } } }); }