Really-amin commited on
Commit
69bc051
·
verified ·
1 Parent(s): 2bd865c

Upload 40 files

Browse files
Files changed (2) hide show
  1. admin.html +230 -231
  2. static/js/apiClient.js +23 -5
admin.html CHANGED
@@ -11,6 +11,14 @@
11
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js" defer></script>
12
  </head>
13
  <body data-theme="dark">
 
 
 
 
 
 
 
 
14
  <div class="app-shell">
15
  <!-- Sidebar Navigation -->
16
  <aside class="sidebar">
@@ -86,12 +94,10 @@
86
  </div>
87
  <div class="status-group">
88
  <div class="status-pill" data-api-health data-state="warn">
89
- <span class="status-dot"></span>
90
- <span>checking</span>
91
  </div>
92
  <div class="status-pill" data-ws-status data-state="warn">
93
- <span class="status-dot"></span>
94
- <span>connecting</span>
95
  </div>
96
  </div>
97
  </header>
@@ -100,87 +106,15 @@
100
  <!-- ========== OVERVIEW PAGE ========== -->
101
  <section id="page-overview" class="page active">
102
  <div class="section-header">
103
- <h2 class="section-title">Global Overview</h2>
104
- <span class="chip">Powered by /api/market/stats</span>
105
- </div>
106
-
107
- <!-- Market Stats Cards -->
108
- <div class="stats-grid" data-overview-stats>
109
- <div class="glass-card stat-card">
110
- <div class="stat-label">Total Market Cap</div>
111
- <div class="stat-value">Loading...</div>
112
- </div>
113
- <div class="glass-card stat-card">
114
- <div class="stat-label">24h Volume</div>
115
- <div class="stat-value">Loading...</div>
116
- </div>
117
- <div class="glass-card stat-card">
118
- <div class="stat-label">BTC Dominance</div>
119
- <div class="stat-value">Loading...</div>
120
- </div>
121
- <div class="glass-card stat-card">
122
- <div class="stat-label">Market Sentiment</div>
123
- <div class="stat-value">Loading...</div>
124
- </div>
125
- </div>
126
-
127
- <div class="grid-two">
128
- <!-- Top Coins Table -->
129
- <div class="glass-card">
130
- <div class="section-header">
131
- <h3>Top Coins</h3>
132
- <span class="text-muted">By market cap</span>
133
- </div>
134
- <div class="table-wrapper">
135
- <table>
136
- <thead>
137
- <tr>
138
- <th>#</th>
139
- <th>Symbol</th>
140
- <th>Name</th>
141
- <th>Price</th>
142
- <th>24h %</th>
143
- <th>Volume</th>
144
- <th>Market Cap</th>
145
- </tr>
146
- </thead>
147
- <tbody data-top-coins-body>
148
- <tr><td colspan="7" style="text-align:center;padding:2rem;">Loading top coins...</td></tr>
149
- </tbody>
150
- </table>
151
- </div>
152
- </div>
153
-
154
- <!-- Sentiment Chart -->
155
- <div class="glass-card">
156
- <div class="section-header">
157
- <h3>Global Sentiment</h3>
158
- <span class="text-muted">Ensemble HF models</span>
159
- </div>
160
- <canvas id="sentiment-chart" height="220"></canvas>
161
- <div style="margin-top:1rem;font-size:0.875rem;color:var(--text-secondary);">
162
- <strong>Models used:</strong> CryptoBERT, FinBERT, Twitter Sentiment<br>
163
- <strong>Method:</strong> Majority voting with confidence scoring
164
- </div>
165
- </div>
166
  </div>
167
- </section>
168
 
169
- <!-- ========== MARKET PAGE ========== -->
170
- <section id="page-market" class="page">
171
- <div class="section-header">
172
- <h2 class="section-title">Market Intelligence</h2>
173
- <div class="controls-bar">
174
- <div class="input-chip">
175
- <svg viewBox="0 0 24 24" width="16" height="16"><path d="M21 20l-5.6-5.6A6.5 6.5 0 1 0 15.4 16L21 21zM5 10.5a5.5 5.5 0 1 1 11 0a5.5 5.5 0 0 1-11 0z" fill="currentColor"/></svg>
176
- <input type="text" placeholder="Search symbol" data-market-search />
177
- </div>
178
- <button class="ghost" data-refresh-market>Refresh</button>
179
- </div>
180
- </div>
181
 
