import { useState } from "react"; import { X, Clock, Send, Trash2, XCircle, RotateCcw, Repeat, Bot } from "lucide-react"; import { cn } from "../lib/utils"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; import { Badge } from "./ui/badge"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "./ui/table"; import { useScheduledMessages } from "../hooks/useScheduledMessages"; import { scheduledMessageService, type CreateScheduledMessage, } from "../api/scheduledMessageService"; type Props = { onClose: () => void; }; const STATUS_BADGE: Record = { pending: "amber", sent: "default", failed: "destructive", cancelled: "muted", }; export const ScheduledMessagesPanel = ({ onClose }: Props) => { const { messages, loading, refresh } = useScheduledMessages(); const [channel, setChannel] = useState<"imessage" | "email">("imessage"); const [recipient, setRecipient] = useState(""); const [subject, setSubject] = useState(""); const [content, setContent] = useState(""); const [scheduledAt, setScheduledAt] = useState(""); const [recurrence, setRecurrence] = useState<"none" | "daily" | "weekly" | "monthly">("none"); const [useAgent, setUseAgent] = useState(false); const [error, setError] = useState(""); const [submitting, setSubmitting] = useState(false); const handleCreate = async () => { setError(""); if (!recipient || !content || !scheduledAt) { setError("Recipient, content, and scheduled time are required."); return; } if (channel === "email" && !subject) { setError("Subject is required for email."); return; } setSubmitting(true); try { const data: CreateScheduledMessage = { recipient, channel, content, scheduled_at: new Date(scheduledAt).toISOString(), recurrence, use_agent: useAgent, }; if (channel === "email") data.subject = subject; await scheduledMessageService.create(data); setRecipient(""); setSubject(""); setContent(""); setScheduledAt(""); setRecurrence("none"); setUseAgent(false); refresh(); } catch (err) { setError(err instanceof Error ? err.message : "Failed to schedule message"); } finally { setSubmitting(false); } }; const handleCancel = async (id: string) => { try { await scheduledMessageService.update(id, { status: "cancelled" }); refresh(); } catch {} }; const handleDelete = async (id: string) => { try { await scheduledMessageService.remove(id); refresh(); } catch {} }; const handleRetry = async (id: string) => { try { const futureTime = new Date(Date.now() + 30_000).toISOString(); await scheduledMessageService.update(id, { scheduled_at: futureTime }); refresh(); } catch {} }; return (
e.target === e.currentTarget && onClose()} >
{/* Header */}

Scheduled Messages

{/* Create form */}
setRecipient(e.target.value)} placeholder={channel === "imessage" ? "+15551234567" : "user@example.com"} className="flex-1" /> setScheduledAt(e.target.value)} className="w-52" />
Repeat: {(["none", "daily", "weekly", "monthly"] as const).map((r) => ( ))}
{useAgent ? "Content is a prompt — Simba's response will be sent" : "Content sent as-is"}
{channel === "email" && ( setSubject(e.target.value)} placeholder="Subject" /> )}