import { type ClassValue, clsx } from 'clsx' import { twMerge } from 'tailwind-merge' import { useState, useEffect, useRef } from 'react' export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } export function formatBytes(bytes: number): string { if (bytes === 0) return '0 B' const k = 1024 const sizes = ['B', 'KB', 'MB', 'GB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}` } export function formatDate(date: string | Date): string { return new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(new Date(date)) } export function formatRelativeTime(date: string | Date): string { const now = new Date() const d = new Date(date) const diff = now.getTime() - d.getTime() const days = Math.floor(diff / 86400000) if (days === 0) return 'Today' if (days === 1) return 'Yesterday' if (days < 7) return `${days}d ago` if (days < 30) return `${Math.floor(days / 7)}w ago` return formatDate(date) } export function truncate(str: string, length: number): string { if (str.length <= length) return str return str.slice(0, length) + '...' } export function getFileIcon(type: string): string { const icons: Record = { '.pdf': '📄', '.docx': '📝', '.csv': '📊', '.xlsx': '📊', '.txt': '📃', '.md': '📃', } return icons[type] || '📄' } export function getPlanColor(plan: string): string { const colors: Record = { free: 'text-gray-600 bg-gray-100', starter: 'text-blue-600 bg-blue-100', pro: 'text-purple-600 bg-purple-100', enterprise: 'text-orange-600 bg-orange-100', } return colors[plan] || colors.free } // IMP-07: Debounce hook for search inputs (300ms default) export function useDebounce(value: T, delay: number = 300): T { const [debouncedValue, setDebouncedValue] = useState(value) useEffect(() => { const timer = setTimeout(() => setDebouncedValue(value), delay) return () => clearTimeout(timer) }, [value, delay]) return debouncedValue } export const AVAILABLE_MODELS = [ { id: 'accounts/fireworks/models/llama-v3p1-70b-instruct', name: 'Llama 3.1 70B', provider: 'Fireworks AI', plans: ['starter', 'pro', 'enterprise'], badge: 'Fast', }, { id: 'accounts/fireworks/models/mixtral-8x7b-instruct', name: 'Mixtral 8x7B', provider: 'Fireworks AI', plans: ['starter', 'pro', 'enterprise'], badge: 'Balanced', }, { id: 'gpt-4o', name: 'GPT-4o', provider: 'OpenAI', plans: ['pro', 'enterprise'], badge: 'Powerful', }, { id: 'gpt-4-turbo', name: 'GPT-4 Turbo', provider: 'OpenAI', plans: ['pro', 'enterprise'], badge: 'Smart', }, { id: 'gpt-3.5-turbo', name: 'GPT-3.5 Turbo', provider: 'OpenAI', plans: ['pro', 'enterprise'], badge: 'Efficient', }, { id: 'claude-3-5-sonnet-20241022', name: 'Claude 3.5 Sonnet', provider: 'Anthropic', plans: ['pro', 'enterprise'], badge: 'Reasoning', }, { id: 'claude-3-opus-20240229', name: 'Claude 3 Opus', provider: 'Anthropic', plans: ['pro', 'enterprise'], badge: 'Advanced', }, { id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro', provider: 'Google', plans: ['pro', 'enterprise'], badge: 'Long Context', }, ] export const CATEGORIES = [ 'Customer Support', 'Sales', 'FAQ', 'E-commerce', 'Healthcare', 'Finance', 'Education', 'HR', 'Legal', 'Other' ] export const INDUSTRIES = [ 'Technology', 'E-commerce', 'Healthcare', 'Finance', 'Education', 'Legal', 'Real Estate', 'Hospitality', 'Retail', 'Other' ] export const LANGUAGES = [ { code: 'en', name: 'English' }, { code: 'fr', name: 'French' }, { code: 'es', name: 'Spanish' }, { code: 'de', name: 'German' }, { code: 'it', name: 'Italian' }, { code: 'pt', name: 'Portuguese' }, { code: 'ja', name: 'Japanese' }, { code: 'ko', name: 'Korean' }, { code: 'zh', name: 'Chinese' }, { code: 'ar', name: 'Arabic' }, ]