import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { AlertTriangle, X, Download, CheckCircle } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useLocalStorage } from '@/hooks/useLocalStorage'; import { useTranslation } from '@/contexts/language'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from '@/components/ui/sheet'; const BACKUP_CONFIRMED_KEY = 'backup-confirmed'; // Session-scoped snooze key. "Remind me later" used to set a PERMANENT // localStorage flag, which silently turned into "never remind again" — a real // safety hole. We now snooze only for the current browser session, so the // reminder returns on the next visit until the user actually saves their login. // Only `backup-confirmed` (set when they back up) stops it for good. const BACKUP_SNOOZE_KEY = 'backup-reminder-snoozed-session'; /** * Gently-persistent backup reminder shown after signup. * Encourages users to save their recovery code (nsec) so they never lose access. * Non-blocking: one tap to back up, one tap to say "already done", or snooze for * this session. It keeps coming back each session until backup is confirmed. * Uses a bottom sheet for a good experience on both phone and desktop. */ export function BackupReminder() { const { user } = useCurrentUser(); const [confirmed, setConfirmed] = useLocalStorage(BACKUP_CONFIRMED_KEY, false); const [showReminder, setShowReminder] = useState(false); const { t } = useTranslation(); const navigate = useNavigate(); useEffect(() => { if (!user) { setShowReminder(false); return; } // Show reminder if: // 1. User is logged in // 2. Not snoozed for THIS session (resets when they come back) // 3. Not confirmed they backed up (the only permanent stop) // Add a small delay so it doesn't immediately pop up on login. const timer = setTimeout(() => { const snoozed = sessionStorage.getItem(BACKUP_SNOOZE_KEY) === 'true'; const shouldShow = !snoozed && !confirmed; setShowReminder(shouldShow); }, 2000); return () => clearTimeout(timer); }, [user, confirmed]); const handleDismiss = () => { // Snooze for this session only — it returns next visit until backup is done. try { sessionStorage.setItem(BACKUP_SNOOZE_KEY, 'true'); } catch { // sessionStorage can throw in strict privacy modes — safe to ignore. } setShowReminder(false); }; const handleConfirmBackup = () => { setConfirmed(true); setShowReminder(false); }; const handleBackupNow = () => { // Client-side nav (HashRouter). window.location.href forced a full reload to // a non-hash path the router couldn't match — it dropped the user on a blank // page instead of the security settings. navigate() keeps it in-app. setShowReminder(false); // SettingsPage deep-links via ?section=… (NOT ?tab=…) — using the wrong // param silently dropped the user on the settings root instead of Security. navigate('/settings?section=security'); }; if (!showReminder) return null; return ( e.preventDefault()} >
{t('backup.title')} {t('backup.subtitle')}
{/* Warning message */}

{t('backup.message')}

⚠️ {t('backup.warning')}

{/* Action buttons - stacked on mobile */}
{/* Dismiss link */}
); }