"use client"; import { Dispatch, SetStateAction, useState, useTransition } from "react"; import Link from "next/link"; import { zodResolver } from "@hookform/resolvers/zod"; import { User } from "@prisma/client"; import { useTranslations } from "next-intl"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { DomainFormData } from "@/lib/dto/domains"; import { cn } from "@/lib/utils"; import { createDomainSchema } from "@/lib/validations/domain"; 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 { Badge } from "../ui/badge"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../ui/collapsible"; import { Switch } from "../ui/switch"; export type FormData = DomainFormData; export type FormType = "add" | "edit"; export interface DomainFormProps { user: Pick; isShowForm: boolean; setShowForm: Dispatch>; type: FormType; initData?: DomainFormData | null; action: string; onRefresh: () => void; } export function DomainForm({ setShowForm, type, initData, action, onRefresh, }: DomainFormProps) { const t = useTranslations("List"); const [isPending, startTransition] = useTransition(); const [isDeleting, startDeleteTransition] = useTransition(); const [isCheckingCf, startCheckCfTransition] = useTransition(); const [isCheckingResend, startCheckResendTransition] = useTransition(); const [currentRecordStatus, setCurrentRecordStatus] = useState( initData?.enable_dns || false, ); const [currentEmailStatus, setCurrentEmailStatus] = useState( initData?.enable_email || false, ); const [isCheckedCfConfig, setIsCheckedCfConfig] = useState(false); const [isCheckedResendConfig, setIsCheckedResendConfig] = useState(false); const { handleSubmit, register, formState: { errors }, getValues, setValue, } = useForm({ resolver: zodResolver(createDomainSchema), defaultValues: { id: initData?.id || "", domain_name: initData?.domain_name || "", enable_short_link: initData?.enable_short_link || false, enable_email: initData?.enable_email || false, enable_dns: initData?.enable_dns || false, cf_zone_id: initData?.cf_zone_id || "", cf_api_key: initData?.cf_api_key || "", cf_email: initData?.cf_email || "", cf_record_types: initData?.cf_record_types || "CNAME,A,TXT", cf_api_key_encrypted: initData?.cf_api_key_encrypted || false, resend_api_key: initData?.resend_api_key || "", min_url_length: initData?.min_url_length, min_email_length: initData?.min_email_length, min_record_length: initData?.min_record_length, max_short_links: initData?.max_short_links || 0, max_email_forwards: initData?.max_email_forwards || 0, max_dns_records: initData?.max_dns_records || 0, active: initData?.active || true, }, }); const onSubmit = handleSubmit((data) => { if (type === "add") { handleCreateDomain(data); } else if (type === "edit") { handleUpdateDomain(data); } }); const handleCreateDomain = async (data: DomainFormData) => { startTransition(async () => { const response = await fetch(`${action}`, { method: "POST", body: JSON.stringify({ data, }), }); if (!response.ok || response.status !== 200) { toast.error("Created Failed!", { description: await response.text(), }); } else { // const res = await response.json(); toast.success(`Created successfully!`); setShowForm(false); onRefresh(); } }); }; const handleUpdateDomain = async (data: DomainFormData) => { startTransition(async () => { if (type === "edit") { const response = await fetch(`${action}`, { method: "PUT", body: JSON.stringify(data), }); if (!response.ok || response.status !== 200) { toast.error("Update Failed", { description: await response.text(), }); } else { await response.json(); toast.success(`Update successfully!`); setShowForm(false); onRefresh(); } } }); }; const handleDeleteDomain = async () => { if (type === "edit") { startDeleteTransition(async () => { const response = await fetch(`${action}`, { method: "DELETE", body: JSON.stringify({ domain_name: initData?.domain_name, }), }); if (!response.ok || response.status !== 200) { toast.error("Delete Failed", { description: await response.text(), }); } else { await response.json(); toast.success(`Success`); setShowForm(false); onRefresh(); } }); } }; const handleCfCheckAccess = async (event) => { event?.stopPropagation(); if (!currentRecordStatus) return; if (isCheckedCfConfig) { setIsCheckedCfConfig(false); } startCheckCfTransition(async () => { const values = getValues(["cf_zone_id", "cf_api_key", "cf_email"]); const res = await fetch( `/api/domain/check-cf?zone_id=${values[0]}&api_key=${values[1]}&email=${values[2]}`, ); if (res.ok) { const data = await res.json(); if (data === 200) { setIsCheckedCfConfig(true); return; } } setIsCheckedCfConfig(false); toast.error("Access Failed", { description: "Please check your Cloudflare settings and try again.", }); }); }; const handleResendCheckAccess = async (event) => { event?.stopPropagation(); if (!currentEmailStatus) return; if (isCheckedResendConfig) { setIsCheckedResendConfig(false); } startCheckResendTransition(async () => { const value = getValues(["resend_api_key", "domain_name"]); const res = await fetch( `/api/domain/check-resend?api_key=${value[0]}&domain=${value[1]}`, ); if (res.ok) { const data = await res.json(); if (data === 200) { setIsCheckedResendConfig(true); return; } } else { setIsCheckedResendConfig(false); toast.error("Failed to send email", { description: await res.text(), }); } }); }; const ReadyBadge = ( active: boolean, isChecked: boolean, isChecking: boolean, type: string, ) => ( type === "cf" ? handleCfCheckAccess(event) : handleResendCheckAccess(event) } > {isChecking && } {isChecked && !isChecking && } {isChecked ? t("Verified") : t("Verify Configuration")} ); return (
{type === "add" ? t("Create Domain") : t("Edit Domain")}

{t("Base")}

{errors?.domain_name ? (

{errors.domain_name.message}

) : (

{t("Required")}. {t("Example")} example.com

)}
setValue("active", value)} disabled />

{t("Services")} ({t("Optional")})

setValue("enable_short_link", value)} />
{ setValue("enable_email", value); setCurrentEmailStatus(value); }} />
{ setValue("enable_dns", value); setCurrentRecordStatus(value); }} />

{t("Cloudflare Configs")} ({t("Optional")})

{ReadyBadge( currentRecordStatus, isCheckedCfConfig, isCheckingCf, "cf", )}
{!currentRecordStatus && (
{" "} {t("Associate with 'Subdomain Service' status")}
)}
{errors?.cf_zone_id ? (

{errors.cf_zone_id.message}

) : (

{t("Optional")}.{" "} {t("How to get zone id?")}

)}
{errors?.cf_api_key ? (

{errors.cf_api_key.message}

) : (

{t("Optional")}.{" "} {t("How to get api key?")}

)}
{errors?.cf_email ? (

{errors.cf_email.message}

) : (

{t("Optional")}.{" "} {t("How to get cloudflare account email?")}

)}
{errors?.cf_record_types ? (

{errors.cf_record_types.message}

) : (

{t("Required")}. {t("Allowed record types")},{" "} {t("use `,` to separate")}

)}

{t("Resend Configs")} ({t("Optional")})

{ReadyBadge( currentEmailStatus, isCheckedResendConfig, isCheckingResend, "resend", )}
{!currentEmailStatus && (
{" "} {t("Associate with 'Email Service' status")}
)}
{errors?.resend_api_key ? (

{errors.resend_api_key.message}

) : (

{t("Optional")}.{" "} {t("How to get resend api key?")}

)}

{t("Limit Configs")} ({t("Optional")})

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