"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import type { RouterOutputs } from "@openstatus/api"; import { Checkbox } from "@openstatus/ui/components/ui/checkbox"; import { Form } from "@openstatus/ui/components/ui/form"; import { FormControl, FormField, FormItem, FormLabel, } from "@openstatus/ui/components/ui/form"; import { Input } from "@openstatus/ui/components/ui/input"; import { cn } from "@openstatus/ui/lib/utils"; import { isTRPCClientError } from "@trpc/client"; import { useExtracted } from "next-intl"; import { useTransition } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, } from "../status-page/status-blank"; type Page = NonNullable; const schema = z.object({ email: z.email(), subscribeComponents: z.boolean(), pageComponents: z.array(z.number().int().positive()), }); export type FormValues = z.infer; export function FormSubscribeEmail({ page, onSubmit, className, ...props }: Omit, "onSubmit"> & { onSubmit: (values: FormValues) => Promise; onSubmitCallback?: () => void; page?: Page | null; }) { const t = useExtracted(); const form = useForm({ resolver: zodResolver(schema), defaultValues: { email: "", subscribeComponents: false, pageComponents: [], }, }); const [isPending, startTransition] = useTransition(); function submitAction(values: FormValues) { if (isPending) return; startTransition(async () => { try { const promise = onSubmit(values); toast.promise(promise, { loading: t("Subscribing..."), success: t("Subscribed"), error: (error) => { if (isTRPCClientError(error)) { return error.message; } return t("Failed to subscribe"); }, }); await promise; } catch (error) { console.error(error); } }); } return (
( {t("Email")} )} /> ( {t("Subscribe to specific components")} )} /> {form.watch("subscribeComponents") && (
{page?.trackers && page.trackers.length > 0 ? ( page.trackers.map((tracker) => { if (tracker.type === "group") { const groupIds = tracker.components.map((c) => c.id); return (
{ const allChecked = groupIds.every((id) => field.value?.includes(id), ); const someChecked = groupIds.some((id) => field.value?.includes(id), ); return ( { const value = field.value ?? []; if (checked) { field.onChange([ ...new Set([...value, ...groupIds]), ]); } else { field.onChange( value.filter( (id) => !groupIds.includes(id), ), ); } }} /> {tracker.groupName} ); }} /> {tracker.components.map((component) => ( ( { const value = field.value ?? []; if (checked) { field.onChange([...value, component.id]); } else { field.onChange( value.filter( (id) => id !== component.id, ), ); } }} /> {component.name} )} /> ))}
); } return ( ( { const value = field.value ?? []; if (checked) { field.onChange([ ...value, tracker.component.id, ]); } else { field.onChange( value.filter( (id) => id !== tracker.component.id, ), ); } }} /> {tracker.component.name} )} /> ); }) ) : ( {t("No components to subscribe to")} {t("This page has no components to subscribe to.")} )}
)} ); }