"use client"; import { Dispatch, SetStateAction, useState, useTransition } from "react"; import { zodResolver } from "@hookform/resolvers/zod"; import { User } from "@prisma/client"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import useSWR from "swr"; import { siteConfig } from "@/config/site"; import { CreateDNSRecord, RecordType } from "@/lib/cloudflare"; import { UserRecordFormData } from "@/lib/dto/cloudflare-dns-record"; import { RECORD_TYPE_ENUMS, TTL_ENUMS } from "@/lib/enums"; import { fetcher } from "@/lib/utils"; import { createRecordSchema } from "@/lib/validations/record"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Icons } from "@/components/shared/icons"; import { FormSectionColumns } from "../dashboard/form-section-columns"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../ui/select"; import { Skeleton } from "../ui/skeleton"; import { Switch } from "../ui/switch"; export type FormData = CreateDNSRecord; export type FormType = "add" | "edit"; export interface RecordFormProps { user: Pick; isShowForm: boolean; setShowForm: Dispatch>; type: FormType; initData?: UserRecordFormData | null; action: string; onRefresh: () => void; } export function RecordForm({ user, isShowForm, setShowForm, type, initData, action, onRefresh, }: RecordFormProps) { const [isPending, startTransition] = useTransition(); const [isDeleting, startDeleteTransition] = useTransition(); const [currentRecordType, setCurrentRecordType] = useState( initData?.type || "CNAME", ); const [currentZoneName, setCurrentZoneName] = useState( initData?.zone_name || "wr.do", ); const [email, setEmail] = useState(user.email); const { handleSubmit, register, formState: { errors }, setValue, } = useForm({ resolver: zodResolver(createRecordSchema), defaultValues: { zone_name: initData?.zone_name || "wr.do", type: initData?.type || "CNAME", ttl: initData?.ttl || 1, proxied: initData?.proxied || false, comment: "Created by wr.do", name: initData?.name ? initData.name.split(".")[0] : "", content: initData?.content || "", }, }); // Fetch the record domains const { data: recordDomains, isLoading } = useSWR<{ domain_name: string }[]>( "/api/domain?feature=record", fetcher, { revalidateOnFocus: false, dedupingInterval: 10000, }, ); const onSubmit = handleSubmit((data) => { if (type === "add") { handleCreateRecord(data); } else if (type === "edit") { handleUpdateRecord(data); } }); const handleCreateRecord = async (data: CreateDNSRecord) => { startTransition(async () => { const response = await fetch(`${action}/add`, { method: "POST", body: JSON.stringify({ records: [data], email, }), }); if (!response.ok || response.status !== 200) { toast.error("Created Failed!", { description: await response.text(), }); } else { toast.success(`Created successfully!`); setShowForm(false); onRefresh(); } }); }; const handleUpdateRecord = async (data: CreateDNSRecord) => { startTransition(async () => { if (type === "edit") { const response = await fetch(`${action}/update`, { method: "POST", body: JSON.stringify({ recordId: initData?.record_id, record: data, userId: initData?.userId, }), }); if (!response.ok || response.status !== 200) { toast.error("Update Failed", { description: await response.text(), }); } else { const res = await response.json(); toast.success(`Update successfully!`); setShowForm(false); onRefresh(); } } }); }; const handleDeleteRecord = async () => { if (type === "edit") { startDeleteTransition(async () => { const response = await fetch(`${action}/delete`, { method: "POST", body: JSON.stringify({ record_id: initData?.record_id, zone_id: initData?.zone_id, active: initData?.active, userId: initData?.userId, }), }); if (!response.ok || response.status !== 200) { toast.error("Delete Failed", { description: await response.text(), }); } else { await response.json(); toast.success(`Success`); setShowForm(false); onRefresh(); } }); } }; return (
{type === "add" ? "Create" : "Edit"} record
{action.indexOf("admin") > -1 && (
setEmail(e.target.value)} />
{errors?.content ? (

{errors.content.message}

) : (

Required. Enter user email

)}
)}
{isLoading ? ( ) : ( )}

Required. Select a domain.

Required.

{(currentRecordType === "CNAME" || currentRecordType === "A") && ( .{currentZoneName} )}
{errors?.name ? (

{errors.name.message}

) : (

Required. E.g. www.

)}
{errors?.content ? (

{errors.content.message}

) : (

{currentRecordType === "CNAME" ? "Required. E.g. www.example.com" : currentRecordType === "A" ? "Required. E.g. 8.8.8.8" : "Required."}

)}
{/*

Enter your comment here (up to 100 characters)

*/}

Optional. Time To Live.

{["A", "CNAME"].includes(currentRecordType) && (
setValue("proxied", value)} />

Proxy status.

)}
{/* Action buttons */}
{type === "edit" && ( )}
); }