2.9.8
Move info boxes to model popups
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// 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`
|
||||
<div class="welcome-overlay" onClick=${onClose}>
|
||||
<div class="welcome-card" role="dialog" aria-modal="true" aria-labelledby="restore-title"
|
||||
onClick=${(e) => e.stopPropagation()} style=${{ maxWidth: '420px' }}>
|
||||
<button class="welcome-close" aria-label="Close" onClick=${onClose}>×</button>
|
||||
<div class="welcome-head">
|
||||
<${Wordmark} />
|
||||
<div style=${{
|
||||
fontFamily: 'Manrope, sans-serif',
|
||||
fontWeight: 600,
|
||||
fontSize: '11px',
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
color: '#7a5c2a',
|
||||
marginTop: '10px',
|
||||
}}>See the world the way your skin does.</div>
|
||||
</div>
|
||||
<h2 class="welcome-title" id="restore-title" style=${{ textAlign: 'center', fontSize: '1.3rem', marginBottom: '8px' }}>
|
||||
Restore your access
|
||||
</h2>
|
||||
<p class="welcome-intro">
|
||||
Enter the email you subscribed with and we'll unlock${' '}
|
||||
<strong>SunScope Extra</strong> on this browser.
|
||||
</p>
|
||||
<form onSubmit=${submit}>
|
||||
<input
|
||||
type="email"
|
||||
required
|
||||
autofocus
|
||||
placeholder="your@email.com"
|
||||
value=${email}
|
||||
onInput=${(e) => setEmail(e.target.value)}
|
||||
style=${{
|
||||
width: '100%',
|
||||
padding: '11px 14px',
|
||||
border: '1.5px solid #c9b08a',
|
||||
borderRadius: '8px',
|
||||
fontFamily: 'Manrope, sans-serif',
|
||||
fontSize: '0.95rem',
|
||||
background: '#fff',
|
||||
color: '#1e1208',
|
||||
marginBottom: '12px',
|
||||
outline: 'none',
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
/>
|
||||
${error && html`<div style=${{
|
||||
padding: '10px 14px',
|
||||
background: '#fdf0e0',
|
||||
border: '1px solid #c9b08a',
|
||||
borderLeft: '3px solid #c8922a',
|
||||
borderRadius: '6px',
|
||||
fontFamily: 'Manrope, sans-serif',
|
||||
fontSize: '0.85rem',
|
||||
color: '#4a3420',
|
||||
marginBottom: '12px',
|
||||
}}>${error}</div>`}
|
||||
<button class="welcome-cta" type="submit" disabled=${busy}>
|
||||
${busy ? 'Checking…' : 'Restore access →'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
Reference in New Issue
Block a user