Spaces:
Running
Running
undefined - Follow Up Deployment
Browse files- index.html +41 -20
index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
| 10 |
.gradient-bg { background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%); }
|
| 11 |
.asset-card:hover { transform: translateY(-5px); box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
|
| 12 |
.pulse { animation: pulse 2s infinite; }
|
| 13 |
-
|
| 14 |
</style>
|
| 15 |
</head>
|
| 16 |
<body class="bg-gray-50 min-h-screen">
|
|
@@ -40,6 +40,7 @@
|
|
| 40 |
</div>
|
| 41 |
</div>
|
| 42 |
|
|
|
|
| 43 |
<div id="asset-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8"></div>
|
| 44 |
</main>
|
| 45 |
|
|
@@ -51,16 +52,29 @@
|
|
| 51 |
</footer>
|
| 52 |
|
| 53 |
<script>
|
| 54 |
-
// Your list of 18 indicators (simplified for CoinGecko data mapping)
|
| 55 |
const indicatorsList = [
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
];
|
| 60 |
|
| 61 |
async function fetchCoinData() {
|
| 62 |
try {
|
| 63 |
-
// Fetch top 50 coins by market cap
|
| 64 |
const response = await fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=1&sparkline=false');
|
| 65 |
const data = await response.json();
|
| 66 |
return data;
|
|
@@ -70,13 +84,23 @@ async function fetchCoinData() {
|
|
| 70 |
}
|
| 71 |
}
|
| 72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
function countIndicators(coin) {
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
}
|
| 81 |
|
| 82 |
function renderAssets(coins) {
|
|
@@ -84,44 +108,41 @@ function renderAssets(coins) {
|
|
| 84 |
container.innerHTML = '';
|
| 85 |
|
| 86 |
coins.forEach((coin, index) => {
|
|
|
|
|
|
|
|
|
|
| 87 |
const card = document.createElement('div');
|
| 88 |
card.className = 'asset-card bg-white rounded-xl shadow-md overflow-hidden p-6 transition-all duration-300 hover:shadow-lg';
|
| 89 |
-
|
| 90 |
card.innerHTML = `
|
| 91 |
<div class="flex justify-between items-start">
|
| 92 |
<div>
|
| 93 |
<h3 class="text-lg font-semibold text-gray-800">#${index + 1} ${coin.name} (${coin.symbol.toUpperCase()})</h3>
|
| 94 |
<p class="text-xl font-bold text-green-600">$${coin.current_price.toLocaleString()}</p>
|
| 95 |
<p class="text-sm ${coin.price_change_percentage_24h >=0 ? 'text-green-500' : 'text-red-500'}">24h Change: ${coin.price_change_percentage_24h.toFixed(2)}%</p>
|
|
|
|
| 96 |
</div>
|
| 97 |
<div class="text-right">
|
| 98 |
<span class="inline-block px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">${coin.indicatorCount} indicators</span>
|
| 99 |
</div>
|
| 100 |
</div>
|
| 101 |
`;
|
| 102 |
-
|
| 103 |
container.appendChild(card);
|
| 104 |
});
|
| 105 |
|
| 106 |
-
// Update timestamp
|
| 107 |
document.getElementById('updateTime').textContent = new Date().toLocaleTimeString();
|
| 108 |
}
|
| 109 |
|
| 110 |
async function refreshData() {
|
| 111 |
const coins = await fetchCoinData();
|
| 112 |
-
// Add indicator count
|
| 113 |
coins.forEach(coin => {
|
| 114 |
coin.indicatorCount = countIndicators(coin);
|
| 115 |
});
|
| 116 |
-
// Sort descending by indicator count
|
| 117 |
coins.sort((a,b) => b.indicatorCount - a.indicatorCount);
|
| 118 |
-
|
| 119 |
renderAssets(coins);
|
| 120 |
}
|
| 121 |
|
| 122 |
-
|
| 123 |
refreshData();
|
| 124 |
-
// Refresh every 60 seconds
|
| 125 |
setInterval(refreshData, 60000);
|
| 126 |
</script>
|
| 127 |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MisoPretty/indicator-tracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
|
|
|
| 10 |
.gradient-bg { background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%); }
|
| 11 |
.asset-card:hover { transform: translateY(-5px); box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
|
| 12 |
.pulse { animation: pulse 2s infinite; }
|
| 13 |
+
.indicator-dot { display: inline-block; width: 14px; height: 14px; border-radius: 50%; margin-right: 4px; margin-bottom: 4px; }
|
| 14 |
</style>
|
| 15 |
</head>
|
| 16 |
<body class="bg-gray-50 min-h-screen">
|
|
|
|
| 40 |
</div>
|
| 41 |
</div>
|
| 42 |
|
| 43 |
+
<div id="indicator-key" class="mb-4 grid grid-cols-2 md:grid-cols-3 gap-2 text-sm"></div>
|
| 44 |
<div id="asset-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8"></div>
|
| 45 |
</main>
|
| 46 |
|
|
|
|
| 52 |
</footer>
|
| 53 |
|
| 54 |
<script>
|
|
|
|
| 55 |
const indicatorsList = [
|
| 56 |
+
{name: 'Major Exchange Listing', color: '#2563eb'},
|
| 57 |
+
{name: 'Unexpected Partnership', color: '#7c3aed'},
|
| 58 |
+
{name: 'Mainnet Launch/Network Upgrade', color: '#16a34a'},
|
| 59 |
+
{name: 'Regulatory Win', color: '#f59e0b'},
|
| 60 |
+
{name: 'Scarcity Shock', color: '#ef4444'},
|
| 61 |
+
{name: 'Whale Accumulation', color: '#6366f1'},
|
| 62 |
+
{name: 'Social Media Hype', color: '#ec4899'},
|
| 63 |
+
{name: 'DeFi/NFT/Ecosystem Boom', color: '#14b8a6'},
|
| 64 |
+
{name: 'Airdrop/Staking Rewards', color: '#f97316'},
|
| 65 |
+
{name: 'Institutional Investment', color: '#6b7280'},
|
| 66 |
+
{name: 'Bull Market/Macro Event', color: '#10b981'},
|
| 67 |
+
{name: 'On-chain Activity Rise', color: '#3b82f6'},
|
| 68 |
+
{name: 'Exchange Volume Spike', color: '#8b5cf6'},
|
| 69 |
+
{name: 'Whale Wallet Movement', color: '#e11d48'},
|
| 70 |
+
{name: 'Retail Access Improvement', color: '#facc15'},
|
| 71 |
+
{name: 'FOMO Speculation', color: '#22c55e'},
|
| 72 |
+
{name: 'High Social/Google Trends', color: '#f472b6'},
|
| 73 |
+
{name: 'Liquidity/Short Squeeze', color: '#f97316'}
|
| 74 |
];
|
| 75 |
|
| 76 |
async function fetchCoinData() {
|
| 77 |
try {
|
|
|
|
| 78 |
const response = await fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=1&sparkline=false');
|
| 79 |
const data = await response.json();
|
| 80 |
return data;
|
|
|
|
| 84 |
}
|
| 85 |
}
|
| 86 |
|
| 87 |
+
function getIndicatorStatus(coin) {
|
| 88 |
+
// For demo, randomly assign some indicators as present
|
| 89 |
+
return indicatorsList.map(ind => ({ name: ind.name, present: Math.random() < 0.5, color: ind.color }));
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
function countIndicators(coin) {
|
| 93 |
+
return getIndicatorStatus(coin).filter(ind => ind.present).length;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
function renderIndicatorKey() {
|
| 97 |
+
const keyContainer = document.getElementById('indicator-key');
|
| 98 |
+
keyContainer.innerHTML = indicatorsList.map(ind => `
|
| 99 |
+
<div class='flex items-center'>
|
| 100 |
+
<span class='indicator-dot' style='background-color:${ind.color}'></span>
|
| 101 |
+
<span>${ind.name}</span>
|
| 102 |
+
</div>
|
| 103 |
+
`).join('');
|
| 104 |
}
|
| 105 |
|
| 106 |
function renderAssets(coins) {
|
|
|
|
| 108 |
container.innerHTML = '';
|
| 109 |
|
| 110 |
coins.forEach((coin, index) => {
|
| 111 |
+
const indicators = getIndicatorStatus(coin);
|
| 112 |
+
const indicatorDots = indicators.map(ind => `<span class='indicator-dot' style='background-color:${ind.present ? ind.color : "#d1d5db"}' title='${ind.name}'></span>`).join('');
|
| 113 |
+
|
| 114 |
const card = document.createElement('div');
|
| 115 |
card.className = 'asset-card bg-white rounded-xl shadow-md overflow-hidden p-6 transition-all duration-300 hover:shadow-lg';
|
|
|
|
| 116 |
card.innerHTML = `
|
| 117 |
<div class="flex justify-between items-start">
|
| 118 |
<div>
|
| 119 |
<h3 class="text-lg font-semibold text-gray-800">#${index + 1} ${coin.name} (${coin.symbol.toUpperCase()})</h3>
|
| 120 |
<p class="text-xl font-bold text-green-600">$${coin.current_price.toLocaleString()}</p>
|
| 121 |
<p class="text-sm ${coin.price_change_percentage_24h >=0 ? 'text-green-500' : 'text-red-500'}">24h Change: ${coin.price_change_percentage_24h.toFixed(2)}%</p>
|
| 122 |
+
<div class='mt-2 flex flex-wrap'>${indicatorDots}</div>
|
| 123 |
</div>
|
| 124 |
<div class="text-right">
|
| 125 |
<span class="inline-block px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">${coin.indicatorCount} indicators</span>
|
| 126 |
</div>
|
| 127 |
</div>
|
| 128 |
`;
|
|
|
|
| 129 |
container.appendChild(card);
|
| 130 |
});
|
| 131 |
|
|
|
|
| 132 |
document.getElementById('updateTime').textContent = new Date().toLocaleTimeString();
|
| 133 |
}
|
| 134 |
|
| 135 |
async function refreshData() {
|
| 136 |
const coins = await fetchCoinData();
|
|
|
|
| 137 |
coins.forEach(coin => {
|
| 138 |
coin.indicatorCount = countIndicators(coin);
|
| 139 |
});
|
|
|
|
| 140 |
coins.sort((a,b) => b.indicatorCount - a.indicatorCount);
|
|
|
|
| 141 |
renderAssets(coins);
|
| 142 |
}
|
| 143 |
|
| 144 |
+
renderIndicatorKey();
|
| 145 |
refreshData();
|
|
|
|
| 146 |
setInterval(refreshData, 60000);
|
| 147 |
</script>
|
| 148 |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MisoPretty/indicator-tracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|