import { ExclamationTriangleIcon } from "@heroicons/react/20/solid"; import { json } from "@remix-run/node"; import { useFetcher, type ShouldRevalidateFunction } from "@remix-run/react"; import { motion } from "framer-motion"; import { useEffect, useRef } from "react"; import { LinkButton } from "~/components/primitives/Buttons"; import { Paragraph } from "~/components/primitives/Paragraph"; import { Popover, PopoverContent, PopoverTrigger } from "~/components/primitives/Popover"; import { SimpleTooltip } from "~/components/primitives/Tooltip"; import { useFeatures } from "~/hooks/useFeatures"; import { BetterStackClient, type AggregateState } from "~/services/betterstack/betterstack.server"; // Prevent Remix from revalidating this route when other fetchers submit export const shouldRevalidate: ShouldRevalidateFunction = () => false; export type IncidentLoaderData = { status: AggregateState; title: string | null; }; export async function loader() { const client = new BetterStackClient(); const result = await client.getIncidentStatus(); if (!result.success) { return json({ status: "operational", title: null }); } return json({ status: result.data.status, title: result.data.title, }); } const DEFAULT_MESSAGE = "Our team is working on resolving the issue. Check our status page for more information."; const POLL_INTERVAL_MS = 60_000; /** Hook to fetch and poll incident status */ export function useIncidentStatus() { const { isManagedCloud } = useFeatures(); const fetcher = useFetcher(); const hasInitiallyFetched = useRef(false); useEffect(() => { if (!isManagedCloud) return; // Initial fetch on mount if (!hasInitiallyFetched.current && fetcher.state === "idle") { hasInitiallyFetched.current = true; fetcher.load("/resources/incidents"); } // Poll every 60 seconds const interval = setInterval(() => { if (fetcher.state === "idle") { fetcher.load("/resources/incidents"); } }, POLL_INTERVAL_MS); return () => clearInterval(interval); }, [isManagedCloud]); return { status: fetcher.data?.status ?? "operational", title: fetcher.data?.title ?? null, hasIncident: (fetcher.data?.status ?? "operational") !== "operational", isManagedCloud, }; } export function IncidentStatusPanel({ isCollapsed = false, title, hasIncident, isManagedCloud, }: { isCollapsed?: boolean; title: string | null; hasIncident: boolean; isManagedCloud: boolean; }) { if (!isManagedCloud || !hasIncident) { return null; } const message = title || DEFAULT_MESSAGE; return (
} content="Active incident" side="right" sideOffset={8} disableHoverableContent asChild />
); } function IncidentPanelContent({ message }: { message: string }) { return (
Active incident
{message} View status page
); }