"use client"; import { Checkbox } from "@/components/ui/checkbox"; import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Form } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; import { useTransition } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; const schema = z.object({ name: z.string(), provider: z.enum([ "slack", "discord", "email", "sms", "webhook", "opsgenie", "pagerduty", "ntfy", "telegram", "whatsapp", "google-chat", ]), data: z.record(z.string(), z.string()).or(z.string()), monitors: z.array(z.number()), }); export type FormValues = z.infer; export function NotifierForm({ defaultValues, className, onSubmit, monitors, ...props }: Omit, "onSubmit"> & { defaultValues?: FormValues; onSubmit?: (values: FormValues) => Promise | void; monitors: { id: number; name: string }[]; }) { const form = useForm({ resolver: zodResolver(schema), defaultValues: defaultValues ?? { name: "", data: { webhook: "", }, monitors: [], }, }); const [isPending, startTransition] = useTransition(); function submitAction(values: FormValues) { if (isPending) return; startTransition(async () => { try { const promise = new Promise((resolve) => setTimeout(resolve, 1000)); toast.promise(promise, { loading: "Saving...", success: () => JSON.stringify(values), error: "Failed to save", }); await promise; onSubmit?.(values); } catch (error) { console.error(error); } }); } return (
( Name Enter a descriptive name for your notifier. )} /> ( Webhook URL )} /> ( Monitors Select the monitors you want to notify.
{ field.onChange( checked ? monitors.map((m) => m.id) : [], ); }} />
{monitors.map((item) => (
{ const newValue = checked ? [...(field.value || []), item.id] : field.value?.filter((id) => id !== item.id); field.onChange(newValue); }} />
))}
)} /> ); }