"use client"; import type { RouterOutputs } from "@openstatus/api"; import { detectWebhookFlavor } from "@openstatus/subscriptions/client"; import { Badge } from "@openstatus/ui/components/ui/badge"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@openstatus/ui/components/ui/tooltip"; import type { ColumnDef } from "@tanstack/react-table"; import { formatDate } from "@/lib/formatter"; import { DataTableRowActions } from "./data-table-row-actions"; type Subscriber = RouterOutputs["pageSubscriber"]["list"][number]; const FLAVOR_LABELS = { slack: "Slack", discord: "Discord", generic: "Webhook", } as const; function detectFlavorBadge(url: string | null) { if (!url) return null; return FLAVOR_LABELS[detectWebhookFlavor(url)]; } export const columns: ColumnDef[] = [ { id: "destination", header: "Destination", enableSorting: false, enableHiding: false, cell: ({ row }) => { const sub = row.original; const raw = sub.channelType === "email" ? sub.email : sub.webhookUrl; const display = sub.name ?? raw ?? ""; const flavor = sub.channelType === "webhook" ? detectFlavorBadge(sub.webhookUrl) : sub.channelType === "slack" ? "Slack" : null; return (
{display} {flavor ? ( {flavor} ) : null}
); }, }, { id: "source", accessorFn: (row) => row.source, header: "Source", enableSorting: false, enableHiding: false, filterFn: (row, id, filterValue: string[]) => { if (!filterValue?.length) return true; return filterValue.includes(row.getValue(id) as string); }, cell: ({ row }) => { const source = row.original.source; const label = source === "vendor" ? "Vendor" : source === "import" ? "Import" : "Self-signup"; return ( {label} ); }, }, { id: "components", header: "Components", enableSorting: false, enableHiding: false, cell: ({ row }) => { const { components, isEntirePage } = row.original; if (isEntirePage) { return ( Entire page ); } return ( {components.length} components {components.map((c) => c.name).join(", ")} ); }, }, { id: "status", accessorFn: (row) => { if (row.unsubscribedAt) return "unsubscribed"; if (!row.acceptedAt) return "pending"; return "active"; }, header: "Status", enableSorting: false, enableHiding: false, filterFn: (row, id, filterValue: string[]) => { if (!filterValue?.length) return true; return filterValue.includes(row.getValue(id) as string); }, cell: ({ row }) => { const status = row.getValue("status") as string; if (status === "unsubscribed") { return Unsubscribed; } if (status === "pending") { return Pending; } return Active; }, }, { accessorKey: "createdAt", header: "Created At", enableSorting: false, enableHiding: false, cell: ({ row }) => { const value = row.getValue("createdAt"); if (value instanceof Date) return formatDate(value); if (!value) return "-"; return value; }, meta: { cellClassName: "font-mono", }, }, { id: "actions", cell: ({ row }) => , meta: { cellClassName: "w-8", }, }, ];