'use client' import { useEffect, useState, useRef, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { cn, formatPrice, formatMins } from '@/lib/utils' import type { Listing } from '@/lib/types' import { fetchListings } from '@/lib/api/listings' const REFRESH_MS = 10_000 function UrgencyBadge({ mins }: { mins: number | null }) { if (mins === null) return const isUrgent = mins <= 60 const isWarning = mins > 60 && mins <= 180 if (isUrgent) { return ( {formatMins(mins)} ) } if (isWarning) { return ( {formatMins(mins)} ) } return ( {formatMins(mins)} ) } function AiBadge({ match }: { match: 1 | 0 | null }) { if (match === 1) return ✓ AI if (match === 0) return ✗ AI return null } function ScorePill({ score }: { score: number }) { const color = score >= 50 ? 'text-g-green' : score >= 20 ? 'text-g-amber' : score >= 0 ? 'text-g-muted' : 'text-g-red' return ( {score > 0 ? `+${score}` : score} ) } function Thumbnail({ src }: { src: string | undefined }) { const [err, setErr] = useState(false) if (!src || err) { return (
) } return ( // eslint-disable-next-line @next/next/no-img-element setErr(true)} className="w-9 h-9 rounded-lg object-cover shrink-0 border border-g-border/30 bg-g-raised" loading="lazy" /> ) } export default function RecentListings() { const [listings, setListings] = useState([]) const [loading, setLoading] = useState(true) const [lastRefresh, setLastRefresh] = useState(null) const alive = useRef(true) const refresh = useCallback(async () => { try { const data = await fetchListings(10) if (alive.current) { setListings(data) setLastRefresh(new Date()) setLoading(false) } } catch { if (alive.current) setLoading(false) } }, []) useEffect(() => { alive.current = true refresh() const id = setInterval(refresh, REFRESH_MS) return () => { alive.current = false clearInterval(id) } }, [refresh]) return ( {/* ── Header ── */}
Recent Captures
{listings.length} lots
{lastRefresh && ( {lastRefresh.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })} )}
{/* ── Body ── */}
{loading ? (
{Array.from({ length: 6 }).map((_, i) => (
))}
) : listings.length === 0 ? (

No lots captured yet

Start the engine to begin scanning

) : ( {listings.map((lot, i) => ( {/* Thumbnail */} {/* Title + meta */}

{lot.title}

{lot.site_name} #{lot.keyword}
{/* Price */}

{formatPrice(lot.price, lot.currency, lot.price_usd)}

{lot.price_usd && lot.currency !== 'USD' && (

${lot.price_usd.toFixed(0)} USD

)}
{/* Time left */}
{/* Score */}
{/* Open arrow — visible on hover */}
))}
)}
{/* ── Footer ── */} {listings.length > 0 && (
Refreshes every {REFRESH_MS / 1000}s View all listings
)} ) }