121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
// Service Worker untuk caching dan offline support
|
|
const CACHE_NAME = 'admin-dashboard-v1';
|
|
const urlsToCache = [
|
|
'/admin',
|
|
'/admin/dashboard',
|
|
'/admin/system-statistics',
|
|
'/admin/classification-history',
|
|
'/admin/manage-admin',
|
|
'https://cdn.tailwindcss.com',
|
|
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
|
|
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
|
|
];
|
|
|
|
// Install Service Worker
|
|
self.addEventListener('install', event => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => {
|
|
console.log('Cache opened');
|
|
return cache.addAll(urlsToCache).catch(err => {
|
|
console.log('Cache addAll partially failed:', err);
|
|
// Continue even if some urls fail to cache
|
|
return Promise.resolve();
|
|
});
|
|
})
|
|
);
|
|
self.skipWaiting();
|
|
});
|
|
|
|
// Activate Service Worker
|
|
self.addEventListener('activate', event => {
|
|
event.waitUntil(
|
|
caches.keys().then(cacheNames => {
|
|
return Promise.all(
|
|
cacheNames.map(cacheName => {
|
|
if (cacheName !== CACHE_NAME) {
|
|
console.log('Deleting old cache:', cacheName);
|
|
return caches.delete(cacheName);
|
|
}
|
|
})
|
|
);
|
|
})
|
|
);
|
|
self.clients.claim();
|
|
});
|
|
|
|
// Fetch Event - Network First, then Cache
|
|
self.addEventListener('fetch', event => {
|
|
const { request } = event;
|
|
const url = new URL(request.url);
|
|
|
|
// Skip non-GET requests
|
|
if (request.method !== 'GET') {
|
|
return;
|
|
}
|
|
|
|
// Skip admin area fetches (always fresh)
|
|
if (url.pathname.includes('/admin/api/')) {
|
|
event.respondWith(
|
|
fetch(request)
|
|
.then(response => {
|
|
// Cache valid responses
|
|
if (response && response.status === 200 && response.type === 'basic') {
|
|
const responseToCache = response.clone();
|
|
caches.open(CACHE_NAME).then(cache => {
|
|
cache.put(request, responseToCache);
|
|
});
|
|
}
|
|
return response;
|
|
})
|
|
.catch(() => {
|
|
// Return cached version if network fails
|
|
return caches.match(request)
|
|
.then(cached => cached || new Response('Offline', { status: 503 }));
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Cache First strategy untuk static assets
|
|
if (request.url.includes('cdn.') ||
|
|
request.url.includes('fonts.') ||
|
|
request.url.includes('cdnjs')) {
|
|
event.respondWith(
|
|
caches.match(request)
|
|
.then(cached => {
|
|
return cached || fetch(request)
|
|
.then(response => {
|
|
if (response && response.status === 200) {
|
|
const responseToCache = response.clone();
|
|
caches.open(CACHE_NAME).then(cache => {
|
|
cache.put(request, responseToCache);
|
|
});
|
|
}
|
|
return response;
|
|
})
|
|
.catch(() => new Response('Resource not available', { status: 404 }));
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Network First for HTML pages
|
|
event.respondWith(
|
|
fetch(request)
|
|
.then(response => {
|
|
if (response && response.status === 200) {
|
|
const responseToCache = response.clone();
|
|
caches.open(CACHE_NAME).then(cache => {
|
|
cache.put(request, responseToCache);
|
|
});
|
|
}
|
|
return response;
|
|
})
|
|
.catch(() => {
|
|
return caches.match(request)
|
|
.then(cached => cached || new Response('Offline - Page not cached', { status: 503 }));
|
|
})
|
|
);
|
|
});
|