"use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" import { use } from "react" import { PageHeader } from "@/components/shared/page-header" import { Button } from "@/components/ui/button" import { Card } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Badge } from "@/components/ui/badge" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { ArrowLeft, Plus, Trash2, Send, Play, Pause, Users, Mail, Clock, } from "lucide-react" import { toast } from "sonner" export default function CampaignDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params) const router = useRouter() const [campaign, setCampaign] = useState(null) const [loading, setLoading] = useState(true) const [newStep, setNewStep] = useState({ subject: "", bodyText: "", delayDays: 3 }) const [addingStep, setAddingStep] = useState(false) const [sending, setSending] = useState(false) const [leadSearch, setLeadSearch] = useState("") const [searchResults, setSearchResults] = useState([]) const [subscribing, setSubscribing] = useState(false) const fetchCampaign = async () => { try { const res = await fetch(`/api/campaigns/${id}`) if (res.ok) setCampaign(await res.json()) } catch (e) { console.error("Failed to load campaign", e); toast.error("Failed to load campaign") } setLoading(false) } useEffect(() => { fetchCampaign() }, [id]) const searchLeads = async (q: string) => { setLeadSearch(q) if (q.length < 2) { setSearchResults([]); return } const res = await fetch(`/api/leads?search=${encodeURIComponent(q)}&limit=10`) if (res.ok) setSearchResults(await res.json()) } const addStep = async () => { if (!newStep.subject.trim()) return setAddingStep(true) try { await fetch(`/api/campaigns/${id}/steps`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newStep), }) setNewStep({ subject: "", bodyText: "", delayDays: 3 }) fetchCampaign() } catch (e) { console.error("Failed to add step", e); toast.error("Failed to add step") } setAddingStep(false) } const subscribeLeads = async (leadIds: string[]) => { setSubscribing(true) try { await fetch(`/api/campaigns/${id}/subscribe`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ leadIds }), }) setLeadSearch("") setSearchResults([]) fetchCampaign() } catch (e) { console.error("Failed to subscribe leads", e); toast.error("Failed to subscribe leads") } setSubscribing(false) } const sendCampaign = async () => { setSending(true) try { const res = await fetch(`/api/campaigns/${id}/send`, { method: "POST" }) const data = await res.json() if (data.sent > 0) fetchCampaign() } catch (e) { console.error("Failed to send campaign", e); toast.error("Failed to send campaign") } setSending(false) } const updateStatus = async (status: string) => { await fetch(`/api/campaigns/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }) fetchCampaign() } if (loading) return
Loading...
if (!campaign) return
Campaign not found
return (

Status

{campaign.status} {campaign.status === "draft" && } {campaign.status === "active" && } {campaign.status === "paused" && }

Subscribers

{campaign.subscribers?.length || 0}

Steps

{campaign.steps?.length || 0}

Created

{new Date(campaign.created_at).toLocaleDateString()}

Steps ({campaign.steps?.length || 0}) Subscribers ({campaign.subscribers?.length || 0}) Send

Add Step

setNewStep(p => ({ ...p, subject: e.target.value }))} placeholder="Follow-up: {{name}}" />
setNewStep(p => ({ ...p, delayDays: parseInt(e.target.value) || 0 }))} />