// push-notifications.jsx — UI para pedir permiso + subscribe a push notifications // Se monta una vez en home cuando hay vendedora logueada. (function () { // Helpers function urlBase64ToUint8Array(b64) { const padding = '='.repeat((4 - b64.length % 4) % 4); const base64 = (b64 + padding).replace(/-/g, '+').replace(/_/g, '/'); const raw = atob(base64); const arr = new Uint8Array(raw.length); for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i); return arr; } async function subscribeToPush(vendedora) { if (!('serviceWorker' in navigator) || !('PushManager' in window)) { return { ok: false, reason: 'no-support' }; } // Obtener VAPID public key const r = await fetch('/api/push/vapid-public-key'); const { key } = await r.json(); if (!key) return { ok: false, reason: 'no-vapid' }; const reg = await navigator.serviceWorker.ready; let sub = await reg.pushManager.getSubscription(); if (!sub) { sub = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(key), }); } // Enviar al backend const sj = sub.toJSON(); const res = await fetch('/api/push/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ vendedora_id: vendedora.id, endpoint: sj.endpoint, p256dh: sj.keys.p256dh, auth: sj.keys.auth, user_agent: navigator.userAgent.slice(0, 200), }), }); if (!res.ok) return { ok: false, reason: 'backend-err' }; return { ok: true }; } function PushPermissionPrompt({ vendedora }) { const T = window.T; const { Icon } = window; const [permission, setPermission] = React.useState( typeof Notification !== 'undefined' ? Notification.permission : 'denied' ); const [dismissed, setDismissed] = React.useState(() => { try { return localStorage.getItem('inova-push-dismissed') === '1'; } catch { return false; } }); const [submitting, setSubmitting] = React.useState(false); // Auto-subscribe si ya hay permiso granted (en cada visit) React.useEffect(() => { if (permission === 'granted' && vendedora?.id) { subscribeToPush(vendedora).catch(() => {}); } }, [permission, vendedora?.id]); if (typeof Notification === 'undefined') return null; if (permission === 'granted') return null; // ya está, no mostrar if (permission === 'denied') return null; // bloqueado, no insistir if (dismissed) return null; async function handleEnable() { setSubmitting(true); try { const result = await Notification.requestPermission(); setPermission(result); if (result === 'granted' && vendedora?.id) { await subscribeToPush(vendedora); } } catch (e) { console.error(e); } setSubmitting(false); } function dismiss() { try { localStorage.setItem('inova-push-dismissed', '1'); } catch {} setDismissed(true); } return (
🔔
Activa los recordatorios
Te avisamos cuando se acerca el día de pagar una cuota. Sin spam, sin promociones.
); } window.PushPermissionPrompt = PushPermissionPrompt; window.subscribeToPush = subscribeToPush; })();