182
- <div class="glass-card">
183
- <div class="table-wrapper">
 
184
  <table>
185
  <thead>
186
  <tr>
@@ -191,219 +125,232 @@
191
  <th>24h %</th>
192
  <th>Volume</th>
193
  <th>Market Cap</th>
194
- <th>Actions</th>
195
  </tr>
196
  </thead>
197
- <tbody data-market-body>
198
- <tr><td colspan="8" style="text-align:center;padding:2rem;">Loading market data...</td></tr>
199
- </tbody>
200
  </table>
201
  </div>
202
  </div>
203
 
204
- <!-- Coin Detail Drawer -->
205
- <div class="drawer" data-market-drawer style="display:none;">
206
- <button class="ghost" data-close-drawer>Close</button>
207
- <h3 data-drawer-symbol>—</h3>
208
- <div data-drawer-stats></div>
209
- <div class="glass-card" data-chart-wrapper>
210
- <canvas id="market-detail-chart" height="180"></canvas>
 
 
 
 
 
 
 
 
 
 
 
 
211
  </div>
212
- <div class="glass-card">
213
- <h4>AI Sentiment Analysis</h4>
214
- <div data-drawer-sentiment></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  </div>
216
- </div>
217
  </section>
218
 
219
  <!-- ========== CHART LAB PAGE ========== -->
220
  <section id="page-chart" class="page">
221
  <div class="section-header">
222
  <h2 class="section-title">Chart Lab</h2>
223
- <div class="controls-bar">
224
- <select data-chart-symbol>
225
- <option value="BTC">Bitcoin (BTC)</option>
226
- <option value="ETH">Ethereum (ETH)</option>
227
- <option value="SOL">Solana (SOL)</option>
228
- <option value="BNB">BNB</option>
229
- <option value="XRP">Ripple (XRP)</option>
230
- <option value="ADA">Cardano (ADA)</option>
231
- </select>
232
- <div class="input-chip">
233
- <button class="ghost active" data-chart-timeframe="7d">7D</button>
234
- <button class="ghost" data-chart-timeframe="30d">30D</button>
235
- <button class="ghost" data-chart-timeframe="90d">90D</button>
236
- </div>
237
  </div>
 
238
  </div>
239
 
240
- <div class="glass-card">
241
- <canvas id="chart-lab-canvas" height="300"></canvas>
242
  </div>
243
 
244
- <div class="glass-card">
245
  <h4>Technical Analysis</h4>
246
- <div class="controls-bar">
247
- <label><input type="checkbox" data-indicator value="MA20" checked /> MA 20</label>
248
- <label><input type="checkbox" data-indicator value="MA50" /> MA 50</label>
249
- <label><input type="checkbox" data-indicator value="RSI" /> RSI</label>
250
- <label><input type="checkbox" data-indicator value="Volume" /> Volume</label>
251
  </div>
252
- <button class="primary" data-run-analysis>🤖 Analyze with AI</button>
253
- <div data-ai-insights class="ai-insights" style="margin-top:1rem;"></div>
254
  </div>
255
  </section>
256
 
257
  <!-- ========== AI ADVISOR PAGE ========== -->
258
  <section id="page-ai" class="page">
259
  <div class="section-header">
260
- <h2 class="section-title">AI-Powered Sentiment & Advisory</h2>
261
- <span class="chip">Ensemble: CryptoBERT + FinBERT + Social</span>
262
  </div>
263
 
264
- <div class="glass-card">
265
- <h4>Sentiment Analysis</h4>
266
- <form data-sentiment-form>
267
- <label>Text to Analyze
268
- <textarea name="text" rows="4" placeholder="Enter crypto-related text, news headline, or social media post for sentiment analysis..."></textarea>
269
- </label>
270
- <button class="primary" type="submit">🧠 Analyze Sentiment</button>
271
- </form>
272
- <div data-sentiment-result style="margin-top:1rem;"></div>
273
- </div>
274
 
275
  <div class="glass-card" style="margin-top:1.5rem;">
