| import { clsx, type ClassValue } from 'clsx'; |
| import { twMerge } from 'tailwind-merge'; |
|
|
| export function cn(...inputs: ClassValue[]) { |
| return twMerge(clsx(inputs)); |
| } |
|
|
| export function formatCurrency(amount: number, currency = 'USD') { |
| return new Intl.NumberFormat('en-US', { |
| style: 'currency', |
| currency, |
| }).format(amount); |
| } |
|
|
| export function formatDate(date: string | Date) { |
| return new Intl.DateTimeFormat('en-US', { |
| month: 'short', |
| day: 'numeric', |
| year: 'numeric', |
| }).format(new Date(date)); |
| } |
|
|
| export function formatTime(date: string | Date) { |
| return new Intl.DateTimeFormat('en-US', { |
| hour: 'numeric', |
| minute: '2-digit', |
| hour12: true, |
| }).format(new Date(date)); |
| } |
|
|
| export function formatRelativeTime(date: string | Date) { |
| const now = new Date(); |
| const then = new Date(date); |
| const diffMs = now.getTime() - then.getTime(); |
| const diffMins = Math.floor(diffMs / 60000); |
| if (diffMins < 1) return 'Just now'; |
| if (diffMins < 60) return `${diffMins}m ago`; |
| const diffHours = Math.floor(diffMins / 60); |
| if (diffHours < 24) return `${diffHours}h ago`; |
| const diffDays = Math.floor(diffHours / 24); |
| return `${diffDays}d ago`; |
| } |
|
|
| export function generateSlug(name: string) { |
| return name |
| .toLowerCase() |
| .replace(/[^a-z0-9]+/g, '-') |
| .replace(/^-|-$/g, ''); |
| } |
|
|
| export function generateId() { |
| return crypto.randomUUID(); |
| } |
|
|
| export function truncate(str: string, length: number) { |
| if (str.length <= length) return str; |
| return str.slice(0, length) + '...'; |
| } |
|
|
| export function getInitials(name: string) { |
| return name |
| .split(' ') |
| .map((n) => n[0]) |
| .join('') |
| .toUpperCase() |
| .slice(0, 2); |
| } |
|
|
| export function getOrderStatusColor(status: string) { |
| const colors: Record<string, string> = { |
| pending: 'bg-amber-100 text-amber-700 border-amber-200', |
| confirmed: 'bg-blue-100 text-blue-700 border-blue-200', |
| preparing: 'bg-purple-100 text-purple-700 border-purple-200', |
| ready: 'bg-emerald-100 text-emerald-700 border-emerald-200', |
| delivered: 'bg-gray-100 text-gray-700 border-gray-200', |
| cancelled: 'bg-red-100 text-red-700 border-red-200', |
| }; |
| return colors[status] || 'bg-gray-100 text-gray-700 border-gray-200'; |
| } |
|
|
| export function getOrderTypeLabel(type: string) { |
| const labels: Record<string, string> = { |
| dine_in: 'Dine In', |
| takeaway: 'Takeaway', |
| delivery: 'Delivery', |
| }; |
| return labels[type] || type; |
| } |
|
|