Spaces:
Sleeping
Sleeping
| /** | |
| * UI Utility Functions | |
| * Works as regular script (not ES6 module) | |
| */ | |
| // Create namespace object | |
| window.UIUtils = { | |
| formatCurrency: function(value) { | |
| if (value === null || value === undefined || value === '') { | |
| return 'β'; | |
| } | |
| const num = Number(value); | |
| if (Number.isNaN(num)) { | |
| return 'β'; | |
| } | |
| // Don't return 'β' for 0, show $0.00 instead | |
| if (num === 0) { | |
| return '$0.00'; | |
| } | |
| if (Math.abs(num) >= 1_000_000_000_000) { | |
| return `$${(num / 1_000_000_000_000).toFixed(2)}T`; | |
| } | |
| if (Math.abs(num) >= 1_000_000_000) { | |
| return `$${(num / 1_000_000_000).toFixed(2)}B`; | |
| } | |
| if (Math.abs(num) >= 1_000_000) { | |
| return `$${(num / 1_000_000).toFixed(2)}M`; | |
| } | |
| if (Math.abs(num) >= 1_000) { | |
| return `$${(num / 1_000).toFixed(2)}K`; | |
| } | |
| return `$${num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })}`; | |
| }, | |
| formatPercent: function(value) { | |
| if (value === null || value === undefined || Number.isNaN(Number(value))) { | |
| return 'β'; | |
| } | |
| const num = Number(value); | |
| return `${num >= 0 ? '+' : ''}${num.toFixed(2)}%`; | |
| }, | |
| setBadge: function(element, value) { | |
| if (!element) return; | |
| element.textContent = value; | |
| }, | |
| renderMessage: function(container, { state, title, body }) { | |
| if (!container) return; | |
| container.innerHTML = ` | |
| <div class="inline-message inline-${state}"> | |
| <strong>${title}</strong> | |
| <p>${body}</p> | |
| </div> | |
| `; | |
| }, | |
| createSkeletonRows: function(count = 3, columns = 5) { | |
| let rows = ''; | |
| for (let i = 0; i < count; i += 1) { | |
| rows += '<tr class="skeleton">'; | |
| for (let j = 0; j < columns; j += 1) { | |
| rows += '<td><span class="skeleton-block"></span></td>'; | |
| } | |
| rows += '</tr>'; | |
| } | |
| return rows; | |
| }, | |
| toggleSection: function(section, active) { | |
| if (!section) return; | |
| section.classList.toggle('active', !!active); | |
| }, | |
| shimmerElements: function(container) { | |
| if (!container) return; | |
| container.querySelectorAll('[data-shimmer]').forEach((el) => { | |
| el.classList.add('shimmer'); | |
| }); | |
| } | |
| }; | |
| // Also expose functions globally for backward compatibility | |
| window.formatCurrency = window.UIUtils.formatCurrency; | |
| window.formatPercent = window.UIUtils.formatPercent; | |
| window.setBadge = window.UIUtils.setBadge; | |
| window.renderMessage = window.UIUtils.renderMessage; | |
| window.createSkeletonRows = window.UIUtils.createSkeletonRows; | |
| window.toggleSection = window.UIUtils.toggleSection; | |
| window.shimmerElements = window.UIUtils.shimmerElements; | |