T5: Offline queue + background sync — fix missing offline banner, add API GET caching to SW

- Added missing #offlineBanner HTML element with queueCountBadge
  (showOfflineBanner/hideOfflineBanner were referencing it but it didn't exist)
- Enhanced SW: API GET calls now use network-first with cache fallback
  (POST/PUT/DELETE still pass through — main thread handles offline queuing)
- Bumped SW cache from canteen-v1 to canteen-v2
This commit is contained in:
2026-05-21 12:01:05 -04:00
parent 622996624a
commit 37ba54b750
2 changed files with 25 additions and 2 deletions
+8
View File
@@ -1149,6 +1149,14 @@
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════
OFFLINE BANNER
═══════════════════════════════════════════════════════════════════════ -->
<div id="offlineBanner" class="offline-banner">
📡 Offline mode — changes will sync when connected
<span id="queueCountBadge" class="queue-count" style="display:none;">0</span>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════
DRAWER
═══════════════════════════════════════════════════════════════════════ -->
+17 -2
View File
@@ -3,7 +3,7 @@
// Caches app shell + CDN deps. Network-first for API, cache fallback for static.
// ═══════════════════════════════════════════════════════════════════════════
const CACHE_NAME = 'canteen-v1';
const CACHE_NAME = 'canteen-v2';
// App shell — core resources needed to boot the PWA
const APP_SHELL = [
@@ -73,8 +73,23 @@ self.addEventListener('fetch', (event) => {
return;
}
// API calls: pass through — main thread handles offline queuing
// API GET calls: network-first, cache fallback (offline reads)
// API POST/PUT/DELETE: pass through — main thread handles offline queuing
if (url.pathname.startsWith('/api/')) {
if (event.request.method === 'GET') {
event.respondWith(
fetch(event.request)
.then((response) => {
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone));
}
return response;
})
.catch(() => caches.match(event.request))
);
}
// Non-GET API calls: pass through — main thread queues offline writes
return;
}