diff --git a/web/index.html b/web/index.html
index 2e09514..7432a41 100644
--- a/web/index.html
+++ b/web/index.html
@@ -27,14 +27,15 @@
{ href: 'daily-bookmarks.css', id: 'dailyBookmarksCss', disabled: true }
];
const jsFiles = [
- 'app.js',
- 'dashboard.js',
- 'settings.js',
- 'ai-debug.js',
- 'vendor/list.min.js',
- 'automation.js',
- 'daily-bookmarks.js',
- 'trade-fairs.js'
+ { src: 'app.js' },
+ { src: 'dashboard.js' },
+ { src: 'settings.js' },
+ { src: 'ai-debug.js' },
+ { src: 'vendor/list.min.js' },
+ { src: 'automation.js' },
+ { src: 'daily-bookmarks.js' },
+ // Optional: new bookmark subpage. If not yet deployed/cached, app must still boot.
+ { src: 'trade-fairs.js', optional: true }
];
function withVersion(value) {
@@ -65,16 +66,51 @@
});
}
+ function normalizeScriptEntry(entry) {
+ if (typeof entry === 'string') {
+ return { src: entry, optional: false };
+ }
+ return {
+ src: entry && entry.src ? entry.src : '',
+ optional: Boolean(entry && entry.optional)
+ };
+ }
+
+ function showBootstrapError(message) {
+ document.body.classList.remove('auth-pending');
+ const loadingEl = document.getElementById('loading');
+ const errorEl = document.getElementById('error');
+ if (loadingEl) {
+ loadingEl.style.display = 'none';
+ }
+ if (errorEl) {
+ errorEl.style.display = 'block';
+ errorEl.textContent = message || 'Die Anwendung konnte nicht geladen werden.';
+ }
+ }
+
function loadScriptsSequentially(list, index = 0) {
return new Promise((resolve, reject) => {
if (index >= list.length) {
resolve();
return;
}
+ const entry = normalizeScriptEntry(list[index]);
+ if (!entry.src) {
+ loadScriptsSequentially(list, index + 1).then(resolve).catch(reject);
+ return;
+ }
const script = document.createElement('script');
- script.src = withVersion(list[index]);
+ script.src = withVersion(entry.src);
script.onload = () => loadScriptsSequentially(list, index + 1).then(resolve).catch(reject);
- script.onerror = reject;
+ script.onerror = () => {
+ if (entry.optional) {
+ console.warn('Optionales Script konnte nicht geladen werden:', entry.src);
+ loadScriptsSequentially(list, index + 1).then(resolve).catch(reject);
+ return;
+ }
+ reject(new Error(`Script konnte nicht geladen werden: ${entry.src}`));
+ };
document.body.appendChild(script);
});
}
@@ -86,10 +122,14 @@
redirectToLogin();
return;
}
+ if (!res.ok) {
+ throw new Error(`Session-Check fehlgeschlagen (${res.status})`);
+ }
loadStyles();
await loadScriptsSequentially(jsFiles);
- } catch (_error) {
- redirectToLogin();
+ } catch (error) {
+ console.error('Bootstrap fehlgeschlagen:', error);
+ showBootstrapError('Fehler beim Laden der Anwendung. Bitte Seite neu laden.');
}
}