Really-amin commited on
Commit
492a29b
·
verified ·
1 Parent(s): 86a935c

Upload 45 files

Browse files
Files changed (2) hide show
  1. index.html +5 -5
  2. static/js/app.js +44 -65
index.html CHANGED
@@ -14,11 +14,11 @@
14
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
15
 
16
  <!-- Styles -->
17
- <link rel="stylesheet" href="/static/css/main.css">
18
- <link rel="stylesheet" href="/static/css/toast.css">
19
- <script src="/static/js/trading-pairs-loader.js" defer></script>
20
- <script src="/static/js/toast.js" defer></script>
21
- <script src="/static/js/app.js" defer></script>
22
 
23
  <!-- Favicon -->
24
  <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🚀</text></svg>">
 
14
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
15
 
16
  <!-- Styles -->
17
+ <link rel="stylesheet" href="/static/css/main.css?v=2">
18
+ <link rel="stylesheet" href="/static/css/toast.css?v=2">
19
+ <script src="/static/js/trading-pairs-loader.js?v=2" defer></script>
20
+ <script src="/static/js/toast.js?v=2" defer></script>
21
+ <script src="/static/js/app.js?v=2" defer></script>
22
 
23
  <!-- Favicon -->
24
  <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🚀</text></svg>">
static/js/app.js CHANGED
@@ -27,38 +27,17 @@
27
  // =============================================================================
28
  // Toast Notification System (use the one from toast.js)
29
  // =============================================================================
30
- // Create a proxy that will use window.toastManager when it's available
31
- const ToastManager = {
32
- get _manager() {
33
- return window.toastManager || window.toast;
34
- },
35
- init() {
36
- if (this._manager && this._manager.init) this._manager.init();
37
- },
38
- show(message, type = 'info', duration = 5000) {
39
- if (this._manager) return this._manager.show(message, type, duration);
40
- console.log(`Toast: ${type} - ${message}`);
41
- },
42
- remove(toast) {
43
- if (toast && toast.remove) toast.remove();
44
- },
45
- success(message, duration) {
46
- if (this._manager && this._manager.success) return this._manager.success(message, duration);
47
- return this.show(message, 'success', duration);
48
- },
49
- error(message, duration) {
50
- if (this._manager && this._manager.error) return this._manager.error(message, duration);
51
- return this.show(message, 'error', duration);
52
- },
53
- warning(message, duration) {
54
- if (this._manager && this._manager.warning) return this._manager.warning(message, duration);
55
- return this.show(message, 'warning', duration);
56
- },
57
- info(message, duration) {
58
- if (this._manager && this._manager.info) return this._manager.info(message, duration);
59
- return this.show(message, 'info', duration);
60
- }
61
- };
62
 
63
  // =============================================================================
64
  // Global State
