Files
sunscope/assets/js/components/WeeklyNudge.js
T
fraxle 7c604ae2be 5.2.1
New welcome note & subscribe reminders
2026-08-16 11:37:28 +01:00

113 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ------------------------------------------------------------------------
// components/WeeklyNudge.js - Friendly weekly reminder for free users.
//
// Shown at most once every 7 days to non-subscribers (never on the very
// first visit - the WelcomeModal owns that moment). Leads with a small
// sun-themed fact so it reads as a bit of sunshine trivia rather than a
// nag, then offers SunScope Extra.
//
// Reuses the .welcome-* overlay/card styling. Purely presentational - the
// open/close state lives in useAppState (weeklyNudgeOpen).
//
// Props:
// onClose - dismiss and stamp the "shown" date (7-day cooldown)
// openRestore - opens the "Already subscribed?" restore modal
// ------------------------------------------------------------------------
import { h } from '../../vendor/preact.js';
import { useEffect, useMemo } from '../../vendor/preact-hooks.js';
import htm from '../../vendor/htm.js';
import { Wordmark } from './Wordmark.js';
import { SUBSCRIBE_URL, SUBSCRIBE_URL_ONEOFF } from './SubscribeModal.js';
const html = htm.bind(h);
// One of these is picked at random each time the nudge appears, so a
// regular user gets a different bit of sun trivia week to week.
const SUN_FACTS = [
{
icon: '☀️',
title: 'Sunlight is eight minutes old',
body: html`Every ray that warms your face left the Sun eight and a half minutes ago and
crossed 93 million miles to get here. The least you can do is dress for it.`,
},
{
icon: '🌡️',
title: 'Shade can feel 15°C cooler',
body: html`Air temperature barely changes when you step into shade — but what your body
feels can drop by ten or fifteen degrees. That gap is exactly what SunSoak measures.`,
},
{
icon: '🧴',
title: 'Clouds are not sunscreen',
body: html`Up to 80% of UV sails straight through thin cloud, which is why overcast days
catch people out. SunScope's UV and sunburn-time columns keep score for you.`,
},
{
icon: '🚗',
title: 'A parked car beats the desert',
body: html`On a mild 22°C afternoon a car's interior can pass 50°C in under an hour —
hotter than the Sahara. SunScope can show you that number before you park.`,
},
{
icon: '💨',
title: 'Wind steals your warmth',
body: html`A brisk breeze can strip several degrees off how cold you feel without moving
the thermometer at all. Wind chill is baked into every SunSoak reading.`,
},
{
icon: '🌅',
title: 'The golden hour is real',
body: html`Low sun travels through far more atmosphere, so early and late light is gentler
on skin — a good reason to check the hourly view before heading out.`,
},
];
export function WeeklyNudge({ onClose, openRestore }) {
const fact = useMemo(() => SUN_FACTS[Math.floor(Math.random() * SUN_FACTS.length)], []);
// 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="nudge-title"
onClick=${(e) => e.stopPropagation()} style=${{ maxWidth: '440px' }}>
<button class="welcome-close" aria-label="Close" onClick=${onClose}>×</button>
<div class="welcome-head">
<${Wordmark} />
<div class="welcome-kicker" style=${{ marginTop: '10px' }}>Your weekly ray of sun</div>
</div>
<div class="nudge-fact">
<span class="nudge-fact-icon" aria-hidden="true">${fact.icon}</span>
<h2 class="welcome-title" id="nudge-title">${fact.title}</h2>
<p class="nudge-fact-body">${fact.body}</p>
</div>
<p class="welcome-remember">
✨ <strong>SunScope Extra</strong> unlocks the 🔒 profiles — hiking, sailing, fishing,
photography, winter sports and the whole Work set — plus Show All and custom columns,
so you can build your own view. £2 a month.
</p>
<a class="welcome-cta" href=${SUBSCRIBE_URL} target="_blank" rel="noopener noreferrer"
style=${{ textDecoration: 'none', textAlign: 'center', marginBottom: '10px' }}>
Subscribe — £2/month
</a>
<div class="nudge-links">
<a href=${SUBSCRIBE_URL_ONEOFF} target="_blank" rel="noopener noreferrer">
Or make a one-off payment →
</a>
<button type="button" onClick=${() => { onClose(); openRestore(); }}>
Already subscribed? Restore access →
</button>
<button type="button" class="nudge-dismiss" onClick=${onClose}>
Maybe next week
</button>
</div>
</div>
</div>`;
}