import { useState, useRef } from "react"; import { Search, Users, Loader2, FileSpreadsheet, Zap, Eye, Sparkles, Globe, Link2 } from "lucide-react"; import { batchAPI } from "../api/client"; import toast from "react-hot-toast"; export default function RecipientInput({ onResearch, onBatchStart, loading, disabled }) { const [mode, setMode] = useState("single"); const [singleInput, setSingleInput] = useState(""); const [batchInput, setBatchInput] = useState(""); const [extractedEmails, setExtractedEmails] = useState([]); const [batchMode, setBatchMode] = useState("manual"); const [delayMin, setDelayMin] = useState(15); const [delayMax, setDelayMax] = useState(45); const [extracting, setExtracting] = useState(false); const [directoryUrl, setDirectoryUrl] = useState(""); const [scraping, setScraping] = useState(false); const fileRef = useRef(null); const handleSingleSubmit = (e) => { e.preventDefault(); if (singleInput.trim() && onResearch) onResearch(singleInput.trim()); }; const handleCSVUpload = async (e) => { const file = e.target.files?.[0]; if (!file) return; setExtracting(true); try { const res = await batchAPI.uploadCSV(file); setExtractedEmails(res.data.emails); setBatchInput(res.data.emails.join("\n")); toast.success(`Found ${res.data.count} emails from ${file.name}`); } catch (err) { toast.error(err.response?.data?.detail || "Failed to parse file"); } setExtracting(false); if (fileRef.current) fileRef.current.value = ""; }; const handleExtractFromText = async () => { if (!batchInput.trim()) return; setExtracting(true); try { const res = await batchAPI.extractEmails(batchInput); setExtractedEmails(res.data.emails); setBatchInput(res.data.emails.join("\n")); toast.success(`Extracted ${res.data.count} emails`); } catch { toast.error("No emails found in the text"); } setExtracting(false); }; const handleUrlScrape = async () => { if (!directoryUrl.trim()) return; setScraping(true); try { const res = await batchAPI.scrapeFaculty(directoryUrl.trim()); const emails = res.data.emails || []; setBatchInput(emails.join("\n")); setExtractedEmails(emails); setMode("batch"); toast.success(`Found ${res.data.count} email addresses!`); } catch (err) { toast.error(err.response?.data?.detail || "Could not scrape page"); } setScraping(false); }; const handleBatchSubmit = () => { const list = batchInput.split("\n").map((l) => l.trim()).filter(Boolean); if (list.length > 0 && onBatchStart) onBatchStart(list, batchMode, delayMin, delayMax); }; const emailCount = batchInput.split("\n").filter((l) => l.trim()).length; const tabClass = (active) => `flex-1 text-[10px] py-1.5 px-1 rounded-lg font-semibold transition-all ${active ? "bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 border border-indigo-500/20" : "text-[var(--c-text-muted)] hover:text-[var(--c-text-secondary)] border border-transparent" }`; return (

Compose & Send

{mode === "single" && (
setSingleInput(e.target.value)} placeholder="recipient@example.com" disabled={disabled || loading} className="w-full input-dark text-sm mb-2.5" />
)} {mode === "scrape" && (
setDirectoryUrl(e.target.value)} placeholder="https://example.com/team" disabled={disabled || scraping} className="w-full text-[12px] outline-none bg-transparent text-[var(--c-text-primary)] placeholder:text-[var(--c-text-muted)]" />
Paste any page URL to extract email addresses
{extractedEmails.length > 0 && (

Found {extractedEmails.length} emails

Switched to Batch tab with all emails loaded

)}
)} {mode === "batch" && (