"use client"; import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { enrichmentApi, EnrichmentFailure } from "@/lib/enrichmentApi"; import { X, RefreshCw, SkipForward, Trash2, AlertCircle, Filter, } from "lucide-react"; interface EnrichmentFailuresModalProps { isOpen: boolean; onClose: () => void; } export function EnrichmentFailuresModal({ isOpen, onClose, }: EnrichmentFailuresModalProps) { const [selectedType, setSelectedType] = useState< "all" | "artist" | "track" | "audio" >("all"); const [selectedFailures, setSelectedFailures] = useState>( new Set() ); const [currentPage, setCurrentPage] = useState(1); const pageSize = 20; const queryClient = useQueryClient(); // Fetch failures const { data: failures, isLoading, refetch, } = useQuery({ queryKey: ["enrichment-failures", selectedType, currentPage], queryFn: async () => { const params: any = { limit: pageSize, offset: (currentPage - 1) * pageSize, resolved: false, }; if (selectedType !== "all") { params.entityType = selectedType; } return enrichmentApi.getFailures(params); }, enabled: isOpen, }); // Fetch counts const { data: counts } = useQuery({ queryKey: ["enrichment-failure-counts"], queryFn: () => enrichmentApi.getFailureCounts(), enabled: isOpen, }); // Retry mutation const retryMutation = useMutation({ mutationFn: (failureIds: string[]) => enrichmentApi.retryFailures(failureIds), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["enrichment-failures"], }); queryClient.invalidateQueries({ queryKey: ["enrichment-failure-counts"], }); queryClient.invalidateQueries({ queryKey: ["enrichment-progress"], }); setSelectedFailures(new Set()); }, }); // Skip mutation const skipMutation = useMutation({ mutationFn: (failureIds: string[]) => enrichmentApi.skipFailures(failureIds), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["enrichment-failures"], }); queryClient.invalidateQueries({ queryKey: ["enrichment-failure-counts"], }); setSelectedFailures(new Set()); }, }); // Delete mutation const deleteMutation = useMutation({ mutationFn: (failureId: string) => enrichmentApi.deleteFailure(failureId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["enrichment-failures"], }); queryClient.invalidateQueries({ queryKey: ["enrichment-failure-counts"], }); }, }); const toggleFailureSelection = (id: string) => { const newSelected = new Set(selectedFailures); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } setSelectedFailures(newSelected); }; const handleSelectAll = () => { if (selectedFailures.size === failures?.failures.length) { setSelectedFailures(new Set()); } else { setSelectedFailures( new Set(failures?.failures.map((f) => f.id) || []) ); } }; const handleRetrySelected = () => { if (selectedFailures.size > 0) { retryMutation.mutate(Array.from(selectedFailures)); } }; const handleSkipSelected = () => { if (selectedFailures.size > 0) { skipMutation.mutate(Array.from(selectedFailures)); } }; if (!isOpen) return null; const totalFailures = counts?.total || 0; const totalPages = Math.ceil((failures?.total || 0) / pageSize); return (
{/* Header */}

Enrichment Failures

{totalFailures} total failure {totalFailures !== 1 ? "s" : ""} to review

{/* Filter Tabs */}
{( [ { key: "all" as const, label: "All", count: counts?.total || 0 }, { key: "artist" as const, label: "Artists", count: counts?.artist || 0, }, { key: "track" as const, label: "Tracks", count: counts?.track || 0, }, { key: "audio" as const, label: "Audio Analysis", count: counts?.audio || 0, }, ] ).map((tab) => ( ))}
{/* Action Bar */} {selectedFailures.size > 0 && (
{selectedFailures.size} selected
)} {/* Failures List */}
{isLoading ? (
Loading failures...
) : failures?.failures.length === 0 ? (

No failures found

All items enriched successfully

) : (
{/* Select All */}
Select all
{failures?.failures.map((failure) => (
toggleFailureSelection(failure.id) } className="w-4 h-4 mt-1 rounded border-white/20 bg-white/10" />
{failure.entityName || failure.entityId} {failure.entityType}

{failure.errorMessage || "Unknown error"}

Retry {failure.retryCount}/ {failure.maxRetries} Last:{" "} {new Date( failure.lastFailedAt ).toLocaleString()} {failure.errorCode && ( <> {failure.errorCode} )}
))}
)}
{/* Pagination */} {totalPages > 1 && (
Page {currentPage} of {totalPages}
)}
); }