feat: integrate PWA support using next-pwa; update configuration in next.config.ts, add service worker files to .gitignore, and include manifest in layout.tsx
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -34,3 +34,8 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# PWA
|
||||
public/sw.js
|
||||
public/workbox-*.js
|
||||
public/swe-worker-*.js
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { OfflineBanner } from '@/components/OfflineBanner'
|
||||
import { ThemeProviders, Toaster } from '@ciphera-net/ui'
|
||||
import { AuthProvider } from '@/lib/auth/context'
|
||||
import type { Metadata, Viewport } from 'next'
|
||||
@@ -31,6 +32,7 @@ export const metadata: Metadata = {
|
||||
shortcut: '/favicon.ico',
|
||||
apple: '/pulse_icon_no_margins.png',
|
||||
},
|
||||
manifest: '/manifest.json',
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
@@ -45,6 +47,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en" className={plusJakartaSans.variable} suppressHydrationWarning>
|
||||
<body className="antialiased min-h-screen flex flex-col bg-white dark:bg-neutral-950 text-neutral-900 dark:text-neutral-50">
|
||||
<OfflineBanner />
|
||||
<ThemeProviders>
|
||||
<AuthProvider>
|
||||
<LayoutContent>{children}</LayoutContent>
|
||||
|
||||
17
components/OfflineBanner.tsx
Normal file
17
components/OfflineBanner.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { useOnlineStatus } from '@/lib/hooks/useOnlineStatus';
|
||||
import { FiWifiOff } from 'react-icons/fi';
|
||||
|
||||
export function OfflineBanner() {
|
||||
const isOnline = useOnlineStatus();
|
||||
|
||||
if (isOnline) return null;
|
||||
|
||||
return (
|
||||
<div className="bg-yellow-500/10 border-b border-yellow-500/20 text-yellow-600 px-4 py-2 text-sm flex items-center justify-center gap-2 font-medium z-50 relative">
|
||||
<FiWifiOff className="w-4 h-4" />
|
||||
<span>You are currently offline. Changes may not be saved.</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
lib/hooks/useOnlineStatus.ts
Normal file
25
lib/hooks/useOnlineStatus.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export function useOnlineStatus() {
|
||||
const [isOnline, setIsOnline] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Check initial status
|
||||
if (typeof window !== 'undefined') {
|
||||
setIsOnline(navigator.onLine);
|
||||
}
|
||||
|
||||
const handleOnline = () => setIsOnline(true);
|
||||
const handleOffline = () => setIsOnline(false);
|
||||
|
||||
window.addEventListener('online', handleOnline);
|
||||
window.addEventListener('offline', handleOffline);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('online', handleOnline);
|
||||
window.removeEventListener('offline', handleOffline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isOnline;
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
import type { NextConfig } from 'next'
|
||||
const withPWA = require("@ducanh2912/next-pwa").default({
|
||||
dest: "public",
|
||||
register: true,
|
||||
skipWaiting: true,
|
||||
disable: process.env.NODE_ENV === "development",
|
||||
});
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
reactStrictMode: true,
|
||||
@@ -17,4 +23,4 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
export default withPWA(nextConfig)
|
||||
|
||||
3248
package-lock.json
generated
3248
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ciphera-net/ui": "^0.0.39",
|
||||
"@ducanh2912/next-pwa": "^10.2.9",
|
||||
"axios": "^1.13.2",
|
||||
"country-flag-icons": "^1.6.4",
|
||||
"d3-scale": "^4.0.2",
|
||||
|
||||
21
public/manifest.json
Normal file
21
public/manifest.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Pulse Analytics",
|
||||
"short_name": "Pulse",
|
||||
"description": "Privacy-friendly website analytics",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#000000",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/pulse_icon_no_margins.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/pulse_icon_no_margins.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user