mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
jf
This commit is contained in:
+34
-201
@@ -1,13 +1,14 @@
|
||||
# Node modules
|
||||
# Dependencies
|
||||
node_modules/
|
||||
frontend/node_modules/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
|
||||
# Build directories
|
||||
/frontend/build
|
||||
# Build outputs
|
||||
/dist
|
||||
/frontend/.next
|
||||
/frontend/out
|
||||
|
||||
# Executables
|
||||
/main
|
||||
@@ -21,11 +22,6 @@ frontend/node_modules/
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
@@ -35,212 +31,49 @@ npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Dependency directories
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Next.js
|
||||
.next/
|
||||
# Local development
|
||||
*.local
|
||||
|
||||
# Cache
|
||||
.cache/
|
||||
.cache-loader/
|
||||
|
||||
# Debug logs from npm
|
||||
npm-debug.log*
|
||||
# Docker overrides
|
||||
docker-compose.override.yml
|
||||
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
# Yarn
|
||||
.yarn/
|
||||
.pnp.*
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.js
|
||||
|
||||
# IDE specific files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# Docker
|
||||
**/docker-compose.override.yml
|
||||
|
||||
# Local development
|
||||
frontend/.env.local
|
||||
frontend/.env.development.local
|
||||
frontend/.env.test.local
|
||||
frontend/.env.production.local
|
||||
|
||||
# Build output
|
||||
# Frontend build files
|
||||
frontend/.next/
|
||||
frontend/out/
|
||||
|
||||
# Debug logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
# Uploads directory
|
||||
/uploads/
|
||||
|
||||
# Database files
|
||||
*.db
|
||||
*.sqlite
|
||||
|
||||
# Local development environment files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Debug files
|
||||
*.debug
|
||||
|
||||
# Local development
|
||||
.DS_Store
|
||||
|
||||
# Local env files
|
||||
.env*.local
|
||||
|
||||
# Local history for editors and IDEs
|
||||
.history/
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Next.js
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Production
|
||||
build
|
||||
|
||||
# Debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Local development
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# IDE
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Build output
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Local env files
|
||||
.env*.local
|
||||
|
||||
# Debug logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Local development
|
||||
.DS_Store
|
||||
|
||||
# Local env files
|
||||
.env*.local
|
||||
|
||||
# Local history for editors and IDEs
|
||||
.history/
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Next.js
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Production
|
||||
build
|
||||
|
||||
# Debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Local development
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# IDE
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Build output
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Local env files
|
||||
.env*.local
|
||||
|
||||
# Debug logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
.pnp.*
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow: /admin/
|
||||
Disallow: /api/
|
||||
Disallow: /login
|
||||
Disallow: /setup
|
||||
Allow: /
|
||||
|
||||
# Sitemap will be served dynamically from backend
|
||||
# Sitemap: /sitemap.xml
|
||||
@@ -0,0 +1,248 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
// Service Worker for PWA support and offline functionality
|
||||
|
||||
const CACHE_VERSION = 'v1.0.0';
|
||||
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',
|
||||
];
|
||||
|
||||
// API endpoints to cache
|
||||
const API_CACHE_ENDPOINTS = [
|
||||
'/api/v1/settings/public',
|
||||
'/api/v1/seo',
|
||||
];
|
||||
|
||||
// Install event - cache static assets
|
||||
self.addEventListener('install', (event) => {
|
||||
console.log('[SW] Installing service worker...');
|
||||
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
console.log('[SW] Caching static assets');
|
||||
return cache.addAll(STATIC_ASSETS.map(url => new Request(url, { cache: 'reload' })));
|
||||
}).catch((error) => {
|
||||
console.error('[SW] Failed to cache static assets:', error);
|
||||
})
|
||||
);
|
||||
|
||||
// Activate immediately
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
// 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
|
||||
.filter((name) => name !== CACHE_NAME)
|
||||
.map((name) => {
|
||||
console.log('[SW] Deleting old cache:', name);
|
||||
return caches.delete(name);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
// Take control immediately
|
||||
return self.clients.claim();
|
||||
});
|
||||
|
||||
// Fetch event - serve from cache, fall back to network
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const { request } = event;
|
||||
const url = new URL(request.url);
|
||||
|
||||
// Skip non-GET requests
|
||||
if (request.method !== 'GET') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip Chrome extensions and non-http(s) requests
|
||||
if (!url.protocol.startsWith('http')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip admin routes
|
||||
if (url.pathname.startsWith('/admin')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle API requests
|
||||
if (url.pathname.startsWith('/api/')) {
|
||||
event.respondWith(handleAPIRequest(request));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle static assets and pages
|
||||
event.respondWith(handleStaticRequest(request));
|
||||
});
|
||||
|
||||
// Handle static requests - Cache First strategy
|
||||
async function handleStaticRequest(request) {
|
||||
try {
|
||||
// Try cache first
|
||||
const cachedResponse = await caches.match(request);
|
||||
if (cachedResponse) {
|
||||
// Return cached response and update in background
|
||||
fetchAndUpdateCache(request);
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// Not in cache - fetch from network
|
||||
const networkResponse = await fetch(request);
|
||||
|
||||
// Cache successful responses
|
||||
if (networkResponse.ok) {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
cache.put(request, networkResponse.clone());
|
||||
}
|
||||
|
||||
return networkResponse;
|
||||
} catch (error) {
|
||||
console.error('[SW] Fetch failed:', error);
|
||||
|
||||
// Return offline page if available
|
||||
const cachedOffline = await caches.match('/offline.html');
|
||||
if (cachedOffline) {
|
||||
return cachedOffline;
|
||||
}
|
||||
|
||||
// Return basic offline response
|
||||
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 {
|
||||
// Try network first for fresh data
|
||||
const networkResponse = await fetch(request);
|
||||
|
||||
// Cache successful responses
|
||||
if (networkResponse.ok) {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
cache.put(request, networkResponse.clone());
|
||||
}
|
||||
|
||||
return networkResponse;
|
||||
} catch (error) {
|
||||
console.log('[SW] Network failed, trying cache:', request.url);
|
||||
|
||||
// Fall back to cache
|
||||
const cachedResponse = await caches.match(request);
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// Return error response
|
||||
return new Response(
|
||||
JSON.stringify({ error: 'Offline - cached data not available' }),
|
||||
{
|
||||
status: 503,
|
||||
statusText: 'Service Unavailable',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Update cache in background
|
||||
async function fetchAndUpdateCache(request) {
|
||||
try {
|
||||
const response = await fetch(request);
|
||||
if (response.ok) {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
cache.put(request, response);
|
||||
}
|
||||
} catch (error) {
|
||||
// Silent fail - we already returned cached version
|
||||
}
|
||||
}
|
||||
|
||||
// Handle background sync for offline actions
|
||||
self.addEventListener('sync', (event) => {
|
||||
console.log('[SW] Background sync:', event.tag);
|
||||
|
||||
if (event.tag === 'sync-data') {
|
||||
event.waitUntil(syncOfflineData());
|
||||
}
|
||||
});
|
||||
|
||||
async function syncOfflineData() {
|
||||
// Implement offline data sync logic here
|
||||
// For example, sync form submissions, votes, etc.
|
||||
console.log('[SW] Syncing offline data...');
|
||||
}
|
||||
|
||||
// Handle push notifications
|
||||
self.addEventListener('push', (event) => {
|
||||
const data = event.data ? event.data.json() : {};
|
||||
|
||||
const title = data.title || 'Fotbal Club';
|
||||
const options = {
|
||||
body: data.body || 'Nová notifikace',
|
||||
icon: '/logo192.png',
|
||||
badge: '/logo192.png',
|
||||
data: data.url || '/',
|
||||
};
|
||||
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(title, options)
|
||||
);
|
||||
});
|
||||
|
||||
// Handle notification clicks
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
event.notification.close();
|
||||
|
||||
const urlToOpen = event.notification.data || '/';
|
||||
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
|
||||
// Check if there's already a window open
|
||||
for (const client of clientList) {
|
||||
if (client.url === urlToOpen && 'focus' in client) {
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
// Open new window
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow(urlToOpen);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Message handler for manual cache updates
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
|
||||
if (event.data && event.data.type === 'CLEAR_CACHE') {
|
||||
event.waitUntil(
|
||||
caches.delete(CACHE_NAME).then(() => {
|
||||
return caches.open(CACHE_NAME);
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[SW] Service Worker loaded successfully');
|
||||
Reference in New Issue
Block a user