'use client' import { useState, useRef } from 'react' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { useUpdateSite, useDeleteSite, useAdaptSite, useSiteSelectors } from '@/hooks/useSites' import { useQueryClient } from '@tanstack/react-query' import type { TargetSite } from '@/lib/types' import { cn } from '@/lib/utils' function HealthBadge({ site }: { site: TargetSite }) { const inCooldown = site.cooldown_until && new Date(site.cooldown_until) > new Date() if (inCooldown) return Cooldown if (site.consecutive_failures > 2) return {site.error_count} errors return OK } function ConfidenceBadge({ siteId }: { siteId: number }) { const { data: sel } = useSiteSelectors(siteId) if (!sel) return const cls = sel.confidence >= 70 ? 'g-badge-green' : sel.confidence >= 40 ? 'g-badge-amber' : 'g-badge-red' return ( {sel.confidence}%{sel.stale ? ' ⚠' : ''} ) } const ADAPT_POLL_DELAY = 45_000 export default function SiteRow({ site }: { site: TargetSite }) { const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: site.id }) const updateSiteMut = useUpdateSite() const deleteSiteMut = useDeleteSite() const adaptSiteMut = useAdaptSite() const qc = useQueryClient() const [adapting, setAdapting] = useState(false) const timerRef = useRef | null>(null) const handleAdapt = () => { adaptSiteMut.mutate(site.id, { onSuccess: () => { setAdapting(true) if (timerRef.current) clearTimeout(timerRef.current) timerRef.current = setTimeout(() => { setAdapting(false) qc.invalidateQueries({ queryKey: ['selectors', site.id] }) }, ADAPT_POLL_DELAY) }, }) } const style = { transform: CSS.Transform.toString(transform), transition } const isAdapting = adaptSiteMut.isPending || adapting return ( ⋮⋮ {site.name} {site.url_template}
) }