feat: Реализован полный CRUD для админ-панели и улучшена функциональность

- Portfolio CRUD: добавление, редактирование, удаление, переключение публикации
- Services CRUD: полное управление услугами с возможностью активации/деактивации
- Banner system: новая модель Banner с CRUD операциями и аналитикой кликов
- Telegram integration: расширенные настройки бота, обнаружение чатов, отправка сообщений
- Media management: улучшенная загрузка файлов с оптимизацией изображений и превью
- UI improvements: обновлённые админ-панели с rich-text редактором и drag&drop загрузкой
- Database: добавлена таблица banners с полями для баннеров и аналитики
This commit is contained in:
2025-10-22 20:32:16 +09:00
parent 150891b29d
commit 9477ff6de0
69 changed files with 11451 additions and 2321 deletions

View File

@@ -1,21 +1,24 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.0';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.0';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.0';
const CACHE_NAME = 'smartsoltech-v1.0.1';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.1';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.1';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-512x512.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css',
'https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js'
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
@@ -155,17 +158,25 @@ async function networkFirst(request) {
}
async function staleWhileRevalidate(request) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
});
return cachedResponse || fetchPromise;
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse && networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
}).catch(error => {
console.log('staleWhileRevalidate fetch failed:', error);
return null;
});
return cachedResponse || fetchPromise || new Response('Not available', { status: 503 });
} catch (error) {
console.error('staleWhileRevalidate error:', error);
return new Response('Service unavailable', { status: 503 });
}
}
// Helper functions