import { Info } from "@openstatus/icons"; import type { ThemeKey } from "@openstatus/theme-store"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useParams, useRouter } from "next/navigation"; import { Link } from "@/components/common/link"; import { Note } from "@/components/common/note"; import { FormCardGroup } from "@/components/forms/form-card"; import { useTRPC } from "@/lib/trpc/client"; import { FormAppearance } from "./form-appearance"; import { FormCustomDomain } from "./form-custom-domain"; import { FormCustomTheme } from "./form-custom-theme"; import { FormDangerZone } from "./form-danger-zone"; import { FormGeneral } from "./form-general"; import { FormLinks } from "./form-links"; import { FormLocale } from "./form-locale"; import { FormPageAccess } from "./form-page-access"; export function FormStatusPageUpdate() { const { id } = useParams<{ id: string }>(); const router = useRouter(); const trpc = useTRPC(); const { data: statusPage, refetch } = useQuery( trpc.page.get.queryOptions({ id: Number.parseInt(id) }), ); const queryClient = useQueryClient(); const { data: monitors } = useQuery(trpc.monitor.list.queryOptions()); const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const updateStatusPageMutation = useMutation( trpc.page.updateGeneral.mutationOptions({ onSuccess: () => { refetch(); // NOTE: invalidate status page list to update name queryClient.invalidateQueries({ queryKey: trpc.page.list.queryKey(), }); }, }), ); const updatePasswordProtectionMutation = useMutation( trpc.page.updatePasswordProtection.mutationOptions({ onSuccess: () => refetch(), }), ); const updateCustomDomainMutation = useMutation( trpc.page.updateCustomDomain.mutationOptions({ onSuccess: () => refetch(), }), ); const updatePageAppearanceMutation = useMutation( trpc.page.updateAppearance.mutationOptions({ onSuccess: () => refetch(), }), ); const deleteStatusPageMutation = useMutation( trpc.page.delete.mutationOptions({ onSuccess: () => { router.push("/status-pages"); // NOTE: invalidate workspace to update the usage queryClient.invalidateQueries({ queryKey: trpc.workspace.get.queryKey(), }); // NOTE: invalidate status page list to update the usage queryClient.invalidateQueries({ queryKey: trpc.page.list.queryKey(), }); }, }), ); const updateCustomThemeMutation = useMutation( trpc.page.updateCustomTheme.mutationOptions({ onSuccess: () => refetch(), }), ); const updateLinksMutation = useMutation( trpc.page.updateLinks.mutationOptions({ onSuccess: () => refetch(), }), ); const updateLocalesMutation = useMutation( trpc.page.updateLocales.mutationOptions({ onSuccess: () => refetch(), }), ); if (!statusPage || !monitors || !workspace) return null; return (

Looking to connect monitors to your status page? Configure them on the{" "} Components page.

{ await updateStatusPageMutation.mutateAsync({ id: Number.parseInt(id), title: values.title, slug: values.slug, description: values.description ?? "", icon: values.icon ?? "", }); }} /> { await updateCustomDomainMutation.mutateAsync({ id: Number.parseInt(id), customDomain: values.domain, }); }} /> { await updateLinksMutation.mutateAsync({ id: Number.parseInt(id), homepageUrl: values.homepageUrl ?? undefined, contactUrl: values.contactUrl ?? undefined, }); }} /> { await updatePageAppearanceMutation.mutateAsync({ id: Number.parseInt(id), forceTheme: values.forceTheme, // `FormAppearance` keeps its internal `theme` value as a // loose `string`; cast to the canonical `ThemeKey` from // `@openstatus/theme-store` (same source the service input // enum is derived from). Invalid submits are caught by the // router's zod parse. configuration: { theme: values.configuration.theme as ThemeKey, }, }); }} /> { await updateCustomThemeMutation.mutateAsync({ id: Number.parseInt(id), customTheme: values.customTheme, }); }} /> { await updateLocalesMutation.mutateAsync({ id: Number.parseInt(id), defaultLocale: values.defaultLocale, locales: values.locales, }); }} /> { await updatePasswordProtectionMutation.mutateAsync({ id: Number.parseInt(id), accessType: values.accessType, password: values.password, authEmailDomains: values.authEmailDomains, allowedIpRanges: values.accessType === "ip-restriction" ? (values.allowedIpRanges ?? null) : null, allowIndex: values.allowIndex, }); }} /> { await deleteStatusPageMutation.mutateAsync({ id: Number.parseInt(id), }); }} />
); }