"use client"; import { useEffect, useState } from 'react'; import { useToast } from '@/hooks/use-toast'; import { Button } from '@/components/ui/button'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Skeleton } from '@/components/ui/skeleton'; import { RecordForm } from './record-form'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Plus, Trash2, Edit, Loader2, FileWarning } from 'lucide-react'; import { Badge } from './ui/badge'; interface DNSRecord { id: string; type: string; name: string; data: string; priority?: number; ttl: number; } interface RecordsListProps { apiKey: string; domain: string; } export function RecordsList({ apiKey, domain }: RecordsListProps) { const [records, setRecords] = useState([]); const [loading, setLoading] = useState(true); const [isAddingRecord, setIsAddingRecord] = useState(false); const [editingRecord, setEditingRecord] = useState(null); const [deletingRecordId, setDeletingRecordId] = useState(null); const [isDeleting, setIsDeleting] = useState(false); const { toast } = useToast(); const fetchRecords = async () => { try { setLoading(true); const response = await fetch(`/api/vultr/domains/${domain}/records`, { headers: { 'X-API-Key': apiKey, }, }); if (!response.ok) { throw new Error('Failed to fetch records'); } const data = await response.json(); setRecords(data.records || []); } catch (error) { console.error('Error fetching records:', error); toast({ title: 'Error', description: 'Failed to fetch DNS records.', variant: 'destructive', }); } finally { setLoading(false); } }; useEffect(() => { if (domain) { fetchRecords(); } }, [domain, apiKey]); const handleDeleteRecord = async () => { if (!deletingRecordId) return; try { setIsDeleting(true); const response = await fetch( `/api/vultr/domains/${domain}/records/${deletingRecordId}`, { method: 'DELETE', headers: { 'X-API-Key': apiKey, }, } ); if (!response.ok) { throw new Error('Failed to delete record'); } toast({ title: 'Success', description: 'DNS record deleted successfully.', }); // Refresh the records list fetchRecords(); } catch (error) { console.error('Error deleting record:', error); toast({ title: 'Error', description: 'Failed to delete DNS record.', variant: 'destructive', }); } finally { setIsDeleting(false); setDeletingRecordId(null); } }; const getRecordTypeColor = (type: string) => { const types: Record = { A: 'bg-blue-500/10 text-blue-500 dark:bg-blue-500/20', AAAA: 'bg-purple-500/10 text-purple-500 dark:bg-purple-500/20', CNAME: 'bg-green-500/10 text-green-500 dark:bg-green-500/20', MX: 'bg-amber-500/10 text-amber-500 dark:bg-amber-500/20', TXT: 'bg-slate-500/10 text-slate-500 dark:bg-slate-500/20', NS: 'bg-indigo-500/10 text-indigo-500 dark:bg-indigo-500/20', SRV: 'bg-rose-500/10 text-rose-500 dark:bg-rose-500/20', CAA: 'bg-cyan-500/10 text-cyan-500 dark:bg-cyan-500/20', }; return types[type] || 'bg-gray-500/10 text-gray-500 dark:bg-gray-500/20'; }; if (loading) { return (
{Array.from({ length: 5 }).map((_, i) => (
))}
); } if (isAddingRecord || editingRecord) { return ( { setIsAddingRecord(false); setEditingRecord(null); }} onSuccess={() => { setIsAddingRecord(false); setEditingRecord(null); fetchRecords(); }} /> ); } return (

DNS Records

{records.length === 0 ? (

No DNS Records Found

This domain doesn't have any DNS records yet. Click the "Add Record" button to create your first record.

) : (
Type Name Value TTL Actions {records.map((record) => ( {record.type}
{record.name || '@'}
{record.priority !== undefined && (
Priority: {record.priority}
)}
{record.data} {record.ttl}
))}
)} !open && setDeletingRecordId(null)}> Are you sure? This will permanently delete this DNS record. This action cannot be undone. Cancel {isDeleting ? ( <> Deleting... ) : ( 'Delete' )}
); }