import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; /** Merge conditional class names and resolve Tailwind conflicts. */ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } /** Human-readable file size, e.g. 1536 -> "1.5 KB". */ export function formatBytes(bytes: number): string { if (!bytes || bytes < 0) return "0 B"; const units = ["B", "KB", "MB", "GB", "TB"]; const i = Math.min( units.length - 1, Math.floor(Math.log(bytes) / Math.log(1024)), ); const value = bytes / Math.pow(1024, i); return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`; } /** Locale-aware date for the Vietnamese UI, e.g. "2 thg 6, 2026 14:30". */ export function formatDateTime(iso: string): string { const d = new Date(iso); if (Number.isNaN(d.getTime())) return "—"; return new Intl.DateTimeFormat("vi-VN", { day: "numeric", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit", }).format(d); } /** Compact relative-ish label used in lists, e.g. "Hôm nay 14:30". */ export function formatDate(iso: string): string { const d = new Date(iso); if (Number.isNaN(d.getTime())) return "—"; return new Intl.DateTimeFormat("vi-VN", { day: "numeric", month: "short", year: "numeric", }).format(d); }