PWA-implementation
This commit is contained in:
106
LittleShop/wwwroot/sw.js
Normal file
106
LittleShop/wwwroot/sw.js
Normal file
@@ -0,0 +1,106 @@
|
||||
// LittleShop Admin - Service Worker
|
||||
// Provides offline functionality and app-like experience
|
||||
|
||||
const CACHE_NAME = 'littleshop-admin-v1';
|
||||
const urlsToCache = [
|
||||
'/Admin/Dashboard',
|
||||
'/Admin/Orders',
|
||||
'/Admin/Products',
|
||||
'/Admin/Categories',
|
||||
'/lib/bootstrap/css/bootstrap.min.css',
|
||||
'/lib/fontawesome/css/all.min.css',
|
||||
'/lib/bootstrap-icons/bootstrap-icons.css',
|
||||
'/css/modern-admin.css',
|
||||
'/lib/jquery/jquery.min.js',
|
||||
'/lib/bootstrap/js/bootstrap.bundle.min.js',
|
||||
'/js/modern-mobile.js',
|
||||
'/lib/fontawesome/webfonts/fa-solid-900.woff2',
|
||||
'/lib/fontawesome/webfonts/fa-brands-400.woff2'
|
||||
];
|
||||
|
||||
// Install event - cache resources
|
||||
self.addEventListener('install', (event) => {
|
||||
console.log('SW: Installing service worker');
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME)
|
||||
.then((cache) => {
|
||||
console.log('SW: Caching app shell');
|
||||
return cache.addAll(urlsToCache);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Activate event - clean up old caches
|
||||
self.addEventListener('activate', (event) => {
|
||||
console.log('SW: Activating service worker');
|
||||
event.waitUntil(
|
||||
caches.keys().then((cacheNames) => {
|
||||
return Promise.all(
|
||||
cacheNames.map((cacheName) => {
|
||||
if (cacheName !== CACHE_NAME) {
|
||||
console.log('SW: Deleting old cache:', cacheName);
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Fetch event - serve from cache, fallback to network
|
||||
self.addEventListener('fetch', (event) => {
|
||||
// Only handle GET requests
|
||||
if (event.request.method !== 'GET') {
|
||||
return;
|
||||
}
|
||||
|
||||
event.respondWith(
|
||||
caches.match(event.request)
|
||||
.then((response) => {
|
||||
// Return cached version or fetch from network
|
||||
return response || fetch(event.request).catch(() => {
|
||||
// If both cache and network fail, show offline page for HTML requests
|
||||
if (event.request.headers.get('accept').includes('text/html')) {
|
||||
return new Response(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>LittleShop Admin - Offline</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: #f9fafb;
|
||||
color: #374151;
|
||||
}
|
||||
.offline-icon { font-size: 4rem; margin-bottom: 1rem; color: #6b7280; }
|
||||
h1 { color: #1f2937; margin-bottom: 0.5rem; }
|
||||
p { color: #6b7280; margin-bottom: 2rem; }
|
||||
.btn {
|
||||
background: #2563eb;
|
||||
color: white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="offline-icon">📱</div>
|
||||
<h1>You're offline</h1>
|
||||
<p>Please check your internet connection and try again.</p>
|
||||
<a href="/Admin/Dashboard" class="btn">Try Again</a>
|
||||
</body>
|
||||
</html>
|
||||
`, {
|
||||
headers: { 'Content-Type': 'text/html' }
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user