File size: 2,477 Bytes
be22d4d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { Link } from "react-router";
import type { StatusResponse } from "@/lib/api";
import { cn } from "@/lib/utils";
import { useI18n } from "@/i18n";

/** Gateway + session summary for the System sidebar block (no separate strip chrome). */
export function SidebarStatusStrip({ status }: SidebarStatusStripProps) {
  const { t } = useI18n();

  if (status === null) {
    return (
      <div className="px-5 py-1.5" aria-hidden>

        <div className="h-2 w-[80%] max-w-full animate-pulse rounded-sm bg-midground/10" />

      </div>
    );
  }

  const gw = gatewayLine(status, t);
  const { activeSessionsLabel, gatewayStatusLabel } = t.app;

  return (
    <Link

      to="/sessions"

      title={t.app.statusOverview}

      className={cn(

        "block text-left",

        "px-5 pb-2 pt-0.5",

        "text-text-secondary",

        "transition-colors hover:text-midground",

        "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-midground/40",

        "focus-visible:ring-inset",

      )}

    >

      <div className="flex flex-col gap-1 font-sans text-xs leading-snug tracking-[0.08em]">

        <p className="break-words">

          <span className="text-text-tertiary">{gatewayStatusLabel}</span>{" "}

          <span className={cn("font-medium", gw.tone)}>{gw.label}</span>

        </p>



        <p className="break-words">

          <span className="text-text-tertiary">{activeSessionsLabel}</span>{" "}

          <span className="tabular-nums text-text-secondary">

            {status.active_sessions}

          </span>

        </p>

      </div>

    </Link>
  );
}

export function gatewayLine(

  status: StatusResponse,

  t: ReturnType<typeof useI18n>["t"],

): { label: string; tone: string } {
  const g = t.app.gatewayStrip;
  const byState: Record<string, { label: string; tone: string }> = {
    running: { label: g.running, tone: "text-success" },
    starting: { label: g.starting, tone: "text-warning" },
    startup_failed: { label: g.failed, tone: "text-destructive" },
    stopped: { label: g.stopped, tone: "text-muted-foreground" },
  };
  if (status.gateway_state && byState[status.gateway_state]) {
    return byState[status.gateway_state];
  }
  return status.gateway_running
    ? { label: g.running, tone: "text-success" }
    : { label: g.off, tone: "text-muted-foreground" };
}

interface SidebarStatusStripProps {
  status: StatusResponse | null;
}