Spaces:
Sleeping
Sleeping
| 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); | |
| } | |