// ------------------------------------------------------------------------ // components/RestoreModal.js - "Already subscribed? Restore access" popup. // // Replaces the old standalone restore.php page. Collects the subscriber's // email, POSTs it to restore.php (now a JSON endpoint), and on an active // subscription flips the app into Pro mode in place - no navigation. // // Reuses the .welcome-* overlay/card styling; input/error styling is inline // to avoid new CSS. All open/close state lives in useAppState. // // Props: // onClose - called when the user dismisses (×, backdrop, or Esc) // setIsPro - state setter from useAppState; called with true on success // ------------------------------------------------------------------------ import { h } from '../../vendor/preact.js'; import { useEffect, useState } from '../../vendor/preact-hooks.js'; import htm from '../../vendor/htm.js'; import { Wordmark } from './Wordmark.js'; const html = htm.bind(h); export function RestoreModal({ onClose, setIsPro }) { const [email, setEmail] = useState(''); const [error, setError] = useState(''); const [busy, setBusy] = useState(false); // Dismiss on Esc. useEffect(() => { const onKey = (e) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', onKey); return () => document.removeEventListener('keydown', onKey); }, [onClose]); const submit = async (e) => { e.preventDefault(); if (busy) return; setError(''); setBusy(true); try { const res = await fetch('/restore.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ email }), }); const data = await res.json(); if (data.active) { try { localStorage.setItem('sunscope_pro', '1'); } catch (err) { /* ignore */ } setIsPro(true); onClose(); return; } setError(data.error || 'No active SunScope Extra subscription found for that email.'); } catch (err) { setError('Something went wrong. Please try again.'); } setBusy(false); }; return html`
`; }