feat: enhance CI workflow and update webapp styles
Some checks failed
CI / lint-and-test (push) Failing after 45s
Some checks failed
CI / lint-and-test (push) Failing after 45s
- Added Node.js setup and webapp testing steps to the CI workflow for improved integration. - Updated HTML to link multiple CSS files for better modularity and organization of styles. - Removed deprecated `style.css` and introduced new CSS files for base styles, calendar, day detail, hints, markers, states, and duty list to enhance maintainability and readability. - Implemented new styles for improved presentation of duty information and user interactions. - Added unit tests for new API functions and contact link rendering to ensure functionality and reliability.
This commit is contained in:
@@ -8,12 +8,12 @@ import { getInitData, isLocalhost } from "./auth.js";
|
||||
import { RETRY_DELAY_MS, RETRY_AFTER_ACCESS_DENIED_MS } from "./constants.js";
|
||||
import {
|
||||
state,
|
||||
accessDeniedEl,
|
||||
prevBtn,
|
||||
nextBtn,
|
||||
loadingEl,
|
||||
errorEl,
|
||||
weekdaysEl
|
||||
getAccessDeniedEl,
|
||||
getPrevBtn,
|
||||
getNextBtn,
|
||||
getLoadingEl,
|
||||
getErrorEl,
|
||||
getWeekdaysEl
|
||||
} from "./dom.js";
|
||||
import { showAccessDenied, hideAccessDenied, showError, setNavEnabled } from "./ui.js";
|
||||
import { fetchDuties, fetchCalendarEvents } from "./api.js";
|
||||
@@ -39,15 +39,19 @@ initTheme();
|
||||
state.lang = getLang();
|
||||
document.documentElement.lang = state.lang;
|
||||
document.title = t(state.lang, "app.title");
|
||||
const loadingEl = getLoadingEl();
|
||||
const loadingTextEl = loadingEl ? loadingEl.querySelector(".loading__text") : null;
|
||||
if (loadingTextEl) loadingTextEl.textContent = t(state.lang, "loading");
|
||||
const dayLabels = weekdayLabels(state.lang);
|
||||
const weekdaysEl = getWeekdaysEl();
|
||||
if (weekdaysEl) {
|
||||
const spans = weekdaysEl.querySelectorAll("span");
|
||||
spans.forEach((span, i) => {
|
||||
if (dayLabels[i]) span.textContent = dayLabels[i];
|
||||
});
|
||||
}
|
||||
const prevBtn = getPrevBtn();
|
||||
const nextBtn = getNextBtn();
|
||||
if (prevBtn) prevBtn.setAttribute("aria-label", t(state.lang, "nav.prev_month"));
|
||||
if (nextBtn) nextBtn.setAttribute("aria-label", t(state.lang, "nav.next_month"));
|
||||
|
||||
@@ -99,12 +103,14 @@ function requireTelegramOrLocalhost(onAllowed) {
|
||||
return;
|
||||
}
|
||||
showAccessDenied(undefined);
|
||||
if (loadingEl) loadingEl.classList.add("hidden");
|
||||
const loading = getLoadingEl();
|
||||
if (loading) loading.classList.add("hidden");
|
||||
}, RETRY_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
showAccessDenied(undefined);
|
||||
if (loadingEl) loadingEl.classList.add("hidden");
|
||||
const loading = getLoadingEl();
|
||||
if (loading) loading.classList.add("hidden");
|
||||
}
|
||||
|
||||
/** AbortController for the in-flight loadMonth request; aborted when a new load starts. */
|
||||
@@ -121,7 +127,9 @@ async function loadMonth() {
|
||||
|
||||
hideAccessDenied();
|
||||
setNavEnabled(false);
|
||||
const loadingEl = getLoadingEl();
|
||||
if (loadingEl) loadingEl.classList.remove("hidden");
|
||||
const errorEl = getErrorEl();
|
||||
if (errorEl) errorEl.hidden = true;
|
||||
const current = state.current;
|
||||
const first = firstDayOfMonth(current);
|
||||
@@ -185,21 +193,26 @@ async function loadMonth() {
|
||||
setNavEnabled(true);
|
||||
return;
|
||||
}
|
||||
if (loadingEl) loadingEl.classList.add("hidden");
|
||||
const loading = getLoadingEl();
|
||||
if (loading) loading.classList.add("hidden");
|
||||
setNavEnabled(true);
|
||||
}
|
||||
|
||||
if (prevBtn) {
|
||||
prevBtn.addEventListener("click", () => {
|
||||
const prevBtnEl = getPrevBtn();
|
||||
if (prevBtnEl) {
|
||||
prevBtnEl.addEventListener("click", () => {
|
||||
if (document.body.classList.contains("day-detail-sheet-open")) return;
|
||||
const accessDeniedEl = getAccessDeniedEl();
|
||||
if (accessDeniedEl && !accessDeniedEl.hidden) return;
|
||||
state.current.setMonth(state.current.getMonth() - 1);
|
||||
loadMonth();
|
||||
});
|
||||
}
|
||||
if (nextBtn) {
|
||||
nextBtn.addEventListener("click", () => {
|
||||
const nextBtnEl = getNextBtn();
|
||||
if (nextBtnEl) {
|
||||
nextBtnEl.addEventListener("click", () => {
|
||||
if (document.body.classList.contains("day-detail-sheet-open")) return;
|
||||
const accessDeniedEl = getAccessDeniedEl();
|
||||
if (accessDeniedEl && !accessDeniedEl.hidden) return;
|
||||
state.current.setMonth(state.current.getMonth() + 1);
|
||||
loadMonth();
|
||||
@@ -227,12 +240,15 @@ if (nextBtn) {
|
||||
(e) => {
|
||||
if (e.changedTouches.length === 0) return;
|
||||
if (document.body.classList.contains("day-detail-sheet-open")) return;
|
||||
const accessDeniedEl = getAccessDeniedEl();
|
||||
if (accessDeniedEl && !accessDeniedEl.hidden) return;
|
||||
const touch = e.changedTouches[0];
|
||||
const deltaX = touch.clientX - startX;
|
||||
const deltaY = touch.clientY - startY;
|
||||
if (Math.abs(deltaX) <= SWIPE_THRESHOLD) return;
|
||||
if (Math.abs(deltaY) > Math.abs(deltaX)) return;
|
||||
const prevBtn = getPrevBtn();
|
||||
const nextBtn = getNextBtn();
|
||||
if (deltaX > SWIPE_THRESHOLD) {
|
||||
if (prevBtn && prevBtn.disabled) return;
|
||||
state.current.setMonth(state.current.getMonth() - 1);
|
||||
|
||||
Reference in New Issue
Block a user