diff --git a/frontend/src/components/Table/Formatter/CertificateFormatter.tsx b/frontend/src/components/Table/Formatter/CertificateFormatter.tsx index 6b791bfbf..9a2d50849 100644 --- a/frontend/src/components/Table/Formatter/CertificateFormatter.tsx +++ b/frontend/src/components/Table/Formatter/CertificateFormatter.tsx @@ -1,18 +1,95 @@ +import cn from "classnames"; +import { differenceInDays, isPast } from "date-fns"; +import OverlayTrigger from "react-bootstrap/OverlayTrigger"; +import Popover from "react-bootstrap/Popover"; import type { Certificate } from "src/api/backend"; -import { T } from "src/locale"; +import { DateFormatter } from "src/components"; +import { parseDate, T } from "src/locale"; + +const getProviderLabel = (provider: string) => { + if (provider === "letsencrypt") { + return "lets-encrypt"; + } + if (provider === "other") { + return "certificates.custom"; + } + return provider; +}; interface Props { certificate?: Certificate; } export function CertificateFormatter({ certificate }: Props) { - let translation = "http-only"; - if (certificate) { - translation = certificate.provider; - if (translation === "letsencrypt") { - translation = "lets-encrypt"; - } else if (translation === "other") { - translation = "certificates.custom"; - } + if (!certificate) { + return ; } - return ; + + const translation = getProviderLabel(certificate.provider); + const expires = certificate.expiresOn ? parseDate(certificate.expiresOn) : null; + const expired = expires ? isPast(expires) : false; + const daysLeft = expires ? differenceInDays(expires, new Date()) : null; + const labelClass = cn({ + "text-danger": expired, + "text-warning": !expired && daysLeft !== null && daysLeft <= 30, + }); + + const name = certificate.niceName || certificate.domainNames?.[0] || `#${certificate.id}`; + + const popover = ( + + + + {name} + #{certificate.id} + + + + + + + + + + {certificate.domainNames?.length ? ( + <> + + + + + + {certificate.domainNames.map((domain) => ( + + {domain} + + ))} + > + ) : null} + {certificate.expiresOn ? ( + <> + + + + + + + + + > + ) : null} + + + ); + + return ( + + + + + + {certificate.provider === "other" && certificate.niceName ? ( + {certificate.niceName} + ) : null} + + + ); }