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
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:
@ -503,6 +503,7 @@ export default function YieldPage() {
|
|||||||
const [refreshing, setRefreshing] = useState(false)
|
const [refreshing, setRefreshing] = useState(false)
|
||||||
const [menuOpen, setMenuOpen] = useState(false)
|
const [menuOpen, setMenuOpen] = useState(false)
|
||||||
const [deletingId, setDeletingId] = useState<number | null>(null)
|
const [deletingId, setDeletingId] = useState<number | null>(null)
|
||||||
|
const [verifyingId, setVerifyingId] = useState<number | null>(null)
|
||||||
|
|
||||||
const tier = (subscription?.tier || 'scout').toLowerCase()
|
const tier = (subscription?.tier || 'scout').toLowerCase()
|
||||||
const tierName = subscription?.tier_name || (tier.charAt(0).toUpperCase() + tier.slice(1))
|
const tierName = subscription?.tier_name || (tier.charAt(0).toUpperCase() + tier.slice(1))
|
||||||
@ -531,6 +532,23 @@ export default function YieldPage() {
|
|||||||
}
|
}
|
||||||
}, [fetchDashboard])
|
}, [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(() => { fetchDashboard() }, [fetchDashboard])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -673,7 +691,7 @@ export default function YieldPage() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="border border-white/[0.08] bg-[#020202] overflow-hidden">
|
<div className="border border-white/[0.08] bg-[#020202] overflow-hidden">
|
||||||
{/* Header */}
|
{/* 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>Domain</div>
|
||||||
<div className="text-center">Status</div>
|
<div className="text-center">Status</div>
|
||||||
<div>Intent</div>
|
<div>Intent</div>
|
||||||
@ -736,22 +754,41 @@ export default function YieldPage() {
|
|||||||
<span>{domain.total_clicks} clicks</span>
|
<span>{domain.total_clicks} clicks</span>
|
||||||
<span className="text-accent font-bold">${domain.total_revenue}</span>
|
<span className="text-accent font-bold">${domain.total_revenue}</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex items-center gap-2">
|
||||||
onClick={() => handleDeleteYield(domain.id, domain.domain)}
|
{/* Verify DNS Button - only for pending domains (mobile) */}
|
||||||
disabled={deletingId === domain.id}
|
{domain.status === 'pending' && (
|
||||||
className="p-1.5 text-white/30 hover:text-rose-400 disabled:opacity-50 transition-colors"
|
<button
|
||||||
>
|
onClick={() => handleVerifyDNS(domain.id, domain.domain)}
|
||||||
{deletingId === domain.id ? (
|
disabled={verifyingId === domain.id}
|
||||||
<Loader2 className="w-4 h-4 animate-spin" />
|
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"
|
||||||
) : (
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
{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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Desktop */}
|
{/* 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">
|
<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>
|
<span className="text-sm font-bold text-white font-mono truncate group-hover:text-accent transition-colors">{domain.domain}</span>
|
||||||
</div>
|
</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_clicks}</div>
|
||||||
<div className="text-right text-sm font-mono text-white/50">{domain.total_conversions}</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="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
|
<button
|
||||||
onClick={() => handleDeleteYield(domain.id, domain.domain)}
|
onClick={() => handleDeleteYield(domain.id, domain.domain)}
|
||||||
disabled={deletingId === domain.id}
|
disabled={deletingId === domain.id}
|
||||||
|
|||||||
Reference in New Issue
Block a user