"use client" import { useCallback, useEffect, useState } from "react" import { ExternalLink, ShoppingCart, Loader2, AlertCircle } from "lucide-react" import { Button } from "@/components/ui/button" import type { EbayCacheState } from "@/lib/ebay-parts-match" import { getTopPartsForManual, type PartForPage } from "@/lib/parts-lookup" import { hasTrustedPartsListings, shouldShowEbayPartsPanel, } from "@/lib/ebay-parts-visibility" interface PartsPanelProps { manualFilename: string className?: string onStateChange?: (state: { isLoading: boolean; isVisible: boolean }) => void } export function PartsPanel({ manualFilename, className = "", onStateChange, }: PartsPanelProps) { const [parts, setParts] = useState([]) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [cache, setCache] = useState(null) const formatFreshness = (value: number | null) => { if (!value) { return "not refreshed yet" } const minutes = Math.max(0, Math.floor(value / 60000)) if (minutes < 60) { return `${minutes}m ago` } const hours = Math.floor(minutes / 60) if (hours < 24) { return `${hours}h ago` } const days = Math.floor(hours / 24) return `${days}d ago` } const loadParts = useCallback(async () => { setIsLoading(true) setError(null) setParts([]) setCache(null) try { const result = await getTopPartsForManual(manualFilename, 5) setParts(result.parts) setError(result.error ?? null) setCache(result.cache ?? null) } catch (err) { console.error("Error loading parts:", err) setParts([]) setCache(null) setError("Could not load parts") } finally { setIsLoading(false) } }, [manualFilename]) useEffect(() => { if (manualFilename) { void loadParts() } }, [loadParts, manualFilename]) const hasListings = hasTrustedPartsListings(parts) const shouldShowPanel = shouldShowEbayPartsPanel({ isLoading, parts, cache, error, }) const cacheFreshnessText = formatFreshness(cache?.freshnessMs ?? null) useEffect(() => { if (!onStateChange) { return } onStateChange({ isLoading, isVisible: shouldShowPanel, }) }, [isLoading, onStateChange, shouldShowPanel]) if (isLoading) { return (
Parts
{cache && (
{cache.lastSuccessfulAt ? `Cache updated ${cacheFreshnessText}` : "Cache warming up"} {cache.isStale ? " • stale" : ""}
)}
Loading parts...
) } if (!shouldShowPanel) { return null } return (
Parts ({parts.length})
{cache && (
{cache.lastSuccessfulAt ? `Cache updated ${cacheFreshnessText}` : "Cache warming up"} {cache.isStale ? " • stale" : ""}
)}
{error && (

Cached eBay listings are unavailable right now.

{error}

)} {parts.map((part, index) => (
{/* Part Header */}
{part.partNumber}
{part.description && (
{part.description}
)}
{/* eBay Listings */} {part.ebayListings.length > 0 && ( )} {/* View All Listings Button */} {part.ebayListings.length > 2 && (
)}
))} {/* View All Parts Button */} {parts.length > 3 && (
)}
) }