- implemented universal ingress credential rotation (slug + pin) - fixed event extension logic (`GREATEST(expires_at, NOW())`) - added UI formatter logic for natural dates (`formatNaturalExpiry`, `formatNaturalJoinTime`) - updated event cards to bounded 2-row compact cards - consolidated CLI expanding snippets - overhauled WAI-ARIA support for delegation drawers - removed legacy "Dismiss" mock buttons for cleanly styled "OK" buttons - updated tests and ensured pure zero-dependency SSR JSX compatibility Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
119 lines
3.6 KiB
TypeScript
119 lines
3.6 KiB
TypeScript
export function formatNaturalExpiry(expiresAt: string | Date): string {
|
|
const expDate = new Date(expiresAt);
|
|
const now = new Date();
|
|
const diffMs = expDate.getTime() - now.getTime();
|
|
|
|
const timeStr = expDate.toLocaleTimeString([], {
|
|
hour: "numeric",
|
|
minute: "2-digit",
|
|
});
|
|
const fullISO = expDate.toISOString();
|
|
|
|
let dateStr = "";
|
|
const isToday = expDate.getDate() === now.getDate() &&
|
|
expDate.getMonth() === now.getMonth() &&
|
|
expDate.getFullYear() === now.getFullYear();
|
|
|
|
const tomorrow = new Date(now);
|
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
const isTomorrow = expDate.getDate() === tomorrow.getDate() &&
|
|
expDate.getMonth() === tomorrow.getMonth() &&
|
|
expDate.getFullYear() === tomorrow.getFullYear();
|
|
|
|
if (isToday) {
|
|
dateStr = "Today";
|
|
} else if (isTomorrow) {
|
|
dateStr = "Tomorrow";
|
|
} else if (expDate.getFullYear() === now.getFullYear()) {
|
|
dateStr = expDate.toLocaleDateString([], {
|
|
month: "short",
|
|
day: "numeric",
|
|
});
|
|
} else {
|
|
dateStr = expDate.toLocaleDateString([], {
|
|
month: "short",
|
|
day: "numeric",
|
|
year: "numeric",
|
|
});
|
|
}
|
|
|
|
let badge = "";
|
|
|
|
if (diffMs <= 0) {
|
|
badge = '<span class="status-badge-red" title="' + fullISO +
|
|
'">Expired</span>';
|
|
} else {
|
|
const totalMins = Math.floor(diffMs / 60000);
|
|
const hours = totalMins / 60;
|
|
const days = hours / 24;
|
|
const months = days / 30;
|
|
const years = days / 365;
|
|
|
|
let timeRemainingStr = "";
|
|
let badgeClass = "status-badge-green";
|
|
|
|
if (hours < 1) {
|
|
timeRemainingStr = totalMins + "m left";
|
|
badgeClass = "status-badge-amber";
|
|
} else if (hours < 24) {
|
|
const h = Math.floor(hours);
|
|
const m = totalMins % 60;
|
|
timeRemainingStr = h + "h " + m + "m left";
|
|
badgeClass = "status-badge-amber";
|
|
} else if (days <= 60) {
|
|
timeRemainingStr = Math.floor(days) + "d left";
|
|
} else if (months <= 12) {
|
|
timeRemainingStr = months.toFixed(1) + " mos left";
|
|
} else {
|
|
timeRemainingStr = years.toFixed(1) + " yrs left";
|
|
}
|
|
|
|
badge = '<span class="' + badgeClass + '" title="' + fullISO + '">' +
|
|
timeRemainingStr + "</span>";
|
|
}
|
|
|
|
return dateStr + " · " + timeStr + " · " + badge;
|
|
}
|
|
|
|
export function formatNaturalJoinTime(
|
|
createdAt: string | Date,
|
|
isActive: boolean = true,
|
|
): string {
|
|
const createdDate = new Date(createdAt);
|
|
const now = new Date();
|
|
|
|
const diffMs = now.getTime() - createdDate.getTime();
|
|
const diffMins = Math.floor(diffMs / 60000);
|
|
|
|
const timeStr = createdDate.toLocaleTimeString([], {
|
|
hour: "numeric",
|
|
minute: "2-digit",
|
|
});
|
|
const isToday = createdDate.getDate() === now.getDate() &&
|
|
createdDate.getMonth() === now.getMonth() &&
|
|
createdDate.getFullYear() === now.getFullYear();
|
|
const dateStr = isToday
|
|
? "Today"
|
|
: createdDate.toLocaleDateString([], { month: "short", day: "numeric" });
|
|
|
|
let durationStr = "";
|
|
if (diffMins < 60) {
|
|
durationStr = diffMins + "m";
|
|
} else {
|
|
const h = Math.floor(diffMins / 60);
|
|
const m = diffMins % 60;
|
|
durationStr = h + "h " + m + "m";
|
|
}
|
|
|
|
const badgeStyle = isActive
|
|
? "background:rgba(34,197,94,0.15);color:#16a34a;padding:2px 6px;border-radius:4px;font-size:0.75rem;font-weight:600;"
|
|
: "background:rgba(234,179,8,0.15);color:#ca8a04;padding:2px 6px;border-radius:4px;font-size:0.75rem;font-weight:600;";
|
|
const badgeText = isActive ? "Active " + durationStr : "Paused";
|
|
|
|
const activeBadge = '<span style="' + badgeStyle + '">' + badgeText +
|
|
"</span>";
|
|
|
|
return "Joined " + dateStr + " · " + timeStr + " · " +
|
|
activeBadge;
|
|
}
|