diff --git a/Js/sw-register.js b/Js/sw-register.js index 86afa33..a90b3b7 100644 --- a/Js/sw-register.js +++ b/Js/sw-register.js @@ -1,132 +1,245 @@ -// Enregistrement du Service Worker -if ('serviceWorker' in navigator) { - window.addEventListener('load', function() { - // S'assurer que nous sommes sur HTTPS en production - if (location.protocol === 'https:' || location.hostname === 'localhost') { - navigator.serviceWorker.register('/service-worker.js') - .then(function(registration) { - console.log('[Service Worker] Enregistré avec succès:', registration.scope); +// Enregistrement du Service Worker amélioré +(function() { + // Vérifier si le Service Worker est supporté + if (!('serviceWorker' in navigator)) { + console.warn('[App] Service Worker non supporté'); + return; + } + + // Vérifier si nous sommes en HTTPS ou localhost + if (window.location.protocol !== 'https:' && window.location.hostname !== 'localhost') { + console.warn('[App] Service Worker nécessite HTTPS en production'); + return; + } + + // Fonction principale d'enregistrement + function registerServiceWorker() { + const swUrl = '/service-worker.js?v=1.1'; + + navigator.serviceWorker.register(swUrl) + .then(function(registration) { + console.log('[Service Worker] Enregistré avec succès:', registration.scope); + + // Vérifier si une mise à jour est disponible + registration.addEventListener('updatefound', function() { + const installingWorker = registration.installing; + console.log('[Service Worker] Mise à jour trouvée:', installingWorker.state); - // Vérifier les mises à jour - registration.addEventListener('updatefound', () => { - const newWorker = registration.installing; - console.log('[Service Worker] Mise à jour trouvée:', newWorker.state); + installingWorker.addEventListener('statechange', function() { + console.log('[Service Worker] Nouvel état:', this.state); - newWorker.addEventListener('statechange', () => { - if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { - // Nouvelle version disponible - console.log('[Service Worker] Nouvelle version disponible'); - this.showUpdateNotification(); - } - }); + if (this.state === 'installed' && navigator.serviceWorker.controller) { + // Nouvelle version disponible + showUpdateNotification(); + } + + if (this.state === 'activated') { + console.log('[Service Worker] Nouveau Service Worker activé'); + // Notifier tous les clients + sendMessageToSW({ type: 'NEW_VERSION_ACTIVATED' }); + } }); - }) - .catch(function(error) { - console.error('[Service Worker] Échec de l\'enregistrement:', error); }); - } - }); - - // Gestion hors ligne - window.addEventListener('online', () => { - document.documentElement.classList.remove('offline'); - console.log('[App] Connexion rétablie'); - this.showOnlineNotification(); - }); - - window.addEventListener('offline', () => { - document.documentElement.classList.add('offline'); - console.log('[App] Mode hors ligne'); - this.showOfflineNotification(); - }); -} - -// Notification de mise à jour -function showUpdateNotification() { - if (window.appConfig?.isAnglophone) { - if (confirm('A new version is available. Reload the page?')) { - window.location.reload(); - } - } else { - if (confirm('Une nouvelle version est disponible. Recharger la page?')) { - window.location.reload(); - } - } -} - -// Notification en ligne -function showOnlineNotification() { - // Créer une notification toast - const toast = document.createElement('div'); - toast.className = 'position-fixed top-0 end-0 p-3'; - toast.style.zIndex = '9999'; - - toast.innerHTML = ` - - `; - - document.body.appendChild(toast); - - // Supprimer après 3 secondes - setTimeout(() => { - toast.remove(); - }, 3000); -} - -// Notification hors ligne -function showOfflineNotification() { - // Créer une notification toast - const toast = document.createElement('div'); - toast.className = 'position-fixed top-0 end-0 p-3'; - toast.style.zIndex = '9999'; - - toast.innerHTML = ` - - `; - - document.body.appendChild(toast); - - // Supprimer après 5 secondes - setTimeout(() => { - toast.remove(); - }, 5000); -} - -// Fonction pour forcer la mise à jour du Service Worker -function updateServiceWorker() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.update().then(() => { - console.log('[Service Worker] Mise à jour forcée'); + + // Vérifier l'état du Service Worker périodiquement + setInterval(() => { + registration.update().catch(err => { + console.debug('[SW] Pas de mise à jour disponible:', err); + }); + }, 60 * 60 * 1000); // Toutes les heures + + return registration; + }) + .catch(function(error) { + console.error('[Service Worker] Erreur d\'enregistrement:', error); + + // Tentative de récupération + if (error.name === 'SecurityError') { + console.warn('[SW] Erreur de sécurité - Vérifiez HTTPS'); + } else if (error.name === 'TypeError') { + console.warn('[SW] Erreur de type - Vérifiez le chemin du SW'); + } }); - }); } -} - -// Exporter pour une utilisation externe -window.serviceWorker = { - update: updateServiceWorker, - isSupported: 'serviceWorker' in navigator -}; \ No newline at end of file + + // Gestion de l'état de connexion + function setupConnectionHandlers() { + window.addEventListener('online', function() { + console.log('[App] Connexion rétablie'); + document.documentElement.classList.remove('offline'); + showOnlineNotification(); + + // Synchroniser les données + if (navigator.serviceWorker.controller) { + sendMessageToSW({ type: 'SYNC_DATA' }); + } + }); + + window.addEventListener('offline', function() { + console.log('[App] Mode hors ligne'); + document.documentElement.classList.add('offline'); + showOfflineNotification(); + }); + + // Vérifier l'état initial + if (!navigator.onLine) { + document.documentElement.classList.add('offline'); + } + } + + // Notification de mise à jour + function showUpdateNotification() { + const isAnglophone = window.appConfig?.isAnglophone || false; + + // Utiliser SweetAlert2 si disponible + if (typeof Swal !== 'undefined') { + Swal.fire({ + title: isAnglophone ? 'Update Available' : 'Mise à jour disponible', + text: isAnglophone + ? 'A new version is available. Reload to update?' + : 'Une nouvelle version est disponible. Recharger pour mettre à jour ?', + icon: 'info', + showCancelButton: true, + confirmButtonText: isAnglophone ? 'Reload' : 'Recharger', + cancelButtonText: isAnglophone ? 'Later' : 'Plus tard', + allowOutsideClick: false + }).then((result) => { + if (result.isConfirmed) { + window.location.reload(); + } + }); + } else { + // Fallback simple + if (confirm(isAnglophone + ? 'New version available. Reload?' + : 'Nouvelle version disponible. Recharger ?')) { + window.location.reload(); + } + } + } + + // Notification en ligne + function showOnlineNotification() { + // Créer un toast temporaire + const toast = document.createElement('div'); + toast.className = 'position-fixed top-0 end-0 p-3'; + toast.style.zIndex = '9999'; + + const isAnglophone = window.appConfig?.isAnglophone || false; + + toast.innerHTML = ` + + `; + + document.body.appendChild(toast); + + // Auto-remove après 3 secondes + setTimeout(() => { + if (toast.parentNode) { + toast.remove(); + } + }, 3000); + } + + // Notification hors ligne + function showOfflineNotification() { + // Créer un toast temporaire + const toast = document.createElement('div'); + toast.className = 'position-fixed top-0 end-0 p-3'; + toast.style.zIndex = '9999'; + + const isAnglophone = window.appConfig?.isAnglophone || false; + + toast.innerHTML = ` + + `; + + document.body.appendChild(toast); + + // Auto-remove après 5 secondes + setTimeout(() => { + if (toast.parentNode) { + toast.remove(); + } + }, 5000); + } + + // Envoyer un message au Service Worker + function sendMessageToSW(message) { + if (navigator.serviceWorker.controller) { + navigator.serviceWorker.controller.postMessage(message); + } + } + + // Obtenir l'état du cache + function getCacheStatus() { + if (navigator.serviceWorker.controller) { + const messageChannel = new MessageChannel(); + + messageChannel.port1.onmessage = function(event) { + console.log('[SW] Cache status:', event.data); + }; + + navigator.serviceWorker.controller.postMessage( + { type: 'GET_CACHE_STATUS' }, + [messageChannel.port2] + ); + } + } + + // Fonction publique pour forcer la mise à jour + function forceUpdate() { + if (navigator.serviceWorker.controller) { + navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' }); + } + } + + // Initialiser quand la page est prête + window.addEventListener('load', function() { + registerServiceWorker(); + setupConnectionHandlers(); + + // Ajouter les écouteurs de visibilité pour les rafraîchissements + document.addEventListener('visibilitychange', function() { + if (!document.hidden && navigator.serviceWorker.controller) { + navigator.serviceWorker.controller.postMessage({ type: 'PAGE_VISIBLE' }); + } + }); + }); + + // Exposer les fonctions publiques + window.serviceWorkerManager = { + forceUpdate: forceUpdate, + getCacheStatus: getCacheStatus, + isSupported: 'serviceWorker' in navigator, + sendMessage: sendMessageToSW + }; + + console.log('[App] Service Worker Manager initialisé'); +})(); \ No newline at end of file diff --git a/Vue/gabarit.php b/Vue/gabarit.php index bc897cb..0e51cfc 100755 --- a/Vue/gabarit.php +++ b/Vue/gabarit.php @@ -35,7 +35,7 @@ foreach ($menus as $key0 => $menuParent) { - <?= htmlspecialchars($_SESSION['vue'] ?? 'INTER SANTÉ') ?> | Portail Santé + <?= htmlspecialchars($_SESSION['vue'] ?? 'INTER SANTE') ?> | Portail Santé RH @@ -69,9 +69,24 @@ foreach ($menus as $key0 => $menuParent) { - - - + + + + + + + + + + + + + + + + + + @@ -82,7 +97,7 @@ foreach ($menus as $key0 => $menuParent) {