diff --git a/frontend/index.html b/frontend/index.html index 0b68506..6fffe1f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,6 +3,9 @@ + + + ROA AUTO diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg new file mode 100644 index 0000000..e2b0333 --- /dev/null +++ b/frontend/public/favicon.svg @@ -0,0 +1,5 @@ + + + ROA + AUTO + diff --git a/frontend/public/icon-192.png b/frontend/public/icon-192.png new file mode 100644 index 0000000..5a1d549 Binary files /dev/null and b/frontend/public/icon-192.png differ diff --git a/frontend/public/icon-512.png b/frontend/public/icon-512.png new file mode 100644 index 0000000..ff6999f Binary files /dev/null and b/frontend/public/icon-512.png differ diff --git a/frontend/src/components/common/UpgradeBanner.vue b/frontend/src/components/common/UpgradeBanner.vue new file mode 100644 index 0000000..8a326df --- /dev/null +++ b/frontend/src/components/common/UpgradeBanner.vue @@ -0,0 +1,54 @@ + + + diff --git a/frontend/src/composables/useOffline.js b/frontend/src/composables/useOffline.js new file mode 100644 index 0000000..87c8a9b --- /dev/null +++ b/frontend/src/composables/useOffline.js @@ -0,0 +1,21 @@ +import { ref, onMounted, onUnmounted } from 'vue' + +const online = ref(navigator.onLine) + +function setOnline() { online.value = true } +function setOffline() { online.value = false } + +let listenersAttached = false + +export function useOffline() { + onMounted(() => { + if (!listenersAttached) { + window.addEventListener('online', setOnline) + window.addEventListener('offline', setOffline) + listenersAttached = true + } + online.value = navigator.onLine + }) + + return { online } +} diff --git a/frontend/src/views/dashboard/DashboardView.vue b/frontend/src/views/dashboard/DashboardView.vue index 2c3d2ca..0ccb3cd 100644 --- a/frontend/src/views/dashboard/DashboardView.vue +++ b/frontend/src/views/dashboard/DashboardView.vue @@ -2,6 +2,8 @@

Dashboard

+ +
@@ -70,6 +72,7 @@ import { ref, onMounted } from 'vue' import { useOrdersStore } from '../../stores/orders.js' import { useSync } from '../../composables/useSync.js' +import UpgradeBanner from '../../components/common/UpgradeBanner.vue' useSync() diff --git a/frontend/src/views/settings/SettingsView.vue b/frontend/src/views/settings/SettingsView.vue index 1667820..c072f57 100644 --- a/frontend/src/views/settings/SettingsView.vue +++ b/frontend/src/views/settings/SettingsView.vue @@ -1,6 +1,287 @@ + + diff --git a/frontend/vite.config.js b/frontend/vite.config.js index f6821ef..638f08e 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,11 +1,45 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import tailwindcss from '@tailwindcss/vite' +import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ vue(), tailwindcss(), + VitePWA({ + registerType: 'autoUpdate', + workbox: { + globPatterns: ['**/*.{js,css,html,svg,wasm}'], + maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, + runtimeCaching: [ + { + urlPattern: /^https?:\/\/.*\/api\//, + handler: 'NetworkFirst', + options: { + cacheName: 'api-cache', + expiration: { maxEntries: 50, maxAgeSeconds: 300 }, + }, + }, + ], + }, + manifest: { + name: 'ROA AUTO - Management Service Auto', + short_name: 'ROA AUTO', + description: 'Aplicatie de management pentru service-uri auto', + theme_color: '#111827', + background_color: '#f9fafb', + display: 'standalone', + orientation: 'portrait-primary', + start_url: '/', + scope: '/', + icons: [ + { src: '/icon-192.png', sizes: '192x192', type: 'image/png' }, + { src: '/icon-512.png', sizes: '512x512', type: 'image/png' }, + { src: '/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }, + ], + }, + }), ], server: { proxy: {