diff --git a/app/views/pwa/service-worker.js b/app/views/pwa/service-worker.js
index 68d5c2ee6..4108a2065 100644
--- a/app/views/pwa/service-worker.js
+++ b/app/views/pwa/service-worker.js
@@ -1,10 +1,69 @@
+const CACHE_VERSION = 'v1';
+const OFFLINE_ASSETS = [
+ '/offline.html',
+ '/logo-offline.svg'
+];
+
+// Install event - cache the offline page and assets
+self.addEventListener('install', (event) => {
+ event.waitUntil(
+ caches.open(CACHE_VERSION).then((cache) => {
+ return cache.addAll(OFFLINE_ASSETS);
+ })
+ );
+ // Activate immediately
+ self.skipWaiting();
+});
+
+// Activate event - clean up old caches
+self.addEventListener('activate', (event) => {
+ event.waitUntil(
+ caches.keys().then((cacheNames) => {
+ return Promise.all(
+ cacheNames.map((cacheName) => {
+ if (cacheName !== CACHE_VERSION) {
+ return caches.delete(cacheName);
+ }
+ })
+ );
+ }).then(() => {
+ // Take control of all pages immediately
+ return self.clients.claim();
+ })
+ );
+});
+
+// Fetch event - serve offline page when network fails
+self.addEventListener('fetch', (event) => {
+ // Handle navigation requests (page loads)
+ if (event.request.mode === 'navigate') {
+ event.respondWith(
+ fetch(event.request).catch((error) => {
+ // Only show offline page for network errors
+ if (error.name === 'TypeError' || !navigator.onLine) {
+ return caches.match('/offline.html');
+ }
+ throw error;
+ })
+ );
+ }
+ // Handle offline assets (logo, etc.)
+ else if (OFFLINE_ASSETS.some(asset => new URL(event.request.url).pathname === asset)) {
+ event.respondWith(
+ caches.match(event.request).then((response) => {
+ return response || fetch(event.request);
+ })
+ );
+ }
+});
+
// Add a service worker for processing Web Push notifications:
//
// self.addEventListener("push", async (event) => {
// const { title, options } = await event.data.json()
// event.waitUntil(self.registration.showNotification(title, options))
// })
-//
+//
// self.addEventListener("notificationclick", function(event) {
// event.notification.close()
// event.waitUntil(
@@ -12,12 +71,12 @@
// for (let i = 0; i < clientList.length; i++) {
// let client = clientList[i]
// let clientPath = (new URL(client.url)).pathname
-//
+//
// if (clientPath == event.notification.data.path && "focus" in client) {
// return client.focus()
// }
// }
-//
+//
// if (clients.openWindow) {
// return clients.openWindow(event.notification.data.path)
// }
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb
index 336547490..72afcaf49 100644
--- a/app/views/sessions/new.html.erb
+++ b/app/views/sessions/new.html.erb
@@ -1,7 +1,3 @@
-<%
- header_title t(".title")
-%>
-
<% if @prefill_demo_credentials %>
diff --git a/config/locales/views/layout/ca.yml b/config/locales/views/layout/ca.yml
index 4741f505a..66e260d7a 100644
--- a/config/locales/views/layout/ca.yml
+++ b/config/locales/views/layout/ca.yml
@@ -6,7 +6,6 @@ ca:
no_account: Nou a %{product_name}?
sign_in: Inicia sessió
sign_up: Crea un compte
- your_account: El teu compte
shared:
footer:
privacy_policy: Política de privacitat
diff --git a/config/locales/views/layout/en.yml b/config/locales/views/layout/en.yml
index 96445f376..1a6ac3bb4 100644
--- a/config/locales/views/layout/en.yml
+++ b/config/locales/views/layout/en.yml
@@ -6,7 +6,6 @@ en:
no_account: New to %{product_name}?
sign_in: Sign in
sign_up: Create account
- your_account: Your account
shared:
footer:
privacy_policy: Privacy Policy
diff --git a/config/locales/views/layout/es.yml b/config/locales/views/layout/es.yml
index 6178965e3..37ffbe463 100644
--- a/config/locales/views/layout/es.yml
+++ b/config/locales/views/layout/es.yml
@@ -6,7 +6,6 @@ es:
no_account: ¿Nuevo en %{product_name}?
sign_in: Iniciar sesión
sign_up: Crear cuenta
- your_account: Tu cuenta
shared:
footer:
privacy_policy: Política de privacidad
diff --git a/config/locales/views/layout/nb.yml b/config/locales/views/layout/nb.yml
index f6833b442..0dde7d43d 100644
--- a/config/locales/views/layout/nb.yml
+++ b/config/locales/views/layout/nb.yml
@@ -6,7 +6,6 @@ nb:
no_account: Ny hos %{product_name}?
sign_in: Logg inn
sign_up: Opprett konto
- your_account: Din konto
shared:
footer:
privacy_policy: Personvernerklæring
diff --git a/config/locales/views/layout/tr.yml b/config/locales/views/layout/tr.yml
index fe2b6634b..eb60b1a27 100644
--- a/config/locales/views/layout/tr.yml
+++ b/config/locales/views/layout/tr.yml
@@ -6,7 +6,6 @@ tr:
no_account: "%{product_name}'ye yeni misiniz?"
sign_in: Giriş yap
sign_up: Hesap oluştur
- your_account: Hesabınız
shared:
footer:
privacy_policy: Gizlilik Politikası
diff --git a/config/locales/views/sessions/en.yml b/config/locales/views/sessions/en.yml
index 98a6ecd9a..88afdafec 100644
--- a/config/locales/views/sessions/en.yml
+++ b/config/locales/views/sessions/en.yml
@@ -15,7 +15,7 @@ en:
forgot_password: Forgot your password?
password: Password
submit: Log in
- title: Sign in to your account
+ title: Sure
password_placeholder: Enter your password
openid_connect: Sign in with OpenID Connect
google_auth_connect: Sign in with Google
diff --git a/public/logo-offline.svg b/public/logo-offline.svg
new file mode 100644
index 000000000..e4d8f87c5
--- /dev/null
+++ b/public/logo-offline.svg
@@ -0,0 +1,6 @@
+
diff --git a/public/offline.html b/public/offline.html
new file mode 100644
index 000000000..e87823fcd
--- /dev/null
+++ b/public/offline.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
Offline - Maybe
+
+
+
+
+

+
+
We're experiencing
technical difficulties
+
It looks like you're offline or we can't reach our servers right now. Please check your connection and try again.
+
+
+
+
+
+
+
diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb
index b756c30ce..a32c04b49 100644
--- a/test/application_system_test_case.rb
+++ b/test/application_system_test_case.rb
@@ -30,7 +30,7 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
click_button "Logout"
# Trigger Capybara's wait mechanism to avoid timing issues with logout
- find("h2", text: "Sign in to your account")
+ find("a", text: "Sign in")
end
def within_testid(testid)