File size: 7,058 Bytes
1ffd8ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Theme Management
const themeToggle = () => {
    const html = document.documentElement;
    const isDark = html.classList.contains('dark');
    
    if (isDark) {
        html.classList.remove('dark');
        html.classList.add('light');
        localStorage.setItem('theme', 'light');
    } else {
        html.classList.remove('light');
        html.classList.add('dark');
        localStorage.setItem('theme', 'dark');
    }
    updateChartColors();
};

// Check system preference on load
if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
    document.documentElement.classList.add('dark');
} else {
    document.documentElement.classList.remove('dark');
}

// Portfolio Chart Data
const portfolioData = [
    { asset: 'Bitcoin', value: 45, color: 'bg-primary-500' },
    { asset: 'Ethereum', value: 30, color: 'bg-secondary-500' },
    { asset: 'Solana', value: 15, color: 'bg-purple-500' },
    { asset: 'USDT', value: 10, color: 'bg-emerald-500' }
];

// Render Chart
function renderChart() {
    const chartContainer = document.getElementById('portfolioChart');
    if (!chartContainer) return;
    
    chartContainer.innerHTML = '';
    
    portfolioData.forEach((item, index) => {
        const bar = document.createElement('div');
        bar.className = `chart-bar w-full ${item.color} rounded-t-lg opacity-90 hover:opacity-100 cursor-pointer relative group`;
        bar.style.height = '0%';
        bar.innerHTML = `
            <div class="absolute -top-8 left-1/2 transform -translate-x-1/2 bg-slate-800 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap">
                ${item.asset}: ${item.value}%
            </div>
        `;
        chartContainer.appendChild(bar);
        
        // Animate height after small delay
        setTimeout(() => {
            bar.style.height = `${item.value * 2}%`;
        }, index * 100 + 100);
    });
}

// Update chart colors based on theme
function updateChartColors() {
    // Force re-render to adjust any theme-specific colors if needed
    renderChart();
}

// Modal Functions
function openModal(type) {
    const overlay = document.getElementById('modalOverlay');
    const modals = document.querySelectorAll('.modal-content');
    
    modals.forEach(m => m.classList.add('hidden'));
    
    const targetModal = document.getElementById(type + 'Modal');
    if (targetModal) {
        targetModal.classList.remove('hidden');
        overlay.classList.remove('hidden');
        // Trigger reflow for animation
        void overlay.offsetWidth;
        overlay.classList.remove('opacity-0');
        targetModal.classList.remove('scale-95');
        targetModal.classList.add('scale-100');
    }
}

function closeModal() {
    const overlay = document.getElementById('modalOverlay');
    const modals = document.querySelectorAll('.modal-content');
    
    overlay.classList.add('opacity-0');
    modals.forEach(m => {
        m.classList.remove('scale-100');
        m.classList.add('scale-95');
    });
    
    setTimeout(() => {
        overlay.classList.add('hidden');
        modals.forEach(m => m.classList.add('hidden'));
    }, 300);
}

// Close modal on outside click
document.getElementById('modalOverlay')?.addEventListener('click', (e) => {
    if (e.target.id === 'modalOverlay') {
        closeModal();
    }
});

// Toast Notification
function showToast(message, type = 'success') {
    const toast = document.getElementById('toast');
    const toastMessage = document.getElementById('toastMessage');
    
    toastMessage.textContent = message;
    
    // Update icon based on type
    const icon = toast.querySelector('i');
    if (type === 'error') {
        icon.setAttribute('data-feather', 'alert-circle');
        icon.classList.remove('text-emerald-400');
        icon.classList.add('text-red-400');
    } else {
        icon.setAttribute('data-feather', 'check-circle');
        icon.classList.remove('text-red-400');
        icon.classList.add('text-emerald-400');
    }
    
    feather.replace();
    
    toast.classList.remove('translate-y-20', 'opacity-0');
    
    setTimeout(() => {
        toast.classList.add('translate-y-20', 'opacity-0');
    }, 3000);
}

// Handle Send Form
function handleSend(e) {
    e.preventDefault();
    closeModal();
    
    // Simulate processing
    setTimeout(() => {
        showToast('Transaction sent successfully!');
        updateBalance(-0.5); // Simulate balance change
    }, 500);
}

// Copy Address
function copyAddress() {
    navigator.clipboard.writeText('0x71C7656EC7ab88b098defB751B7401B5f6d8976F');
    showToast('Address copied to clipboard!');
}

// Balance Update Simulation
let currentBalance = 24589.42;
function updateBalance(change) {
    currentBalance += change;
    const balanceElement = document.querySelector('.balance-amount');
    if (balanceElement) {
        animateValue(balanceElement, currentBalance - change, currentBalance, 1000);
    }
}

function animateValue(obj, start, end, duration) {
    let startTimestamp = null;
    const step = (timestamp) => {
        if (!startTimestamp) startTimestamp = timestamp;
        const progress = Math.min((timestamp - startTimestamp) / duration, 1);
        const value = progress * (end - start) + start;
        obj.innerHTML = '$' + value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
        if (progress < 1) {
            window.requestAnimationFrame(step);
        }
    };
    window.requestAnimationFrame(step);
}

// Simulate live price updates
setInterval(() => {
    const change = (Math.random() - 0.5) * 100;
    currentBalance += change;
    const balanceElement = document.querySelector('.balance-amount');
    if (balanceElement) {
        balanceElement.innerHTML = '$' + currentBalance.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }
    
    // Update percentage indicator
    const percentChange = document.querySelector('.percent-change');
    if (percentChange) {
        const isPositive = change > 0;
        percentChange.innerHTML = `
            <i data-feather="trend-${isPositive ? 'up' : 'down'}" class="w-4 h-4 inline"></i>
            ${Math.abs((change / currentBalance * 100)).toFixed(2)}%
        `;
        percentChange.className = `percent-change text-sm font-medium flex items-center gap-1 ${isPositive ? 'text-emerald-500' : 'text-red-500'}`;
        feather.replace();
    }
}, 5000);

// Initialize
document.addEventListener('DOMContentLoaded', () => {
    renderChart();
    feather.replace();
    
    // Add keyboard shortcuts
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape') closeModal();
    });
});

// Export functions for global access
window.themeToggle = themeToggle;
window.openModal = openModal;
window.closeModal = closeModal;
window.handleSend = handleSend;
window.copyAddress = copyAddress;
window.showToast = showToast;