276
- <h4>AI Query Interface</h4>
277
- <form data-query-form>
278
- <label>Ask a Question
279
- <textarea name="query" rows="3" placeholder="e.g., What is the current Bitcoin price? or Analyze Ethereum trend"></textarea>
280
  </label>
281
- <button class="primary" type="submit">🔍 Submit Query</button>
282
  </form>
283
- <div data-query-result style="margin-top:1rem;"></div>
284
- </div>
285
-
286
- <div class="inline-message inline-info">
287
- ⚠️ AI-generated outputs are experimental and should not be considered financial advice.
288
  </div>
289
  </section>
290
 
291
  <!-- ========== NEWS PAGE ========== -->
292
  <section id="page-news" class="page">
293
  <div class="section-header">
294
- <h2 class="section-title">News & Headlines</h2>
295
- <span class="chip">With AI sentiment analysis</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  </div>
 
297
 
298
- <div class="controls-bar">
299
- <input type="text" placeholder="Search headlines..." data-news-search />
300
- <input type="text" placeholder="Filter by symbol (e.g., BTC)" data-news-symbol />
301
- <button class="ghost" data-refresh-news>Refresh</button>
 
 
 
 
 
 
 
 
 
 
 
302
  </div>
303
 
304
  <div class="glass-card">
305
- <div class="table-wrapper">
 
306
  <table>
307
  <thead>
308
  <tr>
309
- <th>Title</th>
310
- <th>Source</th>
311
- <th>Symbols</th>
312
- <th>Sentiment</th>
313
- <th>Time</th>
314
  <th>Actions</th>
315
  </tr>
316
  </thead>
317
- <tbody data-news-body>
318
- <tr><td colspan="6" style="text-align:center;padding:2rem;">Loading news...</td></tr>
319
- </tbody>
320
  </table>
321
  </div>
322
  </div>
323
- </section>
324
-
325
- <!-- ========== PROVIDERS PAGE ========== -->
326
- <section id="page-providers" class="page">
327
- <div class="section-header">
328
- <h2 class="section-title">API Providers</h2>
329
- <span class="chip">95+ data sources</span>
330
- </div>
331
 
332
- <div class="glass-card">
333
- <div class="table-wrapper">
 
334
  <table>
335
  <thead>
336
  <tr>
337
- <th>Provider</th>
338
- <th>Category</th>
339
- <th>Type</th>
340
  <th>Status</th>
341
- <th>Response Time</th>
342
  </tr>
343
  </thead>
344
- <tbody data-providers-body>
345
- <tr><td colspan="5" style="text-align:center;padding:2rem;">Loading providers...</td></tr>
346
- </tbody>
347
  </table>
348
  </div>
349
  </div>
350
- </section>
351
-
352
- <!-- ========== DATASETS & MODELS PAGE ========== -->
353
- <section id="page-datasets" class="page">
354
- <div class="section-header">
355
- <h2 class="section-title">HuggingFace Datasets & Models</h2>
356
- </div>
357
-
358
- <div class="grid-two">
359
- <!-- Datasets -->
360
- <div class="glass-card">
361
- <h4>📊 Crypto Datasets (14+)</h4>
362
- <div class="table-wrapper">
363
- <table>
364
- <thead>
365
- <tr>
366
- <th>Dataset</th>
367
- <th>Category</th>
368
- <th>Actions</th>
369
- </tr>
370
- </thead>
371
- <tbody data-datasets-body>
372
- <tr><td colspan="3" style="text-align:center;padding:1rem;">Loading...</td></tr>
373
- </tbody>
374
- </table>
375
- </div>
376
- </div>
377
 
378
- <!-- Models -->
379
- <div class="glass-card">
380
- <h4>🤖 AI Models (10+)</h4>
381
- <div class="table-wrapper">
382
- <table>
383
- <thead>
384
- <tr>
385
- <th>Model</th>
386
- <th>Task</th>
387
- <th>Status</th>
388
- </tr>
389
- </thead>
390
- <tbody data-models-body>
391
- <tr><td colspan="3" style="text-align:center;padding:1rem;">Loading...</td></tr>
392
- </tbody>
393
- </table>
394
- </div>
395
- </div>
396
- </div>
397
-
398
- <!-- Model Test Form -->
399
  <div class="glass-card" style="margin-top:1.5rem;">
