Marciano by Hostarys
Operativo

Todo funciona correctamente

Todos los servicios responden con normalidad.

Última comprobación: · Demo con datos simulados

Servicios

OperativoMantenimientoCarga altaDegradadoCaído

Conéctalo a tu monitorización

Cada tarjeta es un <Marciano status="…" />: al cambiar el estado cambia su expresión y deja de dormirse. El grande refleja siempre el peor estado.

Tu endpoint solo tiene que devolver este JSON. La función fetchStatus(url) ya está en components/demos/status/status-board.tsx: descomenta el sondeo y apúntala a tu API.

Formato del endpoint
// GET /api/status
{ "services": [
    { "id": "web",  "status": "online" },
    { "id": "mail", "status": "degraded" }
] }
// status: online | busy | degraded | down | maintenance
React: un Marciano por servicio
"use client";
import { useEffect, useState } from "react";
import { Marciano, type StatusName } from "@hostarys/marciano";

/** Lee el JSON de arriba; null si falla (el panel se queda como estaba). */
async function fetchStatus(url: string) {
  try {
    const res = await fetch(url, { cache: "no-store" });
    if (!res.ok) throw new Error(String(res.status));
    const data = await res.json();
    return data.services as { id: string; status: StatusName }[];
  } catch (err) {
    console.warn("No se pudo leer el estado:", err);
    return null;
  }
}

export function ServiceFlame({ id }: { id: string }) {
  const [status, setStatus] = useState<StatusName>("online");

  useEffect(() => {
    const poll = () => fetchStatus("/api/status").then(list => {
      const s = list?.find(x => x.id === id);
      if (s) setStatus(s.status);
    });
    poll();
    const timer = setInterval(poll, 30000);   // sondeo cada 30 s
    return () => clearInterval(timer);
  }, [id]);

  return <Marciano color="hostarys" status={status} sleepAfter={0} size={86} />;
}
HTML sin frameworks
<marciano-flame status="online" sleep-after="0"></marciano-flame>

<script>
  const m = document.querySelector("marciano-flame");
  async function fetchStatus(url) {
    const res = await fetch(url, { cache: "no-store" });
    const { services } = await res.json();
    m.setAttribute("status", services.find(s => s.id === "web").status);
  }
  fetchStatus("/api/status");
  setInterval(() => fetchStatus("/api/status"), 30000);
</script>

Los datos de esta página son de demostración.