import { useEffect, useState } from "react";
import { toast } from "sonner";
import { useTranslation } from "@termix/plugin-sdk/frontend";
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
Input,
PasswordInput,
Switch,
Textarea,
cn,
} from "@termix/plugin-sdk/ui";
import { CHANNEL_TYPES, type ChannelType } from "../types";
import { EMPTY, configFrom, draftFrom, type Draft } from "./channel-config";
import type { AlertsApi } from "./api";
function Field({
label,
hint,
children,
}: {
label: string;
hint?: string;
children: React.ReactNode;
}) {
return (
{children}
{hint && (
{hint}
)}
);
}
export function ChannelDialog({
api,
open,
channelId,
emailAvailable,
onOpenChange,
onSaved,
}: {
api: AlertsApi;
open: boolean;
/** Null to create a new channel. */
channelId: number | null;
emailAvailable: boolean;
onOpenChange: (open: boolean) => void;
onSaved: () => void;
}) {
const { t } = useTranslation();
const [draft, setDraft] = useState(EMPTY);
const [saving, setSaving] = useState(false);
useEffect(() => {
if (!open) return;
if (channelId === null) {
setDraft(EMPTY);
return;
}
api
.channel(channelId)
.then((channel) => setDraft(draftFrom(channel)))
.catch((error) =>
toast.error(error instanceof Error ? error.message : String(error)),
);
}, [api, channelId, open]);
const set = (key: K, value: Draft[K]) =>
setDraft((current) => ({ ...current, [key]: value }));
const pickType = (type: ChannelType) =>
setDraft((current) => ({
...current,
type,
url:
type === "ntfy" && !current.url
? "https://ntfy.sh"
: type !== "ntfy" && current.url === "https://ntfy.sh"
? ""
: current.url,
}));
const save = async () => {
if (!draft.name.trim()) {
toast.error(t("channels.nameRequired"));
return;
}
setSaving(true);
try {
const input = {
name: draft.name.trim(),
type: draft.type,
config: configFrom(draft),
};
if (channelId === null) await api.createChannel(input);
else await api.updateChannel(channelId, input);
onSaved();
} catch (error) {
toast.error(error instanceof Error ? error.message : String(error));
} finally {
setSaving(false);
}
};
const canReachPrivate = draft.type === "webhook" || draft.type === "ntfy";
return (
);
}