JairoDanielMT commited on
Commit
ddcd034
·
verified ·
1 Parent(s): f500880

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +180 -17
index.html CHANGED
@@ -1,19 +1,182 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title>Dashboard: Últimos 7 días (XRP, PAXG, WLD, USDC) + Earn Morpho (USDC)</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
+ <style>
9
+ body { font-family: Inter, system-ui, Arial; margin: 18px; background:#f7f8fb; color:#111; }
10
+ header { display:flex; gap:12px; align-items:center; margin-bottom:12px; }
11
+ .card { background:white; border-radius:8px; padding:12px; box-shadow:0 6px 18px rgba(20,20,40,0.06); }
12
+ #controls { display:flex; gap:12px; align-items:center; margin-bottom:12px; }
13
+ .small { font-size:0.9rem; color:#555; }
14
+ #grid { display:grid; grid-template-columns: 1fr 300px; gap:12px; }
15
+ #chartCard { min-height:360px; }
16
+ input[type="number"]{ width:120px; padding:6px; border-radius:6px; border:1px solid #ddd; }
17
+ button { padding:8px 10px; border-radius:6px; border:none; background:#2563eb; color:white; cursor:pointer; }
18
+ button.secondary { background:#e5e7eb; color:#111; }
19
+ .asset-toggle { display:flex; gap:6px; flex-wrap:wrap; }
20
+ .asset-toggle label { display:flex; gap:6px; align-items:center; font-size:0.9rem; }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <header>
25
+ <h2>Crypto 7d — XRP, PAXG, WLD, USDC</h2>
26
+ <div class="small">Fuente de precios: CoinGecko · Est. rendement Morpho para USDC (ejemplo).</div>
27
+ </header>
28
+
29
+ <div id="grid">
30
+ <div class="card" id="chartCard">
31
+ <canvas id="priceChart"></canvas>
32
+ </div>
33
+
34
+ <div class="card">
35
+ <h3>Earn Morpho — Estimador (USDC)</h3>
36
+ <div class="small" style="margin-bottom:8px;">Tasa usada (30d APY de referencia): <span id="morphoRateDisplay">4.00%</span></div>
37
+
38
+ <label>Monto en USDC:
39
+ <input id="amount" type="number" min="0" step="0.01" value="1000">
40
+ </label>
41
+ <div style="margin-top:8px; display:flex; gap:8px;">
42
+ <button id="calcBtn">Calcular (7 días)</button>
43
+ <button id="setRateBtn" class="secondary">Usar otra tasa</button>
44
+ </div>
45
+
46
+ <div id="results" style="margin-top:12px;">
47
+ <div class="small">Ganancia estimada (7 días): <strong id="gain7">-</strong></div>
48
+ <div class="small">Total aproximado: <strong id="total7">-</strong></div>
49
+ <div class="small" style="margin-top:6px;">(Cálculo: interés compuesto diario aplicado sobre APY)</div>
50
+ </div>
51
+
52
+ <hr style="margin:12px 0;" />
53
+ <h4>Visibilidad activos</h4>
54
+ <div class="asset-toggle" id="toggles">
55
+ <!-- toggles inserted dynamically -->
56
+ </div>
57
+
58
+ <div style="margin-top:12px;" class="small">
59
+ Nota: CoinGecko API pública se usa para datos históricos. Ajusta la tasa Morpho según la plataforma o fuente que prefieras. Fuentes: CoinGecko y pools/agg. de rendimiento (ejemplo). :contentReference[oaicite:2]{index=2}
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <script>
65
+ const assets = [
66
+ { id: 'xrp', label: 'XRP' },
67
+ { id: 'pax-gold', label: 'PAXG' },
68
+ { id: 'worldcoin', label: 'WLD' },
69
+ { id: 'usd-coin', label: 'USDC' }
70
+ ];
71
+
72
+ // CoinGecko market_chart endpoint: /coins/{id}/market_chart?vs_currency=usd&days=7
73
+ async function fetchPriceSeries(assetId) {
74
+ const url = `https://api.coingecko.com/api/v3/coins/${assetId}/market_chart?vs_currency=usd&days=7&interval=daily`;
75
+ const res = await fetch(url);
76
+ if(!res.ok) throw new Error('Error fetching ' + assetId + ' -> ' + res.status);
77
+ const j = await res.json();
78
+ // j.prices -> [ [timestamp, price], ... ]
79
+ return j.prices.map(p => ({ t: p[0], price: p[1] }));
80
+ }
81
+
82
+ function tsToLabel(ts) {
83
+ const d = new Date(ts);
84
+ return d.toLocaleDateString();
85
+ }
86
+
87
+ function colorFor(label) {
88
+ const map = { 'XRP':'#1e90ff','PAXG':'#bfa34a','WLD':'#7c3aed','USDC':'#16a34a' };
89
+ return map[label] || '#888';
90
+ }
91
+
92
+ (async function init(){
93
+ try {
94
+ // fetch all series in parallel
95
+ const promises = assets.map(a => fetchPriceSeries(a.id));
96
+ const all = await Promise.all(promises);
97
+
98
+ // build common labels from first series timestamps
99
+ const labels = all[0].map(p => tsToLabel(p.t));
100
+
101
+ const datasets = assets.map((a, i) => ({
102
+ label: a.label,
103
+ data: all[i].map(pt => Number(pt.price.toFixed(6))),
104
+ borderColor: colorFor(a.label),
105
+ backgroundColor: colorFor(a.label),
106
+ tension: 0.2,
107
+ fill: false,
108
+ pointRadius: 3
109
+ }));
110
+
111
+ // create toggles
112
+ const togglesDiv = document.getElementById('toggles');
113
+ datasets.forEach((ds, i) => {
114
+ const id = 'chk_' + i;
115
+ const wrapper = document.createElement('label');
116
+ wrapper.innerHTML = `<input type="checkbox" id="${id}" checked data-idx="${i}"> <span style="width:64px;display:inline-block">${ds.label}</span>`;
117
+ togglesDiv.appendChild(wrapper);
118
+ wrapper.querySelector('input').addEventListener('change', e=>{
119
+ const idx = Number(e.target.dataset.idx);
120
+ myChart.data.datasets[idx].hidden = !e.target.checked;
121
+ myChart.update();
122
+ });
123
+ });
124
+
125
+ // Chart.js
126
+ const ctx = document.getElementById('priceChart').getContext('2d');
127
+ window.myChart = new Chart(ctx, {
128
+ type: 'line',
129
+ data: { labels, datasets },
130
+ options: {
131
+ responsive:true,
132
+ interaction: { mode: 'index', intersect: false },
133
+ plugins: { legend: { display: true } },
134
+ scales: {
135
+ y: { ticks: { callback: function(v){ return v; } } }
136
+ }
137
+ }
138
+ });
139
+
140
+ } catch (err) {
141
+ console.error(err);
142
+ document.getElementById('chartCard').innerHTML = '<div class="card"><strong>Error cargando datos:</strong> ' + err.message + '</div>';
143
+ }
144
+ })();
145
+
146
+
147
+ // --- Morpho estimator ---
148
+ let morphoAPY = 0.04; // referencia 4% (30d APY ejemplo). Cámbiala si tienes otro valor.
149
+ document.getElementById('morphoRateDisplay').innerText = (morphoAPY*100).toFixed(2) + '%';
150
+
151
+ function estimateCompound(amount, apy, days) {
152
+ // interest compounded daily approximation
153
+ const daily = apy / 365;
154
+ const total = amount * Math.pow(1 + daily, days);
155
+ return { total, gain: total - amount };
156
+ }
157
+
158
+ document.getElementById('calcBtn').addEventListener('click', ()=>{
159
+ const amt = parseFloat(document.getElementById('amount').value) || 0;
160
+ const res = estimateCompound(amt, morphoAPY, 7);
161
+ document.getElementById('gain7').innerText = res.gain.toFixed(6) + ' USDC';
162
+ document.getElementById('total7').innerText = res.total.toFixed(6) + ' USDC';
163
+ });
164
+
165
+ // quick set rate button => prompt for new %
166
+ document.getElementById('setRateBtn').addEventListener('click', ()=>{
167
+ const v = prompt('Nueva tasa APY (%) — ejemplo 4 para 4%:', (morphoAPY*100).toString());
168
+ if(v !== null) {
169
+ const n = parseFloat(v)/100;
170
+ if(!isNaN(n) && n >= 0) {
171
+ morphoAPY = n;
172
+ document.getElementById('morphoRateDisplay').innerText = (morphoAPY*100).toFixed(2) + '%';
173
+ document.getElementById('calcBtn').click();
174
+ } else alert('Valor inválido');
175
+ }
176
+ });
177
+
178
+ // run initial calc
179
+ document.getElementById('calcBtn').click();
180
+ </script>
181
+ </body>
182
  </html>