/** * Screen states: access denied, error, nav enabled. */ import { state, getCalendarEl, getDutyListEl, getLoadingEl, getErrorEl, getAccessDeniedEl, getHeaderEl, getWeekdaysEl, getPrevBtn, getNextBtn } from "./dom.js"; import { t } from "./i18n.js"; import { escapeHtml } from "./utils.js"; /** * Show access-denied view and hide calendar/list/loading/error. * @param {string} [serverDetail] - message from API 403 detail (shown below main text when present) */ export function showAccessDenied(serverDetail) { const headerEl = getHeaderEl(); const weekdaysEl = getWeekdaysEl(); const calendarEl = getCalendarEl(); const dutyListEl = getDutyListEl(); const loadingEl = getLoadingEl(); const errorEl = getErrorEl(); const accessDeniedEl = getAccessDeniedEl(); if (headerEl) headerEl.hidden = true; if (weekdaysEl) weekdaysEl.hidden = true; if (calendarEl) calendarEl.hidden = true; if (dutyListEl) dutyListEl.hidden = true; if (loadingEl) loadingEl.classList.add("hidden"); if (errorEl) errorEl.hidden = true; if (accessDeniedEl) { const msg = t(state.lang, "access_denied"); accessDeniedEl.innerHTML = "

" + msg + "

"; if (serverDetail && serverDetail.trim()) { const detail = document.createElement("p"); detail.className = "access-denied-detail"; detail.textContent = serverDetail; accessDeniedEl.appendChild(detail); } accessDeniedEl.hidden = false; } } /** * Hide access-denied and show calendar/list/header/weekdays. */ export function hideAccessDenied() { const accessDeniedEl = getAccessDeniedEl(); const headerEl = getHeaderEl(); const weekdaysEl = getWeekdaysEl(); const calendarEl = getCalendarEl(); const dutyListEl = getDutyListEl(); if (accessDeniedEl) accessDeniedEl.hidden = true; if (headerEl) headerEl.hidden = false; if (weekdaysEl) weekdaysEl.hidden = false; if (calendarEl) calendarEl.hidden = false; if (dutyListEl) dutyListEl.hidden = false; } /** Warning icon SVG for error state (24×24). */ const ERROR_ICON_SVG = ''; /** * Show error message and hide loading. * @param {string} msg - Error text * @param {(() => void)|null} [onRetry] - Optional callback for Retry button */ export function showError(msg, onRetry) { const errorEl = getErrorEl(); const loadingEl = getLoadingEl(); if (errorEl) { const retryLabel = t(state.lang, "error.retry"); const safeMsg = typeof msg === "string" ? msg : t(state.lang, "error_generic"); let html = ERROR_ICON_SVG + '

' + escapeHtml(safeMsg) + "

"; if (typeof onRetry === "function") { html += '"; } errorEl.innerHTML = html; errorEl.hidden = false; const retryBtn = errorEl.querySelector(".error-retry"); if (retryBtn && typeof onRetry === "function") { retryBtn.addEventListener("click", () => { onRetry(); }); } } if (loadingEl) loadingEl.classList.add("hidden"); } /** * Enable or disable prev/next month buttons. * @param {boolean} enabled */ export function setNavEnabled(enabled) { const prevBtn = getPrevBtn(); const nextBtn = getNextBtn(); if (prevBtn) prevBtn.disabled = !enabled; if (nextBtn) nextBtn.disabled = !enabled; }