File size: 2,889 Bytes
b66240d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * 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;