redesign certificates page: tabs, drawers, relative expiry, status bar
- Split ACME / Imported / CA-mTLS into tabs with count badges - Add clickable status summary bar (expired / expiring soon / healthy) - Per-tab search filter by name and domain - Replace accordion cards with DataTable for imported certs - Slide-in Drawers (480 px) for add/edit imported and CA certs - File upload + show/hide toggle for private key in ImportCertDrawer - CaCertDrawer: Generate / Import PEM tabs for add, simple form for edit - CA tab: expandable rows showing issued client certs inline - RelativeTime component: "in 45 days" / "EXPIRED 3 days ago" with date tooltip - Remove CreateCaCertDialog and EditCaCertDialog (replaced by CaCertDrawer) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { Tooltip, Typography } from "@mui/material";
|
||||
import type { CertExpiryStatus } from "../page";
|
||||
|
||||
function formatRelative(validTo: string): string {
|
||||
const diff = new Date(validTo).getTime() - Date.now();
|
||||
const absDiff = Math.abs(diff);
|
||||
const days = Math.floor(absDiff / 86400000);
|
||||
const hours = Math.floor(absDiff / 3600000);
|
||||
|
||||
if (diff < 0) {
|
||||
if (days >= 1) return `EXPIRED ${days} day${days !== 1 ? "s" : ""} ago`;
|
||||
return `EXPIRED ${hours} hour${hours !== 1 ? "s" : ""} ago`;
|
||||
}
|
||||
if (days >= 1) return `in ${days} day${days !== 1 ? "s" : ""}`;
|
||||
return `in ${hours} hour${hours !== 1 ? "s" : ""}`;
|
||||
}
|
||||
|
||||
function formatFull(validTo: string): string {
|
||||
return new Date(validTo).toLocaleDateString(undefined, {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
export function RelativeTime({
|
||||
validTo,
|
||||
status,
|
||||
}: {
|
||||
validTo: string | null;
|
||||
status: CertExpiryStatus | null;
|
||||
}) {
|
||||
if (validTo === null || status === null) {
|
||||
return (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
const color =
|
||||
status === "expired"
|
||||
? "error.main"
|
||||
: status === "expiring_soon"
|
||||
? "warning.main"
|
||||
: "success.main";
|
||||
|
||||
return (
|
||||
<Tooltip title={formatFull(validTo)}>
|
||||
<Typography variant="body2" sx={{ color, fontWeight: 500, cursor: "default" }}>
|
||||
{formatRelative(validTo)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user