83 lines
3.3 KiB
JavaScript
83 lines
3.3 KiB
JavaScript
// ------------------------------------------------------------------------
|
||
// components/WelcomeModal.js - First-visit onboarding popup.
|
||
//
|
||
// A friendly, dead-simple overlay that walks a new user through the three
|
||
// key moves in plain language. Auto-shows once on first visit (gated by the
|
||
// sunscope_welcome_seen flag in useAppState) and is reopenable from the
|
||
// footer "How it works" link.
|
||
//
|
||
// Purely presentational - all open/close state lives in useAppState.
|
||
//
|
||
// Props:
|
||
// onClose - called when the user dismisses (Got it, ×, backdrop, or Esc)
|
||
// ------------------------------------------------------------------------
|
||
|
||
import { h } from '../../vendor/preact.js';
|
||
import { useEffect } from '../../vendor/preact-hooks.js';
|
||
import htm from '../../vendor/htm.js';
|
||
|
||
const html = htm.bind(h);
|
||
|
||
const STEPS = [
|
||
{
|
||
icon: '☀️',
|
||
title: 'Watch SunSoak',
|
||
body: html`It's how the sun actually feels, not just air temperature. Pick the
|
||
<strong>Solar model</strong> that matches where you are.`,
|
||
},
|
||
{
|
||
icon: '🎯',
|
||
title: 'Pick a profile',
|
||
body: html`<strong>Places</strong>, <strong>Activities</strong> or <strong>Work</strong> —
|
||
Beach, Cycling, Farming and more — loads the right columns instantly.`,
|
||
},
|
||
{
|
||
icon: '⚙️',
|
||
title: 'Make it yours',
|
||
body: html`Every profile brings its own columns — UV, sunburn time, vehicle interior, soil,
|
||
air quality. <strong>Edit columns</strong> (Extra) lets you pick your own.`,
|
||
},
|
||
];
|
||
|
||
export function WelcomeModal({ onClose }) {
|
||
// Dismiss on Esc.
|
||
useEffect(() => {
|
||
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
|
||
document.addEventListener('keydown', onKey);
|
||
return () => document.removeEventListener('keydown', onKey);
|
||
}, [onClose]);
|
||
|
||
return html`
|
||
<div class="welcome-overlay" onClick=${onClose}>
|
||
<div class="welcome-card" role="dialog" aria-modal="true" aria-labelledby="welcome-title"
|
||
onClick=${(e) => e.stopPropagation()}>
|
||
<button class="welcome-close" aria-label="Close" onClick=${onClose}>×</button>
|
||
<div class="welcome-head">
|
||
<div class="welcome-kicker">Welcome to SunScope</div>
|
||
<h2 class="welcome-title" id="welcome-title">How to read the sky in 3 steps</h2>
|
||
</div>
|
||
<p class="welcome-intro">
|
||
Not your usual forecast — SunScope shows how the weather affects
|
||
<strong>you</strong>: sun, wind chill, UV and more.
|
||
</p>
|
||
<ol class="welcome-steps">
|
||
${STEPS.map((s, i) => html`
|
||
<li class="welcome-step" key=${i}>
|
||
<span class="welcome-step-num">${i + 1}</span>
|
||
<span class="welcome-step-icon" aria-hidden="true">${s.icon}</span>
|
||
<span class="welcome-step-text">
|
||
<span class="welcome-step-title">${s.title}</span>
|
||
<span class="welcome-step-body">${s.body}</span>
|
||
</span>
|
||
</li>`)}
|
||
</ol>
|
||
<p class="welcome-remember">
|
||
✨ <strong>SunScope Extra</strong> unlocks the 🔒 profiles and custom columns,
|
||
£2/month — tap any locked one to subscribe.
|
||
</p>
|
||
<p class="welcome-note">💾 SunScope remembers your choices for next time.</p>
|
||
<button class="welcome-cta" onClick=${onClose}>Got it</button>
|
||
</div>
|
||
</div>`;
|
||
}
|