import type { TZDate } from "@date-fns/tz"; import { format, isSameYear } from "date-fns"; export function formatSize(bytes: number): string { const units = ["byte", "kilobyte", "megabyte", "gigabyte", "terabyte"]; const unitIndex = Math.max( 0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1), ); return Intl.NumberFormat("en-US", { style: "unit", unit: units[unitIndex], }).format(+Math.round(bytes / 1024 ** unitIndex)); } export function formatHoursMinutes(seconds: number) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); if (hours && minutes) { return `${hours}h ${minutes}m`; } if (hours) { return `${hours}h`; } if (minutes) { return `${minutes}m`; } return "0m"; } export function formatDate(date: string, dateFormat?: string | null, checkYear = true) { if (checkYear && isSameYear(new Date(), new Date(date))) { return format(new Date(date), "MMM d"); } return format(new Date(date), dateFormat ?? "P"); } export function formatNumber(value: number | undefined): string { return Intl.NumberFormat("en-US").format(value ?? 0); } export function getInitials(value: string) { const formatted = value.toUpperCase().replace(/[\s.-]/g, ""); if (formatted.split(" ").length > 1) { return `${formatted.charAt(0)}${formatted.charAt(1)}`; } if (value.length > 1) { return formatted.charAt(0) + formatted.charAt(1); } return formatted.charAt(0); } export function formatDateRange(dates: TZDate[]): string { if (!dates.length) return ""; const formatFullDate = (date: TZDate) => format(date, "MMM d"); const formatDay = (date: TZDate) => format(date, "d"); const startDate = dates[0]; const endDate = dates[1]; if (!startDate) return ""; if (dates.length === 1 || !endDate || startDate.getTime() === endDate.getTime()) { return formatFullDate(startDate); } if (startDate.getMonth() === endDate.getMonth()) { // Same month return `${format(startDate, "MMM")} ${formatDay(startDate)} - ${formatDay(endDate)}`; } // Different months return `${formatFullDate(startDate)} - ${formatFullDate(endDate)}`; } export function formatRelativeTime(date: Date): string { const now = new Date(); const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000); if (diffInSeconds < 60) { return "just now"; } const intervals = [ { label: "y", seconds: 31536000 }, { label: "mo", seconds: 2592000 }, { label: "d", seconds: 86400 }, { label: "h", seconds: 3600 }, { label: "m", seconds: 60 }, ] as const; for (const interval of intervals) { const count = Math.floor(diffInSeconds / interval.seconds); if (count > 0) { return `${count}${interval.label} ago`; } } return "just now"; }