// Megosztott komponensek és ikonok const Icon = ({ name, size = 20, stroke = 1.6 }) => { const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' }; switch (name) { case 'home': return ; case 'dashboard': return ; case 'gavel': return ; case 'meter': return ; case 'thumbs-up': return ; case 'plus': return ; case 'check': return ; case 'check2': return ; case 'x': return ; case 'arrow-l': return ; case 'arrow-r': return ; case 'chevron-r': return ; case 'chevron-d': return ; case 'camera': return ; case 'clock': return ; case 'user': return ; case 'users': return ; case 'inbox': return ; case 'coins': return ; case 'wallet': return ; case 'chart': return ; case 'doc': return ; case 'docs': return ; case 'calendar': return ; case 'gantt': return ; case 'settings': return ; case 'shield': return ; case 'logout': return ; case 'image': return ; case 'list': return ; case 'edit': return ; case 'trash': return ; case 'bell': return ; case 'smile': return ; case 'chat': return ; case 'send': return ; case 'paperclip': return ; case 'help': return ; case 'mail': return ; case 'search': return ; case 'filter': return ; case 'upload': return ; case 'download': return ; case 'phone': return ; case 'tag': return ; case 'flash': return ; case 'eye': return ; case 'forint': return ; case 'receipt': return ; case 'lock': return ; case 'attach': return ; case 'building': return ; case 'sparkle': return ; default: return null; } }; // Avatar const Avatar = ({ user, size = 'md' }) => { if (!user) return null; const cls = 'avatar' + (size === 'sm' ? ' sm' : size === 'lg' ? ' lg' : ''); return {user.avatar}; }; // Status pill const StatusPill = ({ status }) => { const map = { pending: { label: 'Jóváhagyásra vár', cls: 'pending' }, approved: { label: 'Jóváhagyva', cls: 'approved' }, rejected: { label: 'Elutasítva', cls: 'rejected' }, paid: { label: 'Kifizetve', cls: 'paid' }, }; const m = map[status] || map.pending; return {m.label}; }; const PhaseChip = ({ phaseId, compact = false }) => { const p = window.getPhase(phaseId); if (!p) return null; return ( {p.code} {!compact && {p.name}} ); }; // Progress bar with label const BudgetBar = ({ spent, pending = 0, budget, height = 8 }) => { const pct = budget > 0 ? Math.min(100, (spent / budget) * 100) : 0; const pendingPct = budget > 0 ? Math.min(100 - pct, (pending / budget) * 100) : 0; const over = spent > budget; return (