import {
useActionMutation,
useActionQuery,
} from "@agent-native/core/client/hooks";
import { useT } from "@agent-native/core/client/i18n";
import { IconChevronRight } from "@tabler/icons-react";
import { useState } from "react";
import { toast } from "sonner";
import { ActionQueryError } from "../../components/action-query-error";
import { DispatchShell } from "../../components/dispatch-shell";
import { TaskQueueHealth } from "../../components/task-queue-health";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "../../components/ui/alert-dialog";
import { Button } from "../../components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "../../components/ui/collapsible";
import { Input } from "../../components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "../../components/ui/select";
import { Textarea } from "../../components/ui/textarea";
export function meta() {
return [{ title: "Destinations — Dispatch" }];
}
function QuickSendRow({
destination,
}: {
destination: { id: string; name: string };
}) {
const t = useT();
const [text, setText] = useState("");
const send = useActionMutation("send-platform-message", {
onSuccess: () => {
toast.success(t("dispatch.pages.messageSent"));
setText("");
},
onError: (error) => {
toast.error(
error instanceof Error
? error.message
: t("dispatch.pages.unableToSendMessage"),
);
},
});
return (
setText(event.target.value)}
placeholder={t("dispatch.pages.quickTestMessage")}
/>
);
}
export default function DestinationsRoute() {
const t = useT();
const destinationsQuery = useActionQuery("list-destinations", {});
const { data } = destinationsQuery;
const [form, setForm] = useState({
name: "",
platform: "slack",
destination: "",
threadRef: "",
notes: "",
});
const [addOpen, setAddOpen] = useState(false);
const upsert = useActionMutation("upsert-destination", {
onSuccess: () => {
toast.success(t("dispatch.pages.destinationSaved"));
setForm((current) => ({
...current,
name: "",
destination: "",
threadRef: "",
notes: "",
}));
},
});
const remove = useActionMutation("delete-destination", {
onSuccess: () => toast.success(t("dispatch.pages.destinationRemoved")),
});
return (
{t("dispatch.pages.savedDestinations")}
{destinationsQuery.isError ? (
void destinationsQuery.refetch()}
/>
) : (
{(data || []).map((destination: any) => (
{destination.name}
{destination.platform} · {destination.destination}
{destination.threadRef
? ` · thread ${destination.threadRef}`
: ""}
{destination.notes && (
{destination.notes}
)}
{t("dispatch.pages.deleteDestinationTitle")}
{t("dispatch.pages.deleteDestinationDescription", {
name: destination.name,
})}
{t("dispatch.pages.cancel")}
remove.mutate({ id: destination.id })
}
>
{t("dispatch.pages.delete")}
Send a test message
))}
{(data?.length || 0) === 0 && (
{t("dispatch.pages.noDestinations")}
)}
)}
{t("dispatch.pages.addDestination")}
Save a reusable delivery target for scheduled or agent-sent
messages.
setForm((current) => ({
...current,
name: event.target.value,
}))
}
placeholder={t("dispatch.pages.dailyDigestChannel")}
/>
setForm((current) => ({
...current,
destination: event.target.value,
}))
}
placeholder={
form.platform === "slack"
? "C0123456789"
: form.platform === "email"
? "teammate+qa@agent-native.test"
: "123456789"
}
/>
setForm((current) => ({
...current,
threadRef: event.target.value,
}))
}
placeholder={t("dispatch.pages.optionalThreadOrTopicId")}
/>
);
}