● Zion Boggan
repos/Drophawk/frontend/components/dashboard/SourceGrid.tsx
zionboggan.com ↗
59 lines · tsx
History for this file →
1
"use client";
2
 
3
import Link from "next/link";
4
import { Server } from "lucide-react";
5
import { Card, CardBody, CardHeader, CardTitle } from "@/components/ui/card";
6
import { Skeleton } from "@/components/ui/skeleton";
7
import { SourceChip } from "@/components/shared/SourceChip";
8
import { useSources } from "@/hooks/useSources";
9
import { formatLatency } from "@/lib/utils";
10
import type { SourceStatus } from "@/lib/types";
11
 
12
const DOT: Record<SourceStatus, string> = {
13
  healthy: "var(--color-accent-green)",
14
  degraded: "var(--color-accent-amber)",
15
  down: "var(--color-accent-red)",
16
  disabled: "var(--color-fg-disabled)",
17
};
18
 
19
export function SourceGrid() {
20
  const { data, isLoading } = useSources();
21
 
22
  return (
23
    <Card className="flex h-full flex-col">
24
      <CardHeader>
25
        <CardTitle className="flex items-center gap-2">
26
          <Server className="h-4 w-4 text-[var(--color-fg-tertiary)]" aria-hidden />
27
          Sources
28
        </CardTitle>
29
        <Link href="/sources" className="text-xs text-[var(--color-accent-teal)] hover:underline">
30
          View all
31
        </Link>
32
      </CardHeader>
33
      <CardBody className="space-y-1.5 pt-3">
34
        {isLoading || !data
35
          ? Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-11" />)
36
          : data.map((s) => (
37
              <Link
38
                key={s.id}
39
                href={`/sources?source=${s.id}`}
40
                className="flex items-center gap-3 rounded-[var(--radius)] px-2 py-2 transition-colors hover:bg-[var(--color-bg-overlay)]"
41
              >
42
                <span className="relative flex h-2 w-2 shrink-0">
43
                  <span
44
                    className="h-2 w-2 rounded-full"
45
                    style={{ backgroundColor: DOT[s.status] }}
46
                    aria-hidden
47
                  />
48
                </span>
49
                <SourceChip id={s.id} size={22} />
50
                <span className="min-w-0 flex-1 truncate text-sm text-[var(--color-fg-secondary)]">{s.name}</span>
51
                <span className="font-mono text-xs tabular text-[var(--color-fg-tertiary)]">
52
                  {formatLatency(s.latency_ms_p50)}
53
                </span>
54
              </Link>
55
            ))}
56
      </CardBody>
57
    </Card>
58
  );
59
}