- Introduced a new `LOG_LEVEL` configuration option in the `.env.example` file to allow users to set the logging level (DEBUG, INFO, WARNING, ERROR). - Updated the `Settings` class to include the `log_level` attribute, normalizing its value to ensure valid logging levels are used. - Modified the logging setup in `run.py` to utilize the configured log level, enhancing flexibility in log management. - Enhanced the Mini App to include the logging level in the JavaScript configuration, allowing for consistent logging behavior across the application. - Added a new `logger.js` module for frontend logging, implementing level-based filtering and console delegation. - Included unit tests for the new logger functionality to ensure proper behavior and level handling.
103 lines
4.3 KiB
HTML
103 lines
4.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
<title></title>
|
|
<link rel="stylesheet" href="css/base.css">
|
|
<link rel="stylesheet" href="css/calendar.css">
|
|
<link rel="stylesheet" href="css/day-detail.css">
|
|
<link rel="stylesheet" href="css/hints.css">
|
|
<link rel="stylesheet" href="css/markers.css">
|
|
<link rel="stylesheet" href="css/duty-list.css">
|
|
<link rel="stylesheet" href="css/states.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="calendar-sticky" id="calendarSticky">
|
|
<header class="header">
|
|
<button type="button" class="nav nav--prev" id="prevMonth" aria-label="">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
|
|
</button>
|
|
<h1 class="title" id="monthTitle"></h1>
|
|
<button type="button" class="nav nav--next" id="nextMonth" aria-label="">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
|
|
</button>
|
|
</header>
|
|
<div class="weekdays">
|
|
<span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
</div>
|
|
<div class="calendar" id="calendar"></div>
|
|
</div>
|
|
<div class="duty-list" id="dutyList"></div>
|
|
<div class="loading" id="loading"><span class="loading__spinner" aria-hidden="true"></span><span class="loading__text"></span></div>
|
|
<div class="error" id="error" hidden></div>
|
|
<div class="access-denied" id="accessDenied" hidden></div>
|
|
<div id="currentDutyView" class="current-duty-view hidden"></div>
|
|
</div>
|
|
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
|
<script>
|
|
if (window.Telegram && window.Telegram.WebApp && window.Telegram.WebApp.ready) {
|
|
window.Telegram.WebApp.ready();
|
|
}
|
|
</script>
|
|
<script src="/app/config.js"></script>
|
|
<script type="importmap">
|
|
{
|
|
"scopes": {
|
|
"./js/": {
|
|
"./js/api.js": "./js/api.js?v=3",
|
|
"./js/auth.js": "./js/auth.js?v=3",
|
|
"./js/calendar.js": "./js/calendar.js?v=2",
|
|
"./js/constants.js": "./js/constants.js?v=2",
|
|
"./js/contactHtml.js": "./js/contactHtml.js?v=2",
|
|
"./js/currentDuty.js": "./js/currentDuty.js?v=2",
|
|
"./js/dateUtils.js": "./js/dateUtils.js?v=2",
|
|
"./js/dayDetail.js": "./js/dayDetail.js?v=2",
|
|
"./js/dom.js": "./js/dom.js?v=3",
|
|
"./js/dutyList.js": "./js/dutyList.js?v=2",
|
|
"./js/hints.js": "./js/hints.js?v=2",
|
|
"./js/i18n.js": "./js/i18n.js?v=3",
|
|
"./js/logger.js": "./js/logger.js?v=1",
|
|
"./js/theme.js": "./js/theme.js?v=2",
|
|
"./js/ui.js": "./js/ui.js?v=2",
|
|
"./js/utils.js": "./js/utils.js?v=2"
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<script type="module" src="js/main.js?v=5" id="main-module"></script>
|
|
<script>
|
|
(function() {
|
|
var loadTimeout = 10000;
|
|
var mainScript = document.getElementById("main-module");
|
|
if (mainScript) {
|
|
mainScript.addEventListener("error", function() {
|
|
var loading = document.getElementById("loading");
|
|
if (loading && !loading.classList.contains("hidden")) {
|
|
loading.classList.add("hidden");
|
|
var err = document.getElementById("error");
|
|
if (err) {
|
|
err.hidden = false;
|
|
err.textContent = "Failed to load app. Check connection and try again.";
|
|
}
|
|
}
|
|
});
|
|
}
|
|
setTimeout(function() {
|
|
if (window.__dtReady) return;
|
|
var loading = document.getElementById("loading");
|
|
if (loading && !loading.classList.contains("hidden")) {
|
|
loading.classList.add("hidden");
|
|
var err = document.getElementById("error");
|
|
if (err) {
|
|
err.hidden = false;
|
|
err.textContent = "App is taking too long to load. Check your connection and refresh.";
|
|
}
|
|
}
|
|
}, loadTimeout);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|