diff --git a/src/components/features/dns-editor.tsx b/src/components/features/dns-editor.tsx new file mode 100644 index 0000000..8f00d2d --- /dev/null +++ b/src/components/features/dns-editor.tsx @@ -0,0 +1,267 @@ +"use client"; + +import type { ColumnDef } from "@tanstack/react-table"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { Copy, FileDown, FileUp, Plus, Trash2 } from "lucide-react"; +import { useState } from "react"; +import type { DnsRecord } from "@/api/contracts/models"; +import { panelService } from "@/api/services/panel-service"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { DataTable } from "@/components/common/data-table"; +import { Card, CardContent } from "@/components/ui/card"; +import { CodeEditor } from "@/components/common/code-editor"; +import { Input } from "@/components/ui/input"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; + +const columns: ColumnDef[] = [ + { accessorKey: "name", header: "Name" }, + { accessorKey: "ttl", header: "TTL" }, + { accessorKey: "class", header: "Class" }, + { + accessorKey: "type", + header: "Type", + cell: ({ row }) => {row.original.type}, + }, + { accessorKey: "record", header: "Record" }, + { + accessorKey: "warning", + header: "Warnings", + cell: ({ row }) => row.original.warning ?? "None", + }, +]; + +const dnsTypes: DnsRecord["type"][] = [ + "A", + "AAAA", + "CNAME", + "MX", + "TXT", + "SRV", + "CAA", + "NS", + "PTR", +]; + +export function DnsEditor() { + const queryClient = useQueryClient(); + const [dialogOpen, setDialogOpen] = useState(false); + const [record, setRecord] = useState>({ + name: "api.example.com.", + ttl: 14400, + type: "A", + record: "198.51.100.40", + }); + const [error, setError] = useState(""); + const { data, isLoading } = useQuery({ + queryKey: ["dns-records"], + queryFn: () => panelService.domains.records(), + }); + const createRecord = useMutation({ + mutationFn: () => panelService.domains.saveRecord(record), + onSuccess: async (response) => { + if (response.error) { + setError(response.error.message); + return; + } + await queryClient.invalidateQueries({ queryKey: ["dns-records"] }); + setDialogOpen(false); + setError(""); + setRecord({ + name: "api.example.com.", + ttl: 14400, + type: "A", + record: "198.51.100.40", + }); + }, + onError: (mutationError) => { + setError( + mutationError instanceof Error ? mutationError.message : "DNS record creation failed.", + ); + }, + }); + return ( +
+ + +
+ {["All", "A", "AAAA", "CNAME", "MX", "TXT", "SRV", "CAA", "NS", "PTR"].map( + (type) => ( + + ), + )} +
+
+ + + + + + + Add DNS record + + Create a DNS record in the active zone and refresh the zone editor. + + +
{ + event.preventDefault(); + setError(""); + createRecord.mutate(); + }} + > + + + + + {record.type === "MX" || record.type === "SRV" ? ( + + ) : null} + {error ? ( +
+ {error} +
+ ) : null} +
+ + +
+
+
+
+ + + + +
+
+
+ {isLoading ? ( +
+ ) : ( + + )} + +
+ ); +}