feat(yield): Add Verify DNS button for pending domains
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled

This commit is contained in:
2025-12-18 15:57:36 +01:00
parent aeafb7257e
commit c822517694

View File

@ -503,6 +503,7 @@ export default function YieldPage() {
const [refreshing, setRefreshing] = useState(false)
const [menuOpen, setMenuOpen] = useState(false)
const [deletingId, setDeletingId] = useState<number | null>(null)
const [verifyingId, setVerifyingId] = useState<number | null>(null)
const tier = (subscription?.tier || 'scout').toLowerCase()
const tierName = subscription?.tier_name || (tier.charAt(0).toUpperCase() + tier.slice(1))
@ -531,6 +532,23 @@ export default function YieldPage() {
}
}, [fetchDashboard])
const handleVerifyDNS = useCallback(async (domainId: number, domainName: string) => {
setVerifyingId(domainId)
try {
const res = await api.verifyYieldDomainDNS(domainId)
if (res.verified) {
alert(`${domainName} is now active! Your landing page is live.`)
fetchDashboard()
} else {
alert(`⏳ DNS not yet propagated for ${domainName}. Please wait 5-15 minutes and try again.`)
}
} catch (err: any) {
alert(`❌ DNS verification failed: ${err.message || 'Unknown error'}`)
} finally {
setVerifyingId(null)
}
}, [fetchDashboard])
useEffect(() => { fetchDashboard() }, [fetchDashboard])
useEffect(() => {
@ -673,7 +691,7 @@ export default function YieldPage() {
) : (
<div className="border border-white/[0.08] bg-[#020202] overflow-hidden">
{/* Header */}
<div className="hidden lg:grid grid-cols-[1fr_80px_140px_120px_70px_60px_80px_50px] gap-4 px-5 py-3 text-[10px] font-mono text-white/40 uppercase tracking-[0.12em] border-b border-white/[0.08] bg-white/[0.02]">
<div className="hidden lg:grid grid-cols-[1fr_80px_140px_120px_70px_60px_80px_90px] gap-4 px-5 py-3 text-[10px] font-mono text-white/40 uppercase tracking-[0.12em] border-b border-white/[0.08] bg-white/[0.02]">
<div>Domain</div>
<div className="text-center">Status</div>
<div>Intent</div>
@ -736,22 +754,41 @@ export default function YieldPage() {
<span>{domain.total_clicks} clicks</span>
<span className="text-accent font-bold">${domain.total_revenue}</span>
</div>
<button
onClick={() => handleDeleteYield(domain.id, domain.domain)}
disabled={deletingId === domain.id}
className="p-1.5 text-white/30 hover:text-rose-400 disabled:opacity-50 transition-colors"
>
{deletingId === domain.id ? (
<Loader2 className="w-4 h-4 animate-spin" />
) : (
<Trash2 className="w-4 h-4" />
<div className="flex items-center gap-2">
{/* Verify DNS Button - only for pending domains (mobile) */}
{domain.status === 'pending' && (
<button
onClick={() => handleVerifyDNS(domain.id, domain.domain)}
disabled={verifyingId === domain.id}
className="px-2 py-1 flex items-center gap-1 text-amber-400 text-[10px] font-mono border border-amber-400/20 hover:border-accent/30 hover:bg-accent/10 transition-all"
>
{verifyingId === domain.id ? (
<Loader2 className="w-3 h-3 animate-spin" />
) : (
<>
<Shield className="w-3 h-3" />
<span>Verify</span>
</>
)}
</button>
)}
</button>
<button
onClick={() => handleDeleteYield(domain.id, domain.domain)}
disabled={deletingId === domain.id}
className="p-1.5 text-white/30 hover:text-rose-400 disabled:opacity-50 transition-colors"
>
{deletingId === domain.id ? (
<Loader2 className="w-4 h-4 animate-spin" />
) : (
<Trash2 className="w-4 h-4" />
)}
</button>
</div>
</div>
</div>
{/* Desktop */}
<div className="hidden lg:grid grid-cols-[1fr_80px_140px_120px_70px_60px_80px_50px] gap-4 items-center px-5 py-3 group-hover:bg-white/[0.02]">
<div className="hidden lg:grid grid-cols-[1fr_80px_140px_120px_70px_60px_80px_90px] gap-4 items-center px-5 py-3 group-hover:bg-white/[0.02]">
<div className="flex items-center gap-3 min-w-0">
<span className="text-sm font-bold text-white font-mono truncate group-hover:text-accent transition-colors">{domain.domain}</span>
</div>
@ -789,7 +826,25 @@ export default function YieldPage() {
<div className="text-right text-sm font-mono text-white/50">{domain.total_clicks}</div>
<div className="text-right text-sm font-mono text-white/50">{domain.total_conversions}</div>
<div className="text-right text-sm font-bold font-mono text-accent">${domain.total_revenue}</div>
<div className="flex justify-end opacity-40 group-hover:opacity-100 transition-all">
<div className="flex justify-end gap-1 opacity-40 group-hover:opacity-100 transition-all">
{/* Verify DNS Button - only for pending domains */}
{domain.status === 'pending' && (
<button
onClick={() => handleVerifyDNS(domain.id, domain.domain)}
disabled={verifyingId === domain.id}
className="h-8 px-2 flex items-center justify-center gap-1 text-amber-400 hover:text-accent text-[10px] font-mono border border-amber-400/20 hover:border-accent/30 hover:bg-accent/10 transition-all"
title="Verify DNS to activate"
>
{verifyingId === domain.id ? (
<Loader2 className="w-3 h-3 animate-spin" />
) : (
<>
<Shield className="w-3 h-3" />
<span>Verify</span>
</>
)}
</button>
)}
<button
onClick={() => handleDeleteYield(domain.id, domain.domain)}
disabled={deletingId === domain.id}