Skip to content
File

Blob: src/client/components/webhooks/webhook-presentation.tsx

typescript46 lines
1import type { WebhookDeliveryOutcome, WebhookProvider } from "@/contracts";
2import { Container, GitBranch, GitCompareArrows } from "lucide-react";
3import { webhookProviderCatalogList } from "@/lib/webhooks";
4 
5const PROVIDER_ICONS: Record<WebhookProvider, React.FC<{ className?: string }>> = {
6 github: GitBranch,
7 gitlab: GitCompareArrows,
8 gitea: Container,
9};
10 
11export const getWebhookProviderIcon = (provider: WebhookProvider) => {
12 const Icon = PROVIDER_ICONS[provider];
13 return <Icon className="h-4 w-4" />;
14};
15 
16const HOSTNAME_PROVIDER_HINTS: ReadonlyArray<{ pattern: string; provider: WebhookProvider }> =
17 webhookProviderCatalogList.flatMap((entry) => {
18 const hints: Array<{ pattern: string; provider: WebhookProvider }> = [
19 { pattern: entry.provider, provider: entry.provider },
20 ];
21 if (entry.provider === "gitea") {
22 hints.push({ pattern: "codeberg", provider: "gitea" });
23 }
24 return hints;
25 });
26 
27export const getRecommendedProvider = (repoUrl: string): WebhookProvider | null => {
28 try {
29 const hostname = new URL(repoUrl).hostname.replace(/^www\./u, "");
30 return HOSTNAME_PROVIDER_HINTS.find((h) => hostname.includes(h.pattern))?.provider ?? null;
31 } catch {
32 return null;
33 }
34};
35 
36export const DELIVERY_OUTCOME_META: Record<
37 WebhookDeliveryOutcome,
38 { label: string; variant: "success" | "warning" | "error" | "default" }
39> = {
40 accepted: { label: "Accepted", variant: "success" },
41 ignored_ping: { label: "Ping", variant: "default" },
42 ignored_event: { label: "Ignored Event", variant: "warning" },
43 ignored_branch: { label: "Ignored Branch", variant: "warning" },
44 queue_full: { label: "Queue Full", variant: "error" },
45};