"use client"; import { useState } from "react"; import { Mail, Loader2, X, AlertCircle, Send, Copy, Check } from "lucide-react"; import { Button } from "@/components/ui/button"; import { generateInvoiceChaseEmailsAction, fetchOverdueInvoices, } from "@/lib/supabase/ai-actions"; import type { InvoiceChaseDraft } from "@/lib/gemini"; interface InvoiceChaseDialogProps { orgName: string; onSent?: () => void; } export function InvoiceChaseDialog({ orgName, onSent }: InvoiceChaseDialogProps) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [generating, setGenerating] = useState(false); const [drafts, setDrafts] = useState([]); const [error, setError] = useState(null); const [selectedInvoices, setSelectedInvoices] = useState([]); const [invoices, setInvoices] = useState< { id: string; invoice_number: string; client_name: string; total_cents: number; due_date: string }[] >([]); const [copiedIdx, setCopiedIdx] = useState(null); const handleOpen = async () => { setOpen(true); setError(null); setDrafts([]); setLoading(true); try { const result = await fetchOverdueInvoices(); if (!result.success) { setError(result.error || "Failed to fetch overdue invoices"); } else { setInvoices(result.invoices || []); setSelectedInvoices((result.invoices || []).map((i) => i.id)); } } catch (e: any) { setError(e.message || "Failed to fetch overdue invoices"); } finally { setLoading(false); } }; const handleGenerate = async () => { if (selectedInvoices.length === 0) { setError("Select at least one invoice to generate emails"); return; } setGenerating(true); setError(null); try { const result = await generateInvoiceChaseEmailsAction(selectedInvoices, orgName); if (!result.success) { if (result.blocked) { setError("You've reached your free tier limit for AI queries. Upgrade to Pro for unlimited access."); } else { setError(result.error || "Failed to generate emails"); } return; } if (result.drafts) { setDrafts(result.drafts); } } catch (e: any) { setError(e.message || "Failed to generate emails"); } finally { setGenerating(false); } }; const handleCopy = (body: string, idx: number) => { navigator.clipboard.writeText(body); setCopiedIdx(idx); setTimeout(() => setCopiedIdx(null), 2000); }; const handleSend = async (draft: InvoiceChaseDraft) => { // For now, just close — actual sending would integrate with email service alert("Email sent! (Integration with email service pending)"); onSent?.(); }; const toggleInvoice = (id: string) => { setSelectedInvoices((prev) => prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id] ); }; return ( <> {/* Trigger button */} {/* Modal */} {open && (
setOpen(false)} />
{/* Header */}

AI Invoice Chase Emails

Select overdue invoices to generate follow-up emails

{/* Content */}
{error && (

{error}

)} {/* Invoice selection */} {loading ? (
) : invoices.length === 0 ? (
No overdue invoices found
) : (
Select Invoices ({selectedInvoices.length}/{invoices.length})
{invoices.map((inv) => ( ))}
)} {/* Generate button */} {invoices.length > 0 && !loading && ( )} {/* Drafts */} {drafts.length > 0 && (

Generated Drafts ({drafts.length})

{drafts.map((draft, idx) => (

{draft.invoice_number}

{draft.subject}

                          {draft.body}
                        
))}
)}
)} ); }