400
- <h4>🧪 Test a Model</h4>
401
  <form data-model-test-form>
402
  <div class="grid-two">
403
  <label>Model
404
- <select name="model" data-model-select>
405
- <option value="">Select a model...</option>
406
- </select>
407
  </label>
408
  <label>Input Text
409
  <textarea name="input" rows="3" placeholder="Enter text to test the model..."></textarea>
@@ -413,6 +360,11 @@
413
  </form>
414
  <div data-model-test-output style="margin-top:1rem;"></div>
415
  </div>
 
 
 
 
 
416
  </section>
417
 
418
  <!-- ========== API EXPLORER PAGE ========== -->
@@ -467,12 +419,59 @@
467
  </div>
468
  </div>
469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  <div class="glass-card" style="margin-top:1.5rem;">
471
- <h4>Request Logs</h4>
472
- <div data-request-logs style="max-height:400px;overflow-y:auto;font-family:monospace;font-size:0.875rem;">
473
- <!-- Populated by JS -->
 
 
 
 
 
 
 
 
 
474
  </div>
475
  </div>
 
 
476
  </section>
477
 
478
  <!-- ========== SETTINGS PAGE ========== -->
@@ -522,4 +521,4 @@
522
  <!-- Load App JS as ES6 Module -->
523
  <script type="module" src="static/js/app.js"></script>
524
  </body>
525
- </html>
 
11
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js" defer></script>
12
  </head>
13
  <body data-theme="dark">
14
+ <!-- ===== تنظیم بک‌اند (اسکریپت) ===== -->
15
+ <script>
16
+ // اگر بک‌اندت روی Space دیگه‌ای هست اینجا عوض کن
17
+ // مثال: window.BACKEND_URL = 'https://aminmckee-crypto-intelligence.hf.space';
18
+ // اگر بک‌اند و داشبورد در یک Space هستن → این خط رو حذف یا کامنت کن
19
+ window.BACKEND_URL = 'https://aminmckee-crypto-intelligence.hf.space';
20
+ </script>
21
+
22
  <div class="app-shell">
23
  <!-- Sidebar Navigation -->
24
  <aside class="sidebar">
 
94
  </div>
95
  <div class="status-group">
96
  <div class="status-pill" data-api-health data-state="warn">
97
+ <span class="status-dot"></span><span>checking</span>
 
98
  </div>
99
  <div class="status-pill" data-ws-status data-state="warn">
100
+ <span class="status-dot"></span><span>connecting</span>
 
101
  </div>
102
  </div>
103
  </header>
 
106
  <!-- ========== OVERVIEW PAGE ========== -->
107
  <section id="page-overview" class="page active">
108
  <div class="section-header">
109
+ <h2 class="section-title">Overview</h2>
110
+ <span class="chip">Live</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  </div>
 
112
 
113
+ <div class="grid-four" data-overview-stats></div>
 
 
 
 
 
 
 
 
 
 
 
114
 
115
+ <div class="glass-card" style="margin-top:1.5rem;">
116
+ <h4>Top 10 Coins</h4>
117
+ <div class="table-container">
118
  <table>
119
  <thead>
120
  <tr>
 
125
  <th>24h %</th>
126
  <th>Volume</th>
127
  <th>Market Cap</th>
 
128
  </tr>
129
  </thead>
130
+ <tbody data-top-coins-body></tbody>
 
 
131
  </table>
132
  </div>
133
  </div>
134
 
135
+ <div class="glass-card" style="margin-top:1.5rem;">
136
+ <h4>Global Sentiment</h4>
137
+ <canvas id="sentiment-chart" height="200"></canvas>
138
+ </div>
139
+ </section>
140
+
141
+ <!-- ========== MARKET PAGE ========== -->
142
+ <section id="page-market" class="page">
143
+ <div class="section-header">
144
+ <h2 class="section-title">Market Explorer</h2>
145
+ <span class="chip">50+ coins</span>
146
+ </div>
147
+
148
+ <div class="search-bar">
149
+ <input type="text" placeholder="Search coins..." data-market-search />
150
+ <div class="button-group">
151
+ <button class="secondary active" data-timeframe="24h">24h</button>
152
+ <button class="secondary" data-timeframe="7d">7d</button>
153
+ <button class="secondary" data-timeframe="30d">30d</button>
154
  </div>
