File size: 2,355 Bytes
cd8bd0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
74
75
76
77
78
79
"use client";

export type WebhookKind = "slack" | "telegram" | "discord" | "custom";
export type ComingSoonKind = "email" | "pagerduty" | "teams";
type AnyKind = WebhookKind | ComingSoonKind;

const KIND_ICONS: Record<AnyKind, string> = {
  slack: "chat",
  telegram: "send",
  discord: "forum",
  custom: "webhook",
  email: "email",
  pagerduty: "notifications_active",
  teams: "groups",
};

const KIND_COLORS: Record<AnyKind, string> = {
  slack: "text-emerald-500",
  telegram: "text-blue-500",
  discord: "text-violet-500",
  custom: "text-amber-500",
  email: "text-text-muted",
  pagerduty: "text-text-muted",
  teams: "text-text-muted",
};

interface IntegrationCardProps {
  kind: AnyKind;
  name: string;
  description: string;
  selected: boolean;
  onSelect?: (kind: WebhookKind) => void;
  disabled?: boolean;
  comingSoonLabel?: string;
}

export function IntegrationCard({
  kind,
  name,
  description,
  selected,
  onSelect,
  disabled,
  comingSoonLabel,
}: IntegrationCardProps) {
  return (
    <button
      type="button"
      onClick={!disabled && onSelect ? () => onSelect(kind as WebhookKind) : undefined}
      disabled={disabled}
      className={`relative flex w-full flex-col items-start gap-2 rounded-xl border p-4 text-left transition-all disabled:cursor-not-allowed disabled:opacity-50 ${
        disabled
          ? "border-border bg-surface"
          : selected
            ? "border-primary bg-primary/5 shadow-sm"
            : "border-border bg-surface hover:border-primary/40 hover:bg-primary/5"
      }`}
    >
      {comingSoonLabel && (
        <span className="absolute right-2 top-2 rounded-full bg-surface px-1.5 py-0.5 text-[10px] font-medium text-text-muted ring-1 ring-border">
          {comingSoonLabel}
        </span>
      )}
      <span className={`material-symbols-outlined text-[28px] ${KIND_COLORS[kind]}`}>
        {KIND_ICONS[kind]}
      </span>
      <div>
        <p className="text-sm font-semibold text-text-main">{name}</p>
        <p className="mt-0.5 text-xs text-text-muted">{description}</p>
      </div>
      {selected && !disabled && (
        <span className="ml-auto mt-auto flex size-5 items-center justify-center rounded-full bg-primary">
          <span className="material-symbols-outlined text-[14px] text-white">check</span>
        </span>
      )}
    </button>
  );
}