'use client' import { useState, useEffect } from 'react' import { createPortal } from 'react-dom' import { motion, AnimatePresence } from 'framer-motion' import { XIcon, CheckCircleIcon, AlertTriangleIcon, ZapIcon } from '@ciphera-net/ui' import { Site, verifySite } from '@/lib/api/sites' import { getRealtime } from '@/lib/api/stats' import { toast, Button } from '@ciphera-net/ui' interface VerificationModalProps { isOpen: boolean onClose: () => void site: Site onVerified?: () => void } export default function VerificationModal({ isOpen, onClose, site, onVerified }: VerificationModalProps) { const [mounted, setMounted] = useState(false) const [status, setStatus] = useState<'idle' | 'checking' | 'success' | 'error'>('idle') const [attempts, setAttempts] = useState(0) useEffect(() => { setMounted(true) return () => setMounted(false) }, []) useEffect(() => { if (isOpen) { setStatus('idle') setAttempts(0) } }, [isOpen]) // * Polling Logic useEffect(() => { let interval: NodeJS.Timeout const maxAttempts = 30 // 60 seconds (2s interval) if (status === 'checking') { interval = setInterval(async () => { setAttempts(prev => { if (prev >= maxAttempts) { setStatus('error') return prev } return prev + 1 }) try { const data = await getRealtime(site.id) if (data.visitors > 0) { setStatus('success') toast.success('Connection established!') try { await verifySite(site.id); onVerified?.() } catch {} } } catch (e) { // Ignore errors } }, 2000) } return () => clearInterval(interval) }, [status, site.id]) const handleStartVerification = () => { const protocol = site.domain.includes('http') ? '' : 'https://' const verificationUrl = `${protocol}${site.domain}/?utm_source=ciphera_verify&_t=${Date.now()}` // * Open site window.open(verificationUrl, '_blank') // * Start polling setStatus('checking') setAttempts(0) } if (!mounted) return null return createPortal( {isOpen && ( <> {/* Backdrop */} {/* Modal */}
{/* Header */}

Verify Installation

{/* Content */}
{status === 'idle' && (

How this works

We will open your website in a new tab. Keep it open while we check if the script sends back a signal.

)} {status === 'checking' && (

Checking connection...

Waiting for signal from {site.domain}

)} {status === 'success' && (

You're all set!

We are successfully receiving data from your website.

)} {status === 'error' && (

Connection Timed Out

Troubleshooting Checklist:

  • Did the new tab open successfully?
  • Is your ad blocker disabled?
  • Is the script inside the <head> tag?
  • Are you running on a valid domain (not localhost)?
)}
)} , document.body ) }