155
+ <label class="input-chip">Live Updates
156
+ <div class="toggle">
157
+ <input type="checkbox" data-live-toggle />
158
+ <span></span>
159
+ </div>
160
+ </label>
161
+ </div>
162
+
163
+ <div class="table-container">
164
+ <table>
165
+ <thead>
166
+ <tr>
167
+ <th>#</th>
168
+ <th>Symbol</th>
169
+ <th>Name</th>
170
+ <th>Price</th>
171
+ <th>24h %</th>
172
+ <th>Volume</th>
173
+ <th>Market Cap</th>
174
+ </tr>
175
+ </thead>
176
+ <tbody data-market-body></tbody>
177
+ </table>
178
+ </div>
179
+
180
+ <aside class="drawer" data-market-drawer>
181
+ <header>
182
+ <h3 data-drawer-symbol></h3>
183
+ <button data-close-drawer>&times;</button>
184
+ </header>
185
+ <div class="drawer-body">
186
+ <div data-drawer-stats></div>
187
+ <div data-chart-wrapper style="margin:1rem 0;">
188
+ <canvas id="market-detail-chart" height="180"></canvas>
189
+ </div>
190
+ <h4>Related Headlines</h4>
191
+ <div data-drawer-news></div>
192
  </div>
193
+ </aside>
194
  </section>
195
 
196
  <!-- ========== CHART LAB PAGE ========== -->
197
  <section id="page-chart" class="page">
198
  <div class="section-header">
199
  <h2 class="section-title">Chart Lab</h2>
200
+ <span class="chip">Interactive</span>
201
+ </div>
202
+
203
+ <div class="search-bar">
204
+ <input type="text" placeholder="Enter symbol (e.g., BTC)..." data-chart-symbol />
205
+ <div class="button-group">
206
+ <button class="secondary active" data-timeframe="1d">1d</button>
207
+ <button class="secondary" data-timeframe="7d">7d</button>
208
+ <button class="secondary" data-timeframe="30d">30d</button>
209
+ <button class="secondary" data-timeframe="90d">90d</button>
 
 
 
 
210
  </div>
211
+ <button class="primary" data-load-chart>Load Chart</button>
212
  </div>
213
 
214
+ <div class="glass-card" style="margin-top:1.5rem;">
215
+ <canvas id="price-chart" height="300"></canvas>
216
  </div>
217
 
218
+ <div class="glass-card" style="margin-top:1.5rem;">
219
  <h4>Technical Analysis</h4>
220
+ <div class="button-group">
221
+ <button class="secondary" data-indicator="sma">SMA</button>
222
+ <button class="secondary" data-indicator="ema">EMA</button>
223
+ <button class="secondary" data-indicator="rsi">RSI</button>
224
+ <button class="secondary" data-indicator="macd">MACD</button>
225
  </div>
226
+ <div data-analysis-output style="margin-top:1rem;"></div>
 
227
  </div>
228
  </section>
229
 
230
  <!-- ========== AI ADVISOR PAGE ========== -->
231
  <section id="page-ai" class="page">
232
  <div class="section-header">
233
+ <h2 class="section-title">AI Advisor</h2>
234
+ <span class="chip">Powered by HF</span>
235
  </div>
236
 
237
+ <form data-query-form>
238
+ <label>Query
239
+ <input type="text" placeholder="Ask about crypto markets..." name="query" />
240
+ </label>
241
+ <button class="primary" type="submit">Ask AI</button>
242
+ </form>
243
+
244
+ <div data-query-output style="margin-top:1.5rem;"></div>
 
 
245
 
246
  <div class="glass-card" style="margin-top:1.5rem;">
247
+ <h4>Sentiment Analyzer</h4>
248
+ <form data-sentiment-form>
249
+ <label>Text
250
+ <textarea name="text" rows="3" placeholder="Enter text for sentiment analysis..."></textarea>
251
  </label>
252
+ <button class="primary" type="submit">Analyze</button>
253
  </form>
254
+ <div data-sentiment-output style="margin-top:1rem;"></div>
 
 
 
 
255
  </div>
256
  </section>
257
 
258
  <!-- ========== NEWS PAGE ========== -->