@@ -153,7 +132,7 @@ document.addEventListener('DOMContentLoaded', () => {
153
  console.log('🚀 Initializing Crypto Intelligence Hub...');
154
 
155
  // Initialize toast manager
156
- ToastManager.init();
157
 
158
  // Check API status
159
  checkAPIStatus();
@@ -244,7 +223,7 @@ function loadTabData(tabId) {
244
 
245
  function refreshCurrentTab() {
246
  loadTabData(AppState.currentTab);
247
- ToastManager.success('Data refreshed successfully');
248
  }
249
 
250
  // =============================================================================
@@ -478,7 +457,7 @@ async function loadDashboard() {
478
  console.log('✅ Dashboard loaded successfully');
479
  } catch (error) {
480
  console.error('❌ Error loading dashboard:', error);
481
- ToastManager.error('Failed to load dashboard. Please check the backend.');
482
 
483
  // Show error state
484
  const systemStatusDiv = document.getElementById('system-status');
@@ -687,7 +666,7 @@ async function loadMarketData() {
687
  console.log('✅ Market data loaded successfully');
688
  } catch (error) {
689
  console.error('❌ Error loading market data:', error);
690
- ToastManager.error('Failed to load market data');
691
 
692
  if (marketDiv) marketDiv.innerHTML = `<div class="alert alert-error">Error loading market data: ${error.message}</div>`;
693
  if (trendingDiv) trendingDiv.innerHTML = '<div class="alert alert-error">Error loading trending coins</div>';
@@ -701,7 +680,7 @@ async function loadMarketData() {
701
 
702
  async function fetchNewsFromAPI() {
703
  console.log('📥 Fetching news from CryptoCompare API...');
704
- ToastManager.info('Fetching latest news from CryptoCompare...');
705
 
706
  const newsListDiv = document.getElementById('news-list');
707
  if (!newsListDiv) return;
@@ -718,16 +697,16 @@ async function fetchNewsFromAPI() {
718
  console.log('Fetch news result:', data);
719
 
720
  if (data.success) {
721
- ToastManager.success(`Successfully fetched and saved ${data.saved} news articles!`);
722
  // Reload news list
723
  loadNews();
724
  } else {
725
- ToastManager.error(`Failed to fetch news: ${data.error}`);
726
  newsListDiv.innerHTML = `<div class="alert alert-error">Error: ${data.error}</div>`;
727
  }
728
  } catch (error) {
729
  console.error('❌ Error fetching news:', error);
730
- ToastManager.error('Failed to fetch news from API');
731
  newsListDiv.innerHTML = `<div class="alert alert-error">Error fetching news: ${error.message}</div>`;
732
  }
733
  }
@@ -837,14 +816,14 @@ async function loadNews() {
837
  `;
838
 
839
  console.log('✅ News loaded successfully');
840
- ToastManager.success(`Loaded ${sortedNews.length} news articles`);
841
  } else {
842
  newsListDiv.innerHTML = '<div class="alert alert-warning">No news articles available at the moment. Click "Fetch Latest News" to load articles.</div>';
843
  console.warn('No news data available');
844
  }
845
  } catch (error) {
846
  console.error('❌ Error loading news:', error);
847
- ToastManager.error('Failed to load news');
848
  newsListDiv.innerHTML = `<div class="alert alert-error">Error loading news: ${error.message}<br>Please check your internet connection and try again.</div>`;
849
  }
850
  }
@@ -963,7 +942,7 @@ async function loadModels() {
963
  console.log('✅ Models loaded successfully');
964
  } catch (error) {
965
  console.error('❌ Error loading models:', error);
966
- ToastManager.error('Failed to load models');
967
 
968
  if (modelsStatusDiv) modelsStatusDiv.innerHTML = `<div class="alert alert-error">Error loading models status: ${error.message}</div>`;
969
  if (modelsListDiv) modelsListDiv.innerHTML = '<div class="alert alert-error">Error loading models list</div>';
@@ -971,7 +950,7 @@ async function loadModels() {
971
  }
972
 
973
  async function initializeModels() {
974
- ToastManager.info('Initializing models... This may take a moment.');
975
 
976
  const modelsStatusDiv = document.getElementById('models-status');
977
  if (modelsStatusDiv) {
@@ -992,18 +971,18 @@ async function initializeModels() {
992
  const modelsFailed = data.models_failed || data.pipelines_failed || 0;
993
 
994
  if (isOk) {
995
- ToastManager.success(`Models initialized successfully! ${modelsLoaded} model(s) loaded.`);
996
  } else if (modelsLoaded > 0) {
997
- ToastManager.warning(`Models partially initialized: ${modelsLoaded} loaded, ${modelsFailed} failed`);
998
  } else {
999
- ToastManager.warning('No models loaded. Using fallback mode.');
1000
  }
1001
 
1002
  // Reload models list and status
1003
  await loadModels();
1004
  } catch (error) {
1005
  console.error('Error initializing models:', error);
1006
- ToastManager.error('Failed to initialize models: ' + error.message);
1007
 
1008
  if (modelsStatusDiv) {
1009
  modelsStatusDiv.innerHTML = `<div class="alert alert-error">Error initializing models: ${error.message}</div>`;
@@ -1029,7 +1008,7 @@ function loadSettings() {
1029
  }
1030
 
1031
  function saveSettings() {
1032
- ToastManager.success('Settings saved successfully!');
1033
  }
1034
 
1035
  function toggleTheme() {
@@ -1155,7 +1134,7 @@ function createConfidenceBar(confidence) {
1155
  }
1156
 
1157
  async function analyzeGlobalSentiment() {
1158
- ToastManager.info('Analyzing global market sentiment...');
1159
  const resultDiv = document.getElementById('global-sentiment-result');
1160
  if (resultDiv) {
1161
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
@@ -1208,14 +1187,14 @@ async function analyzeGlobalSentiment() {
1208
  createSentimentGauge('global-sentiment-gauge', confidence, sentimentClass);
1209
  }, 100);
1210
 
1211
- ToastManager.success('Sentiment analysis complete!');
1212
  } else {
1213
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1214
  }
1215
  } catch (error) {
1216
  console.error('Error analyzing sentiment:', error);
1217
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1218
- ToastManager.error('Failed to analyze sentiment');
1219
  }
1220
  }
1221
 
@@ -1224,11 +1203,11 @@ async function analyzeAssetSentiment() {
1224
  const text = document.getElementById('asset-sentiment-text')?.value;
1225
 
1226
  if (!symbol) {
1227
- ToastManager.warning('Please select a trading pair');
1228
  return;
1229
  }
1230
 
1231
- ToastManager.info('Analyzing asset sentiment...');
1232
  const resultDiv = document.getElementById('asset-sentiment-result');
1233
  if (resultDiv) {
1234
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
@@ -1282,14 +1261,14 @@ async function analyzeAssetSentiment() {
1282
  createSentimentGauge('asset-sentiment-gauge', confidence, sentimentClass);
1283
  }, 100);
1284
 
1285
- ToastManager.success('Asset sentiment analysis complete!');
1286
  } else {
1287
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1288
  }
1289
  } catch (error) {
1290
  console.error('Error analyzing asset sentiment:', error);
1291
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1292
- ToastManager.error('Failed to analyze asset sentiment');
1293
  }
1294
  }
1295
 
@@ -1298,11 +1277,11 @@ async function analyzeSentiment() {
1298
  const mode = document.getElementById('sentiment-mode')?.value || 'auto';
1299
 
1300
  if (!text || text.trim() === '') {
1301
- ToastManager.warning('Please enter text to analyze');
1302
  return;
1303
  }
1304
 
1305
- ToastManager.info('Analyzing sentiment...');
1306
  const resultDiv = document.getElementById('sentiment-result');
1307
  if (resultDiv) {
1308
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
@@ -1353,14 +1332,14 @@ async function analyzeSentiment() {
1353
  createSentimentGauge('sentiment-gauge', confidence, sentimentClass);
1354
  }, 100);
1355
 
1356
- ToastManager.success('Sentiment analysis complete!');
1357
  } else {
1358
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1359
  }
1360
  } catch (error) {
1361
  console.error('Error analyzing sentiment:', error);
1362
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1363
- ToastManager.error('Failed to analyze sentiment');
1364
  }
1365
  }
1366
 
@@ -1373,11 +1352,11 @@ async function runTradingAssistant() {
1373
  const context = document.getElementById('trading-context')?.value;
1374
 
1375
  if (!symbol) {
1376
- ToastManager.warning('Please select a trading symbol');
1377
  return;
1378
  }
1379
 
1380
- ToastManager.info('Generating trading signal...');
1381
  const resultDiv = document.getElementById('trading-assistant-result');
1382
  if (resultDiv) {
1383
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
@@ -1420,14 +1399,14 @@ async function runTradingAssistant() {
1420
  </p>
1421
  </div>
1422
  `;
1423
- ToastManager.success('Trading signal generated!');
1424
  } else {
1425
  resultDiv.innerHTML = '<div class="alert alert-warning">Trading signal unavailable</div>';
1426
  }
1427
  } catch (error) {
1428
  console.error('Error generating trading signal:', error);
1429
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1430
- ToastManager.error('Failed to generate trading signal');
1431
  }
1432
  }
1433
 
@@ -1449,7 +1428,7 @@ function formatNumber(num) {
1449
  // =============================================================================
1450
 
1451
  window.AppState = AppState;
1452
- window.ToastManager = ToastManager;
1453
  window.toggleSidebar = toggleSidebar;
1454
  window.switchTab = switchTab;
1455
  window.refreshCurrentTab = refreshCurrentTab;
 
27
  // =============================================================================
28
  // Toast Notification System (use the one from toast.js)
29
  // =============================================================================
30
+ // Helper function to get toast manager (loaded from toast.js)
31
+ function getToast() {
32
+ return window.toastManager || window.toast || {
33
+ init() {},
34
+ show(msg, type) { console.log(`Toast: ${type} - ${msg}`); },
35
+ success(msg) { this.show(msg, 'success'); },
36
+ error(msg) { this.show(msg, 'error'); },
37
+ warning(msg) { this.show(msg, 'warning'); },
38
+ info(msg) { this.show(msg, 'info'); }
39
+ };
40
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  // =============================================================================
43
  // Global State
 
132
  console.log('🚀 Initializing Crypto Intelligence Hub...');
133
 
134
  // Initialize toast manager
135
+ getToast().init();
136
 
137
  // Check API status
138
  checkAPIStatus();
 
223
 
224
  function refreshCurrentTab() {
225
  loadTabData(AppState.currentTab);
226
+ getToast().success('Data refreshed successfully');
227
  }
228
 
229
  // =============================================================================
 
457
  console.log('✅ Dashboard loaded successfully');
458
  } catch (error) {
459
  console.error('❌ Error loading dashboard:', error);
460
+ getToast().error('Failed to load dashboard. Please check the backend.');
461
 
462
  // Show error state
463
  const systemStatusDiv = document.getElementById('system-status');
 
666
  console.log('✅ Market data loaded successfully');
667
  } catch (error) {
668
  console.error('❌ Error loading market data:', error);
669
+ getToast().error('Failed to load market data');
670
 
671
  if (marketDiv) marketDiv.innerHTML = `<div class="alert alert-error">Error loading market data: ${error.message}</div>`;
672
  if (trendingDiv) trendingDiv.innerHTML = '<div class="alert alert-error">Error loading trending coins</div>';
 
680
 
681
  async function fetchNewsFromAPI() {
682
  console.log('📥 Fetching news from CryptoCompare API...');
683
+ getToast().info('Fetching latest news from CryptoCompare...');
684
 
685
  const newsListDiv = document.getElementById('news-list');
686
  if (!newsListDiv) return;
 
697
  console.log('Fetch news result:', data);
698
 
699
  if (data.success) {
700
+ getToast().success(`Successfully fetched and saved ${data.saved} news articles!`);
701
  // Reload news list
702
  loadNews();
703
  } else {
704
+ getToast().error(`Failed to fetch news: ${data.error}`);
705
  newsListDiv.innerHTML = `<div class="alert alert-error">Error: ${data.error}</div>`;
706
  }
707
  } catch (error) {
708
  console.error('❌ Error fetching news:', error);
709
+ getToast().error('Failed to fetch news from API');
710
  newsListDiv.innerHTML = `<div class="alert alert-error">Error fetching news: ${error.message}</div>`;
711
  }
712
  }
 
816
  `;
817
 
818
  console.log('✅ News loaded successfully');
819
+ getToast().success(`Loaded ${sortedNews.length} news articles`);
820
  } else {
821
  newsListDiv.innerHTML = '<div class="alert alert-warning">No news articles available at the moment. Click "Fetch Latest News" to load articles.</div>';
822
  console.warn('No news data available');
823
  }
824
  } catch (error) {
825
  console.error('❌ Error loading news:', error);
826
+ getToast().error('Failed to load news');
827
  newsListDiv.innerHTML = `<div class="alert alert-error">Error loading news: ${error.message}<br>Please check your internet connection and try again.</div>`;
828
  }
829
  }
 
942
  console.log('✅ Models loaded successfully');
943
  } catch (error) {
944
  console.error('❌ Error loading models:', error);
945
+ getToast().error('Failed to load models');
946
 
947
  if (modelsStatusDiv) modelsStatusDiv.innerHTML = `<div class="alert alert-error">Error loading models status: ${error.message}</div>`;
948
  if (modelsListDiv) modelsListDiv.innerHTML = '<div class="alert alert-error">Error loading models list</div>';
 
950
  }
951
 
952
  async function initializeModels() {
953
+ getToast().info('Initializing models... This may take a moment.');
954
 
955
  const modelsStatusDiv = document.getElementById('models-status');
956
  if (modelsStatusDiv) {
 
971
  const modelsFailed = data.models_failed || data.pipelines_failed || 0;
972
 
973
  if (isOk) {
974
+ getToast().success(`Models initialized successfully! ${modelsLoaded} model(s) loaded.`);
975
  } else if (modelsLoaded > 0) {
976
+ getToast().warning(`Models partially initialized: ${modelsLoaded} loaded, ${modelsFailed} failed`);
977
  } else {
978
+ getToast().warning('No models loaded. Using fallback mode.');
979
  }
980
 
981
  // Reload models list and status
982
  await loadModels();
983
  } catch (error) {
984
  console.error('Error initializing models:', error);
985
+ getToast().error('Failed to initialize models: ' + error.message);
986
 
987
  if (modelsStatusDiv) {
988
  modelsStatusDiv.innerHTML = `<div class="alert alert-error">Error initializing models: ${error.message}</div>`;
 
1008
  }
1009
 
1010
  function saveSettings() {
1011
+ getToast().success('Settings saved successfully!');
1012
  }
1013
 
1014
  function toggleTheme() {
 
1134
  }
1135
 
1136
  async function analyzeGlobalSentiment() {
1137
+ getToast().info('Analyzing global market sentiment...');
1138
  const resultDiv = document.getElementById('global-sentiment-result');
1139
  if (resultDiv) {
1140
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
 
1187
  createSentimentGauge('global-sentiment-gauge', confidence, sentimentClass);
1188
  }, 100);
1189
 
1190
+ getToast().success('Sentiment analysis complete!');
1191
  } else {
1192
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1193
  }
1194
  } catch (error) {
1195
  console.error('Error analyzing sentiment:', error);
1196
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1197
+ getToast().error('Failed to analyze sentiment');
1198
  }
1199
  }
1200
 
 
1203
  const text = document.getElementById('asset-sentiment-text')?.value;
1204
 
1205
  if (!symbol) {
1206
+ getToast().warning('Please select a trading pair');
1207
  return;
1208
  }
1209
 
1210
+ getToast().info('Analyzing asset sentiment...');
1211
  const resultDiv = document.getElementById('asset-sentiment-result');
1212
  if (resultDiv) {
1213
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
 
1261
  createSentimentGauge('asset-sentiment-gauge', confidence, sentimentClass);
1262
  }, 100);
1263
 
1264
+ getToast().success('Asset sentiment analysis complete!');
1265
  } else {
1266
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1267
  }
1268
  } catch (error) {
1269
  console.error('Error analyzing asset sentiment:', error);
1270
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1271
+ getToast().error('Failed to analyze asset sentiment');
1272
  }
1273
  }
1274
 
 
1277
  const mode = document.getElementById('sentiment-mode')?.value || 'auto';
1278
 
1279
  if (!text || text.trim() === '') {
1280
+ getToast().warning('Please enter text to analyze');
1281
  return;
1282
  }
1283
 
1284
+ getToast().info('Analyzing sentiment...');
1285
  const resultDiv = document.getElementById('sentiment-result');
1286
  if (resultDiv) {
1287
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
 
1332
  createSentimentGauge('sentiment-gauge', confidence, sentimentClass);
1333
  }, 100);
1334
 
1335
+ getToast().success('Sentiment analysis complete!');
1336
  } else {
1337
  resultDiv.innerHTML = '<div class="alert alert-warning">Sentiment analysis unavailable</div>';
1338
  }
1339
  } catch (error) {
1340
  console.error('Error analyzing sentiment:', error);
1341
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1342
+ getToast().error('Failed to analyze sentiment');
1343
  }
1344
  }
1345
 
 
1352
  const context = document.getElementById('trading-context')?.value;
1353
 
1354
  if (!symbol) {
1355
+ getToast().warning('Please select a trading symbol');
1356
  return;
1357
  }
1358
 
1359
+ getToast().info('Generating trading signal...');
1360
  const resultDiv = document.getElementById('trading-assistant-result');
1361
  if (resultDiv) {
1362
  resultDiv.innerHTML = '<div class="loading"><div class="spinner"></div> Analyzing...</div>';
 
1399
  </p>
1400
  </div>
1401
  `;
1402
+ getToast().success('Trading signal generated!');
1403
  } else {
1404
  resultDiv.innerHTML = '<div class="alert alert-warning">Trading signal unavailable</div>';
1405
  }
1406
  } catch (error) {
1407
  console.error('Error generating trading signal:', error);
1408
  resultDiv.innerHTML = `<div class="alert alert-error">Error: ${error.message}</div>`;
1409
+ getToast().error('Failed to generate trading signal');
1410
  }
1411
  }
1412
 
 
1428
  // =============================================================================
1429
 
1430
  window.AppState = AppState;
1431
+ // ToastManager is loaded from toast.js as window.toastManager
1432
  window.toggleSidebar = toggleSidebar;
1433
  window.switchTab = switchTab;
1434
  window.refreshCurrentTab = refreshCurrentTab;