import { IconShield } from "@tabler/icons-react"; import { Field, useFormikContext } from "formik"; import Select, { type ActionMeta, components, type OptionProps } from "react-select"; import type { Certificate } from "src/api/backend"; import { useCertificates, useUser } from "src/hooks"; import { DateTimeFormat, intl } from "src/locale"; interface CertOption { readonly value: number | "new"; readonly label: string; readonly subLabel: string; readonly icon: React.ReactNode; } const Option = (props: OptionProps) => { return (
{props.data.icon} {props.data.label}
{props.data.subLabel}
); }; interface Props { id?: string; name?: string; label?: string; required?: boolean; allowNew?: boolean; } export function SSLCertificateField({ name = "certificateId", label = "ssl-certificate", id = "certificateId", required, allowNew, }: Props) { const { data: currentUser } = useUser("me"); const { isLoading, isError, error, data } = useCertificates(); const { values, setFieldValue } = useFormikContext(); const v: any = values || {}; const handleChange = (newValue: any, _actionMeta: ActionMeta) => { setFieldValue(name, newValue?.value); const { sslForced, http2Support, hstsEnabled, hstsSubdomains, dnsChallenge, letsencryptEmail } = v; if (!newValue?.value) { sslForced && setFieldValue("sslForced", false); http2Support && setFieldValue("http2Support", false); hstsEnabled && setFieldValue("hstsEnabled", false); hstsSubdomains && setFieldValue("hstsSubdomains", false); } if (newValue?.value === "new") { if (!letsencryptEmail) { setFieldValue("letsencryptEmail", currentUser?.email); } } else { dnsChallenge && setFieldValue("dnsChallenge", false); } }; const options: CertOption[] = data?.map((cert: Certificate) => ({ value: cert.id, label: cert.niceName, subLabel: `${cert.provider === "letsencrypt" ? "Let's Encrypt" : cert.provider} — Expires: ${ cert.expiresOn ? DateTimeFormat(cert.expiresOn) : "N/A" }`, icon: , })) || []; // Prepend the Add New option if (allowNew) { options?.unshift({ value: "new", label: "Request a new Certificate", subLabel: "with Let's Encrypt", icon: , }); } // Prepend the None option if (!required) { options?.unshift({ value: 0, label: "None", subLabel: "This host will not use HTTPS", icon: , }); } return ( {({ field, form }: any) => (
{isLoading ?
: null} {isError ?
{`${error}`}
: null} {!isLoading && !isError ? (