259
  <section id="page-news" class="page">
260
  <div class="section-header">
261
+ <h2 class="section-title">News Feed</h2>
262
+ <span class="chip">Latest 40</span>
263
+ </div>
264
+
265
+ <div class="search-bar">
266
+ <input type="text" placeholder="Filter headlines..." data-news-search />
267
+ <select data-news-range>
268
+ <option value="24h">Last 24h</option>
269
+ <option value="7d">Last 7d</option>
270
+ <option value="30d">Last 30d</option>
271
+ </select>
272
+ <input type="text" placeholder="Symbol (e.g., BTC)" data-news-symbol />
273
+ </div>
274
+
275
+ <div class="table-container">
276
+ <table>
277
+ <thead>
278
+ <tr>
279
+ <th>Date</th>
280
+ <th>Source</th>
281
+ <th>Title</th>
282
+ <th>Symbols</th>
283
+ <th>Sentiment</th>
284
+ <th>Actions</th>
285
+ </tr>
286
+ </thead>
287
+ <tbody data-news-body></tbody>
288
+ </table>
289
+ </div>
290
+
291
+ <div class="modal-backdrop" data-news-modal>
292
+ <div class="modal" data-news-modal-content></div>
293
+ <button data-close-news-modal>&times;</button>
294
  </div>
295
+ </section>
296
 
297
+ <!-- ========== PROVIDERS PAGE ========== -->
298
+ <section id="page-providers" class="page">
299
+ <div class="section-header">
300
+ <h2 class="section-title">API Providers</h2>
301
+ <span class="chip">Multi-source</span>
302
+ </div>
303
+
304
+ <div data-providers-grid class="grid-three"></div>
305
+ </section>
306
+
307
+ <!-- ========== DATASETS & MODELS PAGE ========== -->
308
+ <section id="page-datasets" class="page">
309
+ <div class="section-header">
310
+ <h2 class="section-title">Datasets & Models</h2>
311
+ <span class="chip">14+ datasets</span>
312
  </div>
313
 
314
  <div class="glass-card">
315
+ <h4>Datasets</h4>
316
+ <div class="table-container">
317
  <table>
318
  <thead>
319
  <tr>
320
+ <th>Name</th>
321
+ <th>Type</th>
322
+ <th>Updated</th>
 
 
323
  <th>Actions</th>
324
  </tr>
325
  </thead>
326
+ <tbody data-datasets-body></tbody>
 
 
327
  </table>
328
  </div>
329
  </div>
 
 
 
 
 
 
 
 
330
 
331
+ <div class="glass-card" style="margin-top:1.5rem;">
332
+ <h4>HF Models</h4>
333
+ <div class="table-container">
334
  <table>
335
  <thead>
336
  <tr>
337
+ <th>Name</th>
338
+ <th>Task</th>
 
339
  <th>Status</th>
340
+ <th>Description</th>
341
  </tr>
342
  </thead>
343
+ <tbody data-models-body></tbody>
 
 
344
  </table>
345
  </div>
346
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  <div class="glass-card" style="margin-top:1.5rem;">
349
+ <h4>Test Model</h4>
350
  <form data-model-test-form>
351
  <div class="grid-two">
352
  <label>Model
353
+ <select name="model" data-model-select></select>
 
 
354
  </label>
355
  <label>Input Text
356
  <textarea name="input" rows="3" placeholder="Enter text to test the model..."></textarea>
 
360
  </form>
361
  <div data-model-test-output style="margin-top:1rem;"></div>
362
  </div>
363
+
364
+ <div class="modal-backdrop" data-dataset-modal>
365
+ <div class="modal" data-dataset-modal-content></div>
366
+ <button data-close-dataset-modal>&times;</button>
367
+ </div>
368
  </section>
369
 
370
  <!-- ========== API EXPLORER PAGE ========== -->
 
419
  </div>
420
  </div>
421
 
