feat(pwa): Add update prompt for new versions
- Change registerType from 'autoUpdate' to 'prompt' - Add UpdatePrompt component that shows when new version available - Users see banner with "Update" or "Later" buttons - Service worker checks for updates every hour 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -54,10 +54,12 @@ import { SeoOrchestrator } from './pages/admin/seo/SeoOrchestrator';
|
||||
import { StatePage } from './pages/public/StatePage';
|
||||
import { SeoPage } from './pages/public/SeoPage';
|
||||
import { PrivateRoute } from './components/PrivateRoute';
|
||||
import { UpdatePrompt } from './components/UpdatePrompt';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<UpdatePrompt />
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
|
||||
45
cannaiq/src/components/UpdatePrompt.tsx
Normal file
45
cannaiq/src/components/UpdatePrompt.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* PWA Update Prompt
|
||||
*
|
||||
* Shows a banner when a new version of the app is available.
|
||||
* Uses the virtual:pwa-register/react hook from vite-plugin-pwa.
|
||||
*/
|
||||
|
||||
import { useRegisterSW } from 'virtual:pwa-register/react';
|
||||
|
||||
export function UpdatePrompt() {
|
||||
const {
|
||||
needRefresh: [needRefresh, setNeedRefresh],
|
||||
updateServiceWorker,
|
||||
} = useRegisterSW({
|
||||
onRegistered(r) {
|
||||
// Check for updates every hour
|
||||
r && setInterval(() => r.update(), 60 * 60 * 1000);
|
||||
},
|
||||
});
|
||||
|
||||
if (!needRefresh) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-4 right-4 z-50 bg-emerald-600 text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-3 max-w-sm">
|
||||
<div className="flex-1">
|
||||
<p className="font-medium">New version available</p>
|
||||
<p className="text-sm text-emerald-100">Refresh to update CannaIQ</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => setNeedRefresh(false)}
|
||||
className="px-3 py-1 text-sm text-emerald-200 hover:text-white"
|
||||
>
|
||||
Later
|
||||
</button>
|
||||
<button
|
||||
onClick={() => updateServiceWorker(true)}
|
||||
className="px-3 py-1 text-sm bg-white text-emerald-600 rounded font-medium hover:bg-emerald-50"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
cannaiq/src/vite-env.d.ts
vendored
1
cannaiq/src/vite-env.d.ts
vendored
@@ -1,4 +1,5 @@
|
||||
/// <reference types="vite/client" />
|
||||
/// <reference types="vite-plugin-pwa/react" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL?: string;
|
||||
|
||||
@@ -6,7 +6,7 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
registerType: 'prompt',
|
||||
includeAssets: ['favicon.svg'],
|
||||
manifest: {
|
||||
name: 'CannaIQ',
|
||||
|
||||
Reference in New Issue
Block a user