import { type ClassValue, clsx } from "clsx"; /** * Utility function to merge class names */ export function cn(...inputs: ClassValue[]) { return clsx(inputs); } /** * Format currency values */ export function formatCurrency( amount: number, currency: string = "USD", locale: string = "en-US" ): string { return new Intl.NumberFormat(locale, { style: "currency", currency, }).format(amount); } /** * Format date values */ export function formatDate( date: Date | string, options: Intl.DateTimeFormatOptions = { year: "numeric", month: "short", day: "numeric", } ): string { const d = typeof date === "string" ? new Date(date) : date; return d.toLocaleDateString("en-US", options); } /** * Format relative time (e.g., "2 hours ago") */ export function formatRelativeTime(date: Date | string): string { const d = typeof date === "string" ? new Date(date) : date; const now = new Date(); const diffInSeconds = Math.floor((now.getTime() - d.getTime()) / 1000); if (diffInSeconds < 60) return "just now"; if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} minutes ago`; if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} hours ago`; if (diffInSeconds < 604800) return `${Math.floor(diffInSeconds / 86400)} days ago`; return formatDate(d); } /** * Truncate text with ellipsis */ export function truncate(text: string, length: number = 100): string { if (text.length <= length) return text; return text.slice(0, length) + "..."; } /** * Generate a random ID */ export function generateId(length: number = 8): string { return Math.random() .toString(36) .substring(2, 2 + length); } /** * Debounce function */ export function debounce unknown>( func: T, wait: number ): (...args: Parameters) => void { let timeout: NodeJS.Timeout; return (...args: Parameters) => { clearTimeout(timeout); timeout = setTimeout(() => func(...args), wait); }; } /** * Sleep/delay function */ export function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); }