7dfaba6e3d
- Add marketing pages: blog, changelog, roadmap, waitlist, security, maintenance - Add GDPR cookie consent banner with preference modal - Add referral system with API routes for code generation/tracking - Add waitlist API with referral support - Add PWA support: manifest, service worker, install prompt - Add onboarding flow with 6-step guided tour - Add in-app notification center with bell dropdown - Add admin launch checklist (32 items across 8 categories) - Update landing page with trust badges - Add Open Graph image and favicon - Configure ESLint for PWA install patterns - Add LAUNCH_CHECKLIST.md with go-to-market guide Supabase migrations for: - blog_posts and blog_categories tables - waitlist_signups table - roadmap_items table - launch_checklist_items table
67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
// PWA Registration and Service Worker management
|
|
|
|
export function registerServiceWorker() {
|
|
if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {
|
|
return;
|
|
}
|
|
|
|
window.addEventListener('load', async () => {
|
|
try {
|
|
const registration = await navigator.serviceWorker.register('/sw.js', {
|
|
scope: '/',
|
|
});
|
|
|
|
// Handle updates
|
|
registration.addEventListener('updatefound', () => {
|
|
const newWorker = registration.installing;
|
|
if (newWorker) {
|
|
newWorker.addEventListener('statechange', () => {
|
|
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
|
// New content available, prompt user to refresh
|
|
window.dispatchEvent(new CustomEvent('sw-update-available'));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
console.log('Service Worker registered:', registration.scope);
|
|
} catch (error) {
|
|
console.error('Service Worker registration failed:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function subscribeToPush(_registration: ServiceWorkerRegistration) {
|
|
// Push subscription disabled for now - requires VAPID key setup
|
|
return null;
|
|
}
|
|
|
|
// Check if app is installed (PWA)
|
|
export function isPWAInstalled(): boolean {
|
|
if (typeof window === 'undefined') return false;
|
|
return (
|
|
window.matchMedia('(display-mode: standalone)').matches ||
|
|
(window.navigator as { standalone?: boolean }).standalone === true
|
|
);
|
|
}
|
|
|
|
// Share API for native sharing
|
|
export async function shareContent(content: {
|
|
title: string;
|
|
text: string;
|
|
url?: string;
|
|
}): Promise<boolean> {
|
|
if (typeof window === 'undefined' || !navigator.share) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
await navigator.share(content);
|
|
return true;
|
|
} catch (error) {
|
|
if ((error as Error).name !== 'AbortError') {
|
|
console.error('Share failed:', error);
|
|
}
|
|
return false;
|
|
}
|
|
} |