'use client'; import { useEffect, useState } from 'react'; import { createClient } from '@/lib/supabase/client'; import { MessageTemplate } from '@/types'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { ArrowLeft, Send, Loader2, Users, Save } from 'lucide-react'; interface AudienceConfig { type: string; tagIds?: string[]; csvContacts?: { phone: string; name?: string }[]; } interface Step4Props { name: string; onNameChange: (name: string) => void; template: MessageTemplate; audience: AudienceConfig; onSend: () => void; onSaveDraft?: () => void; onBack: () => void; isProcessing: boolean; progress: number; } export function Step4ScheduleSend({ name, onNameChange, template, audience, onSend, onSaveDraft, onBack, isProcessing, progress, }: Step4Props) { const [showConfirm, setShowConfirm] = useState(false); const [estimatedReach, setEstimatedReach] = useState(0); const [loadingReach, setLoadingReach] = useState(true); useEffect(() => { async function calculateReach() { setLoadingReach(true); try { const supabase = createClient(); if (audience.type === 'all') { const { count } = await supabase .from('contacts') .select('*', { count: 'exact', head: true }); setEstimatedReach(count ?? 0); } else if (audience.type === 'tags' && audience.tagIds && audience.tagIds.length > 0) { const { data: contactTags } = await supabase .from('contact_tags') .select('contact_id') .in('tag_id', audience.tagIds); const uniqueIds = new Set((contactTags ?? []).map((ct) => ct.contact_id)); setEstimatedReach(uniqueIds.size); } else if (audience.type === 'csv' && audience.csvContacts) { setEstimatedReach(audience.csvContacts.length); } else { setEstimatedReach(0); } } finally { setLoadingReach(false); } } calculateReach(); }, [audience]); const audienceLabel = audience.type === 'all' ? 'All Contacts' : audience.type === 'tags' ? `Tags (${audience.tagIds?.length ?? 0} selected)` : audience.type === 'csv' ? 'CSV Upload' : 'Custom'; return (

Review & Send

Name your broadcast, review the details, and send.

{/* Broadcast Name */}
onNameChange(e.target.value)} placeholder="e.g. Summer Sale Announcement" className="border-border bg-muted text-foreground placeholder:text-muted-foreground" />
{/* Summary Card */}

Summary

Template

{template.name}

Audience

{audienceLabel}

Estimated Reach

{loadingReach ? ( ) : ( <>

{estimatedReach.toLocaleString()}

)}

Language

{template.language ?? 'en_US'}

{/* Processing overlay */} {isProcessing && (

Sending broadcast...

{progress}%
)}
{onSaveDraft && ( )} } > Send Broadcast Confirm Broadcast You are about to send this broadcast to{' '} {estimatedReach.toLocaleString()}{' '} contacts using the{' '} {template.name} template. This action cannot be undone.
); }