All files / components/dashboard EmailVerifiedToast.tsx

24.05% Statements 19/79
37.5% Branches 3/8
50% Functions 1/2
24.05% Lines 19/79

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 1151x             1x 20x 20x 20x 20x   20x 20x   20x                                               20x     20x 20x   20x 20x               20x       20x   20x                                                                                                     20x 20x  
'use client';
 
import { useEffect, useState } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useToast } from '@/hooks/use-toast';
import { createClient } from '@/lib/supabase/client';
 
export function EmailVerifiedToast() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const { toast } = useToast();
  const [hasChecked, setHasChecked] = useState(false);
 
  useEffect(() => {
    const emailVerified = searchParams.get('email_verified');
 
    if (emailVerified === 'true') {
      // Sync the verification badge using the admin API
      // This ensures the badge is created even if auth callback didn't work
      fetch('/api/verification/sync-email', { method: 'POST' })
        .then((res) => res.json())
        .then((result) => {
          console.log('[EmailVerifiedToast] Sync result:', result);
        })
        .catch((err) => {
          console.error('[EmailVerifiedToast] Sync failed:', err);
        });
 
      // Show success toast
      toast({
        title: 'Email Verified! 🎉',
        description:
          'Your email has been successfully verified. You now have the Email Verified badge.',
      });
 
      // Remove the query param from URL without page reload
      const url = new URL(window.location.href);
      url.searchParams.delete('email_verified');
      router.replace(url.pathname, { scroll: false });
    }
  }, [searchParams, toast, router]);
 
  // Check for hash fragment indicating email confirmation callback
  useEffect(() => {
    if (hasChecked) return;
 
    const hash = window.location.hash;
    if (!hash) return;
 
    // Detect email confirmation messages in hash
    const isConfirmationCallback =
      hash.includes('message=Confirmation') ||
      hash.includes('type=email') ||
      hash.includes('email_change');
 
    if (isConfirmationCallback) {
      setHasChecked(true);
      checkAndRefreshEmailStatus();
    }
  }, [hasChecked]);
 
  const checkAndRefreshEmailStatus = async () => {
    try {
      const supabase = createClient();
 
      // Refresh the session to get latest user data
      const {
        data: { user },
        error,
      } = await supabase.auth.getUser();
 
      if (error || !user) return;
 
      // Check if email is now confirmed and is a real email
      const isRealEmail = user.email && !user.email.endsWith('@proofid.internal');
 
      if (user.email_confirmed_at && isRealEmail) {
        // Email is verified! Sync the verification badge using admin API
        try {
          const response = await fetch('/api/verification/sync-email', { method: 'POST' });
          const result = await response.json();
          console.log('[EmailVerifiedToast] Sync result:', result);
        } catch (syncError) {
          console.error('[EmailVerifiedToast] Failed to sync badge:', syncError);
        }
 
        // Show success toast
        toast({
          title: 'Email Verified! 🎉',
          description: 'Your email has been successfully verified.',
        });
 
        // Clear hash and reload to show updated status
        window.history.replaceState(null, '', window.location.pathname);
        window.location.reload();
      } else if (
        window.location.hash.includes('Please+proceed+to+confirm') ||
        window.location.hash.includes('other+email')
      ) {
        // This is the two-step email change - first step completed
        toast({
          title: 'First Step Complete',
          description: 'Please check your NEW email address for the final confirmation link.',
        });
        // Clear hash
        window.history.replaceState(null, '', window.location.pathname);
      }
    } catch (error) {
      console.error('Error checking email status:', error);
    }
  };
 
  return null;
}