"use client"; import { Credenza, CredenzaBody, CredenzaClose, CredenzaContent, CredenzaDescription, CredenzaFooter, CredenzaHeader, CredenzaTitle } from "@app/components/Credenza"; import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert"; import { SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle } from "@app/components/Settings"; import UptimeBar from "@app/components/UptimeBar"; import { TagInput, type Tag } from "@app/components/tags/tag-input"; import { Button } from "@app/components/ui/button"; import { Input } from "@app/components/ui/input"; import { Label } from "@app/components/ui/label"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { usePaidStatus } from "@app/hooks/usePaidStatus"; import { toast } from "@app/hooks/useToast"; import { createApiClient, formatAxiosError } from "@app/lib/api"; import { orgQueries } from "@app/lib/queries"; import { tierMatrix } from "@server/lib/billing/tierMatrix"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { BellPlus, BellRing } from "lucide-react"; import { useTranslations } from "next-intl"; import Link from "next/link"; import { useState } from "react"; import { RolesSelector } from "./roles-selector"; import { UsersSelector } from "./users-selector"; interface UptimeAlertSectionProps { orgId: string; siteId?: number; startingName?: string; resourceId?: number; days?: number; } export default function UptimeAlertSection({ orgId, siteId, startingName, resourceId, days = 90 }: UptimeAlertSectionProps) { const t = useTranslations(); const envContext = useEnvContext(); const api = createApiClient(envContext); const queryClient = useQueryClient(); const { isPaidUser } = usePaidStatus(); const isPaid = isPaidUser(tierMatrix.alertingRules); const { env } = envContext; const [open, setOpen] = useState(false); const [name, setName] = useState( `${siteId ? t("site") : t("resource")} ${startingName} ${t("alertLabel")}` ); const [userTags, setUserTags] = useState([]); const [roleTags, setRoleTags] = useState([]); const [emailTags, setEmailTags] = useState([]); const [activeEmailTagIndex, setActiveEmailTagIndex] = useState< number | null >(null); const [loading, setLoading] = useState(false); const { data: alertRules, isLoading: alertRulesLoading } = useQuery({ ...orgQueries.alertRulesForSource({ orgId, siteId, resourceId }), enabled: isPaid }); const hasRules = (alertRules?.length ?? 0) > 0; async function handleSubmit() { if ( userTags.length === 0 && roleTags.length === 0 && emailTags.length === 0 ) { toast({ variant: "destructive", title: t("uptimeAlertNoRecipients"), description: t("uptimeAlertNoRecipientsDescription") }); return; } setLoading(true); try { await api.put(`/org/${orgId}/alert-rule`, { name, eventType: siteId ? "site_toggle" : "resource_toggle", enabled: true, cooldownSeconds: 0, // default to 0 here because we dont want the extra confusion siteIds: siteId ? [siteId] : [], healthCheckIds: [], resourceIds: resourceId ? [resourceId] : [], userIds: userTags.map((tag) => tag.id), roleIds: roleTags.map((tag) => Number(tag.id)), emails: emailTags.map((tag) => tag.text), webhookActions: [] }); toast({ title: t("uptimeAlertCreated"), description: t("uptimeAlertCreatedDescription") }); setOpen(false); setName(t("uptimeSectionTitle")); setUserTags([]); setRoleTags([]); setEmailTags([]); queryClient.invalidateQueries({ queryKey: orgQueries.alertRulesForSource({ orgId, siteId, resourceId }).queryKey }); } catch (e) { toast({ variant: "destructive", title: t("uptimeAlertCreateFailed"), description: formatAxiosError(e, t("errorOccurred")) }); } setLoading(false); } const rulesListSearch = new URLSearchParams(); if (siteId != null) rulesListSearch.set("siteId", String(siteId)); if (resourceId != null) rulesListSearch.set("resourceId", String(resourceId)); const rulesListHref = `/${orgId}/settings/alerting/rules${ rulesListSearch.toString() ? `?${rulesListSearch}` : "" }`; const alertButton = alertRulesLoading ? ( ) : hasRules ? ( ) : ( ); return ( <>
{t("uptimeSectionTitle")} {t("uptimeSectionDescription", { days })}
{!env.flags.disableEnterpriseFeatures ? alertButton : null}
{t("uptimeCreateEmailAlert")} {siteId ? t("uptimeAlertDescriptionSite") : t("uptimeAlertDescriptionResource")}
setName(e.target.value) } placeholder={t( "uptimeAlertNamePlaceholder" )} />
{ const next = typeof newTags === "function" ? newTags(emailTags) : newTags; setEmailTags(next as Tag[]); }} allowDuplicates={false} sortTags validateTag={(tag) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test( tag ) } delimiterList={[",", "Enter"]} />
); }