feat: enhance CI workflow and update webapp styles
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:
2026-03-02 17:20:33 +03:00
parent e3240d0981
commit 2fb553567f
29 changed files with 2212 additions and 1375 deletions

View File

@@ -67,31 +67,26 @@ export async function apiGet(path, params = {}, options = {}) {
* @returns {Promise<object[]>}
*/
export async function fetchDuties(from, to, signal) {
try {
const res = await apiGet("/api/duties", { from, to }, { signal });
if (res.status === 403) {
let detail = t(state.lang, "access_denied");
try {
const body = await res.json();
if (body && body.detail !== undefined) {
detail =
typeof body.detail === "string"
? body.detail
: (body.detail.msg || JSON.stringify(body.detail));
}
} catch (parseErr) {
/* ignore */
const res = await apiGet("/api/duties", { from, to }, { signal });
if (res.status === 403) {
let detail = t(state.lang, "access_denied");
try {
const body = await res.json();
if (body && body.detail !== undefined) {
detail =
typeof body.detail === "string"
? body.detail
: (body.detail.msg || JSON.stringify(body.detail));
}
const err = new Error("ACCESS_DENIED");
err.serverDetail = detail;
throw err;
} catch (parseErr) {
/* ignore */
}
if (!res.ok) throw new Error(t(state.lang, "error_load_failed"));
return res.json();
} catch (e) {
if (e.name === "AbortError") throw e;
throw e;
const err = new Error("ACCESS_DENIED");
err.serverDetail = detail;
throw err;
}
if (!res.ok) throw new Error(t(state.lang, "error_load_failed"));
return res.json();
}
/**