"use client"; /* eslint-disable react-hooks/set-state-in-effect */ import { useState, useCallback, useEffect } from "react"; import { getAbandonedCarts, manuallyCloseAbandonedCart, resendAbandonedCartEmail, type AbandonedCart } from "@/actions/email-automation/abandoned-cart"; type Props = { brandId: string }; const STATUS_LABELS: Record = { active: { en: "Active", color: "bg-blue-50 text-blue-700 border border-blue-200" }, recovered: { en: "Recovered", color: "bg-green-50 text-green-700 border border-green-200" }, expired: { en: "Expired", color: "bg-stone-100 text-stone-500 border border-stone-200" }, manually_closed: { en: "Manually Closed", color: "bg-amber-50 text-amber-700 border border-amber-200" }, }; const STEP_LABELS: Record = { 0: "Detected", 1: "Email 1 (1h)", 2: "Email 2 (24h)", 3: "Email 3 (48h)", }; function CartItemRow({ item }: { item: { name: string; quantity: number; unit_price: number } }) { return ( {item.name} {item.quantity} ${Number(item.unit_price).toFixed(2)} ); } export default function AbandonedCartDashboard({ brandId }: Props) { const [carts, setCarts] = useState([]); const [stats, setStats] = useState({ total: 0, recovered: 0, active: 0, expired: 0 }); const [loading, setLoading] = useState(false); const [filter, setFilter] = useState<"all" | "active" | "recovered">("all"); const [page, setPage] = useState(0); const PAGE_SIZE = 25; const [selectedCart, setSelectedCart] = useState(null); const [closing, setClosing] = useState(false); const [resending, setResending] = useState(null); const load = useCallback(async () => { setLoading(true); const result = await getAbandonedCarts(brandId); if (result.success) { setCarts(result.carts); setStats(result.stats); } setLoading(false); }, [brandId]); const handleClose = async (cartId: string) => { setClosing(true); await manuallyCloseAbandonedCart(cartId, brandId); await load(); setClosing(false); }; useEffect(() => { setPage(0); }, [filter]); const filteredCarts = carts.filter(c => { if (filter === "active") return c.status === "active"; if (filter === "recovered") return c.status === "recovered"; return true; }); const paginatedCarts = filteredCarts.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE); const totalPages = Math.ceil(filteredCarts.length / PAGE_SIZE); const handleResend = async (cartId: string) => { setResending(cartId); await resendAbandonedCartEmail(cartId, brandId); await load(); setResending(null); }; const cart = selectedCart; return (
{/* Stats row */}
{[ { label: "Total", value: stats.total, color: "text-[var(--admin-text-primary)]" }, { label: "Active", value: stats.active, color: "text-blue-600" }, { label: "Recovered", value: stats.recovered, color: "text-green-600" }, { label: "Expired", value: stats.expired, color: "text-[var(--admin-text-muted)]" }, ].map(s => (

{s.value}

{s.label}

))}
{/* Filter + refresh + pagination */}
{(["all", "active", "recovered"] as const).map(f => ( ))}
{totalPages > 1 && (
{page + 1}/{totalPages}
)}
{/* Carts table */} {filteredCarts.length === 0 ? (

No abandoned carts{filter !== "all" ? ` (${filter})` : ""}

) : (
{paginatedCarts.map(c => { const meta = STATUS_LABELS[c.status] ?? STATUS_LABELS.active; return ( ); })}
Contact Items Total Step Status Detected Actions

{c.contact_name ?? "—"}

{c.contact_email}

{c.cart_snapshot.item_count} items ${Number(c.cart_snapshot.subtotal).toFixed(2)} {STEP_LABELS[c.sequence_step] ?? c.sequence_step} {meta.en} {new Date(c.created_at).toLocaleDateString()}
{c.status === "active" && ( )} {c.status === "active" && ( )}
)} {/* Cart detail modal */} {cart && (
setSelectedCart(null)}>
e.stopPropagation()}>

Abandoned Cart

{cart.contact_email}

{STATUS_LABELS[cart.status]?.en ?? cart.status}

{cart.contact_name ?? "—"}

{cart.contact_email}

Step: {STEP_LABELS[cart.sequence_step] ?? cart.sequence_step}

Cart Items

{cart.cart_snapshot.items.map((item, i) => ( ))}
Item Qty Price
Total ${Number(cart.cart_snapshot.subtotal).toFixed(2)}
{cart.last_email_sent_at && (

Last email sent: {new Date(cart.last_email_sent_at).toLocaleString()}

)} {cart.next_email_at && (

Next email: {new Date(cart.next_email_at).toLocaleString()}

)}
)}
); }