Spaces:
Running
Running
Download script.js from Mahi2305/cryptopulse-explorer: direct link, hf CLI and curl.
- Browser
- Download file 9.05 kB
-
https://huggingface.co/spaces/Mahi2305/cryptopulse-explorer/resolve/main/script.js
- Command line
-
hf download hf://spaces/Mahi2305/cryptopulse-explorer/script.js
-
curl -L -o script.js https://huggingface.co/spaces/Mahi2305/cryptopulse-explorer/resolve/main/script.js
9.05 kB
| // Main JavaScript for CryptoPulse Explorer | |
| // API Configuration | |
| const COINGECKO_API = 'https://api.coingecko.com/api/v3'; | |
| const CRYPTO_DATA = [ | |
| { id: 'bitcoin', symbol: 'btc', name: 'Bitcoin', color: '#f7931a' }, | |
| { id: 'ethereum', symbol: 'eth', name: 'Ethereum', color: '#627eea' }, | |
| { id: 'cardano', symbol: 'ada', name: 'Cardano', color: '#0033ad' }, | |
| { id: 'solana', symbol: 'sol', name: 'Solana', color: '#00ffa3' }, | |
| { id: 'polkadot', symbol: 'dot', name: 'Polkadot', color: '#e6007a' }, | |
| { id: 'dogecoin', symbol: 'doge', name: 'Dogecoin', color: '#c2a633' }, | |
| { id: 'chainlink', symbol: 'link', name: 'Chainlink', color: '#2a5ada' }, | |
| { id: 'litecoin', symbol: 'ltc', name: 'Litecoin', color: '#bfbbbb' } | |
| ]; | |
| // Load Crypto Data | |
| async function loadCryptoData() { | |
| const tableBody = document.getElementById('crypto-table-body'); | |
| if (!tableBody) return; | |
| // Show loading state | |
| tableBody.innerHTML = ` | |
| <tr> | |
| <td colspan="6" class="px-6 py-12 text-center"> | |
| <div class="loading-spinner mx-auto"></div> | |
| <p class="mt-4 text-gray-500">Loading market data...</p> | |
| </td> | |
| </tr> | |
| `; | |
| try { | |
| // In a real application, you would fetch from the API | |
| // For demo purposes, we'll use mock data | |
| const mockData = generateMockCryptoData(); | |
| // Clear loading state | |
| tableBody.innerHTML = ''; | |
| // Populate table with data | |
| mockData.forEach(crypto => { | |
| const row = document.createElement('tr'); | |
| row.className = 'hover:bg-gray-50 transition duration-150'; | |
| const changeClass = crypto.change24h >= 0 ? 'price-up' : 'price-down'; | |
| const changeIcon = crypto.change24h >= 0 ? 'trending-up' : 'trending-down'; | |
| row.innerHTML = ` | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="flex items-center"> | |
| <div class="crypto-icon" style="background-color: ${crypto.color}"> | |
| ${crypto.symbol.toUpperCase().charAt(0)} | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-gray-900">${crypto.name}</div> | |
| <div class="text-sm text-gray-500">${crypto.symbol.toUpperCase()}</div> | |
| </div> | |
| </div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="text-sm font-bold text-gray-900">$${crypto.price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="flex items-center ${changeClass}"> | |
| <i data-feather="${changeIcon}" class="mr-2 w-4 h-4"></i> | |
| <span class="text-sm font-semibold">${crypto.change24h >= 0 ? '+' : ''}${crypto.change24h.toFixed(2)}%</span> | |
| </div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900"> | |
| $${(crypto.marketCap / 1000000000).toFixed(2)}B | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900"> | |
| $${(crypto.volume24h / 1000000000).toFixed(2)}B | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
| <button onclick="addToWatchlist('${crypto.id}')" class="text-primary-600 hover:text-primary-900 mr-3"> | |
| <i data-feather="star" class="w-4 h-4"></i> | |
| </button> | |
| <a href="trade.html?coin=${crypto.id}" class="bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded-lg text-sm font-semibold transition duration-300"> | |
| Trade | |
| </a> | |
| </td> | |
| `; | |
| tableBody.appendChild(row); | |
| }); | |
| // Update Feather icons | |
| feather.replace(); | |
| } catch (error) { | |
| console.error('Error loading crypto data:', error); | |
| tableBody.innerHTML = ` | |
| <tr> | |
| <td colspan="6" class="px-6 py-12 text-center"> | |
| <i data-feather="alert-circle" class="w-12 h-12 text-red-500 mx-auto"></i> | |
| <p class="mt-4 text-gray-500">Failed to load market data. Please try again later.</p> | |
| <button onclick="loadCryptoData()" class="mt-4 bg-primary-600 text-white px-6 py-2 rounded-lg hover:bg-primary-700 transition duration-300"> | |
| Retry | |
| </button> | |
| </td> | |
| </tr> | |
| `; | |
| feather.replace(); | |
| } | |
| } | |
| // Generate Mock Crypto Data | |
| function generateMockCryptoData() { | |
| const basePrices = { | |
| bitcoin: 45000, | |
| ethereum: 3000, | |
| cardano: 2.5, | |
| solana: 100, | |
| polkadot: 20, | |
| dogecoin: 0.15, | |
| chainlink: 25, | |
| litecoin: 75 | |
| }; | |
| return CRYPTO_DATA.map(crypto => { | |
| const basePrice = basePrices[crypto.id]; | |
| const change24h = (Math.random() * 10 - 5); // Random change between -5% and +5% | |
| const currentPrice = basePrice * (1 + change24h / 100); | |
| return { | |
| ...crypto, | |
| price: currentPrice, | |
| change24h: change24h, | |
| marketCap: currentPrice * (1000000 + Math.random() * 5000000), | |
| volume24h: currentPrice * (100000 + Math.random() * 500000) | |
| }; | |
| }); | |
| } | |
| // Add to Watchlist | |
| function addToWatchlist(coinId) { | |
| const coin = CRYPTO_DATA.find(c => c.id === coinId); | |
| if (!coin) return; | |
| // In a real app, this would save to localStorage or backend | |
| alert(`Added ${coin.name} to your watchlist!`); | |
| // Update the star icon | |
| feather.replace(); | |
| } | |
| // Update Market Stats | |
| function updateMarketStats() { | |
| // This would be updated with real API data | |
| const stats = { | |
| marketCap: 2.1 * (1 + Math.random() * 0.02 - 0.01), // Random fluctuation | |
| btcDominance: 52.4 * (1 + Math.random() * 0.005 - 0.0025), | |
| volume24h: 84.2 * (1 + Math.random() * 0.05 - 0.025), | |
| fearGreed: Math.floor(Math.random() * 20 + 70) // Random between 70-90 | |
| }; | |
| // Update DOM elements if they exist | |
| const marketCapEl = document.querySelector('[data-stat="market-cap"]'); | |
| const btcDomEl = document.querySelector('[data-stat="btc-dominance"]'); | |
| const volumeEl = document.querySelector('[data-stat="volume"]'); | |
| const fearGreedEl = document.querySelector('[data-stat="fear-greed"]'); | |
| if (marketCapEl) marketCapEl.textContent = `$${stats.marketCap.toFixed(1)}T`; | |
| if (btcDomEl) btcDomEl.textContent = `${stats.btcDominance.toFixed(1)}%`; | |
| if (volumeEl) volumeEl.textContent = `$${stats.volume24h.toFixed(1)}B`; | |
| if (fearGreedEl) fearGreedEl.textContent = stats.fearGreed; | |
| } | |
| // Initialize when page loads | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Update market stats every 30 seconds | |
| setInterval(updateMarketStats, 30000); | |
| // Initialize tooltips | |
| initTooltips(); | |
| }); | |
| // Initialize Tooltips | |
| function initTooltips() { | |
| const tooltipElements = document.querySelectorAll('[data-tooltip]'); | |
| tooltipElements.forEach(el => { | |
| el.addEventListener('mouseenter', function(e) { | |
| const tooltipText = this.getAttribute('data-tooltip'); | |
| const tooltip = document.createElement('div'); | |
| tooltip.className = 'absolute z-50 px-3 py-2 text-sm text-white bg-gray-900 rounded-lg shadow-lg'; | |
| tooltip.textContent = tooltipText; | |
| tooltip.style.top = `${e.clientY - 40}px`; | |
| tooltip.style.left = `${e.clientX}px`; | |
| tooltip.id = 'custom-tooltip'; | |
| document.body.appendChild(tooltip); | |
| }); | |
| el.addEventListener('mouseleave', function() { | |
| const tooltip = document.getElementById('custom-tooltip'); | |
| if (tooltip) { | |
| tooltip.remove(); | |
| } | |
| }); | |
| }); | |
| } | |
| // Theme Toggle (for future dark mode support) | |
| function toggleTheme() { | |
| const html = document.documentElement; | |
| const currentTheme = html.getAttribute('data-theme'); | |
| const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; | |
| html.setAttribute('data-theme', newTheme); | |
| localStorage.setItem('theme', newTheme); | |
| // Update theme icon | |
| const themeIcon = document.getElementById('theme-icon'); | |
| if (themeIcon) { | |
| themeIcon.setAttribute('data-feather', newTheme === 'dark' ? 'sun' : 'moon'); | |
| feather.replace(); | |
| } | |
| } | |
| // Check for saved theme preference | |
| function loadThemePreference() { | |
| const savedTheme = localStorage.getItem('theme') || 'light'; | |
| document.documentElement.setAttribute('data-theme', savedTheme); | |
| } |