"use client"; import { useEffect, useState } from "react"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { EmptyState } from "@/components/shared/EmptyState"; import { StatusBadge } from "@/components/shared/ProgressCard"; import { toast } from "sonner"; import { BarChart3, Building2, Linkedin, Search, Download, Trash2, RefreshCw } from "lucide-react"; import { cn } from "@/lib/utils"; interface Job { id: string; type: string; status: string; totalLeads: number; emailsFound: number; createdAt: string; error?: string; } interface Stats { totalLeads: number; totalEmails: number; avgHitRate: number; totalJobs: number; } const TYPE_CONFIG: Record = { airscale: { icon: Building2, label: "AirScale", color: "text-blue-400" }, linkedin: { icon: Linkedin, label: "LinkedIn", color: "text-blue-500" }, "linkedin-enrich": { icon: Linkedin, label: "LinkedIn Enrich", color: "text-blue-400" }, serp: { icon: Search, label: "SERP", color: "text-purple-400" }, }; export default function ResultsPage() { const [jobs, setJobs] = useState([]); const [stats, setStats] = useState({ totalLeads: 0, totalEmails: 0, avgHitRate: 0, totalJobs: 0 }); const [loading, setLoading] = useState(true); useEffect(() => { loadJobs(); }, []); const loadJobs = async () => { setLoading(true); try { const res = await fetch("/api/jobs"); const data = await res.json() as { jobs: Job[]; stats: Stats }; setJobs(data.jobs || []); setStats(data.stats || { totalLeads: 0, totalEmails: 0, avgHitRate: 0, totalJobs: 0 }); } catch { toast.error("Failed to load job history"); } finally { setLoading(false); } }; const deleteJob = async (id: string) => { try { await fetch(`/api/jobs/${id}`, { method: "DELETE" }); setJobs(prev => prev.filter(j => j.id !== id)); toast.success("Job deleted"); } catch { toast.error("Failed to delete job"); } }; const downloadJob = (id: string) => { window.open(`/api/export/${id}`, "_blank"); }; const hitRate = (job: Job) => job.totalLeads > 0 ? Math.round((job.emailsFound / job.totalLeads) * 100) : 0; return (
{/* Header */}

Results & History

All past enrichment jobs and their results.

{/* Stats cards */}
{[ { label: "Total Jobs", value: stats.totalJobs, color: "text-white" }, { label: "Total Leads", value: stats.totalLeads.toLocaleString(), color: "text-blue-400" }, { label: "Emails Found", value: stats.totalEmails.toLocaleString(), color: "text-green-400" }, { label: "Avg Hit Rate", value: `${stats.avgHitRate}%`, color: "text-purple-400" }, ].map(stat => (

{stat.value}

{stat.label}

))}
{/* Jobs table */}

Job History

{loading ? (
{Array.from({ length: 5 }).map((_, i) => ( ))}
) : jobs.length === 0 ? ( ) : (
{jobs.map((job, idx) => { const cfg = TYPE_CONFIG[job.type] || { icon: BarChart3, label: job.type, color: "text-gray-400" }; const Icon = cfg.icon; return ( ); })}
Type Job ID Started Status Leads Emails Hit Rate Actions
{cfg.label}
{job.id.slice(0, 12)}... {new Date(job.createdAt).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", })} {job.totalLeads.toLocaleString()} {job.emailsFound.toLocaleString()} = 50 ? "text-green-400" : hitRate(job) >= 20 ? "text-yellow-400" : "text-red-400" )}> {hitRate(job)}%
)}
); }