422
+ <div class="grid-two" style="margin-top:1.5rem;">
423
+ <div class="glass-card">
424
+ <h4>Request Logs</h4>
425
+ <div class="table-container">
426
+ <table>
427
+ <thead>
428
+ <tr>
429
+ <th>Time</th>
430
+ <th>Method</th>
431
+ <th>Endpoint</th>
432
+ <th>Status</th>
433
+ <th>Duration</th>
434
+ </tr>
435
+ </thead>
436
+ <tbody data-request-log></tbody>
437
+ </table>
438
+ </div>
439
+ </div>
440
+
441
+ <div class="glass-card">
442
+ <h4>Error Logs</h4>
443
+ <div class="table-container">
444
+ <table>
445
+ <thead>
446
+ <tr>
447
+ <th>Time</th>
448
+ <th>Endpoint</th>
449
+ <th>Message</th>
450
+ </tr>
451
+ </thead>
452
+ <tbody data-error-log></tbody>
453
+ </table>
454
+ </div>
455
+ </div>
456
+ </div>
457
+
458
  <div class="glass-card" style="margin-top:1.5rem;">
459
+ <h4>WebSocket Events</h4>
460
+ <div class="table-container">
461
+ <table>
462
+ <thead>
463
+ <tr>
464
+ <th>Time</th>
465
+ <th>Type</th>
466
+ <th>Details</th>
467
+ </tr>
468
+ </thead>
469
+ <tbody data-ws-log></tbody>
470
+ </table>
471
  </div>
472
  </div>
473
+
474
+ <button class="secondary" data-refresh-health style="margin-top:1.5rem;">Refresh</button>
475
  </section>
476
 
477
  <!-- ========== SETTINGS PAGE ========== -->
 
521
  <!-- Load App JS as ES6 Module -->
522
  <script type="module" src="static/js/app.js"></script>
523
  </body>
524
+ </html>
static/js/apiClient.js CHANGED
@@ -2,8 +2,27 @@ const DEFAULT_TTL = 60 * 1000; // 1 minute cache
2
 
3
  class ApiClient {
4
  constructor() {
5
- const origin = window?.location?.origin ?? '';
6
- this.baseURL = origin.replace(/\/$/, '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  this.cache = new Map();
8
  this.requestLogs = [];
9
  this.errorLogs = [];
@@ -60,8 +79,7 @@ class ApiClient {
60
  }
61
 
62
  const started = performance.now();
63
- const randomId = (window.crypto && window.crypto.randomUUID && window.crypto.randomUUID())
64
- || `${Date.now()}-${Math.random()}`;
65
  const entry = {
66
  id: randomId,
67
  method,
@@ -190,4 +208,4 @@ class ApiClient {
190
  }
191
 
192
  const apiClient = new ApiClient();
193
- export default apiClient;
 
2
 
3
  class ApiClient {
4
  constructor() {
5
+ // ==== اصلاح هوشمندانه آدرس بک‌اند ====
6
+ // ۱. اگر دستی BACKEND_URL تعریف شده باشه (از HTML)
7
+ // ۲. اگر روی HF Space هستیم و بک‌اند هم همونه → خودکار
8
+ // ۳. در غیر این صورت → بک‌اند معروف و همیشه زنده
9
+ this.baseURL =
10
+ (typeof window.BACKEND_URL === 'string' && window.BACKEND_URL.trim() !== ''
11
+ ? window.BACKEND_URL.trim().replace(/\/$/, '')
12
+ : null) ||
13
+ (window.location.origin.includes('hf.space')
14
+ ? window.location.origin.replace(/\/$/, '')
15
+ : null) ||
16
+ 'https://aminmckee-crypto-intelligence.hf.space';
17
+
18
+ // تضمین نهایی: اگر به هر دلیلی خالی بود
19
+ if (!this.baseURL || this.baseURL === 'null' || this.baseURL === '') {
20
+ this.baseURL = 'https://aminmckee-crypto-intelligence.hf.space';
21
+ }
22
+
23
+ console.log('[ApiClient] Backend URL:', this.baseURL);
24
+ // ==== پایان اصلاح ====
25
+
26
  this.cache = new Map();
27
  this.requestLogs = [];
28
  this.errorLogs = [];
 
79
  }
80
 
81
  const started = performance.now();
82
+ const randomId = (window.crypto && window.crypto.randomUUID && window.crypto.randomUUID()) || `${Date.now()}-${Math.random()}`;
 
83
  const entry = {
84
  id: randomId,
85
  method,
 
208
  }
209
 
210
  const apiClient = new ApiClient();
211
+ export default apiClient;