Sessions 5-7a: 955 tests, deployment ready
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
|
||||
// One-time nag for paid users who haven't been told about MFA yet.
|
||||
// The actual enrollment happens on /settings/security — this modal just
|
||||
// directs them there. We mark prompted=true regardless of action so we
|
||||
// don't pester users who explicitly chose "later".
|
||||
|
||||
export default function MFAPrompt() {
|
||||
const { user, tier, profile, markMFAPrompted } = useAuth();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user || !profile) return;
|
||||
if (tier === 'free') return;
|
||||
if (profile.mfa_setup_prompted) return;
|
||||
setOpen(true);
|
||||
}, [user, tier, profile]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const handleLater = async () => {
|
||||
setOpen(false);
|
||||
await markMFAPrompted();
|
||||
};
|
||||
|
||||
const tierLabel = tier === 'desk' ? 'Desk' : 'Analyst';
|
||||
|
||||
return (
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Secure your account"
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4"
|
||||
>
|
||||
<div
|
||||
className="w-full max-w-md rounded-lg border p-5"
|
||||
style={{
|
||||
background: 'var(--bg-surface)',
|
||||
borderColor: 'var(--border-light)',
|
||||
color: 'var(--text-primary)',
|
||||
}}
|
||||
>
|
||||
<h2 className="text-lg font-semibold">Secure your {tierLabel} account</h2>
|
||||
<p className="mt-2 text-sm" style={{ color: 'var(--text-secondary)' }}>
|
||||
Two-factor authentication takes 60 seconds and protects your subscription, billing details,
|
||||
and Ledger history from password-only attacks.
|
||||
</p>
|
||||
<div className="mt-5 flex justify-end gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleLater}
|
||||
className="rounded border px-4 py-2 text-sm font-semibold"
|
||||
style={{ borderColor: 'var(--border-light)', color: 'var(--text-secondary)' }}
|
||||
>
|
||||
Remind me later
|
||||
</button>
|
||||
<Link
|
||||
href="/settings/security"
|
||||
onClick={() => {
|
||||
void markMFAPrompted();
|
||||
setOpen(false);
|
||||
}}
|
||||
className="rounded px-4 py-2 text-sm font-semibold"
|
||||
style={{ background: 'var(--grade-a)', color: 'var(--bg-0)' }}
|
||||
>
|
||||
Set up now
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user