vor ähnlichkeitsprüfung
This commit is contained in:
110
web/index.html
110
web/index.html
@@ -7,13 +7,89 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/app-icon-64.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="assets/app-icon-192.png">
|
||||
<link rel="apple-touch-icon" href="assets/app-icon-192.png">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="dashboard.css">
|
||||
<link rel="stylesheet" href="settings.css">
|
||||
<link rel="stylesheet" href="automation.css">
|
||||
<link id="dailyBookmarksCss" rel="stylesheet" href="daily-bookmarks.css" disabled>
|
||||
<style>
|
||||
body.auth-pending {
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function gateAssets() {
|
||||
const API_URL = 'https://fb.srv.medeba-media.de/api';
|
||||
const LOGIN_PAGE = 'login.html';
|
||||
const cssFiles = [
|
||||
{ href: 'style.css' },
|
||||
{ href: 'dashboard.css' },
|
||||
{ href: 'settings.css' },
|
||||
{ href: 'automation.css' },
|
||||
{ href: 'daily-bookmarks.css', id: 'dailyBookmarksCss', disabled: true }
|
||||
];
|
||||
const jsFiles = [
|
||||
'app.js',
|
||||
'dashboard.js',
|
||||
'settings.js',
|
||||
'vendor/list.min.js',
|
||||
'automation.js',
|
||||
'daily-bookmarks.js'
|
||||
];
|
||||
|
||||
function redirectToLogin() {
|
||||
try {
|
||||
const redirect = encodeURIComponent(window.location.href);
|
||||
window.location.replace(`${LOGIN_PAGE}?redirect=${redirect}`);
|
||||
} catch (_error) {
|
||||
window.location.replace(LOGIN_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
function loadStyles() {
|
||||
cssFiles.forEach(({ href, id, disabled }) => {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = href;
|
||||
if (id) link.id = id;
|
||||
if (disabled) link.disabled = true;
|
||||
document.head.appendChild(link);
|
||||
});
|
||||
}
|
||||
|
||||
function loadScriptsSequentially(list, index = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (index >= list.length) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const script = document.createElement('script');
|
||||
script.src = list[index];
|
||||
script.onload = () => loadScriptsSequentially(list, index + 1).then(resolve).catch(reject);
|
||||
script.onerror = reject;
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
async function bootstrap() {
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/session`, { credentials: 'include' });
|
||||
if (res.status === 401) {
|
||||
redirectToLogin();
|
||||
return;
|
||||
}
|
||||
loadStyles();
|
||||
await loadScriptsSequentially(jsFiles);
|
||||
} catch (_error) {
|
||||
redirectToLogin();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
bootstrap();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', bootstrap);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="auth-pending">
|
||||
<div class="shell">
|
||||
<header class="site-header site-header--global">
|
||||
<div class="container">
|
||||
@@ -28,6 +104,7 @@
|
||||
<a class="site-nav__btn" data-view-target="bookmarks" href="bookmarks.html">🔖 Bookmarks</a>
|
||||
<a class="site-nav__btn" data-view-target="automation" href="index.html?view=automation">⚡️ Automationen</a>
|
||||
<a class="site-nav__btn" data-view-target="daily-bookmarks" href="index.html?view=daily-bookmarks">✅ Daily Bookmarks</a>
|
||||
<button class="site-nav__btn site-nav__btn--icon" id="logoutBtn" type="button" aria-label="Abmelden">🚪</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1305,12 +1382,6 @@
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
<script src="dashboard.js"></script>
|
||||
<script src="settings.js"></script>
|
||||
<script src="vendor/list.min.js"></script>
|
||||
<script src="automation.js"></script>
|
||||
<script src="daily-bookmarks.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
const buttons = Array.from(document.querySelectorAll('[data-view-target]'));
|
||||
@@ -1320,11 +1391,25 @@
|
||||
const initialParam = params.get('view');
|
||||
const defaultView = viewMap[initialParam] ? initialParam : 'posts';
|
||||
const VIEW_CHANGE_EVENT = 'app:view-change';
|
||||
const BASE_TITLE = 'Post Tracker';
|
||||
const VIEW_TITLES = {
|
||||
posts: 'Beiträge',
|
||||
dashboard: 'Dashboard',
|
||||
settings: 'Einstellungen',
|
||||
bookmarks: 'Bookmarks',
|
||||
automation: 'Automationen',
|
||||
'daily-bookmarks': 'Daily Bookmarks'
|
||||
};
|
||||
|
||||
function dispatchViewChange(view) {
|
||||
window.dispatchEvent(new CustomEvent(VIEW_CHANGE_EVENT, { detail: { view } }));
|
||||
}
|
||||
|
||||
function updateDocumentTitle(view) {
|
||||
const title = VIEW_TITLES[view];
|
||||
document.title = title ? `${title} – ${BASE_TITLE}` : BASE_TITLE;
|
||||
}
|
||||
|
||||
function setView(view, options = { updateHistory: true }) {
|
||||
if (!viewMap[view]) {
|
||||
view = 'posts';
|
||||
@@ -1357,6 +1442,7 @@
|
||||
window.history.pushState({ view }, '', newUrl);
|
||||
}
|
||||
|
||||
updateDocumentTitle(view);
|
||||
dispatchViewChange(view);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user