1import { 2 ask_anything_icon_default, 3 bank_account_icon_default, 4 moatax_icon_default, 5 remote_support_icon_default 6} from "/assets/chunk-Z3AEO5KR.js"; 7import { 8 ChevronLeft, 9 ChevronRight, 10 ChevronsLeft, 11 ChevronsRight 12} from "/assets/chunk-IIJCJCDX.js"; 13import { 14 __toESM, 15 require_jsx_runtime, 16 require_react 17} from "/assets/chunk-Q5NHMIWZ.js"; 18
19// src/app/components/SupportPage.tsx 20var import_react = __toESM(require_react(), 1); 21
22// src/assets/images/manual-card-icon1.svg 23var manual_card_icon1_default = "/assets/manual-card-icon1-7B3RLZST.svg"; 24
25// src/assets/images/manual-card-icon2.svg 26var manual_card_icon2_default = "/assets/manual-card-icon2-KRTANMZY.svg"; 27
28// src/assets/images/manual-card-icon3.svg 29var manual_card_icon3_default = "/assets/manual-card-icon3-GXOHOTAK.svg"; 30
31// src/app/components/SupportPage.tsx 32var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); 33var buildSupportIconClassName = (className) => ["block", "h-full", "w-full", "object-contain", className].filter(Boolean).join(" "); 34var MoataxIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 35 "img", 36 { 37 src: moatax_icon_default, 38 alt: "", 39 className: buildSupportIconClassName(className) 40 } 41); 42var RemoteSupportIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 43 "img", 44 { 45 src: remote_support_icon_default, 46 alt: "", 47 className: buildSupportIconClassName(className) 48 } 49); 50var AskAnythingIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 51 "img", 52 { 53 src: ask_anything_icon_default, 54 alt: "", 55 className: buildSupportIconClassName(className) 56 } 57); 58var BankAccountIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 59 "img", 60 { 61 src: bank_account_icon_default, 62 alt: "", 63 className: buildSupportIconClassName(className) 64 } 65); 66var ManualCardIcon1 = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 67 "img", 68 { 69 src: manual_card_icon1_default, 70 alt: "", 71 className: buildSupportIconClassName(className) 72 } 73); 74var ManualCardIcon2 = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 75 "img", 76 { 77 src: manual_card_icon2_default, 78 alt: "", 79 className: buildSupportIconClassName(className) 80 } 81); 82var ManualCardIcon3 = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 83 "img", 84 { 85 src: manual_card_icon3_default, 86 alt: "", 87 className: buildSupportIconClassName(className) 88 } 89); 90var menuItems = [ 91 { id: "notice", label: "\uACF5\uC9C0\uC0AC\uD56D" }, 92 { id: "faq", label: "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38" }, 93 { id: "qna", label: "\uC9C8\uBB38\uACFC \uB2F5\uBCC0" }, 94 { id: "data", label: "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548" }, 95 { id: "manual", label: "\uC0AC\uC6A9\uC124\uBA85\uC11C" }, 96 { id: "video", label: "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0" } 97]; 98var SUPPORT_HEADER_TITLE = "\uACE0\uAC1D\uC9C0\uC6D0"; 99function getApiBaseUrl() { 100 if (typeof window === "undefined") return "/api"; 101 const { hostname, port, pathname } = window.location; 102 if (hostname === "localhost" && port === "5173") { 103 return "/api"; 104 } 105 if (pathname.startsWith("/spa_new.wrjb.co.kr/")) { 106 return "/spa_new.wrjb.co.kr/api"; 107 } 108 return "/api"; 109} 110function scrollPageToTop() { 111 if (typeof window === "undefined") return; 112 const scroll = () => window.scrollTo({ top: 0, left: 0, behavior: "auto" }); 113 window.requestAnimationFrame(scroll); 114} 115function formatDate(raw) { 116 if (!raw) return "-"; 117 const text = String(raw).trim(); 118 if (text.length >= 10) return text.slice(0, 10); 119 return text; 120} 121function normalizeNoticeHtml(html) { 122 if (!html) return ""; 123 let output = html; 124 const assetOrigin = typeof window === "undefined" ? "" : window.location.origin; 125 output = output.replace( 126 /src\s*=\s*["']\/faqimg\//gi, 127 `src="${assetOrigin}/faqimg/` 128 ); 129 output = output.replace( 130 /src\s*=\s*["']\/img\//gi, 131 `src="${assetOrigin}/img/` 132 ); 133 output = output.replace( 134 /<img\b/gi, 135 '<img style="max-width:100%;height:auto;"' 136 ); 137 return output; 138} 139function decodeHtmlEntities(text) { 140 if (!text) return ""; 141 if (typeof window === "undefined") { 142 return text.replace(/ /gi, " ").replace(/</gi, "<").replace(/>/gi, ">").replace(/"/gi, '"').replace(/'/gi, "'").replace(/&/gi, "&"); 143 } 144 const textarea = window.document.createElement("textarea"); 145 textarea.innerHTML = text; 146 return textarea.value; 147} 148function escapeHtml(text) { 149 return String(text || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); 150} 151function convertHtmlToEditorFallbackText(html) { 152 if (!html) return ""; 153 const normalized = normalizeNoticeHtml(html).replace(/<br\s*\/?>/gi, "\n").replace(/<\/(p|div|li|tr|h[1-6])>/gi, "\n").replace(/<li\b[^>]*>/gi, "- ").replace(/<[^>]+>/g, ""); 154 return decodeHtmlEntities(normalized).replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim(); 155} 156function convertEditorFallbackTextToHtml(text) { 157 const normalized = String(text || "").replace(/\r\n/g, "\n").trim(); 158 if (!normalized) return "<p><br /></p>"; 159 const paragraphs = normalized.split(/\n{2,}/).map((chunk) =>
159 chunk.trim()).filter(Boolean).map((chunk) => `<p>${escapeHtml(chunk).replace(/\n/g, "<br />")}</p>`); 160 return paragraphs.length > 0 ? paragraphs.join("") : "<p><br /></p>"; 161} 162function cleanBoardSubject(subject) { 163 return String(subject || "").replace(/^\s+/, ""); 164} 165function getActiveTinyContent() { 166 try { 167 const tiny = window.tinymce; 168 return String(tiny?.activeEditor?.getContent?.() || "").trim(); 169 } catch { 170 return ""; 171 } 172} 173function getLoginHref() { 174 if (typeof window === "undefined") return "/login"; 175 const current = window.location.pathname + (window.location.search || "") + (window.location.hash || ""); 176 if (window.location.pathname === "/login" || window.location.pathname === "/login/") { 177 return "/login?from_url=%2F"; 178 } 179 return `/login?from_url=${encodeURIComponent(current)}`; 180} 181function isReplySubject(subject) { 182 return /^(?:ã´\s*)?\[ëµë³\]/.test(cleanBoardSubject(subject)); 183} 184function isReplyItem(item) { 185 return Number(item.rep || 0) > 0 || isReplySubject(item.subject); 186} 187function renderBoardSubjectWithReplyMarker(item) { 188 const subject = cleanBoardSubject(item.subject); 189 if (!isReplyItem(item)) return subject; 190 return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 pl-3", children: [ 191 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "shrink-0 text-gray-500", children: "\u21B3" }), 192 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: subject }) 193 ] }); 194} 195function getPaginationPages(totalPages, currentPage, isCompact) { 196 const safeTotal = Math.max(1, Number(totalPages) || 1); 197 const safeCurrent = Math.min( 198 Math.max(1, Number(currentPage) || 1), 199 safeTotal 200 ); 201 const visibleCount = isCompact ? 4 : 10; 202 if (safeTotal <= visibleCount) { 203 return Array.from({ length: safeTotal }, (_, i) => i + 1); 204 } 205 if (!isCompact) { 206 const start2 = Math.max( 207 Math.floor((safeCurrent - 1) / visibleCount) * visibleCount, 208 0 209 ); 210 return Array.from({ length: safeTotal }, (_, i) => i + 1).slice( 211 start2, 212 start2 + visibleCount 213 ); 214 } 215 let start = safeCurrent - 1; 216 if (safeCurrent >= safeTotal - 1) start = safeTotal - visibleCount + 1; 217 start = Math.max(1, start); 218 const end = Math.min(start + visibleCount - 1, safeTotal); 219 return Array.from({ length: end - start + 1 }, (_, i) => start + i); 220} 221async function parseApiJson(response) { 222 const raw = await response.text(); 223 const text = raw.replace(/^\uFEFF/, "").trim(); 224 try { 225 return JSON.parse(text); 226 } catch { 227 const start = text.indexOf("{"); 228 const end = text.lastIndexOf("}"); 229 if (start >= 0 && end > start) { 230 try { 231 return JSON.parse(text.slice(start, end + 1)); 232 } catch { 233 } 234 } 235 const firstBrace = text.indexOf("{"); 236 const lastBracket = text.lastIndexOf("]"); 237 if (firstBrace >= 0 && lastBracket > firstBrace) { 238 const candidate = text.slice(firstBrace, lastBracket + 1); 239 try { 240 const items = JSON.parse(`[${candidate}`); 241 return { ok: true, items }; 242 } catch { 243 } 244 } 245 if (/^\s*},\s*\{/.test(text) && /\]\s*}\s*$/.test(text)) { 246 const core = text.replace(/^\s*},\s*/, "").replace(/\]\s*}\s*$/, ""); 247 try { 248 const items = JSON.parse(`[${core}]`); 249 return { ok: true, items }; 250 } catch { 251 } 252 } 253 throw new Error("invalid_json"); 254 } 255} 256async function postBoardWithFallback(endpoint, queryFields, content) { 257 const requestUrl = `${endpoint}?${new URLSearchParams(queryFields).toString()}`; 258 const urlEncoded = new URLSearchParams(); 259 Object.entries(queryFields).forEach( 260 ([key, value]) => urlEncoded.set(key, value) 261 ); 262 urlEncoded.set("content", content); 263 const encodedResponse = await fetch(requestUrl, { 264 method: "POST", 265 credentials: "include", 266 headers: { 267 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 268 }, 269 body: urlEncoded.toString() 270 }); 271 let encodedData = null; 272 try { 273 encodedData = await parseApiJson(encodedResponse); 274 } catch { 275 encodedData = null; 276 } 277 if (encodedResponse.ok && encodedData?.ok) { 278 return { response: encodedResponse, data: encodedData }; 279 } 280 if (encodedData?.error && !/Content is required/i.test(encodedData.error)) { 281 return { response: encodedResponse, data: encodedData }; 282 } 283 const rawEndpoint = `${endpoint}?${new URLSearchParams({ rawContent: "1", ...queryFields }).toString()}`; 284 const rawResponse = await fetch(rawEndpoint, { 285 method: "POST", 286 credentials: "include", 287 body: content 288 }); 289 const rawText = (await rawResponse.text()).replace(/^\uFEFF/, "").trim(); 290 let rawData = null; 291 try { 292 rawData = JSON.parse(rawText); 293 } catch { 294 const start = rawText.indexOf("{"); 295 const end = rawText.lastIndexOf("}"); 296 if (start >= 0 && end > start) {
297 try { 298 rawData = JSON.parse( 299 rawText.slice(start, end + 1) 300 ); 301 } catch { 302 rawData = null; 303 } 304 } 305 } 306 return { 307 response: rawResponse, 308 data: rawData ?? { ok: false, error: "?\uAE45\uC909 ?\u317D\uB663" } 309 }; 310} 311function SupportPage() { 312 const NOTICE_PAGE_SIZE = 20; 313 const noticeEditorRef = (0, import_react.useRef)(null); 314 const faqEditorRef = (0, import_react.useRef)(null); 315 const qnaEditorRef = (0, import_react.useRef)(null); 316 const dataEditorRef = (0, import_react.useRef)(null); 317 const videoEditorRef = (0, import_react.useRef)(null); 318 const [selectedMenu, setSelectedMenu] = (0, import_react.useState)("notice"); 319 const [isMobileMenuOpen, setIsMobileMenuOpen] = (0, import_react.useState)(false); 320 const [notices, setNotices] = (0, import_react.useState)([]); 321 const [noticePage, setNoticePage] = (0, import_react.useState)(1); 322 const [noticePageSize, setNoticePageSize] = (0, import_react.useState)(NOTICE_PAGE_SIZE); 323 const [noticeTotalCount, setNoticeTotalCount] = (0, import_react.useState)(0); 324 const [noticeTotalPages, setNoticeTotalPages] = (0, import_react.useState)(1); 325 const [noticeSearchField, setNoticeSearchField] = (0, import_react.useState)("all"); 326 const [noticeSearchFieldQuery, setNoticeSearchFieldQuery] = (0, import_react.useState)("all"); 327 const [noticeSearchInput, setNoticeSearchInput] = (0, import_react.useState)(""); 328 const [noticeSearchKeyword, setNoticeSearchKeyword] = (0, import_react.useState)(""); 329 const [isLoadingNotice, setIsLoadingNotice] = (0, import_react.useState)(false); 330 const [noticeError, setNoticeError] = (0, import_react.useState)(""); 331 const [noticeDetail, setNoticeDetail] = (0, import_react.useState)(null); 332 const [isNoticeWriteMode, setIsNoticeWriteMode] = (0, import_react.useState)(false); 333 const [noticeWriteModeType, setNoticeWriteModeType] = (0, import_react.useState)("create"); 334 const [noticeWriteTargetIdx, setNoticeWriteTargetIdx] = (0, import_react.useState)(null); 335 const [isNoticeSubmitting, setIsNoticeSubmitting] = (0, import_react.useState)(false); 336 const [noticeWriteName, setNoticeWriteName] = (0, import_react.useState)(""); 337 const [noticeWriteEmail, setNoticeWriteEmail] = (0, import_react.useState)(""); 338 const [noticeWriteSubject, setNoticeWriteSubject] = (0, import_react.useState)(""); 339 const [noticeWriteContent, setNoticeWriteContent] = (0, import_react.useState)(""); 340 const [pendingNoticeIdx, setPendingNoticeIdx] = (0, import_react.useState)(null); 341 const [faqs, setFaqs] = (0, import_react.useState)([]); 342 const [faqPage, setFaqPage] = (0, import_react.useState)(1); 343 const [faqPageSize, setFaqPageSize] = (0, import_react.useState)(NOTICE_PAGE_SIZE); 344 const [faqTotalCount, setFaqTotalCount] = (0, import_react.useState)(0); 345 const [faqTotalPages, setFaqTotalPages] = (0, import_react.useState)(1); 346 const [faqSearchField, setFaqSearchField] = (0, import_react.useState)("all"); 347 const [faqSearchFieldQuery, setFaqSearchFieldQuery] = (0, import_react.useState)("all"); 348 const [faqSearchInput, setFaqSearchInput] = (0, import_react.useState)(""); 349 const [faqSearchKeyword, setFaqSearchKeyword] = (0, import_react.useState)(""); 350 const [faqAutoOpenFirst, setFaqAutoOpenFirst] = (0, import_react.useState)(false); 351 const [isLoadingFaq, setIsLoadingFaq] = (0, import_react.useState)(false); 352 const [faqError, setFaqError] = (0, import_react.useState)(""); 353 const [faqDetail, setFaqDetail] = (0, import_react.useState)(null); 354 const [isFaqWriteMode, setIsFaqWriteMode] = (0, import_react.useState)(false); 355 const [faqWriteModeType, setFaqWriteModeType] = (0, import_react.useState)("create"); 356 const [faqWriteTargetIdx, setFaqWriteTargetIdx] = (0, import_react.useState)( 357 null 358 ); 359 const [isFaqSubmitting, setIsFaqSubmitting] = (0, import_react.useState)(false); 360 const [faqWriteName, setFaqWriteName] = (0, import_react.useState)(""); 361 const [faqWriteEmail, setFaqWriteEmail] = (0, import_react.useState)(""); 362 const [faqWriteSubject, setFaqWriteSubject] = (0, import_react.useState)(""); 363 const [faqWriteContent, setFaqWriteContent] = (0, import_react.useState)(""); 364 const [pendingFaqIdx, setPendingFaqIdx] = (0, import_react.useState)(null); 365 const [qnas, setQnas] = (0, import_react.useState)([]);
366 const [qnaPage, setQnaPage] = (0, import_react.useState)(1); 367 const [qnaPageSize, setQnaPageSize] = (0, import_react.useState)(NOTICE_PAGE_SIZE); 368 const [qnaTotalCount, setQnaTotalCount] = (0, import_react.useState)(0); 369 const [qnaTotalPages, setQnaTotalPages] = (0, import_react.useState)(1); 370 const [qnaSearchField, setQnaSearchField] = (0, import_react.useState)("all"); 371 const [qnaSearchFieldQuery, setQnaSearchFieldQuery] = (0, import_react.useState)("all"); 372 const [qnaSearchInput, setQnaSearchInput] = (0, import_react.useState)(""); 373 const [qnaSearchKeyword, setQnaSearchKeyword] = (0, import_react.useState)(""); 374 const [isLoadingQna, setIsLoadingQna] = (0, import_react.useState)(false); 375 const [qnaError, setQnaError] = (0, import_react.useState)(""); 376 const [qnaDetail, setQnaDetail] = (0, import_react.useState)(null); 377 const [isQnaWriteMode, setIsQnaWriteMode] = (0, import_react.useState)(false); 378 const [qnaWriteModeType, setQnaWriteModeType] = (0, import_react.useState)("create"); 379 const [qnaWriteTargetIdx, setQnaWriteTargetIdx] = (0, import_react.useState)( 380 null 381 ); 382 const [isQnaSubmitting, setIsQnaSubmitting] = (0, import_react.useState)(false); 383 const [qnaWriteName, setQnaWriteName] = (0, import_react.useState)(""); 384 const [qnaWriteEmail, setQnaWriteEmail] = (0, import_react.useState)(""); 385 const [qnaWriteSubject, setQnaWriteSubject] = (0, import_react.useState)(""); 386 const [qnaWriteContent, setQnaWriteContent] = (0, import_react.useState)(""); 387 const [dataItems, setDataItems] = (0, import_react.useState)([]); 388 const [dataPage, setDataPage] = (0, import_react.useState)(1); 389 const [dataPageSize, setDataPageSize] = (0, import_react.useState)(NOTICE_PAGE_SIZE); 390 const [dataTotalCount, setDataTotalCount] = (0, import_react.useState)(0); 391 const [dataTotalPages, setDataTotalPages] = (0, import_react.useState)(1); 392 const [dataSearchField, setDataSearchField] = (0, import_react.useState)("all"); 393 const [dataSearchFieldQuery, setDataSearchFieldQuery] = (0, import_react.useState)("all"); 394 const [dataSearchInput, setDataSearchInput] = (0, import_react.useState)(""); 395 const [dataSearchKeyword, setDataSearchKeyword] = (0, import_react.useState)(""); 396 const [isLoadingData, setIsLoadingData] = (0, import_react.useState)(false); 397 const [dataError, setDataError] = (0, import_react.useState)(""); 398 const [dataDetail, setDataDetail] = (0, import_react.useState)(null); 399 const [videos, setVideos] = (0, import_react.useState)([]); 400 const [videoPage, setVideoPage] = (0, import_react.useState)(1); 401 const [videoPageSize, setVideoPageSize] = (0, import_react.useState)(NOTICE_PAGE_SIZE); 402 const [videoTotalCount, setVideoTotalCount] = (0, import_react.useState)(0); 403 const [videoTotalPages, setVideoTotalPages] = (0, import_react.useState)(1); 404 const [videoSearchField, setVideoSearchField] = (0, import_react.useState)("all"); 405 const [videoSearchFieldQuery, setVideoSearchFieldQuery] = (0, import_react.useState)("all"); 406 const [videoSearchInput, setVideoSearchInput] = (0, import_react.useState)(""); 407 const [videoSearchKeyword, setVideoSearchKeyword] = (0, import_react.useState)(""); 408 const [isLoadingVideo, setIsLoadingVideo] = (0, import_react.useState)(false); 409 const [videoError, setVideoError] = (0, import_react.useState)(""); 410 const [videoDetail, setVideoDetail] = (0, import_react.useState)(null); 411 const [pendingVideoIdx, setPendingVideoIdx] = (0, import_react.useState)(null); 412 const [isVideoWriteMode, setIsVideoWriteMode] = (0, import_react.useState)(false); 413 const [videoWriteModeType, setVideoWriteModeType] = (0, import_react.useState)("create"); 414 const [videoWriteTargetIdx, setVideoWriteTargetIdx] = (0, import_react.useState)( 415 null 416 ); 417 const [isVideoSubmitting, setIsVideoSubmitting] = (0, import_react.useState)(false); 418 const [videoWriteName, setVideoWriteName] = (0, import_react.useState)(""); 419 const [videoWriteEmail, setVideoWriteEmail] = (0, import_react.useState)(""); 420 const [videoWriteSubject, setVideoWriteSubject] = (0, import_react.useState)(""); 421 const [videoWriteContent, setVideoWriteContent] = (0, import_react.useState)(""); 422 const [isDataWriteMode, setIsDataWriteMode] = (0, import_react.useState)(false); 423 const [dataWriteModeType, setDataWriteModeType] = (0, import_react.useState)("create"); 424 const [dataWriteTargetIdx, setDataWriteTargetIdx] = (0, import_react.useState)( 425 null 426 ); 427 const [isDataSubmitting, setIsDataSubmitting] = (0, import_react.useState)(false); 428 const [dataWriteName, setDataWriteName] = (0, import_react.useState)(""); 429 const [dataWriteEmail, setDataWriteEmail] = (0, import_react.useState)(""); 430 const [dataWriteSubject, setDataWriteSubject] = (0, import_react.useState)(""); 431 const [dataWriteContent, setDataWriteContent] = (0, import_react.useState)(""); 432 const [isAuthenticated, setIsAuthenticated] = (0, import_react.useState)(false); 433 const [authRole, setAuthRole] = (0, import_react.useState)(""); 434 const [sessionUserId, setSessionUserId] = (0, import_react.useState)(""); 435 const [sessionWriterName, setSessionWriterName] = (0, import_react.useState)(""); 436 const [sessionWriterEmail, setSessionWriterEmail] = (0, import_react.useState)(""); 437 const [isCompactPagination, setIsCompactPagination] = (0, import_react.useState)(false); 438 const [BundledEditorComponent, setBundledEditorComponent] = (0, import_react.useState)(null); 439 const [isTinyEditorLoading, setIsTinyEditorLoading] = (0, import_react.useState)(false); 440 const [usePlainTextEditorFallback, setUsePlainTextEditorFallback] = (0, import_react.useState)(false); 441 const skipNextDetailHistoryRef = (0, import_react.useRef)(false); 442 const selectedMenuButtonStyle = { 443 backgroundColor: "#F2F3F7", 444 color: "#101828" 445 }; 446 const selectedMenuIconStyle = { color: "#101828" }; 447 const resetFaqSearchState = () => { 448 setFaqPage(1); 449 setFaqSearchField("all"); 450 setFaqSearchFieldQuery("all"); 451 setFaqSearchInput(""); 452 setFaqSearchKeyword(""); 453 setFaqAutoOpenFirst(false); 454 setPendingFaqIdx(null); 455 }; 456 const closeAllDetails = () => { 457 setNoticeDetail(null); 458 setFaqDetail(null); 459 setQnaDetail(null); 460 setDataDetail(null); 461 setVideoDetail(null); 462 setIsNoticeWriteMode(false); 463 setIsFaqWriteMode(false); 464 setIsQnaWriteMode(false); 465 setIsDataWriteMode(false); 466 setIsVideoWriteMode(false); 467 }; 468 const pushDetailHistory = () => { 469 if (typeof window === "undefined") return; 470 if (skipNextDetailHistoryRef.current) { 471 skipNextDetailHistoryRef.current = false;
472 return; 473 } 474 const state = window.history.state; 475 if (state?.supportDetail === true) return; 476 window.history.pushState({ ...state || {}, supportDetail: true }, ""); 477 }; 478 const closeDetailWithBack = () => { 479 if (typeof window === "undefined") { 480 closeAllDetails(); 481 return; 482 } 483 const state = window.history.state; 484 if (state?.supportDetail === true) { 485 window.history.back(); 486 return; 487 } 488 closeAllDetails(); 489 }; 490 const handleMenuClick = (menuId) => { 491 setSelectedMenu(menuId); 492 setIsMobileMenuOpen(false); 493 if (menuId !== "notice") { 494 setNoticeDetail(null); 495 setIsNoticeWriteMode(false); 496 } 497 if (menuId !== "faq") { 498 setFaqDetail(null); 499 setIsFaqWriteMode(false); 500 } 501 if (menuId === "faq") { 502 resetFaqSearchState(); 503 } 504 if (menuId !== "qna") { 505 setQnaDetail(null); 506 setIsQnaWriteMode(false); 507 } 508 if (menuId !== "data") { 509 setDataDetail(null); 510 setIsDataWriteMode(false); 511 } 512 if (menuId !== "video") { 513 setVideoDetail(null); 514 setIsVideoWriteMode(false); 515 } 516 }; 517 (0, import_react.useEffect)(() => { 518 const onPopState = () => { 519 closeAllDetails(); 520 }; 521 window.addEventListener("popstate", onPopState); 522 return () => window.removeEventListener("popstate", onPopState); 523 }, []); 524 (0, import_react.useEffect)(() => { 525 scrollPageToTop(); 526 }, [ 527 selectedMenu, 528 noticeDetail?.idx, 529 faqDetail?.idx, 530 qnaDetail?.idx, 531 dataDetail?.idx, 532 videoDetail?.idx, 533 isNoticeWriteMode, 534 isFaqWriteMode, 535 isQnaWriteMode, 536 isDataWriteMode, 537 noticeWriteModeType, 538 faqWriteModeType, 539 qnaWriteModeType, 540 dataWriteModeType 541 ]); 542 (0, import_react.useEffect)(() => { 543 if (typeof window === "undefined") return; 544 const mediaQuery = window.matchMedia("(max-width: 500px)"); 545 const syncCompactPagination = () => setIsCompactPagination(mediaQuery.matches); 546 syncCompactPagination(); 547 mediaQuery.addEventListener("change", syncCompactPagination); 548 return () => mediaQuery.removeEventListener("change", syncCompactPagination); 549 }, []); 550 (0, import_react.useEffect)(() => { 551 if (typeof window === "undefined") return; 552 const params = new URLSearchParams(window.location.search); 553 const menu = params.get("menu"); 554 const idxRaw = params.get("idx"); 555 const idx = idxRaw ? Number(idxRaw) : NaN; 556 if (menu === "notice") { 557 setSelectedMenu("notice"); 558 if (Number.isFinite(idx) && idx > 0) setPendingNoticeIdx(idx); 559 } else if (menu === "faq") { 560 setSelectedMenu("faq"); 561 if (Number.isFinite(idx) && idx >
561 0) setPendingFaqIdx(idx); 562 const searchField = params.get("searchField"); 563 const searchKeyword = params.get("searchKeyword"); 564 const openFirst = params.get("openFirst"); 565 if (searchField) { 566 setFaqSearchField(searchField); 567 setFaqSearchFieldQuery(searchField); 568 } 569 if (searchKeyword) { 570 setFaqSearchInput(searchKeyword); 571 setFaqSearchKeyword(searchKeyword); 572 } 573 if (openFirst === "1") { 574 setFaqAutoOpenFirst(true); 575 skipNextDetailHistoryRef.current = true; 576 } 577 if (searchField || searchKeyword || openFirst === "1") { 578 const cleanParams = new URLSearchParams(); 579 cleanParams.set("menu", "faq"); 580 if (Number.isFinite(idx) && idx > 0) { 581 cleanParams.set("idx", String(idx)); 582 } 583 const cleanQuery = cleanParams.toString(); 584 window.history.replaceState( 585 window.history.state, 586 "", 587 `${window.location.pathname}${cleanQuery ? `?${cleanQuery}` : ""}` 588 ); 589 } 590 } else if (menu === "qna") { 591 setSelectedMenu("qna"); 592 } else if (menu === "data") { 593 setSelectedMenu("data"); 594 } else if (menu === "manual" || menu === "remote") { 595 setSelectedMenu("manual"); 596 } else if (menu === "video") { 597 setSelectedMenu("video"); 598 if (Number.isFinite(idx) && idx > 0) setPendingVideoIdx(idx); 599 } 600 }, []); 601 (0, import_react.useEffect)(() => { 602 if (selectedMenu !== "notice") return; 603 const controller = new AbortController(); 604 const fetchNotices = async () => { 605 setIsLoadingNotice(true); 606 setNoticeError(""); 607 try { 608 const response = await fetch( 609 `${getApiBaseUrl()}/notices/list.asp?page=${noticePage}&pageSize=${NOTICE_PAGE_SIZE}&searchField=${encodeURIComponent(noticeSearchFieldQuery)}&searchKeyword=${encodeURIComponent(noticeSearchKeyword)}`, 610 { 611 method: "GET", 612 credentials: "include", 613 signal: controller.signal 614 } 615 ); 616 const data = await parseApiJson(response); 617 if (!response.ok || !data.ok) { 618 setNoticeError("\u6028\uB4ED??\u044B\uBE46??\u907A\uB348\uC72D?\u317C? \uF9CF\uC0B5\uBEFD?\uB4EC\uB572??"); 619 setNotices([]); 620 setNoticeTotalCount(0); 621 setNoticeTotalPages(1); 622 return; 623 } 624 setNotices(Array.isArray(data.items) ? data.items : []); 625 setNoticePage( 626 Number.isFinite(Number(data.page)) ? Number(data.page) : noticePage 627 ); 628 setNoticePageSize( 629 Number.isFinite(Number(data.pageSize)) ? Number(data.pageSize) : NOTICE_PAGE_SIZE 630 ); 631 setNoticeTotalCount( 632 Number.isFinite(Number(data.totalCount)) ? Number(data.totalCount) : 0 633 ); 634 setNoticeTotalPages( 635 Number.isFinite(Number(data.totalPages)) ? Number(data.totalPages) : 1 636 ); 637 } catch { 638 if (!controller.signal.aborted) { 639 setNoticeError("\u6028\uB4ED??\u044B\uBE46 ?\uBDBF\uAECC???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E."); 640 setNotices([]); 641 setNoticeTotalCount(0); 642 setNoticeTotalPages(1); 643 } 644 } finally { 645 if (!controller.signal.aborted) { 646 setIsLoadingNotice(false); 647 } 648 } 649 }; 650 void fetchNotices(); 651 return () => controller.abort(); 652 }, [selectedMenu, noticePage, noticeSearchFieldQuery, noticeSearchKeyword]); 653 (0, import_react.useEffect)(() => { 654 if (selectedMenu !== "notice") return; 655 if (!pendingNoticeIdx) return; 656 if (notices.length === 0) return; 657 const target = notices.find( 658 (item) => Number(item.idx) === pendingNoticeIdx 659 ); 660 if (!target) return; 661 setNoticeDetail(target); 662 setPendingNoticeIdx(null); 663 pushDetailHistory(); 664 }, [selectedMenu, pendingNoticeIdx, notices]); 665 (0, import_react.useEffect)(() => { 666 if (selectedMenu !== "faq") return; 667 const controller = new AbortController(); 668 const fetchFaqs = async () => { 669 setIsLoadingFaq(true); 670 setFaqError(""); 671 try { 672 const response = await fetch( 673 `${getApiBaseUrl()}/faqs/list.asp?page=${faqPage}&pageSize=${NOTICE_PAGE_SIZE}&searchField=${encodeURIComponent(faqSearchFieldQuery)}&searchKeyword=${encodeURIComponent(faqSearchKeyword)}`, 674 { 675 method: "GET", 676 credentials: "include", 677 signal: controller.signal 678 } 679 ); 680 let data = null; 681 try { 682 data = await parseApiJson(response); 683 } catch { 684 setFaqError( 685 `?\uBA2F\uFF1C?\uC10E\uB497 \uF9DE\uB348\u0426 ?\uBB10\uB59F ?\uB6AF\uB59B ?\u317D\uB663 (HTTP ${response.status})` 686 ); 687 setFaqs([]); 688 setFaqTotalCount(0); 689 setFaqTotalPages(1); 690 return; 691 } 692 if (!response.ok) { 693 setFaqError(`?\uBA2F\uFF1C?\uC10E\uB497 \uF9DE\uB348\u0426 ?\uBDBF\uAECC ?\u317D\uB663 (HTTP ${response.status})`); 694 setFaqs([]); 695 setFaqTotalCount(0); 696 setFaqTotalPages(1); 697 return; 698 } 699 if (!data.ok) { 700 setFaqError("?\uBA2F\uFF1C?\uC10E\uB497 \uF9DE\uB348\u0426??\u907A\uB348\uC72D?\u317C? \uF9CF\uC0B5\uBEFD?\uB4EC\uB572??"); 701 setFaqs([]); 702 setFaqTotalCount(0); 703 setFaqTotalPages(1); 704 return; 705 } 706 setFaqs(Array.isArray(data.items) ? data.items : []); 707 setFaqPage( 708 Number.isFinite(Number(data.page)) ? Number(data.page) : faqPage 709 ); 710 setFaqPageSize( 711 Number.isFinite(Number(data.pageSize)) ? Number(data.pageSize) : NOTICE_PAGE_SIZE 712 ); 713 setFaqTotalCount( 714 Number.isFinite(Number(data.totalCount)) ? Number(data.totalCount) : 0 715 ); 716 setFaqTotalPages( 717 Number.isFinite(Number(data.totalPages)) ? Number(data.totalPages) : 1 718 ); 719 } catch { 720 if (!controller.signal.aborted) { 721 setFaqError("?\uBA2F\uFF1C?\uC10E\uB497 \uF9DE\uB348\u0426 ?\uBDBF\uAECC???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E."); 722 setFaqs([]); 723 setFaqTotalCount(0); 724 setFaqTotalPages(1); 725 } 726 } finally { 727 if (!controller.signal.aborted) { 728 setIsLoadingFaq(false); 729 } 730 } 731 }; 732 void fetchFaqs(); 733 return () => controller.abort(); 734 }, [selectedMenu, faqPage, faqSearchFieldQuery, faqSearchKeyword]); 735 (0, import_react.useEffect)(() => { 736 if (selectedMenu !== "faq") return; 737 if (!pendingFaqIdx) return; 738 const target = faqs.find((item) => Number(item.idx) === pendingFaqIdx); 739 if (target) { 740 setFaqDetail(target); 741 setPendingFaqIdx(null); 742 pushDetailHistory(); 743 return; 744 }
745 let cancelled = false; 746 const fetchFaqDetailByIdx = async () => { 747 try { 748 const response = await fetch( 749 `${getApiBaseUrl()}/faqs/view.asp?idx=${pendingFaqIdx}`, 750 { 751 method: "GET", 752 credentials: "include" 753 } 754 ); 755 const data = await parseApiJson( 756 response 757 ); 758 if (!response.ok || !data?.ok || !data.item || cancelled) return; 759 setFaqDetail(data.item); 760 pushDetailHistory(); 761 } catch { 762 } finally { 763 if (!cancelled) setPendingFaqIdx(null); 764 } 765 }; 766 void fetchFaqDetailByIdx(); 767 return () => { 768 cancelled = true; 769 }; 770 }, [selectedMenu, pendingFaqIdx, faqs]); 771 (0, import_react.useEffect)(() => { 772 if (selectedMenu !== "faq") return; 773 if (!faqAutoOpenFirst) return; 774 if (faqDetail) return; 775 if (faqs.length === 0) return; 776 setFaqAutoOpenFirst(false); 777 void openFaqDetail(faqs[0]); 778 }, [selectedMenu, faqAutoOpenFirst, faqDetail, faqs]); 779 (0, import_react.useEffect)(() => { 780 if (selectedMenu !== "qna") return; 781 const controller = new AbortController(); 782 const fetchQnas = async () => { 783 setIsLoadingQna(true); 784 setQnaError(""); 785 try { 786 const response = await fetch( 787 `${getApiBaseUrl()}/qnas/list.asp?page=${qnaPage}&pageSize=${NOTICE_PAGE_SIZE}&searchField=${encodeURIComponent(qnaSearchFieldQuery)}&searchKeyword=${encodeURIComponent(qnaSearchKeyword)}`, 788 { 789 method: "GET", 790 credentials: "include", 791 signal: controller.signal 792 } 793 ); 794 let data = null; 795 try { 796 data = await parseApiJson(response); 797 } catch { 798 setQnaError( 799 `\uF9DE\uB348\u0426\u6028??\uB4EC? ?\uBB10\uB59F ?\uB6AF\uB59B ?\u317D\uB663 (HTTP ${response.status})` 800 ); 801 setQnas([]); 802 setQnaTotalCount(0); 803 setQnaTotalPages(1); 804 return; 805 } 806 if (!response.ok) { 807 setQnaError(`\uF9DE\uB348\u0426\u6028??\uB4EC? ?\uBDBF\uAECC ?\u317D\uB663 (HTTP ${response.status})`); 808 setQnas([]); 809 setQnaTotalCount(0); 810 setQnaTotalPages(1); 811 return; 812 } 813 if (!data.ok) { 814 setQnaError("\uF9DE\uB348\u0426\u6028??\uB4EC???\u907A\uB348\uC72D?\u317C? \uF9CF\uC0B5\uBEFD?\uB4EC\uB572??"); 815 setQnas([]); 816 setQnaTotalCount(0); 817 setQnaTotalPages(1); 818 return; 819 } 820 const resolvedItems = Array.isArray(data.items) ? data.items : []; 821 const resolvedPage = Number.isFinite(Number(data.page)) ? Number(data.page) : qnaPage; 822 const resolvedPageSize = Number.isFinite(Number(data.pageSize)) ? Number(data.pageSize) : NOTICE_PAGE_SIZE; 823 const resolvedTotalPages = Number.isFinite(Number(data.totalPages)) ? Number(data.totalPages) : resolvedItems.length >= resolvedPageSize ? resolvedPage + 1 : resolvedPage; 824 const resolvedTotalCount = Number.isFinite(Number(data.totalCount)) ? Number(data.totalCount) : (Math.max(1, resolvedPage) - 1) * resolvedPageSize + resolvedItems.length; 825 setQnas(resolvedItems); 826 setQnaPage(resolvedPage); 827 setQnaPageSize(resolvedPageSize); 828 setQnaTotalCount(resolvedTotalCount); 829 setQnaTotalPages(Math.max(1, resolvedTotalPages)); 830 } catch { 831 if (!controller.signal.aborted) { 832 setQnaError("\uF9DE\uB348\u0426\u6028??\uB4EC? ?\uBDBF\uAECC???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E."); 833 setQnas([]); 834 setQnaTotalCount(0); 835 setQnaTotalPages(1); 836 } 837 } finally { 838 if (!controller.signal.aborted) { 839 setIsLoadingQna(false); 840 } 841 } 842 }; 843 void fetchQnas(); 844 return () => controller.abort(); 845 }, [selectedMenu, qnaPage, qnaSearchFieldQuery, qnaSearchKeyword]); 846 (0, import_react.useEffect)(() => { 847 if (selectedMenu !== "data") return; 848 const controller = new AbortController(); 849 const fetchDataItems = async () => { 850 setIsLoadingData(true); 851 setDataError("");
852 try { 853 const response = await fetch( 854 `${getApiBaseUrl()}/props/list.asp?page=${dataPage}&pageSize=${NOTICE_PAGE_SIZE}&searchField=${encodeURIComponent(dataSearchFieldQuery)}&searchKeyword=${encodeURIComponent(dataSearchKeyword)}`, 855 { 856 method: "GET", 857 credentials: "include", 858 signal: controller.signal 859 } 860 ); 861 let data = null; 862 try { 863 data = await parseApiJson(response); 864 } catch { 865 setDataError( 866 `1:1 \u81FE\uBA84\uC4FD \u8ADB??\uC496\uBE1E ?\uBB10\uB59F ?\uB6AF\uB59B ?\u317D\uB663 (HTTP ${response.status})` 867 ); 868 setDataItems([]); 869 setDataTotalCount(0); 870 setDataTotalPages(1); 871 return; 872 } 873 if (!response.ok) { 874 setDataError( 875 `1:1 \u81FE\uBA84\uC4FD \u8ADB??\uC496\uBE1E ?\uBDBF\uAECC ?\u317D\uB663 (HTTP ${response.status})` 876 ); 877 setDataItems([]); 878 setDataTotalCount(0); 879 setDataTotalPages(1); 880 return; 881 } 882 if (!data.ok) { 883 setDataError("1:1 \u81FE\uBA84\uC4FD \u8ADB??\uC496\uBE1E??\u907A\uB348\uC72D?\u317C? \uF9CF\uC0B5\uBEFD?\uB4EC\uB572??"); 884 setDataItems([]); 885 setDataTotalCount(0); 886 setDataTotalPages(1); 887 return; 888 } 889 setDataItems(Array.isArray(data.items) ? data.items : []); 890 setDataPage( 891 Number.isFinite(Number(data.page)) ? Number(data.page) : dataPage 892 ); 893 setDataPageSize( 894 Number.isFinite(Number(data.pageSize)) ? Number(data.pageSize) : NOTICE_PAGE_SIZE 895 ); 896 setDataTotalCount( 897 Number.isFinite(Number(data.totalCount)) ? Number(data.totalCount) : 0 898 ); 899 setDataTotalPages( 900 Number.isFinite(Number(data.totalPages)) ? Number(data.totalPages) : 1 901 ); 902 } catch { 903 if (!controller.signal.aborted) { 904 setDataError("1:1 \u81FE\uBA84\uC4FD \u8ADB??\uC496\uBE1E ?\uBDBF\uAECC???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E."); 905 setDataItems([]); 906 setDataTotalCount(0); 907 setDataTotalPages(1); 908 } 909 } finally { 910 if (!controller.signal.aborted) { 911 setIsLoadingData(false); 912 } 913 } 914 }; 915 void fetchDataItems(); 916 return () => controller.abort(); 917 }, [selectedMenu, dataPage, dataSearchFieldQuery, dataSearchKeyword]); 918 (0, import_react.useEffect)(() => { 919 if (selectedMenu !== "video") return; 920 const controller = new AbortController(); 921 const fetchVideos = async () => { 922 setIsLoadingVideo(true); 923 setVideoError(""); 924 try { 925 const response = await fetch( 926 `${getApiBaseUrl()}/videos/list.asp?page=${videoPage}&pageSize=${NOTICE_PAGE_SIZE}&searchField=${encodeURIComponent(videoSearchFieldQuery)}&searchKeyword=${encodeURIComponent(videoSearchKeyword)}`, 927 { 928 method: "GET", 929 credentials: "include", 930 signal: controller.signal 931 } 932 ); 933 const data = await parseApiJson(response); 934 if (!response.ok || !data.ok) { 935 setVideoError("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC744 \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."); 936 setVideos([]); 937 setVideoTotalCount(0); 938 setVideoTotalPages(1); 939 return; 940 } 941 setVideos(Array.isArray(data.items) ? data.items : []); 942 setVideoPage( 943 Number.isFinite(Number(data.page)) ? Number(data.page) : videoPage 944 ); 945 setVideoPageSize( 946 Number.isFinite(Number(data.pageSize)) ? Number(data.pageSize) : NOTICE_PAGE_SIZE 947 ); 948 setVideoTotalCount( 949 Number.isFinite(Number(data.totalCount)) ? Number(data.totalCount) : 0 950 ); 951 setVideoTotalPages( 952 Number.isFinite(Number(data.totalPages)) ? Number(data.totalPages) : 1 953 ); 954 } catch { 955 if (!controller.signal.aborted) { 956 setVideoError("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0 \uC694\uCCAD\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4."); 957 setVideos([]); 958 setVideoTotalCount(0); 959 setVideoTotalPages(1); 960 } 961 } finally { 962 if (!controller.signal.aborted) { 963 setIsLoadingVideo(false); 964 } 965 } 966 }; 967 void fetchVideos(); 968 return () => controller.abort(); 969 }, [selectedMenu, videoPage, videoSearchFieldQuery, videoSearchKeyword]); 970 (0, import_react.useEffect)(() => { 971 if (selectedMenu !== "video") return; 972 if (!pendingVideoIdx) return; 973 const target = videos.find((item) => Number(item.idx) === pendingVideoIdx); 974 if (target) { 975 setVideoDetail(target); 976 setPendingVideoIdx(null); 977 pushDetailHistory(); 978 return; 979 }
980 let cancelled = false; 981 const fetchVideoDetailByIdx = async () => { 982 try { 983 const response = await fetch( 984 `${getApiBaseUrl()}/videos/view.asp?idx=${pendingVideoIdx}`, 985 { 986 method: "GET", 987 credentials: "include" 988 } 989 ); 990 const data = await parseApiJson( 991 response 992 ); 993 if (!response.ok || !data?.ok || !data.item || cancelled) return; 994 setVideoDetail(data.item); 995 pushDetailHistory(); 996 } catch { 997 } finally { 998 if (!cancelled) setPendingVideoIdx(null); 999 } 1000 }; 1001 void fetchVideoDetailByIdx(); 1002 return () => { 1003 cancelled = true; 1004 }; 1005 }, [selectedMenu, pendingVideoIdx, videos]); 1006 (0, import_react.useEffect)(() => { 1007 const saved = localStorage.getItem("wrjb_user"); 1008 if (saved) { 1009 setIsAuthenticated(true); 1010 try { 1011 const user = JSON.parse(saved); 1012 setAuthRole(String(user.role || "")); 1013 setSessionUserId(String(user.id || "")); 1014 setSessionWriterName(String(user.name || user.id || "")); 1015 setSessionWriterEmail(String(user.email || "")); 1016 } catch { 1017 setAuthRole(""); 1018 setSessionUserId(""); 1019 setSessionWriterName(""); 1020 setSessionWriterEmail(""); 1021 } 1022 } 1023 const syncSession = async () => { 1024 try { 1025 const response = await fetch(`${getApiBaseUrl()}/auth/session.asp`, { 1026 method: "GET", 1027 credentials: "include" 1028 }); 1029 const data = await parseApiJson(response); 1030 const authenticated = Boolean( 1031 response.ok && data.ok && data.authenticated 1032 ); 1033 setIsAuthenticated(authenticated); 1034 setAuthRole(authenticated ? String(data.user?.role || "") : ""); 1035 setSessionUserId(authenticated ? String(data.user?.id || "") : ""); 1036 if (authenticated) { 1037 setSessionWriterName(String(data.user?.name || data.user?.id || "")); 1038 setSessionWriterEmail(String(data.user?.email || "")); 1039 } else { 1040 setSessionUserId(""); 1041 setSessionWriterName(""); 1042 setSessionWriterEmail(""); 1043 } 1044 } catch { 1045 } 1046 }; 1047 void syncSession(); 1048 }, []); 1049 (0, import_react.useEffect)(() => { 1050 if (usePlainTextEditorFallback) return; 1051 if (BundledEditorComponent) return; 1052 const shouldLoadEditor = isNoticeWriteMode || isFaqWriteMode || isQnaWriteMode || isDataWriteMode || isVideoWriteMode; 1053 if (!shouldLoadEditor) return; 1054 let cancelled = false; 1055 setIsTinyEditorLoading(true); 1056 import("/assets/chunk-4WWDW3VQ.js").then((module) => { 1057 if (cancelled) return; 1058 setBundledEditorComponent(() => module.BundledTinyMceEditor); 1059 }).catch((err) => { 1060 if (cancelled) return; 1061 console.error("Bundled TinyMCE module load failed:", err); 1062 setUsePlainTextEditorFallback(true); 1063 window.alert( 1064 "\uC5D0\uB514\uD130\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD574 \uAE30\uBCF8 \uC785\uB825\uCC3D\uC73C\uB85C \uC804\uD658\uD569\uB2C8\uB2E4. \uB0B4\uC6A9\uC744 \uC785\uB825\uD558\uC2E0 \uD6C4 \uB4F1\uB85D\uD574 \uC8FC\uC138\uC694." 1065 ); 1066 }).finally(() => { 1067 if (!cancelled) { 1068 setIsTinyEditorLoading(false); 1069 } 1070 }); 1071 return () => { 1072 cancelled = true; 1073 }; 1074 }, [ 1075 BundledEditorComponent, 1076 usePlainTextEditorFallback, 1077 isNoticeWriteMode, 1078 isFaqWriteMode, 1079 isQnaWriteMode, 1080 isDataWriteMode, 1081 isVideoWriteMode 1082 ]); 1083 const submitNoticeSearch = () => { 1084 setNoticePage(1); 1085 setNoticeSearchFieldQuery(noticeSearchField); 1086 setNoticeSearchKeyword(noticeSearchInput.trim()); 1087 }; 1088 const submitFaqSearch = () => { 1089 setFaqPage(1); 1090 setFaqSearchFieldQuery(faqSearchField); 1091 setFaqSearchKeyword(faqSearchInput.trim()); 1092 }; 1093 const submitQnaSearch = () => { 1094 setQnaPage(1); 1095 setQnaSearchFieldQuery(qnaSearchField); 1096 setQnaSearchKeyword(qnaSearchInput.trim()); 1097 }; 1098 const submitDataSearch = () => { 1099 setDataPage(1); 1100 setDataSearchFieldQuery(dataSearchField); 1101 setDataSearchKeyword(dataSearchInput.trim()); 1102 }; 1103 const submitVideoSearch = () => { 1104 setVideoPage(1); 1105 setVideoSearchFieldQuery(videoSearchField); 1106 setVideoSearchKeyword(videoSearchInput.trim()); 1107 }; 1108 const selectedMenuLabel = (0, import_react.useMemo)( 1109 () => menuItems.find((item) => item.id === selectedMenu)?.label ?? "", 1110 [selectedMenu] 1111 ); 1112 const openNoticeDetail = async (notice) => { 1113 setIsNoticeWriteMode(false); 1114 pushDetailHistory(); 1115 setNoticeDetail(notice); 1116 try { 1117 const response = await fetch( 1118 `${getApiBaseUrl()}/notices/view.asp?idx=${notice.idx}`, 1119 { 1120 method: "GET", 1121 credentials: "include" 1122 } 1123 ); 1124 const data = await parseApiJson( 1125 response 1126 ); 1127 if (response.ok && data.ok && data.item) { 1128 setNoticeDetail(data.item); 1129 setNotices( 1130 (prev) => prev.map((item) => item.idx === data.item.idx ? data.item : item) 1131 ); 1132 } 1133 } catch { 1134 } 1135 }; 1136 const openFaqDetail = async (faq) => { 1137 pushDetailHistory(); 1138 setFaqDetail(faq); 1139 try { 1140 const response = await fetch( 1141 `${getApiBaseUrl()}/faqs/view.asp?idx=${faq.idx}`, 1142 { 1143 method: "GET", 1144 credentials: "include" 1145 } 1146 ); 1147 const data = await parseApiJson( 1148 response 1149 ); 1150 if (response.ok && data.ok && data.item) { 1151 setFaqDetail(data.item); 1152 setFaqs( 1153 (prev) => prev.map((item) => item.idx === data.item.idx ? data.item : item) 1154 ); 1155 } 1156 } catch { 1157 } 1158 }; 1159 const openQnaDetail = async (qna) => { 1160 setIsQnaWriteMode(false); 1161 pushDetailHistory(); 1162 setQnaDetail(qna); 1163 try { 1164 const response = await fetch( 1165 `${getApiBaseUrl()}/qnas/view.asp?idx=${qna.idx}`, 1166 { 1167 method: "GET", 1168 credentials: "include" 1169 } 1170 ); 1171 const data = await parseApiJson( 1172 response 1173 ); 1174 if (response.ok && data.ok && data.item) { 1175 setQnaDetail(data.item); 1176 } 1177 } catch { 1178 } 1179 }; 1180 const openQnaWrite = () => { 1181 if (!ensureSupportWriteLogin()) return; 1182 setUsePlainTextEditorFallback(false); 1183 setQnaDetail(null); 1184 setQnaWriteModeType("create"); 1185 setQnaWriteTargetIdx(null); 1186 setQnaWriteName(sessionWriterName); 1187 setQnaWriteEmail(sessionWriterEmail); 1188 setQnaWriteSubject("");
1189 setQnaWriteContent("<p><br /></p>"); 1190 setIsQnaWriteMode(true); 1191 }; 1192 const openQnaEdit = () => { 1193 if (!qnaDetail) return; 1194 if (!canEditBoard("qna", qnaDetail)) { 1195 window.alert("\uC791\uC131\uC790 \uBCF8\uC778\uB9CC \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1196 return; 1197 } 1198 setUsePlainTextEditorFallback(false); 1199 setQnaWriteModeType("edit"); 1200 setQnaWriteTargetIdx(qnaDetail.idx); 1201 setQnaWriteName(qnaDetail.name || ""); 1202 setQnaWriteEmail(qnaDetail.email || ""); 1203 setQnaWriteSubject(qnaDetail.subject || ""); 1204 setQnaWriteContent(qnaDetail.content || "<p><br /></p>"); 1205 setQnaDetail(null); 1206 setIsQnaWriteMode(true); 1207 }; 1208 const openQnaReply = () => { 1209 if (!qnaDetail) return; 1210 if (!isAdmin) { 1211 window.alert("\uB2F5\uBCC0\uC740 \uAD00\uB9AC\uC790\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1212 return; 1213 } 1214 setUsePlainTextEditorFallback(false); 1215 const sourceName = (qnaDetail.name || "\uC791\uC131\uC790").trim(); 1216 const sourceContent = String(qnaDetail.content || "").trim(); 1217 const baseSubject = String(qnaDetail.subject || "").trim(); 1218 setQnaWriteModeType("reply"); 1219 setQnaWriteTargetIdx(qnaDetail.idx); 1220 setQnaWriteName(sessionWriterName); 1221 setQnaWriteEmail(sessionWriterEmail); 1222 setQnaWriteSubject(`[\uB2F5\uBCC0] ${baseSubject || "\uC81C\uBAA9 \uC5C6\uC74C"}`); 1223 setQnaWriteContent( 1224 `<p><br /></p><p>[${sourceName}] \uB2D8\uAED8\uC11C \uC4F0\uC2E0 \uB0B4\uC6A9 \uC785\uB2C8\uB2E4.</p><p>--------------------------------------------------</p>${sourceContent}` 1225 ); 1226 setQnaDetail(null); 1227 setIsQnaWriteMode(true); 1228 }; 1229 const handleQnaDelete = async () => { 1230 if (!qnaDetail) return; 1231 if (!canDeleteBoard("qna", qnaDetail)) { 1232 window.alert("\uC791\uC131\uC790 \uBCF8\uC778\uB9CC \uC0AD\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1233 return; 1234 } 1235 if (!window.confirm("\uC815\uB9D0 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) return; 1236 try { 1237 const body = new URLSearchParams(); 1238 body.set("idx", String(qnaDetail.idx)); 1239 const response = await fetch(`${getApiBaseUrl()}/qnas/delete.asp`, { 1240 method: "POST", 1241 credentials: "include", 1242 headers: { 1243 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 1244 }, 1245 body: body.toString() 1246 }); 1247 const data = await parseApiJson(response); 1248 if (!response.ok || !data.ok) { 1249 window.alert(data.error || `\uC0AD\uC81C \uC2E4\uD328 (HTTP ${response.status})`); 1250 return; 1251 } 1252 const targetIdx = qnaDetail.idx; 1253 setQnaDetail(null); 1254 setQnas((prev) => prev.filter((item) => item.idx !== targetIdx)); 1255 setQnaTotalCount((prev) => Math.max(0, prev - 1)); 1256 window.alert("\uC0AD\uC81C\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1257 } catch { 1258 window.alert("\uC0AD\uC81C \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1259 } 1260 }; 1261 const handleQnaWriteSubmit = async () => { 1262 const subject = String(qnaWriteSubject || "").trim(); 1263 const content = String(qnaEditorRef.current?.getContent?.() || "").trim() || getActiveTinyContent() || String(qnaWriteContent || "").trim(); 1264 const name = String(qnaWriteName || "").trim(); 1265 const email = String(qnaWriteEmail || "").trim(); 1266 if (!subject) return void window.alert("\uC81C\uBAA9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1267 if (!content || content === "<p><br></p>" || content === "<p><br /></p>") 1268 return void window.alert("\uB0B4\uC6A9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1269 if (!name) return void window.alert("?\uBB12\uAF66?\uBA2E? ?\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1270 try { 1271 setIsQnaSubmitting(true); 1272 let endpoint = `${getApiBaseUrl()}/qnas/write.asp`; 1273 const queryFields = { subject, name, email }; 1274 if (qnaWriteModeType === "edit") { 1275 if (!qnaWriteTargetIdx) { 1276 if (!qnaWriteTargetIdx) 1277 return void window.alert("\uC218\uC815 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1278 }
1279 queryFields.idx = String(qnaWriteTargetIdx); 1280 } else if (qnaWriteModeType === "reply") { 1281 if (!qnaWriteTargetIdx) 1282 return void window.alert("\uB2F5\uBCC0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1283 endpoint = `${getApiBaseUrl()}/qnas/reply.asp`; 1284 queryFields.parentIdx = String(qnaWriteTargetIdx); 1285 } 1286 const { response, data } = await postBoardWithFallback( 1287 endpoint, 1288 queryFields, 1289 content 1290 ); 1291 if (!response.ok || !data.ok || !data.item) { 1292 window.alert(data.error || `?\uAE45\uC909 ?\u317D\uB663 (HTTP ${response.status})`); 1293 return; 1294 } 1295 setIsQnaWriteMode(false); 1296 setQnaWriteTargetIdx(null); 1297 setQnaWriteName(sessionWriterName); 1298 setQnaWriteEmail(sessionWriterEmail); 1299 setQnaDetail(data.item); 1300 setQnas( 1301 (prev) => mergeThreadedBoardItem( 1302 prev, 1303 data.item, 1304 qnaWriteModeType, 1305 qnaWriteTargetIdx 1306 ) 1307 ); 1308 if (qnaWriteModeType === "create" || qnaWriteModeType === "reply") { 1309 setQnaTotalCount((prev) => prev + 1); 1310 } 1311 window.alert("\uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1312 pushDetailHistory(); 1313 } catch { 1314 window.alert("\uB4F1\uB85D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1315 } finally { 1316 setIsQnaSubmitting(false); 1317 } 1318 }; 1319 const openDataDetail = async (item) => { 1320 setIsDataWriteMode(false); 1321 pushDetailHistory(); 1322 setDataDetail(item); 1323 try { 1324 const response = await fetch( 1325 `${getApiBaseUrl()}/props/hit.asp?idx=${item.idx}`, 1326 { 1327 method: "GET", 1328 credentials: "include" 1329 } 1330 ); 1331 const data = await parseApiJson(response); 1332 if (!response.ok || !data.ok || !data.updated) return; 1333 setDataItems( 1334 (prev) => prev.map( 1335 (row) => row.idx === item.idx ? { ...row, hit: (row.hit || 0) + 1 } : row 1336 ) 1337 ); 1338 setDataDetail( 1339 (prev) => prev && prev.idx === item.idx ? { ...prev, hit: (prev.hit || 0) + 1 } : prev 1340 ); 1341 } catch { 1342 } 1343 }; 1344 const openVideoDetail = async (item) => { 1345 pushDetailHistory(); 1346 setVideoDetail(item); 1347 try { 1348 const response = await fetch( 1349 `${getApiBaseUrl()}/videos/view.asp?idx=${item.idx}`, 1350 { 1351 method: "GET", 1352 credentials: "include" 1353 } 1354 ); 1355 const data = await parseApiJson( 1356 response 1357 ); 1358 if (response.ok && data.ok && data.item) { 1359 setVideoDetail(data.item); 1360 setVideos( 1361 (prev) => prev.map((row) => row.idx === data.item.idx ? data.item : row) 1362 ); 1363 } 1364 } catch { 1365 } 1366 }; 1367 const openVideoWrite = () => { 1368 if (!ensureSupportWriteLogin()) return; 1369 if (!isAdmin) { 1370 window.alert("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC740 \uAD00\uB9AC\uC790\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1371 return; 1372 } 1373 setUsePlainTextEditorFallback(false); 1374 setVideoDetail(null); 1375 setVideoWriteModeType("create"); 1376 setVideoWriteTargetIdx(null); 1377 setVideoWriteName(sessionWriterName); 1378 setVideoWriteEmail(sessionWriterEmail); 1379 setVideoWriteSubject(""); 1380 setVideoWriteContent("<p><br /></p>"); 1381 setIsVideoWriteMode(true); 1382 }; 1383 const openVideoEdit = () => { 1384 if (!videoDetail) return; 1385 if (!isAdmin) { 1386 window.alert("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC740 \uAD00\uB9AC\uC790\uB9CC \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1387 return; 1388 } 1389 setUsePlainTextEditorFallback(false); 1390 setVideoWriteModeType("edit"); 1391 setVideoWriteTargetIdx(videoDetail.idx); 1392 setVideoWriteName(videoDetail.name || ""); 1393 setVideoWriteEmail(videoDetail.email || ""); 1394 setVideoWriteSubject(videoDetail.subject || ""); 1395 setVideoWriteContent(videoDetail.content || "<p><br /></p>"); 1396 setVideoDetail(null); 1397 setIsVideoWriteMode(true); 1398 }; 1399 const handleVideoDelete = async () => { 1400 if (!videoDetail) return; 1401 if (!isAdmin) { 1402 window.alert("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC740 \uAD00\uB9AC\uC790\uB9CC \uC0AD\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1403 return; 1404 } 1405 if (!window.confirm("\uC815\uB9D0 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) return; 1406 try { 1407 const body = new URLSearchParams(); 1408 body.set("idx", String(videoDetail.idx)); 1409 const response = await fetch(`${getApiBaseUrl()}/videos/delete.asp`, { 1410 method: "POST", 1411 credentials: "include", 1412 headers: { 1413 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 1414 }, 1415 body: body.toString() 1416 }); 1417 const data = await parseApiJson(response); 1418 if (!response.ok || !data.ok) { 1419 window.alert(data.error || `\uC0AD\uC81C \uC2E4\uD328 (HTTP ${response.status})`); 1420 return; 1421 } 1422 const targetIdx = videoDetail.idx; 1423 setVideoDetail(null); 1424 setVideos((prev) => prev.filter((item) => item.idx !== targetIdx)); 1425 setVideoTotalCount((prev) => Math.max(0, prev - 1)); 1426 window.alert("\uC0AD\uC81C\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1427 } catch { 1428 window.alert("\uC0AD\uC81C \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1429 } 1430 }; 1431 const handleVideoWriteSubmit = async () => { 1432 const subject = String(videoWriteSubject || "").trim(); 1433 const content = String(videoEditorRef.current?.getContent?.() || "").trim() || getActiveTinyContent() || String(videoWriteContent || "").trim(); 1434 const normalizedContent = normalizeVideoHelpContent(content); 1435 const name = String(videoWriteName || "").trim(); 1436 const email = String(videoWriteEmail || "").trim(); 1437 if (!subject) return void window.alert("\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."); 1438 if (!content || content === "<p><br></p>" || content === "<p><br /></p>") 1439 return void window.alert("\uB0B4\uC6A9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."); 1440 if (!name) return void window.alert("\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694."); 1441 try { 1442 setIsVideoSubmitting(true); 1443 let endpoint = `${getApiBaseUrl()}/videos/write.asp`; 1444 const queryFields = { subject, name, email }; 1445 if (videoWriteModeType === "edit") { 1446 if (!videoWriteTargetIdx) { 1447 window.alert("\uC218\uC815 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1448 return; 1449 } 1450 endpoint = `${getApiBaseUrl()}/videos/update.asp`; 1451 queryFields.idx = String(videoWriteTargetIdx); 1452 } 1453 const { response, data } = await postBoardWithFallback( 1454 endpoint, 1455 queryFields, 1456 normalizedContent 1457 ); 1458 if (!response.ok || !data.ok || !data.item) { 1459 window.alert(data.error || `\uB4F1\uB85D \uC2E4\uD328 (HTTP ${response.status})`); 1460 return; 1461 } 1462 setIsVideoWriteMode(false); 1463 setVideoWriteModeType("create"); 1464 setVideoWriteTargetIdx(null); 1465 setVideoWriteName(sessionWriterName); 1466 setVideoWriteEmail(sessionWriterEmail); 1467 setVideoDetail(data.item); 1468 setVideos( 1469 (prev) => videoWriteModeType === "edit" ? prev.map( 1470 (item) => item.idx === data.item.idx ? data.item : item 1471 ) : [data.item, ...prev] 1472 ); 1473 if (videoWriteModeType === "create") { 1474 setVideoTotalCount((prev) => prev + 1); 1475 } 1476 window.alert( 1477 videoWriteModeType === "edit" ? "\uC218\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4." : "\uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4." 1478 ); 1479 pushDetailHistory(); 1480 } catch { 1481 window.alert("\uB4F1\uB85D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1482 } finally { 1483 setIsVideoSubmitting(false); 1484 } 1485 }; 1486 const openDataWrite = () => { 1487 if (!ensureSupportWriteLogin()) return; 1488 setUsePlainTextEditorFallback(false); 1489 setDataDetail(null); 1490 setDataWriteModeType("create"); 1491 setDataWriteTargetIdx(null); 1492 setDataWriteName(sessionWriterName); 1493 setDataWriteEmail(sessionWriterEmail); 1494 setDataWriteSubject(""); 1495 setDataWriteContent("<p><br /></p>"); 1496 setIsDataWriteMode(true); 1497 }; 1498 const openDataEdit = () => { 1499 if (!dataDetail) return; 1500 if (!canEditBoard("data", dataDetail)) { 1501 window.alert("\uC791\uC131\uC790 \uBCF8\uC778\uB9CC \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1502 return; 1503 } 1504 setUsePlainTextEditorFallback(false); 1505 setDataWriteModeType("edit"); 1506 setDataWriteTargetIdx(dataDetail.idx); 1507 setDataWriteName(dataDetail.name || ""); 1508 setDataWriteEmail(dataDetail.email || ""); 1509 setDataWriteSubject(dataDetail.subject || ""); 1510 setDataWriteContent(dataDetail.content || "<p><br /></p>"); 1511 setDataDetail(null); 1512 setIsDataWriteMode(true); 1513 }; 1514 const openDataReply = () => { 1515 if (!dataDetail) return; 1516 if (!isAdmin) { 1517 window.alert("\uB2F5\uBCC0\uC740 \uAD00\uB9AC\uC790\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1518 return; 1519 } 1520 setUsePlainTextEditorFallback(false); 1521 const sourceName = (dataDetail.name || "\uC791\uC131\uC790").trim(); 1522 const sourceContent = String(dataDetail.content || "").trim(); 1523 const baseSubject = String(dataDetail.subject || "").trim(); 1524 setDataWriteModeType("reply"); 1525 setDataWriteTargetIdx(dataDetail.idx); 1526 setDataWriteName(sessionWriterName); 1527 setDataWriteEmail(sessionWriterEmail); 1528 setDataWriteSubject(`[\uB2F5\uBCC0] ${baseSubject || "\uC81C\uBAA9 \uC5C6\uC74C"}`); 1529 setDataWriteContent( 1530 `<p><br /></p><p>[${sourceName}] \uB2D8\uAED8\uC11C \uC4F0\uC2E0 \uB0B4\uC6A9 \uC785\uB2C8\uB2E4.</p><p>--------------------------------------------------</p>${sourceContent}` 1531 ); 1532 setDataDetail(null); 1533 setIsDataWriteMode(true); 1534 }; 1535 const handleDataDelete = async () => { 1536 if (!dataDetail) return; 1537 if (!canDeleteBoard("data", dataDetail)) { 1538 window.alert("\uC791\uC131\uC790 \uBCF8\uC778\uB9CC \uC0AD\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1539 return; 1540 } 1541 if (!window.confirm("\uC815\uB9D0 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) return; 1542 try { 1543 const body = new URLSearchParams(); 1544 body.set("idx", String(dataDetail.idx)); 1545 const response = await fetch(`${getApiBaseUrl()}/props/delete.asp`, { 1546 method: "POST", 1547 credentials: "include", 1548 headers: { 1549 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 1550 }, 1551 body: body.toString() 1552 }); 1553 const data = await parseApiJson(response); 1554 if (!response.ok || !data.ok) { 1555 window.alert(data.error || `\uC0AD\uC81C \uC2E4\uD328 (HTTP ${response.status})`); 1556 return; 1557 } 1558 const targetIdx = dataDetail.idx; 1559 setDataDetail(null); 1560 setDataItems((prev) => prev.filter((item) => item.idx !== targetIdx)); 1561 setDataTotalCount((prev) => Math.max(0, prev - 1)); 1562 window.alert("\uC0AD\uC81C\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1563 } catch { 1564 window.alert("\uC0AD\uC81C \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1565 } 1566 }; 1567 const handleDataWriteSubmit = async () => { 1568 const subject = String(dataWriteSubject || "").trim(); 1569 const content = String(dataEditorRef.current?.getContent?.() || "").trim() || getActiveTinyContent() || String(dataWriteContent || "").trim(); 1570 const name = String(dataWriteName || "").trim(); 1571 const email = String(dataWriteEmail || "").trim(); 1572 if (!subject) return void window.alert("\uC81C\uBAA9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1573 if (!content || content === "<p><br></p>" || content === "<p><br /></p>") 1574 return void window.alert("\uB0B4\uC6A9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1575 if (!name) return void window.alert("?\uBB12\uAF66?\uBA2E? ?\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1576 try { 1577 setIsDataSubmitting(true); 1578 let endpoint = `${getApiBaseUrl()}/props/write.asp`; 1579 const queryFields = { subject, name, email }; 1580 if (dataWriteModeType === "edit") { 1581 if (!dataWriteTargetIdx) { 1582 if (!dataWriteTargetIdx) 1583 return void window.alert("\uC218\uC815 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1584 } 1585 queryFields.idx = String(dataWriteTargetIdx); 1586 } else if (dataWriteModeType === "reply") { 1587 if (!dataWriteTargetIdx) 1588 return void window.alert("\uB2F5\uBCC0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1589 endpoint = `${getApiBaseUrl()}/props/reply.asp`; 1590 queryFields.parentIdx = String(dataWriteTargetIdx); 1591 } 1592 const { response, data } = await postBoardWithFallback( 1593 endpoint, 1594 queryFields, 1595 content 1596 ); 1597 if (!response.ok || !data.ok || !data.item) { 1598 window.alert(data.error || `?\uAE45\uC909 ?\u317D\uB663 (HTTP ${response.status})`); 1599 return; 1600 } 1601 setIsDataWriteMode(false); 1602 setDataWriteTargetIdx(null); 1603 setDataWriteName(sessionWriterName); 1604 setDataWriteEmail(sessionWriterEmail); 1605 setDataDetail(data.item); 1606 setDataItems( 1607 (prev) => mergeThreadedBoardItem( 1608 prev, 1609 data.item, 1610 dataWriteModeType, 1611 dataWriteTargetIdx 1612 ) 1613 ); 1614 if (dataWriteModeType === "create" || dataWriteModeType === "reply") { 1615 setDataTotalCount((prev) => prev + 1); 1616 } 1617 window.alert("\uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1618 pushDetailHistory(); 1619 } catch { 1620 window.alert("\uB4F1\uB85D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1621 } finally { 1622 setIsDataSubmitting(false); 1623 } 1624 }; 1625 const renderNoticeContent = (content) => { 1626 const normalized = normalizeNoticeHtml(content || ""); 1627 if (/<[a-z][\s\S]*>/i.test(content)) { 1628 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 1629 "div", 1630 { 1631 className: "text-[15px] text-gray-700 leading-7", 1632 dangerouslySetInnerHTML: { __html: normalized } 1633 } 1634 ); 1635 } 1636 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-[15px] text-gray-700 leading-7 whitespace-pre-wrap", children: content }); 1637 }; 1638 const extractYouTubeVideoId = (content) => { 1639 const normalized = String(content || "").replace(/&/gi, "&").replace(/&/gi, "&").trim(); 1640 const legacyMatch = normalized.match(/youtube\(\s*["']([^"']+)["']/i); 1641 if (legacyMatch?.[1]) return legacyMatch[1]; 1642 const oembedMatch = normalized.match(/<oembed[^>]+url=["']([^"']+)["']/i); 1643 const target = oembedMatch?.[1] || normalized; 1644 const urlMatch = target.match( 1645 /(?:youtube\.com\/(?:watch\?[^"'<>\s]*v=|embed\/|v\/|shorts\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/i 1646 ); 1647 if (urlMatch?.[1]) return urlMatch[1]; 1648 const queryMatch = target.match(/[?&]v=([A-Za-z0-9_-]{11})/i); 1649 if (queryMatch?.[1]) return queryMatch[1]; 1650 if (/^[A-Za-z0-9_-]{11}$/.test(target)) return target; 1651 return ""; 1652 }; 1653 const normalizeVideoHelpContent = (content) => { 1654 const videoId = extractYouTubeVideoId(content); 1655 return videoId ? `youtube("${videoId}", 640, 385, "");` : content; 1656 }; 1657 const renderVideoContent = (content) => { 1658 const rawContent = String(content || ""); 1659 const youtubeMatch = rawContent.match( 1660 /youtube\(\s*["']([^"']+)["']\s*,\s*(\d+)\s*,\s*(\d+)/i 1661 ); 1662 const videoId = youtubeMatch?.[1] || extractYouTubeVideoId(rawContent); 1663 if (videoId) { 1664 const width = Math.max(320, Number(youtubeMatch?.[2]) || 640); 1665 const height = Math.max(180, Number(youtubeMatch?.[3]) || 385); 1666 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-full overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 1667 "iframe", 1668 { 1669 title: videoDetail?.subject || "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0", 1670 width, 1671 height, 1672 src: `https://www.youtube.com/embed/${videoId}?rel=0`, 1673 frameBorder: "0", 1674 allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", 1675 allowFullScreen: true 1676 } 1677 ) }); 1678 } 1679 return renderNoticeContent(content); 1680 }; 1681 const isAdmin = authRole === "admin"; 1682 const supportActionButtonClass = "support-board-action-button"; 1683 const promptLoginForWrite = () => { 1684 if (typeof window === "u
1684ndefined") return; 1685 window.alert("\uB85C\uADF8\uC778 \uD6C4 \uAE00\uC4F0\uAE30\uAC00 \uAC00\uB2A5\uD569\uB2C8\uB2E4."); 1686 window.location.href = getLoginHref(); 1687 }; 1688 const ensureSupportWriteLogin = () => { 1689 if (!isAuthenticated) { 1690 promptLoginForWrite(); 1691 return false; 1692 } 1693 return true; 1694 }; 1695 const mergeThreadedBoardItem = (items, item, mode, targetIdx) => { 1696 const exists = items.some((current) => current.idx === item.idx); 1697 if (exists) { 1698 return items.map( 1699 (current) => current.idx === item.idx ? item : current 1700 ); 1701 } 1702 if (mode !== "reply" || !targetIdx) { 1703 return [item, ...items]; 1704 } 1705 const parentIndex = items.findIndex((current) => current.idx === targetIdx); 1706 if (parentIndex < 0) { 1707 return [item, ...items]; 1708 } 1709 const threadIdxNum = item.idx_num ?? items[parentIndex].idx_num ?? items[parentIndex].idx; 1710 let insertIndex = parentIndex + 1; 1711 while (insertIndex < items.length && (items[insertIndex].idx_num ?? items[insertIndex].idx) === threadIdxNum) { 1712 insertIndex += 1; 1713 } 1714 return [...items.slice(0, insertIndex), item, ...items.slice(insertIndex)]; 1715 }; 1716 const currentUserId = String(sessionUserId || "").trim().toLowerCase(); 1717 const currentItemOwnerId = (item) => String(item?.userid || "").trim().toLowerCase(); 1718 const isCurrentUserOwner = (item) => currentUserId !== "" && currentItemOwnerId(item) === currentUserId; 1719 const canWriteBoard = (menuId) => { 1720 if (menuId === "notice" || menuId === "faq" || menuId === "video") 1721 return authRole === "admin"; 1722 if (menuId === "qna" || menuId === "data") return isAuthenticated; 1723 return false; 1724 }; 1725 const canEditBoard = (menuId, item) => { 1726 if (menuId === "notice" || menuId === "faq" || menuId === "video") 1727 return authRole === "admin"; 1728 if (menuId === "qna" || menuId === "data") { 1729 return authRole === "admin" || isCurrentUserOwner(item); 1730 } 1731 return false; 1732 }; 1733 const canDeleteBoard = (menuId, item) => { 1734 if (menuId === "video") return authRole === "admin"; 1735 return canEditBoard(menuId, item); 1736 }; 1737 const canReplyBoard = (menuId) => authRole === "admin" && (menuId === "notice" || menuId === "faq" || menuId === "qna" || menuId === "data"); 1738 const openNoticeWrite = () => { 1739 if (!ensureSupportWriteLogin()) return; 1740 if (!isAdmin) { 1741 window.alert("\uACF5\uC9C0\uC0AC\uD56D\uC740 \uAD00\uB9AC\uC790\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1742 return; 1743 } 1744 setUsePlainTextEditorFallback(false); 1745 setNoticeDetail(null); 1746 setNoticeWriteModeType("create"); 1747 setNoticeWriteTargetIdx(null); 1748 setNoticeWriteName(sessionWriterName); 1749 setNoticeWriteEmail(sessionWriterEmail); 1750 setNoticeWriteSubject(""); 1751 setNoticeWriteContent("<p><br /></p>"); 1752 setIsNoticeWriteMode(true); 1753 }; 1754 const openFaqWrite = () => { 1755 if (!ensureSupportWriteLogin()) return; 1756 if (!isAdmin) { 1757 window.alert("\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC740 \uAD00\uB9AC\uC790\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1758 return; 1759 } 1760 setUsePlainTextEditorFallback(false); 1761 setFaqDetail(null); 1762 setFaqWriteModeType("create"); 1763 setFaqWriteTargetIdx(null); 1764 setFaqWriteName(sessionWriterName); 1765 setFaqWriteEmail(sessionWriterEmail); 1766 setFaqWriteSubject(""); 1767 setFaqWriteContent("<p><br /></p>"); 1768 setIsFaqWriteMode(true); 1769 }; 1770 const openFaqEdit = () => { 1771 if (!faqDetail) return; 1772 if (!isAdmin) { 1773 window.alert("\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC740 \uAD00\uB9AC\uC790\uB9CC \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1774 return; 1775 } 1776 setUsePlainTextEditorFallback(false); 1777 setFaqWriteModeType("edit"); 1778 setFaqWriteTargetIdx(faqDetail.idx); 1779 setFaqWriteName(faqDetail.name || ""); 1780 setFaqWriteEmail(faqDetail.email || ""); 1781 setFaqWriteSubject(faqDetail.subject || ""); 1782 setFaqWriteContent(faqDetail.content || "<p><br /></p>"); 1783 setFaqDetail(null); 1784 setIsFaqWriteMode(true); 1785 }; 1786 const openFaqReply = () => { 1787 if (!faqDetail) return; 1788 if (!isAdmin) { 1789 window.alert("\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC740 \uAD00\uB9AC\uC790\uB9CC \uB2F5\uBCC0\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1790 return; 1791 } 1792 setUsePlainTextEditorFallback(false); 1793 const sourceName = (faqDetail.name || "\uC791\uC131\uC790").trim(); 1794 const sourceContent = String(faqDetail.content || "").trim(); 1795 const baseSubject = String(faqDetail.subject || "").trim(); 1796 setFaqWriteModeType("reply"); 1797 setFaqWriteTargetIdx(faqDetail.idx); 1798 setFaqWriteName(sessionWriterName); 1799 setFaqWriteEmail(sessionWriterEmail); 1800 setFaqWriteSubject(`[\uB2F5\uBCC0] ${baseSubject || "\uC81C\uBAA9 \uC5C6\uC74C"}`); 1801 setFaqWriteContent( 1802 `<p><br /></p><p>[${sourceName}] \uB2D8\uAED8\uC11C \uC4F0\uC2E0 \uB0B4\uC6A9 \uC785\uB2C8\uB2E4.</p><p>--------------------------------------------------</p>${sourceContent}` 1803 ); 1804 setFaqDetail(null); 1805 setIsFaqWriteMode(true); 1806 }; 1807 const handleFaqDelete = async () => { 1808 if (!faqDetail) return; 1809 if (!isAdmin) { 1810 window.alert("\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC740 \uAD00\uB9AC\uC790\uB9CC \uC0AD\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1811 return; 1812 } 1813 if (!window.confirm("\uC815\uB9D0 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) return; 1814 try { 1815 const body = new URLSearchParams(); 1816 body.set("idx", String(faqDetail.idx)); 1817 const response = await fetch(`${getApiBaseUrl()}/faqs/delete.asp`, { 1818 method: "POST", 1819 credentials: "include", 1820 headers: { 1821 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 1822 }, 1823 body: body.toString() 1824 }); 1825 const data = await parseApiJson(response); 1826 if (!response.ok || !data.ok) { 1827 window.alert(data.error || `\uC0AD\uC81C \uC2E4\uD328 (HTTP ${response.status})`); 1828 return; 1829 } 1830 const targetIdx = faqDetail.idx; 1831 setFaqDetail(null); 1832 setFaqs((prev) => prev.filter((item) => item.idx !== targetIdx)); 1833 setFaqTotalCount((prev) => Math.max(0, prev - 1)); 1834 window.alert("\uC0AD\uC81C\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1835 } catch { 1836 window.alert("\uC0AD\uC81C \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1837 } 1838 }; 1839 const handleFaqWriteSubmit = async () => { 1840 const subject = String(faqWriteSubject || "").trim(); 1841 const content = String(faqEditorRef.current?.getContent?.() || "").trim() || getActiveTinyContent() || String(faqWriteContent || "").trim(); 1842 const name = String(faqWriteName || "").trim(); 1843 const email = String(faqWriteEmail || "").trim(); 1844 if (!subject) return void window.alert("\uC81C\uBAA9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1845 if (!content || content === "<p><br></p>" || content === "<p><br /></p>") 1846 return void window.alert("\uB0B4\uC6A9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1847 if (!name) return void window.alert("?\uBB12\uAF66?\uBA2E? ?\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1848 try { 1849 setIsFaqSubmitting(true); 1850 let endpoint = `${getApiBaseUrl()}/faqs/write.asp`; 1851 const queryFields = { subject, name, email }; 1852 if (faqWriteModeType === "edit") { 1853 if (!faqWriteTargetIdx) { 1854 if (!faqWriteTargetIdx) 1855 return void window.alert("\uC218\uC815 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1856 } 1857 queryFields.idx = String(faqWriteTargetIdx); 1858 } else if (faqWriteModeType === "reply") { 1859 if (!faqWriteTargetIdx) 1860 return void window.alert("\uB2F5\uBCC0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1861 endpoint = `${getApiBaseUrl()}/faqs/reply.asp`; 1862 queryFields.parentIdx = String(faqWriteTargetIdx); 1863 } 1864 const { response, data } = await postBoardWithFallback( 1865 endpoint, 1866 queryFields, 1867 content 1868 ); 1869 if (!response.ok || !data.ok || !data.item) { 1870 window.alert(data.error || `?\uAE45\uC909 ?\u317D\uB663 (HTTP ${response.status})`); 1871 return; 1872 } 1873 setIsFaqWriteMode(false); 1874 setFaqWriteTargetIdx(null); 1875 setFaqWriteName(sessionWriterName); 1876 setFaqWriteEmail(sessionWriterEmail); 1877 setFaqDetail(data.item); 1878 setFaqs( 1879 (prev) => mergeThreadedBoardItem( 1880 prev, 1881 data.item, 1882 faqWriteModeType, 1883 faqWriteTargetIdx 1884 ) 1885 ); 1886 if (faqWriteModeType === "create" || faqWriteModeType === "reply") { 1887 setFaqTotalCount((prev) => prev + 1); 1888 } 1889 window.alert("\uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1890 pushDetailHistory(); 1891 } catch { 1892 window.alert("\uB4F1\uB85D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1893 } finally { 1894 setIsFaqSubmitting(false); 1895 } 1896 }; 1897 const openNoticeEdit = () => { 1898 if (!noticeDetail) return; 1899 if (!isAdmin) { 1900 window.alert("\uACF5\uC9C0\uC0AC\uD56D\uC740 \uAD00\uB9AC\uC790\uB9CC \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1901 return; 1902 } 1903 setUsePlainTextEditorFallback(false); 1904 setNoticeWriteModeType("edit"); 1905 setNoticeWriteTargetIdx(noticeDetail.idx); 1906 setNoticeWriteName(noticeDetail.name || ""); 1907 setNoticeWriteEmail(noticeDetail.email || ""); 1908 setNoticeWriteSubject(noticeDetail.subject || ""); 1909 setNoticeWriteContent(noticeDetail.content || "<p><br /></p>"); 1910 setNoticeDetail(null); 1911 setIsNoticeWriteMode(true); 1912 }; 1913 const openNoticeReply = () => { 1914 if (!noticeDetail) return; 1915 if (!isAdmin) { 1916 window.alert("\uACF5\uC9C0\uC0AC\uD56D\uC740 \uAD00\uB9AC\uC790\uB9CC \uB2F5\uBCC0\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1917 return; 1918 } 1919 setUsePlainTextEditorFallback(false); 1920 const sourceName = (noticeDetail.name || "\uC791\uC131\uC790").trim(); 1921 const sourceContent = String(noticeDetail.content || "").trim(); 1922 const replyPrefix = "[\uB2F5\uBCC0] "; 1923 const baseSubject = String(noticeDetail.subject || "").trim();
1924 const replySubject = `${replyPrefix}${baseSubject || "\uC81C\uBAA9 \uC5C6\uC74C"}`; 1925 const replyBody = `<p><br /></p><p>[${sourceName}] \uB2D8\uAED8\uC11C \uC4F0\uC2E0 \uB0B4\uC6A9 \uC785\uB2C8\uB2E4.</p><p>--------------------------------------------------</p>${sourceContent}`; 1926 setNoticeWriteModeType("reply"); 1927 setNoticeWriteTargetIdx(noticeDetail.idx); 1928 setNoticeWriteName(sessionWriterName); 1929 setNoticeWriteEmail(sessionWriterEmail); 1930 setNoticeWriteSubject(replySubject); 1931 setNoticeWriteContent(replyBody); 1932 setNoticeDetail(null); 1933 setIsNoticeWriteMode(true); 1934 }; 1935 const handleNoticeDelete = async () => { 1936 if (!noticeDetail) return; 1937 if (!isAdmin) { 1938 window.alert("\uACF5\uC9C0\uC0AC\uD56D\uC740 \uAD00\uB9AC\uC790\uB9CC \uC0AD\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."); 1939 return; 1940 } 1941 if (!window.confirm("\uC815\uB9D0 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) return; 1942 try { 1943 const body = new URLSearchParams(); 1944 body.set("idx", String(noticeDetail.idx)); 1945 const response = await fetch(`${getApiBaseUrl()}/notices/delete.asp`, { 1946 method: "POST", 1947 credentials: "include", 1948 headers: { 1949 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 1950 }, 1951 body: body.toString() 1952 }); 1953 const data = await parseApiJson(response); 1954 if (!response.ok || !data.ok) { 1955 window.alert(data.error || `\uC0AD\uC81C \uC2E4\uD328 (HTTP ${response.status})`); 1956 return; 1957 } 1958 const targetIdx = noticeDetail.idx; 1959 setNoticeDetail(null); 1960 setNotices((prev) => prev.filter((item) => item.idx !== targetIdx)); 1961 setNoticeTotalCount((prev) => Math.max(0, prev - 1)); 1962 window.alert("\uC0AD\uC81C\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 1963 } catch { 1964 window.alert("\uC0AD\uC81C \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 1965 } 1966 }; 1967 const handleNoticeWriteSubmit = async () => { 1968 const subject = String(noticeWriteSubject || "").trim(); 1969 const content = String(noticeEditorRef.current?.getContent?.() || "").trim() || getActiveTinyContent() || String(noticeWriteContent || "").trim(); 1970 const name = String(noticeWriteName || "").trim(); 1971 const email = String(noticeWriteEmail || "").trim(); 1972 if (!subject) { 1973 window.alert("\uC81C\uBAA9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1974 return; 1975 } 1976 if (!content || content === "<p><br></p>" || content === "<p><br /></p>") { 1977 window.alert("\uB0B4\uC6A9???\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1978 return; 1979 } 1980 if (!name) { 1981 window.alert("?\uBB12\uAF66?\uBA2E? ?\uB085\uC830?\uB301\uFF1C?\uBA84\uC282."); 1982 return; 1983 } 1984 try { 1985 setIsNoticeSubmitting(true); 1986 let endpoint = `${getApiBaseUrl()}/notices/write.asp`; 1987 const queryFields = { subject, name, email }; 1988 if (noticeWriteModeType === "edit") { 1989 if (!noticeWriteTargetIdx) { 1990 window.alert("\uC218\uC815 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1991 return; 1992 } 1993 endpoint = `${getApiBaseUrl()}/notices/update.asp`; 1994 queryFields.idx = String(noticeWriteTargetIdx); 1995 } else if (noticeWriteModeType === "reply") { 1996 if (!noticeWriteTargetIdx) { 1997 window.alert("\uB2F5\uBCC0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."); 1998 return; 1999 } 2000 endpoint = `${getApiBaseUrl()}/notices/reply.asp`; 2001 queryFields.parentIdx = String(noticeWriteTargetIdx); 2002 } 2003 const { response, data } = await postBoardWithFallback( 2004 endpoint, 2005 queryFields, 2006 content 2007 ); 2008 if (!response.ok || !data.ok || !data.item) { 2009 window.alert(data.error || `?\uAE45\uC909 ?\u317D\uB663 (HTTP ${response.status})`); 2010 return; 2011 } 2012 setIsNoticeWriteMode(false); 2013 setNoticeWriteTargetIdx(null); 2014 setNoticeWriteName(sessionWriterName); 2015 setNoticeWriteEmail(sessionWriterEmail); 2016 setNoticeDetail(data.item); 2017 setNotices( 2018 (prev) => mergeThreadedBoardItem( 2019 prev, 2020 data.item, 2021 noticeWriteModeType, 2022 noticeWriteTargetIdx 2023 ) 2024 ); 2025 if (noticeWriteModeType === "create" || noticeWriteModeType === "reply") { 2026 setNoticeTotalCount((prev) => prev + 1); 2027 } 2028 window.alert("\uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."); 2029 pushDetailHistory(); 2030 } catch { 2031 window.alert("\uB4F1\uB85D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."); 2032 } finally { 2033 setIsNoticeSubmitting(false); 2034 } 2035 }; 2036 const readImageAsDataUrl = (file) => new Promise((resolve, reject) => { 2037 const reader = new FileReader(); 2038 reader.onload = () => { 2039 const result = typeof reader.result === "string" ? reader.result : ""; 2040 result ? resolve(result) : reject(new Error("?\uB300?\uF9DE\x80 \u6FE1\uC495\uBC76???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E.")); 2041 }; 2042 reader.onerror = () => reject(new Error("?\uB300?\uF9DE\x80 \u6FE1\uC495\uBC76???\u317D\uB663?\uB349\uB4BF?\uB348\uB58E."));
2043 reader.readAsDataURL(file); 2044 }); 2045 const compressImageAsDataUrl = async (file) => { 2046 const original = await readImageAsDataUrl(file); 2047 if (!file.type.startsWith("image/") || file.type === "image/svg+xml") 2048 return original; 2049 if (original.length <= 8e4) return original; 2050 return new Promise((resolve) => { 2051 const image = new Image(); 2052 image.onload = () => { 2053 const maxWidth = 900; 2054 const scale = Math.min(1, maxWidth / Math.max(image.width, 1)); 2055 const width = Math.max(1, Math.round(image.width * scale)); 2056 const height = Math.max(1, Math.round(image.height * scale)); 2057 const canvas = document.createElement("canvas"); 2058 canvas.width = width; 2059 canvas.height = height; 2060 const ctx = canvas.getContext("2d"); 2061 if (!ctx) { 2062 resolve(original); 2063 return; 2064 } 2065 ctx.fillStyle = "#fff"; 2066 ctx.fillRect(0, 0, width, height); 2067 ctx.drawImage(image, 0, 0, width, height); 2068 let result = canvas.toDataURL("image/jpeg", 0.72); 2069 for (const quality of [0.62, 0.52, 0.42, 0.34]) { 2070 if (result.length <= 8e4) break; 2071 result = canvas.toDataURL("image/jpeg", quality); 2072 } 2073 resolve(result.length < original.length ? result : original); 2074 }; 2075 image.onerror = () => resolve(original); 2076 image.src = original; 2077 }); 2078 }; 2079 const renderTinyEditor = ({ 2080 value, 2081 onChange, 2082 editorRef 2083 }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "notice-tinymce-wrap rounded-md border border-gray-300 overflow-hidden bg-white", children: usePlainTextEditorFallback ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2084 "textarea", 2085 { 2086 value: convertHtmlToEditorFallbackText(value), 2087 onChange: (e) => onChange(convertEditorFallbackTextToHtml(e.target.value)), 2088 className: "min-h-[360px] w-full resize-y border-0 px-4 py-3 text-[15px] leading-7 text-gray-700 outline-none", 2089 placeholder: "\uB0B4\uC6A9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694." 2090 } 2091 ) : isTinyEditorLoading || !BundledEditorComponent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "min-h-[220px] flex items-center justify-center text-sm text-gray-500", children: "\uC5D0\uB514\uD130\uB97C \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4..." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2092 BundledEditorComponent, 2093 { 2094 value, 2095 onChange, 2096 editorRef, 2097 compressImageAsDataUrl 2098 } 2099 ) }); 2100 const renderDetailActions = (label) => { 2101 const menuId = label === "\uACF5\uC9C0\uC0AC\uD56D" ? "notice" : label === "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38" ? "faq" : label === "\uC9C8\uBB38\uACFC \uB2F5\uBCC0" ? "qna" : label === "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548" ? "data" : label === "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0" ? "video" : null;
2102 const currentDetail = menuId === "notice" ? noticeDetail : menuId === "faq" ? faqDetail : menuId === "qna" ? qnaDetail : menuId === "data" ? dataDetail : menuId === "video" ? videoDetail : null; 2103 return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 2104 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2105 "button", 2106 { 2107 type: "button", 2108 className: supportActionButtonClass, 2109 onClick: closeDetailWithBack, 2110 children: "\uBAA9\uB85D" 2111 } 2112 ), 2113 menuId && canWriteBoard(menuId) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2114 "button", 2115 { 2116 type: "button", 2117 className: supportActionButtonClass, 2118 onClick: () => { 2119 if (menuId === "notice") { 2120 openNoticeWrite(); 2121 return; 2122 } 2123 if (menuId === "faq") { 2124 openFaqWrite(); 2125 return; 2126 } 2127 if (menuId === "qna") { 2128 openQnaWrite(); 2129 return; 2130 } 2131 if (menuId === "data") { 2132 openDataWrite(); 2133 return; 2134 } 2135 if (menuId === "video") { 2136 openVideoWrite(); 2137 } 2138 }, 2139 children: "\uAE00\uC4F0\uAE30" 2140 } 2141 ) : null, 2142 menuId && canEditBoard(menuId, currentDetail) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2143 "button", 2144 { 2145 type: "button", 2146 className: supportActionButtonClass, 2147 onClick: () => { 2148 if (menuId === "notice") { 2149 openNoticeEdit(); 2150 return; 2151 } 2152 if (menuId === "faq") { 2153 openFaqEdit(); 2154 return; 2155 } 2156 if (menuId === "qna") { 2157 openQnaEdit(); 2158 return; 2159 } 2160 if (menuId === "data") { 2161 openDataEdit(); 2162 return; 2163 } 2164 if (menuId === "video") { 2165 openVideoEdit(); 2166 } 2167 }, 2168 children: "\uC218\uC815" 2169 } 2170 ) : null, 2171 menuId && canDeleteBoard(menuId, currentDetail) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2172 "button", 2173 { 2174 type: "button", 2175 className: supportActionButtonClass, 2176 onClick: () => { 2177 if (menuId === "notice") { 2178 void handleNoticeDelete(); 2179 return; 2180 } 2181 if (menuId === "faq") { 2182 void handleFaqDelete(); 2183 return; 2184 } 2185 if (menuId === "qna") { 2186 void handleQnaDelete(); 2187 return; 2188 } 2189 if (menuId === "data") { 2190 void handleDataDelete(); 2191 return; 2192 } 2193 if (menuId === "video") { 2194 void handleVideoDelete(); 2195 } 2196 }, 2197 children: "\uC0AD\uC81C" 2198 } 2199 ) : null, 2200 menuId && canReplyBoard(menuId) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2201 "button", 2202 { 2203 type: "button", 2204 className: supportActionButtonClass, 2205 onClick: () => { 2206 if (menuId === "notice") { 2207 openNoticeReply(); 2208 return; 2209 } 2210 if (menuId === "faq") { 2211 openFaqReply(); 2212 return; 2213 } 2214 if (menuId === "qna") { 2215 openQnaReply(); 2216 return; 2217 } 2218 if (menuId === "data") { 2219 openDataReply(); 2220 } 2221 }, 2222 children: "\uB2F5\uBCC0" 2223 } 2224 ) : null 2225 ] }); 2226 }; 2227 const renderNoticeBoard = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [ 2228 !noticeDetail && !isNoticeWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-wrap flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-center", children: [
2229 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 2230 "select", 2231 { 2232 value: noticeSearchField, 2233 onChange: (e) => setNoticeSearchField(e.target.value), 2234 className: "board-search-select bg-white", 2235 children: [ 2236 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\uC804\uCCB4" }), 2237 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "subject", children: "\uC81C\uBAA9" }), 2238 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "\uB0B4\uC6A9" }), 2239 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "name", children: "\uC791\uC131\uC790" }) 2240 ] 2241 } 2242 ), 2243 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-row flex items-center gap-4 w-auto", children: [ 2244 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2245 "input", 2246 { 2247 type: "text", 2248 value: noticeSearchInput, 2249 onChange: (e) => setNoticeSearchInput(e.target.value), 2250 onKeyDown: (e) => { 2251 if (e.key === "Enter") submitNoticeSearch(); 2252 }, 2253 placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2254 className: "board-search-input flex-1 sm:w-[260px] bg-white" 2255 } 2256 ),
2257 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2258 "button", 2259 { 2260 type: "button", 2261 onClick: submitNoticeSearch, 2262 className: "board-search-button", 2263 children: "\uAC80\uC0C9" 2264 } 2265 ) 2266 ] }) 2267 ] }) : null, 2268 noticeDetail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2269 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2270 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2271 "h3", 2272 { 2273 className: "m-0 text-[20px] font-bold text-[#101828]", 2274 style: { marginBottom: "12px" }, 2275 children: renderBoardSubjectWithReplyMarker(noticeDetail) 2276 } 2277 ), 2278 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-2 text-[14px] text-gray-600", children: [ 2279 "\uC791\uC131\uC790 ", 2280 noticeDetail.name || "-", 2281 " | \uB4F1\uB85D\uC77C", 2282 " ", 2283 formatDate(noticeDetail.insdate), 2284 " | \uC870\uD68C", 2285 noticeDetail.hit 2286 ] }) 2287 ] }),
2288 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 py-6 min-h-[260px]", children: renderNoticeContent(noticeDetail.content || "") }), 2289 renderDetailActions("\uACF5\uC9C0\uC0AC\uD56D") 2290 ] }) : null, 2291 isNoticeWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2292 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2293 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2294 "h3", 2295 { 2296 className: "m-0 text-[20px] font-bold text-[#101828]", 2297 style: { marginBottom: "36px" }, 2298 children: noticeWriteModeType === "edit" ? "\uACF5\uC9C0\uC0AC\uD56D \uAE00 \uC218\uC815" : noticeWriteModeType === "reply" ? "\uACF5\uC9C0\uC0AC\uD56D \uB2F5\uBCC0" : "\uACF5\uC9C0\uC0AC\uD56D \uAE00\uC4F0\uAE30" 2299 } 2300 ), 2301 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
2302 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ 2303 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2304 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC791\uC131\uC790" }), 2305 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2306 "input", 2307 { 2308 type: "text", 2309 value: noticeWriteName, 2310 onChange: (e) => setNoticeWriteName(e.target.value), 2311 placeholder: "\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2312 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2313 } 2314 ) 2315 ] }), 2316 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2317 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC774\uBA54\uC77C" }),
2318 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2319 "input", 2320 { 2321 type: "text", 2322 value: noticeWriteEmail, 2323 onChange: (e) => setNoticeWriteEmail(e.target.value), 2324 placeholder: "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2325 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2326 } 2327 ) 2328 ] }) 2329 ] }), 2330 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2331 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC81C\uBAA9" }), 2332 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2333 "input", 2334 { 2335 type: "text", 2336 value: noticeWriteSubject, 2337 onChange: (e) => setNoticeWriteSubject(e.target.value), 2338 placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2339 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2340 } 2341 ) 2342 ] }),
2343 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2344 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uB0B4\uC6A9" }), 2345 renderTinyEditor({ 2346 value: noticeWriteContent, 2347 onChange: setNoticeWriteContent, 2348 editorRef: noticeEditorRef 2349 }) 2350 ] }) 2351 ] }) 2352 ] }), 2353 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 2354 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2355 "button", 2356 { 2357 type: "button", 2358 className: supportActionButtonClass, 2359 disabled: isNoticeSubmitting, 2360 onClick: () => { 2361 setIsNoticeWriteMode(false); 2362 setNoticeWriteTargetIdx(null); 2363 setNoticeWriteName(sessionWriterName); 2364 setNoticeWriteEmail(sessionWriterEmail); 2365 }, 2366 children: "\uBAA9\uB85D" 2367 } 2368 ),
2369 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2370 "button", 2371 { 2372 type: "button", 2373 className: supportActionButtonClass, 2374 disabled: isNoticeSubmitting, 2375 onClick: () => { 2376 void handleNoticeWriteSubmit(); 2377 }, 2378 children: isNoticeSubmitting ? noticeWriteModeType === "edit" ? "\uC218\uC815 \uC911..." : noticeWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D \uC911..." : "\uB4F1\uB85D \uC911..." : noticeWriteModeType === "edit" ? "\uC218\uC815" : noticeWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D" : "\uB4F1\uB85D" 2379 } 2380 ) 2381 ] }) 2382 ] }) : null, 2383 !noticeDetail && !isNoticeWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-outer rounded-2xl overflow-hidden p-0 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-inner overflow-x-auto rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "board-table w-full min-w-[1080px] table-fixed border-separate border-spacing-0 [&_th]:!px-5 [&_td]:!px-5 [&_td]:py-5 [&_th]:text-[16px] [&_td]:text-[15px] [&_th]:font-semibold [&_td]:font-normal [&_th]:text-[#101828] [&_td]:text-[#364153]", children: [
2384 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("colgroup", { children: [ 2385 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-number w-[88px]" }), 2386 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-subject w-[180px]" }), 2387 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-author w-[240px]" }), 2388 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-date w-[240px]" }), 2389 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-hit w-[170px]" }) 2390 ] }), 2391 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b-2 border-[#E5E7EB] text-[#101828]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "font-semibold text-[16px]", children: [ 2392 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uBC88\uD638" }), 2393 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC81C\uBAA9" }),
2394 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 2395 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 2396 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center", children: "\uC870\uD68C" }) 2397 ] }) }), 2398 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "bg-white", children: isLoadingNotice ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2399 "td", 2400 { 2401 colSpan: 5, 2402 className: "px-4 py-10 text-center text-gray-500", 2403 children: "\uACF5\uC9C0\uC0AC\uD56D\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4." 2404 } 2405 ) }) : noticeError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2406 "td", 2407 { 2408 colSpan: 5, 2409 className: "px-4 py-10 text-center text-red-500", 2410 children: noticeError 2411 } 2412 ) }) : notices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2413 "td", 2414 { 2415 colSpan: 5, 2416 className: "px-4 py-10 text-center text-gray-500", 2417 children: "\uACF5\uC9C0\uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." 2418 } 2419 ) }) : notices.map((notice, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 2420 "tr", 2421 { 2422 className: "[&>td]:border-b [&>td]:border-gray-300 hover:bg-sky-50 transition-colors cursor-pointer", 2423 onClick: () => void openNoticeDetail(notice), 2424 children: [
2425 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-number", children: noticeTotalCount > 0 ? Math.max( 2426 noticeTotalCount - (noticePage - 1) * noticePageSize - index, 2427 1 2428 ) : notice.idx }), 2429 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "board-col-subject", children: [ 2430 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "board-subject-ellipsis m-0", children: renderBoardSubjectWithReplyMarker(notice) }), 2431 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-row-meta", children: [ 2432 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 2433 "\uC791\uC131\uC790: ", 2434 notice.name || "-" 2435 ] }), 2436 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 2437 "\uB4F1\uB85D\uC77C: ", 2438 formatDate(notice.insdate) 2439 ] }) 2440 ] }) 2441 ] }),
2442 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-author", children: notice.name || "-" }), 2443 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-date", children: formatDate(notice.insdate) }), 2444 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-hit", children: Number.isFinite(Number(notice.hit)) ? Number(notice.hit) : 0 }) 2445 ] 2446 }, 2447 notice.idx 2448 )) }) 2449 ] }) }) }) : null, 2450 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [ 2451 !noticeDetail && !isNoticeWriteMode && noticeTotalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-pagination mb-3 flex items-center justify-center gap-3 text-[16px]", children: [ 2452 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2453 "button", 2454 { 2455 type: "button", 2456 className: "board-page-button", 2457 disabled: noticePage <= 1, 2458 onClick: () => setNoticePage(1), 2459 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsLeft, { size: 16, strokeWidth: 2 }) 2460 } 2461 ),
2462 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2463 "button", 2464 { 2465 type: "button", 2466 className: "board-page-button", 2467 disabled: noticePage <= 1, 2468 onClick: () => setNoticePage((prev) => Math.max(prev - 1, 1)), 2469 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { size: 16, strokeWidth: 2 }) 2470 } 2471 ), 2472 getPaginationPages( 2473 noticeTotalPages, 2474 noticePage, 2475 isCompactPagination 2476 ).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2477 "button", 2478 { 2479 type: "button", 2480 className: `board-page-button ${p === noticePage ? "is-active" : ""}`, 2481 onClick: () => setNoticePage(p), 2482 children: p 2483 }, 2484 p 2485 )), 2486 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2487 "button", 2488 { 2489 type: "button", 2490 className: "board-page-button", 2491 disabled: noticePage >= noticeTotalPages, 2492 onClick: () => setNoticePage((prev) => Math.min(prev + 1, noticeTotalPages)), 2493 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { size: 16, strokeWidth: 2 }) 2494 } 2495 ),
2496 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2497 "button", 2498 { 2499 type: "button", 2500 className: "board-page-button", 2501 disabled: noticePage >= noticeTotalPages, 2502 onClick: () => setNoticePage(noticeTotalPages), 2503 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsRight, { size: 16, strokeWidth: 2 }) 2504 } 2505 ) 2506 ] }) : null, 2507 !noticeDetail && !isNoticeWriteMode && canWriteBoard("notice") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2508 "button", 2509 { 2510 type: "button", 2511 className: "support-board-action-button", 2512 onClick: openNoticeWrite, 2513 children: "\uAE00\uC4F0\uAE30" 2514 } 2515 ) : null 2516 ] }) 2517 ] }); 2518 const renderFaqBoard = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [ 2519 !faqDetail && !isFaqWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-wrap flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-center", children: [
2520 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 2521 "select", 2522 { 2523 value: faqSearchField, 2524 onChange: (e) => setFaqSearchField(e.target.value), 2525 className: "board-search-select bg-white", 2526 children: [ 2527 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\uC804\uCCB4" }), 2528 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "subject", children: "\uC81C\uBAA9" }), 2529 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "\uB0B4\uC6A9" }), 2530 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "name", children: "\uC791\uC131\uC790" }) 2531 ] 2532 } 2533 ), 2534 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-row flex items-center gap-4 w-auto", children: [ 2535 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2536 "input", 2537 { 2538 type: "text", 2539 value: faqSearchInput, 2540 onChange: (e) => setFaqSearchInput(e.target.value), 2541 onKeyDown: (e) => { 2542 if (e.key === "Enter") submitFaqSearch(); 2543 }, 2544 placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2545 className: "board-search-input flex-1 sm:w-[260px] bg-white" 2546 } 2547 ),
2548 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2549 "button", 2550 { 2551 type: "button", 2552 onClick: submitFaqSearch, 2553 className: "board-search-button", 2554 children: "\uAC80\uC0C9" 2555 } 2556 ) 2557 ] }) 2558 ] }) : null, 2559 faqDetail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2560 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2561 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2562 "h3", 2563 { 2564 className: "m-0 text-[20px] font-bold text-[#101828]", 2565 style: { marginBottom: "12px" }, 2566 children: renderBoardSubjectWithReplyMarker(faqDetail) 2567 } 2568 ), 2569 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-2 text-[14px] text-gray-600", children: [ 2570 "\uC791\uC131\uC790 ", 2571 faqDetail.name || "-", 2572 " | \uB4F1\uB85D\uC77C", 2573 " ", 2574 formatDate(faqDetail.insdate), 2575 " | \uC870\uD68C", 2576 faqDetail.hit 2577 ] }) 2578 ] }),
2579 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 py-6 min-h-[260px]", children: renderNoticeContent(faqDetail.content || "") }), 2580 renderDetailActions("\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38") 2581 ] }) : null, 2582 isFaqWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2583 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2584 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2585 "h3", 2586 { 2587 className: "m-0 text-[20px] font-bold text-[#101828]", 2588 style: { marginBottom: "36px" }, 2589 children: faqWriteModeType === "edit" ? "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38 \uAE00 \uC218\uC815" : faqWriteModeType === "reply" ? "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38 \uB2F5\uBCC0" : "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38 \uAE00\uC4F0\uAE30" 2590 } 2591 ), 2592 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
2593 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ 2594 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2595 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC791\uC131\uC790" }), 2596 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2597 "input", 2598 { 2599 type: "text", 2600 value: faqWriteName, 2601 onChange: (e) => setFaqWriteName(e.target.value), 2602 placeholder: "\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2603 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2604 } 2605 ) 2606 ] }), 2607 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2608 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC774\uBA54\uC77C" }),
2609 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2610 "input", 2611 { 2612 type: "text", 2613 value: faqWriteEmail, 2614 onChange: (e) => setFaqWriteEmail(e.target.value), 2615 placeholder: "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2616 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2617 } 2618 ) 2619 ] }) 2620 ] }), 2621 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2622 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC81C\uBAA9" }), 2623 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2624 "input", 2625 { 2626 type: "text", 2627 value: faqWriteSubject, 2628 onChange: (e) => setFaqWriteSubject(e.target.value), 2629 placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2630 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2631 } 2632 ) 2633 ] }),
2634 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2635 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uB0B4\uC6A9" }), 2636 renderTinyEditor({ 2637 value: faqWriteContent, 2638 onChange: setFaqWriteContent, 2639 editorRef: faqEditorRef 2640 }) 2641 ] }) 2642 ] }) 2643 ] }), 2644 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 2645 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2646 "button", 2647 { 2648 type: "button", 2649 className: supportActionButtonClass, 2650 disabled: isFaqSubmitting, 2651 onClick: () => { 2652 setIsFaqWriteMode(false); 2653 setFaqWriteTargetIdx(null); 2654 setFaqWriteName(""); 2655 setFaqWriteEmail(""); 2656 }, 2657 children: "\uBAA9\uB85D" 2658 } 2659 ),
2660 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2661 "button", 2662 { 2663 type: "button", 2664 className: supportActionButtonClass, 2665 disabled: isFaqSubmitting, 2666 onClick: () => { 2667 void handleFaqWriteSubmit(); 2668 }, 2669 children: isFaqSubmitting ? faqWriteModeType === "edit" ? "\uC800\uC7A5 \uC911..." : faqWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D \uC911..." : "\uB4F1\uB85D \uC911..." : faqWriteModeType === "edit" ? "\uC800\uC7A5" : faqWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D" : "\uB4F1\uB85D" 2670 } 2671 ) 2672 ] }) 2673 ] }) : null, 2674 !faqDetail && !isFaqWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-outer rounded-2xl overflow-hidden p-0 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-inner overflow-x-auto rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "board-table w-full min-w-[1080px] table-fixed border-separate border-spacing-0 [&_th]:!px-5 [&_td]:!px-5 [&_td]:py-5 [&_th]:text-[16px] [&_td]:text-[15px] [&_th]:font-semibold [&_td]:font-normal [&_th]:text-[#101828] [&_td]:text-[#364153]", children: [
2675 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("colgroup", { children: [ 2676 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-number w-[88px]" }), 2677 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-subject w-[180px]" }), 2678 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-author w-[240px]" }), 2679 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-date w-[240px]" }), 2680 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-hit w-[170px]" }) 2681 ] }), 2682 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b-2 border-[#E5E7EB] text-[#101828]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "font-semibold text-[16px]", children: [ 2683 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uBC88\uD638" }), 2684 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC81C\uBAA9" }),
2685 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 2686 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 2687 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center", children: "\uC870\uD68C" }) 2688 ] }) }), 2689 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "bg-white", children: isLoadingFaq ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2690 "td", 2691 { 2692 colSpan: 5, 2693 className: "px-4 py-10 text-center text-gray-500", 2694 children: "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4." 2695 } 2696 ) }) : faqError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2697 "td", 2698 { 2699 colSpan: 5, 2700 className: "px-4 py-10 text-center text-red-500", 2701 children: faqError 2702 } 2703 ) }) : faqs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2704 "td", 2705 { 2706 colSpan: 5, 2707 className: "px-4 py-10 text-center text-gray-500", 2708 children: "\uC790\uC8FC\uD558\uB294 \uC9C8\uBB38\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." 2709 } 2710 ) }) : faqs.map((faq, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 2711 "tr", 2712 { 2713 className: "[&>td]:border-b [&>td]:border-gray-300 hover:bg-sky-50 transition-colors cursor-pointer", 2714 onClick: () => void openFaqDetail(faq), 2715 children: [
2716 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-number", children: faqTotalCount > 0 ? Math.max( 2717 faqTotalCount - (faqPage - 1) * faqPageSize - index, 2718 1 2719 ) : faq.idx }), 2720 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "board-col-subject", children: [ 2721 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "board-subject-ellipsis m-0", children: renderBoardSubjectWithReplyMarker(faq) }), 2722 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-row-meta", children: [ 2723 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 2724 "\uC791\uC131\uC790: ", 2725 faq.name || "-" 2726 ] }), 2727 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 2728 "\uB4F1\uB85D\uC77C: ", 2729 formatDate(faq.insdate) 2730 ] }) 2731 ] }) 2732 ] }),
2733 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-author", children: faq.name || "-" }), 2734 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-date", children: formatDate(faq.insdate) }), 2735 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-hit", children: Number.isFinite(Number(faq.hit)) ? Number(faq.hit) : 0 }) 2736 ] 2737 }, 2738 faq.idx 2739 )) }) 2740 ] }) }) }) : null, 2741 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [ 2742 !faqDetail && !isFaqWriteMode && faqTotalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-pagination mb-3 flex items-center justify-center gap-3 text-[16px]", children: [ 2743 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2744 "button", 2745 { 2746 type: "button", 2747 className: "board-page-button", 2748 disabled: faqPage <= 1, 2749 onClick: () => setFaqPage(1), 2750 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsLeft, { size: 16, strokeWidth: 2 }) 2751 } 2752 ),
2753 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2754 "button", 2755 { 2756 type: "button", 2757 className: "board-page-button", 2758 disabled: faqPage <= 1, 2759 onClick: () => setFaqPage((prev) => Math.max(prev - 1, 1)), 2760 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { size: 16, strokeWidth: 2 }) 2761 } 2762 ), 2763 getPaginationPages( 2764 faqTotalPages, 2765 faqPage, 2766 isCompactPagination 2767 ).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2768 "button", 2769 { 2770 type: "button", 2771 className: `board-page-button ${p === faqPage ? "is-active" : ""}`, 2772 onClick: () => setFaqPage(p), 2773 children: p 2774 }, 2775 p 2776 )), 2777 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2778 "button", 2779 { 2780 type: "button", 2781 className: "board-page-button", 2782 disabled: faqPage >= faqTotalPages, 2783 onClick: () => setFaqPage((prev) => Math.min(prev + 1, faqTotalPages)), 2784 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { size: 16, strokeWidth: 2 }) 2785 } 2786 ),
2787 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2788 "button", 2789 { 2790 type: "button", 2791 className: "board-page-button", 2792 disabled: faqPage >= faqTotalPages, 2793 onClick: () => setFaqPage(faqTotalPages), 2794 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsRight, { size: 16, strokeWidth: 2 }) 2795 } 2796 ) 2797 ] }) : null, 2798 !faqDetail && !isFaqWriteMode && canWriteBoard("faq") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2799 "button", 2800 { 2801 type: "button", 2802 className: "support-board-action-button", 2803 onClick: openFaqWrite, 2804 children: "\uAE00\uC4F0\uAE30" 2805 } 2806 ) : null 2807 ] }) 2808 ] }); 2809 const renderQnaBoard = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [ 2810 !qnaDetail && !isQnaWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-wrap flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-center", children: [
2811 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 2812 "select", 2813 { 2814 value: qnaSearchField, 2815 onChange: (e) => setQnaSearchField(e.target.value), 2816 className: "board-search-select bg-white", 2817 children: [ 2818 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\uC804\uCCB4" }), 2819 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "subject", children: "\uC81C\uBAA9" }), 2820 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "\uB0B4\uC6A9" }), 2821 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "name", children: "\uC791\uC131\uC790" }) 2822 ] 2823 } 2824 ), 2825 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-row flex items-center gap-4 w-auto", children: [ 2826 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2827 "input", 2828 { 2829 type: "text", 2830 value: qnaSearchInput, 2831 onChange: (e) => setQnaSearchInput(e.target.value), 2832 onKeyDown: (e) => { 2833 if (e.key === "Enter") submitQnaSearch(); 2834 }, 2835 placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2836 className: "board-search-input flex-1 sm:w-[260px] bg-white" 2837 } 2838 ),
2839 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2840 "button", 2841 { 2842 type: "button", 2843 onClick: submitQnaSearch, 2844 className: "board-search-button", 2845 children: "\uAC80\uC0C9" 2846 } 2847 ) 2848 ] }) 2849 ] }) : null, 2850 qnaDetail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2851 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2852 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2853 "h3", 2854 { 2855 className: "m-0 text-[20px] font-bold text-[#101828]", 2856 style: { marginBottom: "12px" }, 2857 children: renderBoardSubjectWithReplyMarker(qnaDetail) 2858 } 2859 ), 2860 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-2 text-[14px] text-gray-600", children: [ 2861 "\uC791\uC131\uC790 ", 2862 qnaDetail.name || "-", 2863 " | \uB4F1\uB85D\uC77C", 2864 " ", 2865 formatDate(qnaDetail.insdate), 2866 " | \uC870\uD68C", 2867 qnaDetail.hit 2868 ] }) 2869 ] }),
2870 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 py-6 min-h-[260px]", children: renderNoticeContent(qnaDetail.content || "") }), 2871 renderDetailActions("\uC9C8\uBB38\uACFC \uB2F5\uBCC0") 2872 ] }) : null, 2873 isQnaWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 2874 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 2875 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2876 "h3", 2877 { 2878 className: "m-0 text-[20px] font-bold text-[#101828]", 2879 style: { marginBottom: "36px" }, 2880 children: qnaWriteModeType === "edit" ? "\uC9C8\uBB38\uACFC \uB2F5\uBCC0 \uAE00 \uC218\uC815" : qnaWriteModeType === "reply" ? "\uC9C8\uBB38\uACFC \uB2F5\uBCC0 \uB2F5\uBCC0" : "\uC9C8\uBB38\uACFC \uB2F5\uBCC0 \uAE00\uC4F0\uAE30" 2881 } 2882 ), 2883 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
2884 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ 2885 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2886 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC791\uC131\uC790" }), 2887 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2888 "input", 2889 { 2890 type: "text", 2891 value: qnaWriteName, 2892 onChange: (e) => setQnaWriteName(e.target.value), 2893 placeholder: "\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2894 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2895 } 2896 ) 2897 ] }), 2898 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2899 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC774\uBA54\uC77C" }),
2900 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2901 "input", 2902 { 2903 type: "email", 2904 value: qnaWriteEmail, 2905 onChange: (e) => setQnaWriteEmail(e.target.value), 2906 placeholder: "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2907 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2908 } 2909 ) 2910 ] }) 2911 ] }), 2912 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2913 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC81C\uBAA9" }), 2914 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2915 "input", 2916 { 2917 type: "text", 2918 value: qnaWriteSubject, 2919 onChange: (e) => setQnaWriteSubject(e.target.value), 2920 placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 2921 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 2922 } 2923 ) 2924 ] }),
2925 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 2926 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uB0B4\uC6A9" }), 2927 renderTinyEditor({ 2928 value: qnaWriteContent, 2929 onChange: setQnaWriteContent, 2930 editorRef: qnaEditorRef 2931 }) 2932 ] }) 2933 ] }) 2934 ] }), 2935 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 2936 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2937 "button", 2938 { 2939 type: "button", 2940 className: supportActionButtonClass, 2941 disabled: isQnaSubmitting, 2942 onClick: () => { 2943 setIsQnaWriteMode(false); 2944 setQnaWriteTargetIdx(null); 2945 setQnaWriteName(sessionWriterName); 2946 setQnaWriteEmail(sessionWriterEmail); 2947 }, 2948 children: "\uBAA9\uB85D" 2949 } 2950 ),
2951 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2952 "button", 2953 { 2954 type: "button", 2955 className: supportActionButtonClass, 2956 disabled: isQnaSubmitting, 2957 onClick: () => { 2958 void handleQnaWriteSubmit(); 2959 }, 2960 children: isQnaSubmitting ? qnaWriteModeType === "edit" ? "\uC800\uC7A5 \uC911..." : qnaWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D \uC911..." : "\uB4F1\uB85D \uC911..." : qnaWriteModeType === "edit" ? "\uC800\uC7A5" : qnaWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D" : "\uB4F1\uB85D" 2961 } 2962 ) 2963 ] }) 2964 ] }) : null, 2965 !qnaDetail && !isQnaWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-outer rounded-2xl overflow-hidden p-0 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-inner overflow-x-auto rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "board-table w-full min-w-[1080px] table-fixed border-separate border-spacing-0 [&_th]:!px-5 [&_td]:!px-5 [&_td]:py-5 [&_th]:text-[16px] [&_td]:text-[15px] [&_th]:font-semibold [&_td]:font-normal [&_th]:text-[#101828] [&_td]:text-[#364153]", children: [
2966 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("colgroup", { children: [ 2967 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-number w-[88px]" }), 2968 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-subject w-[180px]" }), 2969 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-author w-[240px]" }), 2970 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-date w-[240px]" }), 2971 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-hit w-[170px]" }) 2972 ] }), 2973 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b-2 border-[#E5E7EB] text-[#101828]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "font-semibold text-[16px]", children: [ 2974 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uBC88\uD638" }), 2975 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC81C\uBAA9" }),
2976 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 2977 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uB4F1\uB85D\uC77C" }), 2978 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center", children: "\uC870\uD68C" }) 2979 ] }) }), 2980 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "bg-white", children: isLoadingQna ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2981 "td", 2982 { 2983 colSpan: 5, 2984 className: "px-4 py-10 text-center text-gray-500", 2985 children: "\uC9C8\uBB38\uACFC \uB2F5\uBCC0\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4." 2986 } 2987 ) }) : qnaError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2988 "td", 2989 { 2990 colSpan: 5, 2991 className: "px-4 py-10 text-center text-red-500", 2992 children: qnaError 2993 } 2994 ) }) : qnas.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 2995 "td", 2996 { 2997 colSpan: 5, 2998 className: "px-4 py-10 text-center text-gray-500", 2999 children: "\uC9C8\uBB38\uACFC \uB2F5\uBCC0\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." 3000 } 3001 ) }) : qnas.map((qna, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3002 "tr", 3003 { 3004 className: "[&>td]:border-b [&>td]:border-gray-300 hover:bg-sky-50 transition-colors cursor-pointer", 3005 onClick: () => void openQnaDetail(qna), 3006 children: [
3007 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-number", children: qnaTotalCount > 0 ? Math.max( 3008 qnaTotalCount - (qnaPage - 1) * qnaPageSize - index, 3009 1 3010 ) : qna.idx }), 3011 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "board-col-subject", children: [ 3012 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "board-subject-ellipsis m-0", children: renderBoardSubjectWithReplyMarker(qna) }), 3013 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-row-meta", children: [ 3014 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 3015 "\uC791\uC131\uC790: ", 3016 qna.name || "-" 3017 ] }), 3018 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 3019 "\uB4F1\uB85D\uC77C: ", 3020 formatDate(qna.insdate) 3021 ] }) 3022 ] }) 3023 ] }),
3024 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-author", children: qna.name || "-" }), 3025 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-date", children: formatDate(qna.insdate) }), 3026 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-hit", children: Number.isFinite(Number(qna.hit)) ? Number(qna.hit) : 0 }) 3027 ] 3028 }, 3029 qna.idx 3030 )) }) 3031 ] }) }) }) : null, 3032 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [ 3033 !qnaDetail && !isQnaWriteMode && qnaTotalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-pagination mb-3 flex items-center justify-center gap-3 text-[16px]", children: [ 3034 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3035 "button", 3036 { 3037 type: "button", 3038 className: "board-page-button", 3039 disabled: qnaPage <= 1, 3040 onClick: () => setQnaPage(1), 3041 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsLeft, { size: 16, strokeWidth: 2 }) 3042 } 3043 ),
3044 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3045 "button", 3046 { 3047 type: "button", 3048 className: "board-page-button", 3049 disabled: qnaPage <= 1, 3050 onClick: () => setQnaPage((prev) => Math.max(prev - 1, 1)), 3051 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { size: 16, strokeWidth: 2 }) 3052 } 3053 ), 3054 getPaginationPages( 3055 qnaTotalPages, 3056 qnaPage, 3057 isCompactPagination 3058 ).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3059 "button", 3060 { 3061 type: "button", 3062 className: `board-page-button ${p === qnaPage ? "is-active" : ""}`, 3063 onClick: () => setQnaPage(p), 3064 children: p 3065 }, 3066 p 3067 )), 3068 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3069 "button", 3070 { 3071 type: "button", 3072 className: "board-page-button", 3073 disabled: qnaPage >= qnaTotalPages, 3074 onClick: () => setQnaPage((prev) => Math.min(prev + 1, qnaTotalPages)), 3075 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { size: 16, strokeWidth: 2 }) 3076 } 3077 ),
3078 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3079 "button", 3080 { 3081 type: "button", 3082 className: "board-page-button", 3083 disabled: qnaPage >= qnaTotalPages, 3084 onClick: () => setQnaPage(qnaTotalPages), 3085 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsRight, { size: 16, strokeWidth: 2 }) 3086 } 3087 ) 3088 ] }) : null, 3089 !qnaDetail && !isQnaWriteMode && canWriteBoard("qna") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3090 "button", 3091 { 3092 type: "button", 3093 className: "support-board-action-button", 3094 onClick: openQnaWrite, 3095 children: "\uAE00\uC4F0\uAE30" 3096 } 3097 ) : null 3098 ] }) 3099 ] }); 3100 const renderDataBoard = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [ 3101 !dataDetail && !isDataWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-wrap flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-center", children: [
3102 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3103 "select", 3104 { 3105 value: dataSearchField, 3106 onChange: (e) => setDataSearchField(e.target.value), 3107 className: "board-search-select bg-white", 3108 children: [ 3109 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\uC804\uCCB4" }), 3110 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "subject", children: "\uC81C\uBAA9" }), 3111 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "\uB0B4\uC6A9" }), 3112 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "name", children: "\uC791\uC131\uC790" }) 3113 ] 3114 } 3115 ), 3116 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-row flex items-center gap-4 w-auto", children: [ 3117 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3118 "input", 3119 { 3120 type: "text", 3121 value: dataSearchInput, 3122 onChange: (e) => setDataSearchInput(e.target.value), 3123 onKeyDown: (e) => { 3124 if (e.key === "Enter") submitDataSearch(); 3125 }, 3126 placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3127 className: "board-search-input flex-1 sm:w-[260px] bg-white" 3128 } 3129 ),
3130 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3131 "button", 3132 { 3133 type: "button", 3134 onClick: submitDataSearch, 3135 className: "board-search-button", 3136 children: "\uAC80\uC0C9" 3137 } 3138 ) 3139 ] }) 3140 ] }) : null, 3141 dataDetail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 3142 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 3143 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3144 "h3", 3145 { 3146 className: "m-0 text-[20px] font-bold text-[#101828]", 3147 style: { marginBottom: "12px" }, 3148 children: renderBoardSubjectWithReplyMarker(dataDetail) 3149 } 3150 ), 3151 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-2 text-[14px] text-gray-600", children: [ 3152 "\uC791\uC131\uC790 ", 3153 dataDetail.name || "-", 3154 " | \uB4F1\uB85D\uC77C", 3155 " ", 3156 formatDate(dataDetail.insdate), 3157 " | \uC870\uD68C", 3158 dataDetail.hit 3159 ] }) 3160 ] }),
3161 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 py-6 min-h-[260px]", children: renderNoticeContent(dataDetail.content || "") }), 3162 renderDetailActions("1:1 \uBB38\uC758 \uBC0F \uC81C\uC548") 3163 ] }) : null, 3164 isDataWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 3165 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 3166 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3167 "h3", 3168 { 3169 className: "m-0 text-[20px] font-bold text-[#101828]", 3170 style: { marginBottom: "36px" }, 3171 children: dataWriteModeType === "edit" ? "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548 \uAE00 \uC218\uC815" : dataWriteModeType === "reply" ? "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548 \uB2F5\uBCC0" : "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548 \uAE00\uC4F0\uAE30" 3172 } 3173 ), 3174 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
3175 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ 3176 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3177 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC791\uC131\uC790" }), 3178 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3179 "input", 3180 { 3181 type: "text", 3182 value: dataWriteName, 3183 onChange: (e) => setDataWriteName(e.target.value), 3184 placeholder: "\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3185 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3186 } 3187 ) 3188 ] }), 3189 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3190 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC774\uBA54\uC77C" }),
3191 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3192 "input", 3193 { 3194 type: "email", 3195 value: dataWriteEmail, 3196 onChange: (e) => setDataWriteEmail(e.target.value), 3197 placeholder: "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3198 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3199 } 3200 ) 3201 ] }) 3202 ] }), 3203 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3204 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC81C\uBAA9" }), 3205 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3206 "input", 3207 { 3208 type: "text", 3209 value: dataWriteSubject, 3210 onChange: (e) => setDataWriteSubject(e.target.value), 3211 placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3212 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3213 } 3214 ) 3215 ] }),
3216 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3217 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uB0B4\uC6A9" }), 3218 renderTinyEditor({ 3219 value: dataWriteContent, 3220 onChange: setDataWriteContent, 3221 editorRef: dataEditorRef 3222 }) 3223 ] }) 3224 ] }) 3225 ] }), 3226 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 3227 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3228 "button", 3229 { 3230 type: "button", 3231 className: supportActionButtonClass, 3232 disabled: isDataSubmitting, 3233 onClick: () => { 3234 setIsDataWriteMode(false); 3235 setDataWriteTargetIdx(null); 3236 setDataWriteName(sessionWriterName); 3237 setDataWriteEmail(sessionWriterEmail); 3238 }, 3239 children: "\uBAA9\uB85D" 3240 } 3241 ),
3242 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3243 "button", 3244 { 3245 type: "button", 3246 className: supportActionButtonClass, 3247 disabled: isDataSubmitting, 3248 onClick: () => { 3249 void handleDataWriteSubmit(); 3250 }, 3251 children: isDataSubmitting ? dataWriteModeType === "edit" ? "\uC800\uC7A5 \uC911..." : dataWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D \uC911..." : "\uB4F1\uB85D \uC911..." : dataWriteModeType === "edit" ? "\uC800\uC7A5" : dataWriteModeType === "reply" ? "\uB2F5\uBCC0 \uB4F1\uB85D" : "\uB4F1\uB85D" 3252 } 3253 ) 3254 ] }) 3255 ] }) : null, 3256 !dataDetail && !isDataWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-outer rounded-2xl overflow-hidden p-0 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-inner overflow-x-auto rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "board-table w-full min-w-[1080px] table-fixed border-separate border-spacing-0 [&_th]:!px-5 [&_td]:!px-5 [&_td]:py-5 [&_th]:text-[16px] [&_td]:text-[15px] [&_th]:font-semibold [&_td]:font-normal [&_th]:text-[#101828] [&_td]:text-[#364153]", children: [
3257 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("colgroup", { children: [ 3258 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-number w-[88px]" }), 3259 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-subject w-[180px]" }), 3260 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-author w-[240px]" }), 3261 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-date w-[240px]" }), 3262 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-hit w-[170px]" }) 3263 ] }), 3264 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b-2 border-[#E5E7EB] text-[#101828]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "font-semibold text-[16px]", children: [ 3265 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uBC88\uD638" }), 3266 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC81C\uBAA9" }),
3267 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 3268 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uB4F1\uB85D\uC77C" }), 3269 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center", children: "\uC870\uD68C" }) 3270 ] }) }), 3271 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "bg-white", children: isLoadingData ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3272 "td", 3273 { 3274 colSpan: 5, 3275 className: "px-4 py-10 text-center text-gray-500", 3276 children: "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4." 3277 } 3278 ) }) : dataError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3279 "td", 3280 { 3281 colSpan: 5, 3282 className: "px-4 py-10 text-center text-red-500", 3283 children: dataError 3284 } 3285 ) }) : dataItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3286 "td", 3287 { 3288 colSpan: 5, 3289 className: "px-4 py-10 text-center text-gray-500", 3290 children: "1:1 \uBB38\uC758 \uBC0F \uC81C\uC548\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." 3291 } 3292 ) }) : dataItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3293 "tr", 3294 { 3295 className: "[&>td]:border-b [&>td]:border-gray-300 hover:bg-sky-50 transition-colors cursor-pointer", 3296 onClick: () => void openDataDetail(item), 3297 children: [
3298 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-number", children: dataTotalCount > 0 ? Math.max( 3299 dataTotalCount - (dataPage - 1) * dataPageSize - index, 3300 1 3301 ) : item.idx }), 3302 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { className: "board-col-subject", children: [ 3303 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "board-subject-ellipsis m-0", children: renderBoardSubjectWithReplyMarker(item) }), 3304 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-row-meta", children: [ 3305 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 3306 "\uC791\uC131\uC790: ", 3307 item.name || "-" 3308 ] }), 3309 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [ 3310 "\uB4F1\uB85D\uC77C: ", 3311 formatDate(item.insdate) 3312 ] }) 3313 ] }) 3314 ] }),
3315 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-author", children: item.name || "-" }), 3316 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-date", children: formatDate(item.insdate) }), 3317 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-hit", children: Number.isFinite(Number(item.hit)) ? Number(item.hit) : 0 }) 3318 ] 3319 }, 3320 item.idx 3321 )) }) 3322 ] }) }) }) : null, 3323 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [ 3324 !dataDetail && !isDataWriteMode && dataTotalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-pagination mb-3 flex items-center justify-center gap-3 text-[16px]", children: [ 3325 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3326 "button", 3327 { 3328 type: "button", 3329 className: "board-page-button", 3330 disabled: dataPage <= 1, 3331 onClick: () => setDataPage(1), 3332 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsLeft, { size: 16, strokeWidth: 2 }) 3333 } 3334 ),
3335 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3336 "button", 3337 { 3338 type: "button", 3339 className: "board-page-button", 3340 disabled: dataPage <= 1, 3341 onClick: () => setDataPage((prev) => Math.max(prev - 1, 1)), 3342 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { size: 16, strokeWidth: 2 }) 3343 } 3344 ), 3345 getPaginationPages( 3346 dataTotalPages, 3347 dataPage, 3348 isCompactPagination 3349 ).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3350 "button", 3351 { 3352 type: "button", 3353 className: `board-page-button ${p === dataPage ? "is-active" : ""}`, 3354 onClick: () => setDataPage(p), 3355 children: p 3356 }, 3357 p 3358 )), 3359 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3360 "button", 3361 { 3362 type: "button", 3363 className: "board-page-button", 3364 disabled: dataPage >= dataTotalPages, 3365 onClick: () => setDataPage((prev) => Math.min(prev + 1, dataTotalPages)), 3366 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { size: 16, strokeWidth: 2 }) 3367 } 3368 ),
3369 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3370 "button", 3371 { 3372 type: "button", 3373 className: "board-page-button", 3374 disabled: dataPage >= dataTotalPages, 3375 onClick: () => setDataPage(dataTotalPages), 3376 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsRight, { size: 16, strokeWidth: 2 }) 3377 } 3378 ) 3379 ] }) : null, 3380 !dataDetail && !isDataWriteMode && canWriteBoard("data") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3381 "button", 3382 { 3383 type: "button", 3384 className: "support-board-action-button", 3385 onClick: openDataWrite, 3386 children: "\uAE00\uC4F0\uAE30" 3387 } 3388 ) : null 3389 ] }) 3390 ] }); 3391 const renderManualBoard = () => { 3392 const manualLinks = [ 3393 { 3394 title: "\uC628\uB77C\uC778 \uC0AC\uC6A9 \uC124\uBA85\uC11C", 3395 description: "\uCC98\uC74C \uC0AC\uC6A9\uD558\uC2DC\uB294 \uBD84\uB3C4 \uC27D\uAC8C \uB530\uB77C\uD560 \uC218 \uC788\uB3C4\uB85D \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.", 3396 actionText: "\uC0AC\uC6A9\uC124\uBA85\uC11C \uBCF4\uB7EC\uAC00\uAE30", 3397 href: "/help/index.html", 3398 Icon: ManualCardIcon1 3399 }, 3400 { 3401 title: "\uB9E4\uB274\uC5BC PDF \uB2E4\uC6B4\uB85C\uB4DC", 3402 description: "\uC0AC\uC6A9\uC124\uBA85\uC11C\uB97C \uB0B4\uB824\uBC1B\uC544 \uC778\uC1C4\uBCF8\uC73C\uB85C \uBCF4\uAD00\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", 3403 actionText: "PDF\uB2E4\uC6B4\uB85C\uB4DC\uD558\uAE30", 3404 href: "/download/menual_h.pdf", 3405 Icon: ManualCardIcon2 3406 }, 3407 { 3408 title: "Adobe Reader \uB2E4\uC6B4\uB85C\uB4DC", 3409 description: "PDF \uBB38\uC11C\uB97C \uC5F4\uAE30 \uC704\uD574 \uD544\uC694\uD55C \uBB34\uB8CC \uD504\uB85C\uADF8\uB7A8\uC785\uB2C8\uB2E4.", 3410 actionText: "\uBDF0\uC5B4\uB2E4\uC6B4\uB85C\uB4DC\uD558\uAE30", 3411 href: "https://get.adobe.com/kr/reader/", 3412 Icon: ManualCardIcon3 3413 } 3414 ]; 3415 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "manual-guide-wrap rounded-[20px] px-5 py-10 sm:px-8 sm:py-12", children: [
3416 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "manual-guide-title m-0 text-center font-bold text-[#101828]", children: "\uC628\uB77C\uC778 \uC0AC\uC6A9\uC124\uBA85\uC11C" }), 3417 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "manual-guide-desc mx-auto mt-4 mb-0 max-w-[860px] text-center text-[#667085]", children: [ 3418 "- \uD504\uB85C\uADF8\uB7A8 \uBC0F \uC11C\uBE44\uC2A4 \uC774\uC6A9 \uBC29\uBC95\uC774 \uC790\uC138\uD558\uAC8C \uC124\uBA85\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.", 3419 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}), 3420 "- \uC2E0\uC18D\uD558\uAC8C \uCC3E\uC544 \uBCFC \uC218 \uC788\uB294 \uC778\uB371\uC2A4\uB97C \uC81C\uACF5\uD569\uB2C8\uB2E4.", 3421 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}), 3422 "- \uAC15\uB825\uD55C \uD0A4\uC6CC\uB4DC \uAC80\uC0C9\uC774 \uAC00\uB2A5\uD569\uB2C8\uB2E4.", 3423 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}), 3424 "- \uC778\uC1C4\uAC00 \uAC00\uB2A5\uD55C PDF \uD30C\uC77C\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4." 3425 ] }),
3426 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "manual-guide-grid mt-10", children: manualLinks.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3427 "div", 3428 { 3429 className: `manual-guide-card rounded-2xl bg-[#F2F3F7] p-7 ${idx === 2 ? "manual-guide-card-wide" : ""}`, 3430 children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-4", children: [ 3431 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "manual-guide-icon-circle flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(item.Icon, { className: "w-full h-full" }) }), 3432 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [ 3433 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "manual-guide-card-title m-0 font-bold text-[#101828]", children: item.title }), 3434 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "manual-guide-card-desc mt-2 mb-0 text-[#475467]", children: item.description }),
3435 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3436 "a", 3437 { 3438 href: item.href, 3439 target: "_blank", 3440 rel: "noreferrer", 3441 className: "manual-guide-card-link mt-3 mb-0 inline-block font-semibold", 3442 children: [ 3443 item.actionText, 3444 " ", 3445 "\u203A" 3446 ] 3447 } 3448 ) 3449 ] }) 3450 ] }) 3451 }, 3452 item.title 3453 )) }) 3454 ] }) }); 3455 }; 3456 const renderVideoBoard = () => { 3457 return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-4", children: [ 3458 !videoDetail && !isVideoWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-wrap flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-center", children: [ 3459 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3460 "select", 3461 { 3462 value: videoSearchField, 3463 onChange: (e) => setVideoSearchField(e.target.value), 3464 className: "board-search-select bg-white", 3465 children: [
3466 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\uC804\uCCB4" }), 3467 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "subject", children: "\uC81C\uBAA9" }), 3468 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "\uB0B4\uC6A9" }), 3469 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "name", children: "\uC791\uC131\uC790" }) 3470 ] 3471 } 3472 ), 3473 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-search-row flex items-center gap-4 w-auto", children: [ 3474 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3475 "input", 3476 { 3477 type: "text", 3478 value: videoSearchInput, 3479 onChange: (e) => setVideoSearchInput(e.target.value), 3480 onKeyDown: (e) => { 3481 if (e.key === "Enter") submitVideoSearch(); 3482 }, 3483 placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3484 className: "board-search-input flex-1 sm:w-[260px] bg-white" 3485 } 3486 ),
3487 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3488 "button", 3489 { 3490 type: "button", 3491 onClick: submitVideoSearch, 3492 className: "board-search-button", 3493 children: "\uAC80\uC0C9" 3494 } 3495 ) 3496 ] }) 3497 ] }) : null, 3498 videoDetail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 3499 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 3500 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3501 "h3", 3502 { 3503 className: "m-0 text-[20px] font-bold text-[#101828]", 3504 style: { marginBottom: "12px" }, 3505 children: videoDetail.subject 3506 } 3507 ), 3508 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-2 text-[14px] text-gray-600", children: [ 3509 "\uC791\uC131\uC790 ", 3510 videoDetail.name || "-", 3511 " | \uB4F1\uB85D\uC77C", 3512 " ", 3513 formatDate(videoDetail.insdate), 3514 " | \uC870\uD68C", 3515 videoDetail.hit 3516 ] }) 3517 ] }),
3518 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 py-6 min-h-[260px]", children: renderVideoContent(videoDetail.content || "") }), 3519 renderDetailActions("\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0") 3520 ] }) : null, 3521 isVideoWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "support-detail-view rounded-2xl overflow-hidden bg-white", children: [ 3522 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 pt-5 pb-3", children: [ 3523 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3524 "h3", 3525 { 3526 className: "m-0 text-[20px] font-bold text-[#101828]", 3527 style: { marginBottom: "36px" }, 3528 children: videoWriteModeType === "edit" ? "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0 \uAE00 \uC218\uC815" : "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0 \uAE00\uC4F0\uAE30" 3529 } 3530 ), 3531 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [ 3532 /* @__P
3532URE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ 3533 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3534 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC791\uC131\uC790" }), 3535 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3536 "input", 3537 { 3538 type: "text", 3539 value: videoWriteName, 3540 onChange: (e) => setVideoWriteName(e.target.value), 3541 placeholder: "\uC791\uC131\uC790\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3542 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3543 } 3544 ) 3545 ] }), 3546 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3547 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC774\uBA54\uC77C" }),
3548 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3549 "input", 3550 { 3551 type: "email", 3552 value: videoWriteEmail, 3553 onChange: (e) => setVideoWriteEmail(e.target.value), 3554 placeholder: "\uC774\uBA54\uC77C\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3555 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3556 } 3557 ) 3558 ] }) 3559 ] }), 3560 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3561 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uC81C\uBAA9" }), 3562 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3563 "input", 3564 { 3565 type: "text", 3566 value: videoWriteSubject, 3567 onChange: (e) => setVideoWriteSubject(e.target.value), 3568 placeholder: "\uC81C\uBAA9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.", 3569 className: "support-write-input w-full rounded-md border border-gray-300 px-4 py-3 text-[15px] bg-white" 3570 } 3571 ) 3572 ] }),
3573 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ 3574 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "block mb-2 text-[14px] text-gray-600", children: "\uB0B4\uC6A9" }), 3575 renderTinyEditor({ 3576 value: videoWriteContent, 3577 onChange: setVideoWriteContent, 3578 editorRef: videoEditorRef 3579 }) 3580 ] }) 3581 ] }) 3582 ] }), 3583 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "px-5 py-4 border-t border-gray-200 flex flex-wrap justify-end gap-3", children: [ 3584 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3585 "button", 3586 { 3587 type: "button", 3588 className: supportActionButtonClass, 3589 disabled: isVideoSubmitting, 3590 onClick: () => { 3591 setIsVideoWriteMode(false); 3592 setVideoWriteModeType("create"); 3593 setVideoWriteTargetIdx(null); 3594 setVideoWriteName(sessionWriterName); 3595 setVideoWriteEmail(sessionWriterEmail); 3596 }, 3597 children: "\uBAA9\uB85D" 3598 } 3599 ),
3600 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3601 "button", 3602 { 3603 type: "button", 3604 className: supportActionButtonClass, 3605 disabled: isVideoSubmitting, 3606 onClick: () => { 3607 void handleVideoWriteSubmit(); 3608 }, 3609 children: isVideoSubmitting ? videoWriteModeType === "edit" ? "\uC218\uC815 \uC911..." : "\uB4F1\uB85D \uC911..." : videoWriteModeType === "edit" ? "\uC218\uC815" : "\uB4F1\uB85D" 3610 } 3611 ) 3612 ] }) 3613 ] }) : null, 3614 !videoDetail && !isVideoWriteMode ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-outer rounded-2xl overflow-hidden p-0 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "board-table-inner overflow-x-auto rounded-xl", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "board-table w-full min-w-[1080px] table-fixed border-separate border-spacing-0 [&_th]:!px-5 [&_td]:!px-5 [&_td]:py-5 [&_th]:text-[16px] [&_td]:text-[15px] [&_th]:font-semibold [&_td]:font-normal [&_th]:text-[#101828] [&_td]:text-[#364153]", children: [
3615 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("colgroup", { children: [ 3616 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-number w-[88px]" }), 3617 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-subject w-[180px]" }), 3618 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-author w-[240px]" }), 3619 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-date w-[240px]" }), 3620 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { className: "board-col-hit w-[170px]" }) 3621 ] }), 3622 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b-2 border-[#E5E7EB] text-[#101828]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "font-semibold text-[16px]", children: [ 3623 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uBC88\uD638" }), 3624 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC81C\uBAA9" }),
3625 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC790" }), 3626 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center border-r border-blue-200", children: "\uC791\uC131\uC77C" }), 3627 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "pt-6 pb-[22px] text-center", children: "\uC870\uD68C" }) 3628 ] }) }), 3629 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { className: "bg-white", children: isLoadingVideo ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3630 "td", 3631 { 3632 colSpan: 5, 3633 className: "px-4 py-10 text-center text-gray-500", 3634 children: "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\uC785\uB2C8\uB2E4." 3635 } 3636 ) }) : videoError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3637 "td", 3638 { 3639 colSpan: 5, 3640 className: "px-4 py-10 text-center text-red-500", 3641 children: videoError 3642 } 3643 ) }) : videos.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3644 "td", 3645 { 3646 colSpan: 5, 3647 className: "px-4 py-10 text-center text-gray-500", 3648 children: "\uB3D9\uC601\uC0C1 \uB3C4\uC6C0\uB9D0\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." 3649 } 3650 ) }) : videos.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3651 "tr", 3652 { 3653 className: "[&>td]:border-b [&>td]:border-gray-300 hover:bg-sky-50 transition-colors cursor-pointer", 3654 onClick: () => void openVideoDetail(item), 3655 children: [
3656 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-number", children: videoTotalCount > 0 ? Math.max( 3657 videoTotalCount - (videoPage - 1) * videoPageSize - index, 3658 1 3659 ) : item.idx }), 3660 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-subject text-left", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3661 "button", 3662 { 3663 type: "button", 3664 onClick: (event) => { 3665 event.stopPropagation(); 3666 void openVideoDetail(item); 3667 }, 3668 className: "text-left font-medium text-[#101828] hover:text-[#115DE6] hover:underline", 3669 children: item.subject 3670 } 3671 ) }), 3672 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-author", children: item.name }), 3673 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-date", children: formatDate(item.insdate) }),
3674 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "board-col-hit", children: item.hit }) 3675 ] 3676 }, 3677 item.idx 3678 )) }) 3679 ] }) }) }) : null, 3680 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-right", children: [ 3681 !videoDetail && !isVideoWriteMode && videoTotalCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "board-pagination mb-3 flex items-center justify-center gap-3 text-[16px]", children: [ 3682 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3683 "button", 3684 { 3685 type: "button", 3686 className: "board-page-button", 3687 disabled: videoPage <= 1, 3688 onClick: () => setVideoPage(1), 3689 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsLeft, { size: 16, strokeWidth: 2 }) 3690 } 3691 ), 3692 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3693 "button", 3694 { 3695 type: "button", 3696 className: "board-page-button", 3697 disabled: videoPage <= 1, 3698 onClick: () => setVideoPage((prev) => Math.max(prev - 1, 1)), 3699 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeft, { size: 16, strokeWidth: 2 }) 3700 } 3701 ), 3702 getPaginationPages( 3703 videoTotalPages, 3704 videoPage, 3705 isCompactPagination 3706 ).map((pageNum) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3707 "button", 3708 { 3709 type: "button", 3710 className: `board-page-button ${pageNum === videoPage ? "is-active" : ""}`, 3711 onClick: () => setVideoPage(pageNum), 3712 children: pageNum 3713 }, 3714 pageNum 3715 )),
3716 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3717 "button", 3718 { 3719 type: "button", 3720 className: "board-page-button", 3721 disabled: videoPage >= videoTotalPages, 3722 onClick: () => setVideoPage((prev) => Math.min(prev + 1, videoTotalPages)), 3723 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { size: 16, strokeWidth: 2 }) 3724 } 3725 ), 3726 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3727 "button", 3728 { 3729 type: "button", 3730 className: "board-page-button", 3731 disabled: videoPage >= videoTotalPages, 3732 onClick: () => setVideoPage(videoTotalPages), 3733 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronsRight, { size: 16, strokeWidth: 2 }) 3734 } 3735 ) 3736 ] }) : null, 3737 !videoDetail && !isVideoWriteMode && canWriteBoard("video") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3738 "button", 3739 { 3740 type: "button", 3741 className: "support-board-action-button", 3742 onClick: openVideoWrite, 3743 children: "\uAE00\uC4F0\uAE30" 3744 } 3745 ) : null 3746 ] }) 3747 ] }); 3748 }; 3749 const renderPlaceholder = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-h-[480px] flex items-center justify-center text-gray-500 text-lg", children: [ 3750 selectedMenuLabel, 3751 " \uC601\uC5ED\uC740 \uB2E4\uC74C \uB2E8\uACC4\uC5D0\uC11C \uAD6C\uD604\uB429\uB2C8\uB2E4." 3752 ] }); 3753 return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { className: "min-h-screen bg-white transition-colors duration-300 pt-[104px] lg:pt-[120px]", children: [ 3754 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3755 "div", 3756 { 3757 className: "support-page-header-hero bg-[#0E2547] border-b border-gray-200 py-12 flex items-center relative overflow-hidden", 3758 style: { backgroundColor: "#0E2547" }, 3759 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "subpage-hero-inner max-w-[1440px] mx-auto px-4 sm:px-6 lg:px-8 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
3760 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-4xl font-bold text-white mb-4", children: SUPPORT_HEADER_TITLE }), 3761 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3762 "p", 3763 { 3764 className: "text-[#AEBFDD] leading-relaxed", 3765 style: { color: "#AEBFDD" }, 3766 children: [ 3767 "\uADC0\uC0AC\uC758 \uC131\uACF5\uC801\uC778 \uACBD\uC601\uC744 \uC704\uD574 \uCD5C\uC120\uC744 \uB2E4\uD574 \uB178\uB825\uD558\uACE0 \uC788\uC2B5\uB2C8\uB2E4.", 3768 " ", 3769 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", { className: "product-subtitle-break" }), 3770 "\uC5B8\uC81C\uB4E0 \uC5F0\uB77D\uC744 \uC8FC\uC2DC\uBA74 \uC815\uC131\uC744 \uB2E4\uD574 \uB3C4\uC640\uB4DC\uB9AC\uACA0\uC2B5\uB2C8\uB2E4." 3771 ] 3772 } 3773 ) 3774 ] }) }) }) 3775 } 3776 ), 3777 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-[1440px] mx-auto px-4 sm:px-6 lg:px-8 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col lg:flex-row gap-4 lg:gap-8", children: [
3778 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", { className: "hidden lg:block lg:w-64 flex-shrink-0 space-y-4", children: [ 3779 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bg-white border border-gray-200 rounded-xl overflow-hidden", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3780 "button", 3781 { 3782 onClick: () => handleMenuClick(item.id), 3783 className: `w-full flex items-center justify-between px-6 py-4 text-left transition-all border-b border-gray-200 last:border-b-0 ${selectedMenu === item.id ? "font-semibold" : "text-gray-700 hover:bg-gray-50"}`, 3784 style: selectedMenu === item.id ? selectedMenuButtonStyle : void 0, 3785 children: [ 3786 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.label }), 3787 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3788 ChevronRight, 3789 { 3790 className: `w-5 h-5 transition-transform ${selectedMenu === item.id ? "" : "text-gray-400"}`, 3791 style: selectedMenu === item.id ? selectedMenuIconStyle : void 0 3792 } 3793 ) 3794 ] 3795 }, 3796 item.id 3797 )) }),
3798 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [ 3799 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3800 "a", 3801 { 3802 href: "/support?menu=faq&searchField=subject&searchKeyword=%EC%A0%84%EC%9E%90%EC%84%B8%EA%B8%88%EA%B3%84%EC%82%B0%EC%84%9C%20%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95&openFirst=1", 3803 className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4 hover:bg-gray-100 transition-all", 3804 children: [ 3805 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3806 "div", 3807 { 3808 className: "flex items-center justify-center flex-shrink-0", 3809 style: { width: "36px", height: "36px" }, 3810 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MoataxIcon, { className: "w-full h-full" }) 3811 } 3812 ), 3813 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [
3814 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-gray-600 m-[0px] text-[14px]", children: "\uC27D\uACE0 \uAC04\uB2E8\uD55C \uC804\uC790\uC138\uAE08\uACC4\uC0B0\uC11C" }), 3815 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3816 "p", 3817 { 3818 className: "font-bold text-[18px]", 3819 style: { color: "#364153" }, 3820 children: "\uBAA8\uC544\uD0DD\uC2A4" 3821 } 3822 ) 3823 ] }) 3824 ] 3825 } 3826 ), 3827 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3828 "a", 3829 { 3830 href: "https://www.startsupport.com/allntop", 3831 target: "_blank", 3832 rel: "noreferrer", 3833 className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4 hover:bg-gray-100 transition-all", 3834 children: [ 3835 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3836 "div", 3837 { 3838 className: "flex items-center justify-center flex-shrink-0", 3839 style: { width: "36px", height: "36px" }, 3840 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RemoteSupportIcon, { className: "w-full h-full" }) 3841 } 3842 ),
3843 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 3844 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-gray-600 m-[0px] text-[14px]", children: "\uC6D0\uACA9 \uACE0\uAC1D\uC9C0\uC6D0\uC13C\uD130" }), 3845 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3846 "p", 3847 { 3848 className: "font-bold text-[18px]", 3849 style: { color: "#364153" }, 3850 children: "\uC6D0\uACA9\uC9C0\uC6D0\uC11C\uBE44\uC2A4" 3851 } 3852 ) 3853 ] }) 3854 ] 3855 } 3856 ), 3857 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4", children: [ 3858 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3859 "div", 3860 { 3861 className: "flex items-center justify-center flex-shrink-0", 3862 style: { width: "36px", height: "36px" }, 3863 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AskAnythingIcon, { className: "w-full h-full" }) 3864 } 3865 ),
3866 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 3867 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-600 mx-[0px] mt-[0px] mb-[2px] text-[14px]", children: "\uBB34\uC5C7\uC774\uB4E0 \uBB3C\uC5B4\uBCF4\uC138\uC694" }), 3868 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3869 "p", 3870 { 3871 className: "font-bold text-[16px]", 3872 style: { color: "#364153" }, 3873 children: "0505-855-7788" 3874 } 3875 ), 3876 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-gray-500 mt-0.5 text-[14px]", children: [ 3877 "AM 09:00 ~ PM 06:00", 3878 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}), 3879 "\uC810\uC2EC\uC2DC\uAC04 12:00 ~ 13:00" 3880 ] }) 3881 ] }) 3882 ] }), 3883 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4", children: [
3884 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3885 "div", 3886 { 3887 className: "flex items-center justify-center flex-shrink-0", 3888 style: { width: "36px", height: "36px" }, 3889 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BankAccountIcon, { className: "w-full h-full" }) 3890 } 3891 ), 3892 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 3893 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-600 mx-[0px] mt-[0px] mb-[2px] text-[14px]", children: "\uC785\uAE08\uACC4\uC88C\uBC88\uD638" }), 3894 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3895 "p", 3896 { 3897 className: "font-bold text-[16px]", 3898 style: { color: "#364153" }, 3899 children: "370-910009-27204" 3900 } 3901 ), 3902 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-500 mt-0.5 text-[14px]", children: "\uD558\uB098\uC740\uD589 (\uC8FC)\uD734\uD14D\uC18C\uD504\uD2B8" }) 3903 ] }) 3904 ] }) 3905 ] }) 3906 ] }),
3907 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "lg:hidden flex-shrink-0 order-1", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bg-white border border-gray-200 rounded-xl overflow-hidden", children: [ 3908 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3909 "button", 3910 { 3911 onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen), 3912 className: "w-full flex items-center justify-between px-6 py-4 text-gray-900 font-semibold transition-all border-b border-gray-200", 3913 children: [ 3914 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: selectedMenuLabel }), 3915 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3916 ChevronRight, 3917 { 3918 className: `w-5 h-5 transition-transform duration-300 ${isMobileMenuOpen ? "rotate-90" : "rotate-0"}` 3919 } 3920 ) 3921 ] 3922 } 3923 ), 3924 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3925 "div", 3926 { 3927 className: `transition-all duration-300 ease-in-out overflow-hidden ${isMobileMenuOpen ? "max-h-[500px] opacity-100" : "max-h-0 opacity-0"}`, 3928 children: menuItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3929 "button", 3930 { 3931 onClick: () => handleMenuClick(item.id), 3932 className: `w-full flex items-center justify-between px-6 py-4 text-left transition-all ${index === menuItems.length - 1 ? "" : "border-b border-gray-200"} ${selectedMenu === item.id ? "font-semibold" : "text-gray-700 hover:bg-gray-50"}`, 3933 style: selectedMenu === item.id ? selectedMenuButtonStyle : void 0, 3934 children: [
3935 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.label }), 3936 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3937 ChevronRight, 3938 { 3939 className: `w-5 h-5 transition-transform ${selectedMenu === item.id ? "" : "text-gray-400"}`, 3940 style: selectedMenu === item.id ? selectedMenuIconStyle : void 0 3941 } 3942 ) 3943 ] 3944 }, 3945 item.id 3946 )) 3947 } 3948 ) 3949 ] }) }), 3950 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1 order-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "support-content-panel bg-white border border-gray-200 rounded-xl p-6 md:p-8 lg:p-12", children: selectedMenu === "notice" ? renderNoticeBoard() : selectedMenu === "faq" ? renderFaqBoard() : selectedMenu === "qna" ? renderQnaBoard() : selectedMenu === "data" ? renderDataBoard() : selectedMenu === "manual" ? renderManualBoard() : selectedMenu === "video" ? renderVideoBoard() : renderPlaceholder() }) }),
3951 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lg:hidden flex-shrink-0 order-3 space-y-3", children: [ 3952 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3953 "a", 3954 { 3955 href: "/support?menu=faq&searchField=subject&searchKeyword=%EC%A0%84%EC%9E%90%EC%84%B8%EA%B8%88%EA%B3%84%EC%82%B0%EC%84%9C%20%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95&openFirst=1", 3956 className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4 hover:bg-gray-100 transition-all", 3957 children: [ 3958 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3959 "div", 3960 { 3961 className: "flex items-center justify-center flex-shrink-0", 3962 style: { width: "36px", height: "36px" }, 3963 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MoataxIcon, { className: "w-full h-full" }) 3964 } 3965 ), 3966 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [
3967 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-gray-600 m-[0px] text-[14px]", children: "\uC27D\uACE0 \uAC04\uB2E8\uD55C \uC804\uC790\uC138\uAE08\uACC4\uC0B0\uC11C" }), 3968 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3969 "p", 3970 { 3971 className: "font-bold text-[18px]", 3972 style: { color: "#364153" }, 3973 children: "\uBAA8\uC544\uD0DD\uC2A4" 3974 } 3975 ) 3976 ] }) 3977 ] 3978 } 3979 ), 3980 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( 3981 "a", 3982 { 3983 href: "https://www.startsupport.com/allntop", 3984 target: "_blank", 3985 rel: "noreferrer", 3986 className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4 hover:bg-gray-100 transition-all", 3987 children: [ 3988 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3989 "div", 3990 { 3991 className: "flex items-center justify-center flex-shrink-0", 3992 style: { width: "36px", height: "36px" }, 3993 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RemoteSupportIcon, { className: "w-full h-full" }) 3994 } 3995 ),
3996 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 3997 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-gray-600 m-[0px] text-[14px]", children: "\uC6D0\uACA9 \uACE0\uAC1D\uC9C0\uC6D0\uC13C\uD130" }), 3998 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 3999 "p", 4000 { 4001 className: "font-bold text-[18px]", 4002 style: { color: "#364153" }, 4003 children: "\uC6D0\uACA9\uC9C0\uC6D0\uC11C\uBE44\uC2A4" 4004 } 4005 ) 4006 ] }) 4007 ] 4008 } 4009 ), 4010 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4", children: [ 4011 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 4012 "div", 4013 { 4014 className: "flex items-center justify-center flex-shrink-0", 4015 style: { width: "36px", height: "36px" }, 4016 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AskAnythingIcon, { className: "w-full h-full" }) 4017 } 4018 ),
4019 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 4020 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-600 mx-[0px] mt-[0px] mb-[2px] text-[14px]", children: "\uBB34\uC5C7\uC774\uB4E0 \uBB3C\uC5B4\uBCF4\uC138\uC694" }), 4021 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 4022 "p", 4023 { 4024 className: "font-bold text-[18px]", 4025 style: { color: "#364153" }, 4026 children: "0505-855-7788" 4027 } 4028 ), 4029 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-gray-500 mt-0.5 text-[14px]", children: [ 4030 "AM 09:00 ~ PM 06:00", 4031 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}), 4032 "\uC810\uC2EC\uC2DC\uAC04 12:00 ~ 13:00" 4033 ] }) 4034 ] }) 4035 ] }), 4036 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "w-full bg-white border border-gray-200 rounded-xl p-4 flex items-center gap-4", children: [
4037 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 4038 "div", 4039 { 4040 className: "flex items-center justify-center flex-shrink-0", 4041 style: { width: "36px", height: "36px" }, 4042 children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BankAccountIcon, { className: "w-full h-full" }) 4043 } 4044 ), 4045 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-left flex-1", children: [ 4046 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-600 mx-[0px] mt-[0px] mb-[2px] text-[14px]", children: "\uC785\uAE08\uACC4\uC88C\uBC88\uD638" }), 4047 /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 4048 "p", 4049 { 4050 className: "font-bold text-[18px]", 4051 style: { color: "#364153" }, 4052 children: "370-910009-27204" 4053 } 4054 ), 4055 /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-gray-500 mt-0.5 text-[14px]", children: "\uD558\uB098\uC740\uD589 (\uC8FC)\uD734\uD14D\uC18C\uD504\uD2B8" }) 4056 ] }) 4057 ] }) 4058 ] }) 4059 ] }) }) 4060 ] }); 4061} 4062export { 4063 SupportPage 4064};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.