'use client' import { useEffect, useState } from 'react' import { getApiBase } from '../lib/auth' import BrandingLogo from '../ui/BrandingLogo' import './recaps.css' type LinkAction = { action: 'confirm' | 'unsubscribe'; token: string } export default function EmailRecapLinkPage() { const [link, setLink] = useState(null) const [state, setState] = useState('loading') const [error, setError] = useState('') const [busy, setBusy] = useState(false) useEffect(() => { let controller: AbortController | null = null const checkLink = () => { controller?.abort() const abort = new AbortController() controller = abort setError(''); setState('loading'); setLink(null) // Fragments stay out of web-server access logs and referrers. Opening the link only checks it. const params = new URLSearchParams(window.location.hash.slice(1)) const action = params.get('action') const token = params.get('token') || '' if ((action !== 'confirm' && action !== 'unsubscribe') || !/^[A-Za-z0-9_-]{40,100}$/.test(token)) { setError('This email link is incomplete. Open Profile to manage your monthly recaps.'); setState('error'); return } const payload = { action, token } as LinkAction setLink(payload) void fetch(`${getApiBase()}/email-recaps/check`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), signal: abort.signal, credentials: 'omit' }).then(async (response) => { const result = await response.json().catch(() => ({})) if (!response.ok) throw new Error(typeof result.detail === 'string' ? result.detail : 'Could not check this email link. Please open it again.') if (!abort.signal.aborted) setState(result.state) }).catch((err: Error) => { if (!abort.signal.aborted) { setError(err.message); setState('error') } }) } checkLink() window.addEventListener('hashchange', checkLink) return () => { controller?.abort(); window.removeEventListener('hashchange', checkLink) } }, []) const apply = async () => { if (!link || busy) return setBusy(true); setError('') try { const response = await fetch(`${getApiBase()}/email-recaps/confirm`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(link), credentials: 'omit' }) const result = await response.json().catch(() => ({})) if (!response.ok) throw new Error(typeof result.detail === 'string' ? result.detail : 'Could not update your preference. Please try again.') setState(result.state) window.history.replaceState(null, '', '/email-recaps') } catch (err) { setError(err instanceof Error ? err.message : 'Could not update your preference.') } finally { setBusy(false) } } const done = state === 'enabled' || state === 'off' return
Magent
Personal monthly recaps

{state === 'enabled' ? 'You’re on the list.' : state === 'off' ? 'Recaps are turned off.' : state === 'loading' ? 'Checking your email link' : state === 'error' ? 'This link needs another look' : link?.action === 'unsubscribe' ? 'Unsubscribe from recaps?' : 'Your month, delivered.'}

{state === 'enabled' ? 'Your email is confirmed. You’ll receive your personal viewing recap when the monthly schedule runs.' : state === 'off' ? 'You won’t receive further monthly recaps. You can turn them back on in Profile.' : state === 'ready' && link?.action === 'unsubscribe' ? 'This turns off your monthly viewing emails. You can still explore all your reports in Magent.' : state === 'ready' ? 'Confirm to receive your minutes, movies, episodes, longest run and requests each month.' : ''}

{error &&

{error}

} {state === 'ready' && } {(done || state === 'error') && Manage email preferences ↗} {state === 'loading' &&

One moment…

}
}