"use client"; import { Button } from "@app/components/ui/button"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@app/components/ui/form"; import { Input } from "@app/components/ui/input"; import { useToast } from "@app/hooks/useToast"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { Credenza, CredenzaBody, CredenzaClose, CredenzaContent, CredenzaDescription, CredenzaFooter, CredenzaHeader, CredenzaTitle } from "@app/components/Credenza"; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { useTranslations } from "next-intl"; import { formatAxiosError } from "@app/lib/api"; import { CreateDomainResponse } from "@server/routers/domain/createOrgDomain"; import { StrategySelect } from "@app/components/StrategySelect"; import { AxiosResponse } from "axios"; import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert"; import { InfoIcon, AlertTriangle } from "lucide-react"; import CopyToClipboard from "@app/components/CopyToClipboard"; import { InfoSection, InfoSectionContent, InfoSections, InfoSectionTitle } from "@app/components/InfoSection"; import { useOrgContext } from "@app/hooks/useOrgContext"; const formSchema = z.object({ baseDomain: z.string().min(1, "Domain is required"), type: z.enum(["ns", "cname"]) }); type FormValues = z.infer; type CreateDomainFormProps = { open: boolean; setOpen: (open: boolean) => void; onCreated?: (domain: CreateDomainResponse) => void; }; export default function CreateDomainForm({ open, setOpen, onCreated }: CreateDomainFormProps) { const [loading, setLoading] = useState(false); const [createdDomain, setCreatedDomain] = useState(null); const api = createApiClient(useEnvContext()); const t = useTranslations(); const { toast } = useToast(); const { org } = useOrgContext(); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { baseDomain: "", type: "ns" } }); function reset() { form.reset(); setLoading(false); setCreatedDomain(null); } async function onSubmit(values: FormValues) { setLoading(true); try { const response = await api.put>( `/org/${org.org.orgId}/domain`, values ); const domainData = response.data.data; setCreatedDomain(domainData); toast({ title: t("success"), description: t("domainCreatedDescription") }); onCreated?.(domainData); } catch (e) { toast({ title: t("error"), description: formatAxiosError(e), variant: "destructive" }); } finally { setLoading(false); } } const domainType = form.watch("type"); const baseDomain = form.watch("baseDomain"); return ( { setOpen(val); reset(); }} > {t("domainAdd")} {t("domainAddDescription")} {!createdDomain ? (
( )} /> ( {t("domain")} )} /> ) : (
Add DNS Records Add the following DNS records to your domain provider to complete the setup.
{domainType === "ns" && createdDomain.nsRecords && (

NS Records

Record
Type: NS
Name: {baseDomain}
Value: {createdDomain.nsRecords.map( ( nsRecord, index ) => (
) )}
)} {domainType === "cname" && ( <> {createdDomain.cnameRecords && createdDomain.cnameRecords.length > 0 && (

CNAME Records

{createdDomain.cnameRecords.map( ( cnameRecord, index ) => ( Record{" "} {index + 1}
Type: CNAME
Name: { cnameRecord.baseDomain }
Value:
) )}
)} {createdDomain.txtRecords && createdDomain.txtRecords.length > 0 && (

TXT Records

{createdDomain.txtRecords.map( ( txtRecord, index ) => ( Record{" "} {index + 1}
Type: TXT
Name: { txtRecord.baseDomain }
Value:
) )}
)} )}
Save These Records Make sure to save these DNS records as you will not see them again. DNS Propagation DNS changes may take some time to propagate across the internet. This can take anywhere from a few minutes to 48 hours, depending on your DNS provider and TTL settings.
)}
{!createdDomain && ( )}
); }