import React, { useState, useEffect } from 'react'; import { Download, Mail, Loader2, CheckCircle2, Search, Filter } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Progress } from '@/components/ui/progress'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { motion, AnimatePresence } from 'framer-motion'; import SequenceCard from './SequenceCard'; import { apiFetch } from '@/lib/api'; import { useGeneratorWorkflow } from '@/context/GeneratorWorkflowContext'; export default function SequenceViewer() { const { isGenerating, generationComplete, selectedProducts, uploadedFile, includeLinkedin, genPhase, contacts, sequences, progress, contactCount, } = useGeneratorWorkflow(); const [searchQuery, setSearchQuery] = useState(''); const [filterProduct, setFilterProduct] = useState('all'); const [displayedCount, setDisplayedCount] = useState(50); useEffect(() => { setDisplayedCount(50); }, [searchQuery, filterProduct]); const handleDownload = async () => { if (!uploadedFile?.fileId) return; try { const response = await apiFetch(`/api/download-sequences?file_id=${uploadedFile.fileId}`); if (response.ok) { const blob = await response.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'email_sequences_fixed.csv'; a.click(); URL.revokeObjectURL(url); } else { alert('Failed to download CSV. Please try again.'); } } catch (error) { console.error('Download error:', error); alert('Error downloading CSV. Please try again.'); } }; const filteredContacts = contacts.filter((contact) => { const matchesSearch = searchQuery === '' || contact.firstName?.toLowerCase().includes(searchQuery.toLowerCase()) || contact.lastName?.toLowerCase().includes(searchQuery.toLowerCase()) || contact.company?.toLowerCase().includes(searchQuery.toLowerCase()) || contact.email?.toLowerCase().includes(searchQuery.toLowerCase()); const matchesFilter = filterProduct === 'all' || contact.product === filterProduct; return matchesSearch && matchesFilter; }); const displayedContacts = filteredContacts.slice(0, displayedCount); const hasMore = filteredContacts.length > displayedCount; const loadMore = () => { setDisplayedCount((prev) => Math.min(prev + 50, filteredContacts.length)); }; const showProgress = isGenerating || !generationComplete; const phaseLabel = includeLinkedin && genPhase === 'linkedin' && isGenerating ? 'LinkedIn sequences' : 'Email sequences'; return (
{generationComplete ? (
) : (
)}

{generationComplete ? 'Generation complete!' : `Generating ${phaseLabel}…`}

{contacts.length} contacts · {sequences.length} generated rows {contactCount ? ` · ~${contactCount} contacts in file` : ''}

{generationComplete && ( )}
{showProgress ? : null}
{sequences.length > 0 && (
setSearchQuery(e.target.value)} className="pl-10" />
)}
{displayedContacts.map((contact, index) => ( ))} {hasMore && (
)} {filteredContacts.length > 0 && (
Showing {displayedContacts.length} of {filteredContacts.length} contacts
)}
{!isGenerating && contacts.length === 0 && sequences.length === 0 && (

No sequences yet

Click "Generate Sequences" to start

)}
); }