From a9b9161c40ec2fb6b4188f531d499df540c267f3 Mon Sep 17 00:00:00 2001 From: Pallavi Kumari Date: Thu, 16 Oct 2025 23:37:55 +0530 Subject: [PATCH] template for Domain Settings --- messages/en-US.json | 5 +- src/components/DomainInfoCard.tsx | 269 ++++++++++++++++++++++++++---- 2 files changed, 238 insertions(+), 36 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index a60e432c..b2dbb302 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -1898,6 +1898,7 @@ "enterCustomResolver": "Enter Custom Resolver", "preferWildcardCert": "Prefer Wildcard Certificate", "unverified": "Unverified", - "domainSetting": "DomainSetting", - "domainSettingDescription": "Configure settings for your domain" + "domainSetting": "Domain Settings", + "domainSettingDescription": "Configure settings for your domain", + "preferWildcardCertDescription": "Attempt to generate a wildcard certificate (require a properly configured certificate resolver)." } diff --git a/src/components/DomainInfoCard.tsx b/src/components/DomainInfoCard.tsx index 951633f2..8564acfa 100644 --- a/src/components/DomainInfoCard.tsx +++ b/src/components/DomainInfoCard.tsx @@ -11,49 +11,250 @@ import { import { useTranslations } from "next-intl"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { useDomainContext } from "@app/hooks/useDomainContext"; +import { SettingsContainer, SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionFooter, SettingsSectionForm, SettingsSectionHeader, SettingsSectionTitle } from "./Settings"; +import { Button } from "./ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, + FormDescription +} from "@app/components/ui/form"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select"; +import { Input } from "./ui/input"; +import { CheckboxWithLabel } from "./ui/checkbox"; +import { useForm } from "react-hook-form"; +import z from "zod"; +import { toASCII } from "punycode"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { build } from "@server/build"; +import { Switch } from "./ui/switch"; type DomainInfoCardProps = {}; +// Helper functions for Unicode domain handling +function toPunycode(domain: string): string { + try { + const parts = toASCII(domain); + return parts; + } catch (error) { + return domain.toLowerCase(); + } +} + + +function isValidDomainFormat(domain: string): boolean { + const unicodeRegex = /^(?!:\/\/)([^\s.]+\.)*[^\s.]+$/; + + if (!unicodeRegex.test(domain)) { + return false; + } + + const parts = domain.split('.'); + for (const part of parts) { + if (part.length === 0 || part.startsWith('-') || part.endsWith('-')) { + return false; + } + if (part.length > 63) { + return false; + } + } + + if (domain.length > 253) { + return false; + } + + return true; +} + +const formSchema = z.object({ + baseDomain: z + .string() + .min(1, "Domain is required") + .refine((val) => isValidDomainFormat(val), "Invalid domain format") + .transform((val) => toPunycode(val)), + type: z.enum(["ns", "cname", "wildcard"]), + certResolver: z.string().nullable().optional(), + preferWildcardCert: z.boolean().optional() +}); + +type FormValues = z.infer; + +const certResolverOptions = [ + { id: "default", title: "Default" }, + { id: "custom", title: "Custom Resolver" } +]; + + export default function DomainInfoCard({ }: DomainInfoCardProps) { const { domain, updateDomain } = useDomainContext(); const t = useTranslations(); const { env } = useEnvContext(); + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + baseDomain: "", + type: build == "oss" || !env.flags.usePangolinDns ? "wildcard" : "ns", + certResolver: null, + preferWildcardCert: false + } + }); + return ( - - - - - - {t("type")} - - - - {domain.type} - - - - - - {t("status")} - - - {domain.verified ? ( -
-
- {t("verified")} -
- ) : ( -
-
- {t("unverified")} -
- )} -
-
-
-
-
+ <> + + + + + + {t("type")} + + + + {domain.type} + + + + + + {t("status")} + + + {domain.verified ? ( +
+
+ {t("verified")} +
+ ) : ( +
+
+ {t("unverified")} +
+ )} +
+
+
+
+
+ + + + + + {/* Domain Settings */} + {/* Add condition later to only show when domain is wildcard */} + + + + + {t("domainSetting")} + + + + + +
+ + ( + + {t("certResolver")} + + + + + {field.value !== null && field.value !== "default" && ( +
+ + field.onChange(e.target.value)} + /> + + ( + + +
+ + {t("preferWildcardCert")} +
+
+ + + {t("preferWildcardCertDescription")} + + +
+ )} + /> +
+ )} +
+ )} + /> + + +
+
+ + + + +
+
+ ); }