All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
Mobile Progressive Web App für Baustellen-Doku, spricht die REST-API des Dolibarr-Bericht-Moduls. MVP-Features: - Vanilla JavaScript, kein Build-Step nötig - Login mit Dolibarr-Credentials → JWT (7 Tage) - Auftragsliste mit Suche und Multi-User-Filter - Auftragsdetail mit Kunde, Adresse, Click-to-Call - Foto-Aufnahme via Kamera oder Galerie (multiple) - Clientseitige Bildverkleinerung (max 2000px, JPEG q=0.85) - Offline-Queue in IndexedDB für Uploads ohne Netz - Auto-Sync bei Online-Event mit Status-Badge - Service Worker für App-Shell-Cache - PWA-installierbar (Manifest, Icons, Theme-Color) Hosting: awl.data-it-solution.de/baustelle/ via Apache-Alias Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.6 KiB
JavaScript
55 lines
1.6 KiB
JavaScript
/* Mini Hash-Router für die PWA.
|
|
* Routen:
|
|
* #/login
|
|
* #/orders
|
|
* #/orders/<id>
|
|
* #/orders/<id>/upload
|
|
* #/settings
|
|
*/
|
|
(function () {
|
|
const routes = {};
|
|
let currentRoute = null;
|
|
|
|
function on(pattern, handler) {
|
|
// Pattern: '/orders/:id'
|
|
const re = new RegExp('^' + pattern.replace(/:[a-z]+/gi, '([^/]+)') + '$');
|
|
const params = (pattern.match(/:([a-z]+)/gi) || []).map(s => s.slice(1));
|
|
routes[pattern] = { re, params, handler };
|
|
}
|
|
|
|
async function navigate(hash) {
|
|
if (!hash) hash = window.location.hash || '#/orders';
|
|
const path = hash.replace(/^#/, '') || '/orders';
|
|
for (const key of Object.keys(routes)) {
|
|
const r = routes[key];
|
|
const m = path.match(r.re);
|
|
if (m) {
|
|
const args = {};
|
|
r.params.forEach((p, i) => { args[p] = decodeURIComponent(m[i + 1]); });
|
|
currentRoute = { pattern: key, args };
|
|
try {
|
|
await r.handler(args);
|
|
} catch (e) {
|
|
console.error(e);
|
|
showToast('Fehler: ' + e.message, 'error');
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
// Default
|
|
navigate('#/orders');
|
|
}
|
|
|
|
function go(hash) {
|
|
if (hash !== window.location.hash) {
|
|
window.location.hash = hash;
|
|
} else {
|
|
navigate(hash);
|
|
}
|
|
}
|
|
|
|
window.addEventListener('hashchange', () => navigate());
|
|
document.addEventListener('DOMContentLoaded', () => navigate());
|
|
|
|
window.router = { on, navigate, go };
|
|
})();
|