"use client"; import { ColumnDef } from "@tanstack/react-table"; import { ExtendedColumnDef } from "@app/components/ui/data-table"; import { DomainsDataTable } from "@app/components/DomainsDataTable"; import { Button } from "@app/components/ui/button"; import { ArrowRight, ArrowUpDown, MoreHorizontal, RefreshCw } from "lucide-react"; import { useState } from "react"; import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog"; import { formatAxiosError } from "@app/lib/api"; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { Badge } from "@app/components/ui/badge"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import CreateDomainForm from "@app/components/CreateDomainForm"; import { useToast } from "@app/hooks/useToast"; import { useOrgContext } from "@app/hooks/useOrgContext"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu"; import Link from "next/link"; export type DomainRow = { domainId: string; baseDomain: string; type: string; verified: boolean; failed: boolean; tries: number; configManaged: boolean; certResolver: string; preferWildcardCert: boolean; }; type Props = { domains: DomainRow[]; orgId: string; }; export default function DomainsTable({ domains, orgId }: Props) { const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [selectedDomain, setSelectedDomain] = useState( null ); const [isRefreshing, setIsRefreshing] = useState(false); const [restartingDomains, setRestartingDomains] = useState>( new Set() ); const env = useEnvContext(); const api = createApiClient(env); const router = useRouter(); const t = useTranslations(); const { toast } = useToast(); const { org } = useOrgContext(); const refreshData = async () => { setIsRefreshing(true); try { await new Promise((resolve) => setTimeout(resolve, 200)); router.refresh(); } catch (error) { toast({ title: t("error"), description: t("refreshError"), variant: "destructive" }); } finally { setIsRefreshing(false); } }; const deleteDomain = async (domainId: string) => { try { await api.delete(`/org/${org.org.orgId}/domain/${domainId}`); toast({ title: t("success"), description: t("domainDeletedDescription") }); setIsDeleteModalOpen(false); refreshData(); } catch (e) { toast({ title: t("error"), description: formatAxiosError(e), variant: "destructive" }); } }; const restartDomain = async (domainId: string) => { setRestartingDomains((prev) => new Set(prev).add(domainId)); try { await api.post(`/org/${org.org.orgId}/domain/${domainId}/restart`); toast({ title: t("success"), description: t("domainRestartedDescription", { fallback: "Domain verification restarted successfully" }) }); refreshData(); } catch (e) { toast({ title: t("error"), description: formatAxiosError(e), variant: "destructive" }); } finally { setRestartingDomains((prev) => { const newSet = new Set(prev); newSet.delete(domainId); return newSet; }); } }; const getTypeDisplay = (type: string) => { switch (type) { case "ns": return t("selectDomainTypeNsName"); case "cname": return t("selectDomainTypeCnameName"); case "wildcard": return t("selectDomainTypeWildcardName"); default: return type; } }; const typeColumn: ExtendedColumnDef = { accessorKey: "type", friendlyName: t("type"), header: ({ column }) => { return ( ); }, cell: ({ row }) => { const type = row.original.type; return {getTypeDisplay(type)}; } }; const statusColumn: ExtendedColumnDef = { accessorKey: "verified", friendlyName: t("status"), header: ({ column }) => { return ( ); }, cell: ({ row }) => { const { verified, failed, type } = row.original; if (verified) { return type == "wildcard" ? ( {t("manual")} ) : ( {t("verified")} ); } else if (failed) { return ( {t("failed", { fallback: "Failed" })} ); } else { return {t("pending")}; } } }; const columns: ExtendedColumnDef[] = [ { accessorKey: "baseDomain", enableHiding: false, friendlyName: t("domain"), header: ({ column }) => { return ( ); } }, ...(env.env.flags.usePangolinDns ? [typeColumn] : []), ...(env.env.flags.usePangolinDns ? [statusColumn] : []), { id: "actions", enableHiding: false, header: () => , cell: ({ row }) => { const domain = row.original; const isRestarting = restartingDomains.has(domain.domainId); return (
{t("viewSettings")} { setSelectedDomain(domain); setIsDeleteModalOpen(true); }} > {t("delete")} {domain.failed && ( )} {/* */}
); } } ]; return ( <> {selectedDomain && ( { setIsDeleteModalOpen(val); setSelectedDomain(null); }} dialog={

{t("domainQuestionRemove")}

{t("domainMessageRemove")}

} buttonText={t("domainConfirmDelete")} onConfirm={async () => deleteDomain(selectedDomain.domainId) } string={selectedDomain.baseDomain} title={t("domainDelete")} /> )} { refreshData(); }} /> setIsCreateModalOpen(true)} onRefresh={refreshData} isRefreshing={isRefreshing} /> ); }