diff --git a/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx b/apps/dokploy/components/dashboard/settings/certificates/handle-certificate.tsx similarity index 65% rename from apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx rename to apps/dokploy/components/dashboard/settings/certificates/handle-certificate.tsx index 6f7ef6821c..f3e27b1847 100644 --- a/apps/dokploy/components/dashboard/settings/certificates/add-certificate.tsx +++ b/apps/dokploy/components/dashboard/settings/certificates/handle-certificate.tsx @@ -1,5 +1,5 @@ import { zodResolver } from "@hookform/resolvers/zod"; -import { HelpCircle, PlusIcon } from "lucide-react"; +import { HelpCircle, PlusIcon, SquarePen } from "lucide-react"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; @@ -47,7 +47,7 @@ const certificateDataHolder = const privateKeyDataHolder = "-----BEGIN PRIVATE KEY-----\nMIIFRDCCAyygAwIBAgIUEPOR47ys6VDwMVB9tYoeEka83uQwDQYJKoZIhvcNAQELBQAwGTEXMBUGA1UEAwwObWktZG9taW5pby5jb20wHhcNMjQwMzExMDQyNzU3WhcN\n-----END PRIVATE KEY-----"; -const addCertificate = z.object({ +const handleCertificateSchema = z.object({ name: z.string().min(1, "Name is required"), certificateData: z.string().min(1, "Certificate data is required"), privateKey: z.string().min(1, "Private key is required"), @@ -55,100 +55,143 @@ const addCertificate = z.object({ serverId: z.string().optional(), }); -type AddCertificate = z.infer; +type HandleCertificateForm = z.infer; -export const AddCertificate = () => { +interface Props { + certificateId?: string; +} + +export const HandleCertificate = ({ certificateId }: Props) => { const [open, setOpen] = useState(false); const utils = api.useUtils(); const { data: isCloud } = api.settings.isCloud.useQuery(); - const { mutateAsync, isError, error, isLoading } = - api.certificates.create.useMutation(); const { data: servers } = api.server.withSSHKey.useQuery(); const hasServers = servers && servers.length > 0; - // Show dropdown logic based on cloud environment - // Cloud: show only if there are remote servers (no Dokploy option) - // Self-hosted: show only if there are remote servers (Dokploy is default, hide if no remote servers) - const shouldShowServerDropdown = hasServers; + const shouldShowServerDropdown = hasServers && !certificateId; // Hide on edit + + const { data: existingCert, refetch } = api.certificates.one.useQuery( + { certificateId: certificateId || "" }, + { enabled: !!certificateId }, + ); + + const { mutateAsync, isError, error, isLoading } = certificateId + ? api.certificates.update.useMutation() + : api.certificates.create.useMutation(); - const form = useForm({ + const form = useForm({ defaultValues: { name: "", certificateData: "", privateKey: "", autoRenew: false, }, - resolver: zodResolver(addCertificate), + resolver: zodResolver(handleCertificateSchema), }); + useEffect(() => { - form.reset(); - }, [form, form.formState.isSubmitSuccessful, form.reset]); + if (existingCert) { + form.reset({ + name: existingCert.name, + certificateData: existingCert.certificateData, + privateKey: existingCert.privateKey, + autoRenew: existingCert.autoRenew ?? false, + }); + } else { + form.reset({ + name: "", + certificateData: "", + privateKey: "", + autoRenew: false, + }); + } + }, [existingCert, form, open]); - const onSubmit = async (data: AddCertificate) => { + const onSubmit = async (data: HandleCertificateForm) => { await mutateAsync({ + ...(certificateId ? { certificateId } : {}), name: data.name, certificateData: data.certificateData, privateKey: data.privateKey, autoRenew: data.autoRenew, serverId: data.serverId === "dokploy" ? undefined : data.serverId, organizationId: "", - }) + } as any) .then(async () => { - toast.success("Certificate Created"); + toast.success( + certificateId ? "Certificate Updated" : "Certificate Created", + ); await utils.certificates.all.invalidate(); + if (certificateId) { + refetch(); + } setOpen(false); }) .catch(() => { - toast.error("Error creating the Certificate"); + toast.error( + certificateId + ? "Error updating the Certificate" + : "Error creating the Certificate", + ); }); }; + return ( - - + + {certificateId ? ( + + ) : ( + + )} - Add New Certificate + + {certificateId ? "Update" : "Add New"} Certificate + - Upload or generate a certificate to secure your application + {certificateId + ? "Modify the certificate details" + : "Upload or generate a certificate to secure your application"} {isError && {error?.message}}
{ - return ( - - Certificate Name - - - - - - ); - }} + render={({ field }) => ( + + Certificate Name + + + + + + )} /> ( -
- Certificate Data -
+ Certificate Data