This commit is contained in:
Tomas Dvorak
2025-11-02 01:04:02 +01:00
parent ac886502e0
commit b9cea0cd77
153 changed files with 43713 additions and 1700 deletions
+10 -1
View File
@@ -6,8 +6,9 @@
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<!-- Optional SVG logo if available in public folder (keeps ICO as fallback) -->
<!-- <link rel="icon" type="image/svg+xml" href="%PUBLIC_URL%/logo.svg" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="theme-color" content="#000000" />
<meta name="color-scheme" content="light dark" />
<meta
name="description"
content="Oficiální webové stránky fotbalového klubu - aktuality, zápasy, tabulky, hráči a fotogalerie"
@@ -18,6 +19,14 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- Performance: preconnect to Google Fonts origins used by the app -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<!-- Performance: preconnect to YouTube origins for faster video/thumbnail loads -->
<link rel="preconnect" href="https://www.youtube.com" crossorigin />
<link rel="preconnect" href="https://i.ytimg.com" crossorigin />
<link rel="preconnect" href="https://s.ytimg.com" crossorigin />
<link rel="preconnect" href="https://www.google.com" crossorigin />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
+37 -5
View File
@@ -1,19 +1,18 @@
/* eslint-disable no-restricted-globals */
// Service Worker for PWA support and offline functionality
const CACHE_VERSION = 'v1.0.0';
const CACHE_VERSION = 'v1.0.1';
const CACHE_NAME = `fotbal-club-cache-${CACHE_VERSION}`;
// Assets to cache on install
const STATIC_ASSETS = [
'/',
'/index.html',
'/static/css/main.css',
'/static/js/main.js',
'/manifest.json',
'/favicon.ico',
'/logo192.png',
'/logo512.png',
'/robots.txt',
];
// API endpoints to cache
@@ -75,11 +74,22 @@ self.addEventListener('fetch', (event) => {
return;
}
// Only handle same-origin requests
if (url.origin !== self.location.origin) {
return;
}
// Skip admin routes
if (url.pathname.startsWith('/admin')) {
return;
}
// Handle SPA navigations with app shell fallback
if (request.mode === 'navigate') {
event.respondWith(handleNavigationRequest(request));
return;
}
// Handle API requests
if (url.pathname.startsWith('/api/')) {
event.respondWith(handleAPIRequest(request));
@@ -114,8 +124,8 @@ async function handleStaticRequest(request) {
} catch (error) {
console.error('[SW] Fetch failed:', error);
// Return offline page if available
const cachedOffline = await caches.match('/offline.html');
// Return app shell (index.html) if available
const cachedOffline = await caches.match('/index.html');
if (cachedOffline) {
return cachedOffline;
}
@@ -129,6 +139,28 @@ async function handleStaticRequest(request) {
}
}
// Handle SPA navigation requests - Network First with index.html fallback
async function handleNavigationRequest(request) {
try {
const networkResponse = await fetch(request);
if (networkResponse && networkResponse.ok) {
return networkResponse;
}
} catch (error) {
console.error('[SW] Navigation fetch failed:', error);
}
// Fallback to cached index.html (app shell)
const cachedIndex = await caches.match('/index.html');
if (cachedIndex) {
return cachedIndex;
}
return new Response('Offline - Please check your connection', {
status: 503,
statusText: 'Service Unavailable',
headers: { 'Content-Type': 'text/plain' },
});
}
// Handle API requests - Network First strategy with cache fallback
async function handleAPIRequest(request) {
try {