Spaces:
Running
Running
Update docs.html
Browse files
docs.html
CHANGED
|
@@ -1336,7 +1336,7 @@
|
|
| 1336 |
--theme-text-primary: #f0f0f0;
|
| 1337 |
}
|
| 1338 |
|
| 1339 |
-
/*
|
| 1340 |
.theme-green {
|
| 1341 |
--theme-primary: #4caf50;
|
| 1342 |
--theme-secondary: #81c784;
|
|
@@ -1346,116 +1346,122 @@
|
|
| 1346 |
--theme-text-primary: #e8f5e8;
|
| 1347 |
}
|
| 1348 |
|
| 1349 |
-
/* Enhanced theme coverage -
|
| 1350 |
-
|
| 1351 |
-
background: linear-gradient(135deg, var(--theme-bg-
|
| 1352 |
-
border: 2px solid var(--theme-primary);
|
| 1353 |
-
}
|
| 1354 |
-
|
| 1355 |
-
.search-input {
|
| 1356 |
-
background: var(--theme-bg-tertiary);
|
| 1357 |
-
border: 1px solid var(--theme-primary);
|
| 1358 |
color: var(--theme-text-primary);
|
| 1359 |
}
|
| 1360 |
|
| 1361 |
-
.
|
| 1362 |
-
|
| 1363 |
-
|
|
|
|
| 1364 |
}
|
| 1365 |
|
| 1366 |
-
|
|
|
|
| 1367 |
background: linear-gradient(135deg, var(--theme-primary) 0%, var(--theme-secondary) 100%);
|
| 1368 |
-
border:
|
| 1369 |
color: var(--theme-bg-primary);
|
| 1370 |
}
|
| 1371 |
|
| 1372 |
-
.search-btn:hover {
|
| 1373 |
-
background:
|
|
|
|
| 1374 |
}
|
| 1375 |
|
| 1376 |
-
.
|
| 1377 |
background: var(--theme-bg-secondary);
|
| 1378 |
-
border: 1px solid var(--theme-primary);
|
| 1379 |
-
}
|
| 1380 |
-
|
| 1381 |
-
.theme-btn {
|
| 1382 |
border: 2px solid var(--theme-primary);
|
| 1383 |
color: var(--theme-text-primary);
|
| 1384 |
-
background: var(--theme-bg-tertiary);
|
| 1385 |
}
|
| 1386 |
|
| 1387 |
-
.
|
| 1388 |
-
|
| 1389 |
-
|
| 1390 |
}
|
| 1391 |
|
| 1392 |
-
|
|
|
|
| 1393 |
background: linear-gradient(135deg, var(--theme-bg-secondary) 0%, var(--theme-bg-tertiary) 100%);
|
| 1394 |
-
border: 2px solid var(--theme-primary);
|
| 1395 |
-
}
|
| 1396 |
-
|
| 1397 |
-
.stats-section {
|
| 1398 |
-
background: var(--theme-bg-secondary);
|
| 1399 |
border: 1px solid var(--theme-primary);
|
|
|
|
| 1400 |
}
|
| 1401 |
|
| 1402 |
-
.stats-
|
| 1403 |
-
color: var(--theme-primary);
|
| 1404 |
-
border-bottom: 2px solid var(--theme-primary);
|
| 1405 |
-
}
|
| 1406 |
-
|
| 1407 |
-
.stat-item {
|
| 1408 |
background: var(--theme-bg-tertiary);
|
| 1409 |
border: 1px solid var(--theme-primary);
|
| 1410 |
}
|
| 1411 |
|
| 1412 |
-
.
|
| 1413 |
-
color: var(--theme-
|
| 1414 |
}
|
| 1415 |
|
| 1416 |
-
.
|
| 1417 |
color: var(--theme-primary);
|
| 1418 |
}
|
| 1419 |
|
| 1420 |
-
|
| 1421 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1422 |
border: 2px solid var(--theme-primary);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1423 |
}
|
| 1424 |
|
| 1425 |
-
.
|
| 1426 |
-
|
| 1427 |
-
|
|
|
|
|
|
|
| 1428 |
}
|
| 1429 |
|
| 1430 |
-
.
|
| 1431 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1432 |
border: none;
|
| 1433 |
-
color: var(--theme-
|
|
|
|
|
|
|
|
|
|
| 1434 |
}
|
| 1435 |
|
| 1436 |
-
.
|
| 1437 |
-
|
| 1438 |
}
|
| 1439 |
|
| 1440 |
-
|
| 1441 |
-
|
| 1442 |
-
height: 45px;
|
| 1443 |
-
width: 200px;
|
| 1444 |
-
overflow: hidden;
|
| 1445 |
-
padding: 8px 12px;
|
| 1446 |
}
|
| 1447 |
|
| 1448 |
.floating-user-widget.collapsed .widget-content {
|
| 1449 |
opacity: 0;
|
| 1450 |
height: 0;
|
| 1451 |
-
|
| 1452 |
-
padding: 0;
|
| 1453 |
-
}
|
| 1454 |
-
|
| 1455 |
-
.floating-user-widget.collapsed .widget-header {
|
| 1456 |
-
margin-bottom: 0;
|
| 1457 |
}
|
| 1458 |
|
|
|
|
| 1459 |
.widget-user-info {
|
| 1460 |
display: flex;
|
| 1461 |
align-items: center;
|
|
@@ -1471,47 +1477,145 @@
|
|
| 1471 |
}
|
| 1472 |
|
| 1473 |
.widget-user-details h4 {
|
|
|
|
| 1474 |
margin: 0;
|
| 1475 |
font-size: 0.9rem;
|
| 1476 |
-
color: var(--theme-text-primary);
|
| 1477 |
}
|
| 1478 |
|
| 1479 |
.widget-user-details p {
|
|
|
|
| 1480 |
margin: 0;
|
| 1481 |
font-size: 0.8rem;
|
| 1482 |
-
color: var(--theme-text-secondary);
|
| 1483 |
}
|
| 1484 |
|
| 1485 |
.widget-rank {
|
| 1486 |
text-align: center;
|
| 1487 |
padding: 8px;
|
| 1488 |
-
background: var(--theme-bg-
|
| 1489 |
-
border-radius:
|
| 1490 |
border: 1px solid var(--theme-primary);
|
| 1491 |
}
|
| 1492 |
|
| 1493 |
.rank-title {
|
| 1494 |
-
font-size: 0.
|
| 1495 |
-
color: var(--theme-
|
| 1496 |
margin-bottom: 4px;
|
| 1497 |
}
|
| 1498 |
|
| 1499 |
.rank-value {
|
|
|
|
|
|
|
| 1500 |
font-size: 0.9rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1501 |
font-weight: bold;
|
|
|
|
| 1502 |
color: var(--theme-primary);
|
| 1503 |
}
|
| 1504 |
|
| 1505 |
-
|
| 1506 |
-
|
| 1507 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1508 |
color: var(--theme-text-primary);
|
| 1509 |
}
|
| 1510 |
|
| 1511 |
-
.
|
| 1512 |
-
|
| 1513 |
-
|
| 1514 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1515 |
}
|
| 1516 |
|
| 1517 |
/* Added floating user widget styles */
|
|
@@ -1792,13 +1896,14 @@
|
|
| 1792 |
<div class="sidebar" id="sidebar">
|
| 1793 |
<!-- Added theme selector to sidebar -->
|
| 1794 |
<div class="theme-selector">
|
| 1795 |
-
<h3>🎨 Theme
|
| 1796 |
<div class="theme-buttons">
|
| 1797 |
<button class="theme-btn default current" onclick="changeTheme('default')">Default</button>
|
| 1798 |
<button class="theme-btn red" onclick="changeTheme('red')">Red</button>
|
| 1799 |
<button class="theme-btn black" onclick="changeTheme('black')">Black</button>
|
| 1800 |
<button class="theme-btn yellow" onclick="changeTheme('yellow')">Yellow</button>
|
| 1801 |
-
<
|
|
|
|
| 1802 |
</div>
|
| 1803 |
</div>
|
| 1804 |
|
|
@@ -2033,10 +2138,7 @@
|
|
| 2033 |
document.querySelectorAll('.theme-btn').forEach(btn => {
|
| 2034 |
btn.classList.remove('current');
|
| 2035 |
});
|
| 2036 |
-
|
| 2037 |
-
if (themeBtn) {
|
| 2038 |
-
themeBtn.classList.add('current');
|
| 2039 |
-
}
|
| 2040 |
|
| 2041 |
// Save theme preference
|
| 2042 |
localStorage.setItem('selectedTheme', theme);
|
|
@@ -2060,39 +2162,416 @@
|
|
| 2060 |
}
|
| 2061 |
|
| 2062 |
window.addEventListener('DOMContentLoaded', async () => {
|
| 2063 |
-
const
|
| 2064 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2065 |
|
| 2066 |
-
|
|
|
|
| 2067 |
|
| 2068 |
-
|
| 2069 |
-
|
| 2070 |
-
|
| 2071 |
-
|
| 2072 |
} else {
|
| 2073 |
-
|
| 2074 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2075 |
}
|
| 2076 |
-
|
| 2077 |
-
changeTheme(selectedTheme);
|
| 2078 |
|
|
|
|
| 2079 |
|
| 2080 |
-
|
| 2081 |
-
|
|
|
|
|
|
|
|
|
|
| 2082 |
|
| 2083 |
-
|
| 2084 |
-
|
| 2085 |
-
|
| 2086 |
-
|
| 2087 |
-
|
| 2088 |
-
|
| 2089 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2090 |
|
| 2091 |
-
|
| 2092 |
-
|
| 2093 |
-
|
| 2094 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2095 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2096 |
});
|
| 2097 |
|
| 2098 |
function toggleDetails(id, button) {
|
|
|
|
| 1336 |
--theme-text-primary: #f0f0f0;
|
| 1337 |
}
|
| 1338 |
|
| 1339 |
+
/* Added green theme */
|
| 1340 |
.theme-green {
|
| 1341 |
--theme-primary: #4caf50;
|
| 1342 |
--theme-secondary: #81c784;
|
|
|
|
| 1346 |
--theme-text-primary: #e8f5e8;
|
| 1347 |
}
|
| 1348 |
|
| 1349 |
+
/* Enhanced theme coverage - applying theme colors to all elements */
|
| 1350 |
+
html, body {
|
| 1351 |
+
background: linear-gradient(135deg, var(--theme-bg-primary) 0%, var(--theme-bg-secondary) 50%, var(--theme-bg-tertiary) 100%);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1352 |
color: var(--theme-text-primary);
|
| 1353 |
}
|
| 1354 |
|
| 1355 |
+
.header {
|
| 1356 |
+
background: linear-gradient(135deg, var(--theme-bg-secondary) 0%, var(--theme-bg-tertiary) 100%);
|
| 1357 |
+
border-bottom: 2px solid var(--theme-primary);
|
| 1358 |
+
box-shadow: 0 4px 20px rgba(0, 188, 212, 0.3);
|
| 1359 |
}
|
| 1360 |
|
| 1361 |
+
/* Apply theme colors to all buttons, inputs, and interactive elements */
|
| 1362 |
+
.search-btn, .theme-btn, .view-profile-btn, .show-all-btn {
|
| 1363 |
background: linear-gradient(135deg, var(--theme-primary) 0%, var(--theme-secondary) 100%);
|
| 1364 |
+
border: 1px solid var(--theme-primary);
|
| 1365 |
color: var(--theme-bg-primary);
|
| 1366 |
}
|
| 1367 |
|
| 1368 |
+
.search-btn:hover, .theme-btn:hover, .view-profile-btn:hover, .show-all-btn:hover {
|
| 1369 |
+
background: var(--theme-secondary);
|
| 1370 |
+
box-shadow: 0 4px 15px rgba(var(--theme-primary), 0.4);
|
| 1371 |
}
|
| 1372 |
|
| 1373 |
+
.search-input {
|
| 1374 |
background: var(--theme-bg-secondary);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1375 |
border: 2px solid var(--theme-primary);
|
| 1376 |
color: var(--theme-text-primary);
|
|
|
|
| 1377 |
}
|
| 1378 |
|
| 1379 |
+
.search-input:focus {
|
| 1380 |
+
border-color: var(--theme-secondary);
|
| 1381 |
+
box-shadow: 0 0 10px rgba(var(--theme-primary), 0.3);
|
| 1382 |
}
|
| 1383 |
|
| 1384 |
+
/* Apply theme to all cards and containers */
|
| 1385 |
+
.user-card, .nft-card, .group-card, .stats-section {
|
| 1386 |
background: linear-gradient(135deg, var(--theme-bg-secondary) 0%, var(--theme-bg-tertiary) 100%);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1387 |
border: 1px solid var(--theme-primary);
|
| 1388 |
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
|
| 1389 |
}
|
| 1390 |
|
| 1391 |
+
.stats-item {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1392 |
background: var(--theme-bg-tertiary);
|
| 1393 |
border: 1px solid var(--theme-primary);
|
| 1394 |
}
|
| 1395 |
|
| 1396 |
+
.stats-item .label {
|
| 1397 |
+
color: var(--theme-secondary);
|
| 1398 |
}
|
| 1399 |
|
| 1400 |
+
.stats-item .value {
|
| 1401 |
color: var(--theme-primary);
|
| 1402 |
}
|
| 1403 |
|
| 1404 |
+
/* Enhanced floating widget with smaller collapsed state */
|
| 1405 |
+
.floating-user-widget {
|
| 1406 |
+
position: fixed;
|
| 1407 |
+
bottom: 20px;
|
| 1408 |
+
right: 20px;
|
| 1409 |
+
width: 300px;
|
| 1410 |
+
background: linear-gradient(135deg, var(--theme-bg-secondary) 0%, var(--theme-bg-tertiary) 100%);
|
| 1411 |
border: 2px solid var(--theme-primary);
|
| 1412 |
+
border-radius: 12px;
|
| 1413 |
+
padding: 15px;
|
| 1414 |
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
|
| 1415 |
+
z-index: 1000;
|
| 1416 |
+
transition: all 0.3s ease;
|
| 1417 |
+
backdrop-filter: blur(10px);
|
| 1418 |
}
|
| 1419 |
|
| 1420 |
+
.floating-user-widget.collapsed {
|
| 1421 |
+
height: 45px; /* Made collapsed state smaller */
|
| 1422 |
+
width: 200px; /* Reduced width when collapsed */
|
| 1423 |
+
padding: 8px 12px; /* Reduced padding when collapsed */
|
| 1424 |
+
overflow: hidden;
|
| 1425 |
}
|
| 1426 |
|
| 1427 |
+
.widget-header {
|
| 1428 |
+
display: flex;
|
| 1429 |
+
justify-content: space-between;
|
| 1430 |
+
align-items: center;
|
| 1431 |
+
margin-bottom: 10px;
|
| 1432 |
+
cursor: pointer;
|
| 1433 |
+
}
|
| 1434 |
+
|
| 1435 |
+
.widget-title {
|
| 1436 |
+
font-weight: bold;
|
| 1437 |
+
color: var(--theme-primary);
|
| 1438 |
+
font-size: 0.9rem;
|
| 1439 |
+
}
|
| 1440 |
+
|
| 1441 |
+
.collapse-btn {
|
| 1442 |
+
background: none;
|
| 1443 |
border: none;
|
| 1444 |
+
color: var(--theme-primary);
|
| 1445 |
+
font-size: 1.2rem;
|
| 1446 |
+
cursor: pointer;
|
| 1447 |
+
transition: transform 0.3s ease;
|
| 1448 |
}
|
| 1449 |
|
| 1450 |
+
.collapse-btn.collapsed {
|
| 1451 |
+
transform: rotate(180deg);
|
| 1452 |
}
|
| 1453 |
|
| 1454 |
+
.widget-content {
|
| 1455 |
+
transition: opacity 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1456 |
}
|
| 1457 |
|
| 1458 |
.floating-user-widget.collapsed .widget-content {
|
| 1459 |
opacity: 0;
|
| 1460 |
height: 0;
|
| 1461 |
+
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1462 |
}
|
| 1463 |
|
| 1464 |
+
/* Enhanced widget styling with theme colors */
|
| 1465 |
.widget-user-info {
|
| 1466 |
display: flex;
|
| 1467 |
align-items: center;
|
|
|
|
| 1477 |
}
|
| 1478 |
|
| 1479 |
.widget-user-details h4 {
|
| 1480 |
+
color: var(--theme-text-primary);
|
| 1481 |
margin: 0;
|
| 1482 |
font-size: 0.9rem;
|
|
|
|
| 1483 |
}
|
| 1484 |
|
| 1485 |
.widget-user-details p {
|
| 1486 |
+
color: var(--theme-secondary);
|
| 1487 |
margin: 0;
|
| 1488 |
font-size: 0.8rem;
|
|
|
|
| 1489 |
}
|
| 1490 |
|
| 1491 |
.widget-rank {
|
| 1492 |
text-align: center;
|
| 1493 |
padding: 8px;
|
| 1494 |
+
background: var(--theme-bg-primary);
|
| 1495 |
+
border-radius: 6px;
|
| 1496 |
border: 1px solid var(--theme-primary);
|
| 1497 |
}
|
| 1498 |
|
| 1499 |
.rank-title {
|
| 1500 |
+
font-size: 0.7rem;
|
| 1501 |
+
color: var(--theme-secondary);
|
| 1502 |
margin-bottom: 4px;
|
| 1503 |
}
|
| 1504 |
|
| 1505 |
.rank-value {
|
| 1506 |
+
font-weight: bold;
|
| 1507 |
+
color: var(--theme-primary);
|
| 1508 |
font-size: 0.9rem;
|
| 1509 |
+
}
|
| 1510 |
+
|
| 1511 |
+
/* Enhanced loading animations with theme colors */
|
| 1512 |
+
.loading-enhanced {
|
| 1513 |
+
display: flex;
|
| 1514 |
+
flex-direction: column;
|
| 1515 |
+
align-items: center;
|
| 1516 |
+
justify-content: center;
|
| 1517 |
+
gap: 15px;
|
| 1518 |
+
padding: 40px 20px;
|
| 1519 |
+
color: var(--theme-text-secondary);
|
| 1520 |
+
}
|
| 1521 |
+
|
| 1522 |
+
.loading-pulse {
|
| 1523 |
+
width: 60px;
|
| 1524 |
+
height: 60px;
|
| 1525 |
+
border: 3px solid var(--theme-primary);
|
| 1526 |
+
border-radius: 50%;
|
| 1527 |
+
position: relative;
|
| 1528 |
+
animation: pulse 2s infinite;
|
| 1529 |
+
}
|
| 1530 |
+
|
| 1531 |
+
.loading-pulse::before {
|
| 1532 |
+
content: '';
|
| 1533 |
+
position: absolute;
|
| 1534 |
+
top: 50%;
|
| 1535 |
+
left: 50%;
|
| 1536 |
+
transform: translate(-50%, -50%);
|
| 1537 |
+
width: 30px;
|
| 1538 |
+
height: 30px;
|
| 1539 |
+
background: var(--theme-primary);
|
| 1540 |
+
border-radius: 50%;
|
| 1541 |
+
animation: innerPulse 2s infinite;
|
| 1542 |
+
}
|
| 1543 |
+
|
| 1544 |
+
@keyframes pulse {
|
| 1545 |
+
0%, 100% { transform: scale(1); opacity: 1; }
|
| 1546 |
+
50% { transform: scale(1.1); opacity: 0.7; }
|
| 1547 |
+
}
|
| 1548 |
+
|
| 1549 |
+
@keyframes innerPulse {
|
| 1550 |
+
0%, 100% { transform: translate(-50%, -50%) scale(1); }
|
| 1551 |
+
50% { transform: translate(-50%, -50%) scale(0.8); }
|
| 1552 |
+
}
|
| 1553 |
+
|
| 1554 |
+
.loading-text {
|
| 1555 |
+
font-size: 1.1rem;
|
| 1556 |
font-weight: bold;
|
| 1557 |
+
text-align: center;
|
| 1558 |
color: var(--theme-primary);
|
| 1559 |
}
|
| 1560 |
|
| 1561 |
+
.loading-subtext {
|
| 1562 |
+
font-size: 0.9rem;
|
| 1563 |
+
opacity: 0.8;
|
| 1564 |
+
text-align: center;
|
| 1565 |
+
color: var(--theme-secondary);
|
| 1566 |
+
}
|
| 1567 |
+
|
| 1568 |
+
/* Enhanced NFT and group card styles with theme colors */
|
| 1569 |
+
.nft-card, .group-card {
|
| 1570 |
+
position: relative;
|
| 1571 |
+
overflow: hidden;
|
| 1572 |
+
transition: all 0.3s ease;
|
| 1573 |
+
}
|
| 1574 |
+
|
| 1575 |
+
.nft-card:hover, .group-card:hover {
|
| 1576 |
+
transform: translateY(-5px);
|
| 1577 |
+
box-shadow: 0 8px 25px rgba(var(--theme-primary), 0.3);
|
| 1578 |
+
}
|
| 1579 |
+
|
| 1580 |
+
.nft-card::before, .group-card::before {
|
| 1581 |
+
content: '';
|
| 1582 |
+
position: absolute;
|
| 1583 |
+
top: 0;
|
| 1584 |
+
left: 0;
|
| 1585 |
+
right: 0;
|
| 1586 |
+
height: 3px;
|
| 1587 |
+
background: linear-gradient(90deg, var(--theme-primary), var(--theme-secondary));
|
| 1588 |
+
}
|
| 1589 |
+
|
| 1590 |
+
/* Apply theme to all text elements */
|
| 1591 |
+
h1, h2, h3, h4, h5, h6 {
|
| 1592 |
+
color: var(--theme-primary);
|
| 1593 |
+
}
|
| 1594 |
+
|
| 1595 |
+
p, span, div {
|
| 1596 |
color: var(--theme-text-primary);
|
| 1597 |
}
|
| 1598 |
|
| 1599 |
+
.error {
|
| 1600 |
+
color: #ff6b6b;
|
| 1601 |
+
background: rgba(255, 107, 107, 0.1);
|
| 1602 |
+
border: 1px solid #ff6b6b;
|
| 1603 |
+
padding: 10px;
|
| 1604 |
+
border-radius: 6px;
|
| 1605 |
+
}
|
| 1606 |
+
|
| 1607 |
+
/* Theme loading indicator */
|
| 1608 |
+
.theme-loading {
|
| 1609 |
+
position: fixed;
|
| 1610 |
+
top: 50%;
|
| 1611 |
+
left: 50%;
|
| 1612 |
+
transform: translate(-50%, -50%);
|
| 1613 |
+
background: var(--theme-bg-secondary);
|
| 1614 |
+
border: 2px solid var(--theme-primary);
|
| 1615 |
+
border-radius: 12px;
|
| 1616 |
+
padding: 20px;
|
| 1617 |
+
z-index: 9999;
|
| 1618 |
+
display: none;
|
| 1619 |
}
|
| 1620 |
|
| 1621 |
/* Added floating user widget styles */
|
|
|
|
| 1896 |
<div class="sidebar" id="sidebar">
|
| 1897 |
<!-- Added theme selector to sidebar -->
|
| 1898 |
<div class="theme-selector">
|
| 1899 |
+
<h3>🎨 Theme</h3>
|
| 1900 |
<div class="theme-buttons">
|
| 1901 |
<button class="theme-btn default current" onclick="changeTheme('default')">Default</button>
|
| 1902 |
<button class="theme-btn red" onclick="changeTheme('red')">Red</button>
|
| 1903 |
<button class="theme-btn black" onclick="changeTheme('black')">Black</button>
|
| 1904 |
<button class="theme-btn yellow" onclick="changeTheme('yellow')">Yellow</button>
|
| 1905 |
+
<!-- Added green theme button -->
|
| 1906 |
+
<button class="theme-btn green" onclick="changeTheme('green')">🟢</button>
|
| 1907 |
</div>
|
| 1908 |
</div>
|
| 1909 |
|
|
|
|
| 2138 |
document.querySelectorAll('.theme-btn').forEach(btn => {
|
| 2139 |
btn.classList.remove('current');
|
| 2140 |
});
|
| 2141 |
+
document.querySelector(`.theme-btn.${theme}`).classList.add('current');
|
|
|
|
|
|
|
|
|
|
| 2142 |
|
| 2143 |
// Save theme preference
|
| 2144 |
localStorage.setItem('selectedTheme', theme);
|
|
|
|
| 2162 |
}
|
| 2163 |
|
| 2164 |
window.addEventListener('DOMContentLoaded', async () => {
|
| 2165 |
+
const savedTheme = localStorage.getItem('selectedTheme') || 'default';
|
| 2166 |
+
changeTheme(savedTheme);
|
| 2167 |
+
|
| 2168 |
+
// Set up search functionality
|
| 2169 |
+
const searchBtn = document.getElementById('searchBtn');
|
| 2170 |
+
const searchInput = document.getElementById('searchInput');
|
| 2171 |
+
|
| 2172 |
+
searchBtn.addEventListener('click', () => {
|
| 2173 |
+
const chatId = searchInput.value.trim();
|
| 2174 |
+
if (chatId) {
|
| 2175 |
+
searchUser(chatId);
|
| 2176 |
+
}
|
| 2177 |
+
});
|
| 2178 |
+
|
| 2179 |
+
searchInput.addEventListener('keypress', (e) => {
|
| 2180 |
+
if (e.key === 'Enter') {
|
| 2181 |
+
const chatId = searchInput.value.trim();
|
| 2182 |
+
if (chatId) {
|
| 2183 |
+
searchUser(chatId);
|
| 2184 |
+
}
|
| 2185 |
+
}
|
| 2186 |
+
});
|
| 2187 |
+
|
| 2188 |
+
// Get userId from Telegram WebApp start parameter or current user
|
| 2189 |
+
let userId;
|
| 2190 |
+
let isViewingOther = false;
|
| 2191 |
|
| 2192 |
+
const initData = Telegram.WebApp.initDataUnsafe;
|
| 2193 |
+
const startParam = initData.start_param;
|
| 2194 |
|
| 2195 |
+
if (startParam) {
|
| 2196 |
+
userId = startParam;
|
| 2197 |
+
isViewingOther = true;
|
| 2198 |
+
document.getElementById('welcomeTitle').textContent = `Viewing Profile`;
|
| 2199 |
} else {
|
| 2200 |
+
const user = initData.user;
|
| 2201 |
+
if (user && user.id) {
|
| 2202 |
+
userId = user.id;
|
| 2203 |
+
document.getElementById('welcomeTitle').textContent = `Welcome to Finral`;
|
| 2204 |
+
} else {
|
| 2205 |
+
document.getElementById('chatId').innerHTML = '<div class="error">❌ Unable to fetch chat ID</div>';
|
| 2206 |
+
return;
|
| 2207 |
+
}
|
| 2208 |
}
|
|
|
|
|
|
|
| 2209 |
|
| 2210 |
+
document.getElementById('chatId').textContent = userId;
|
| 2211 |
|
| 2212 |
+
try {
|
| 2213 |
+
// Fetch user banner with fallback
|
| 2214 |
+
try {
|
| 2215 |
+
const bannerRes = await fetch(`https://reaperxxxx-testldb.hf.space/user/${userId}/banner`);
|
| 2216 |
+
const bannerData = await bannerRes.json();
|
| 2217 |
|
| 2218 |
+
const bannerEl = document.getElementById('banner');
|
| 2219 |
+
if (bannerData.status && bannerData.catboxUrl) {
|
| 2220 |
+
bannerEl.src = bannerData.catboxUrl;
|
| 2221 |
+
} else {
|
| 2222 |
+
bannerEl.src = 'https://files.catbox.moe/pdt55w.jpg';
|
| 2223 |
+
}
|
| 2224 |
+
document.getElementById('bannerContainer').style.display = 'block';
|
| 2225 |
+
} catch (err) {
|
| 2226 |
+
const bannerEl = document.getElementById('banner');
|
| 2227 |
+
bannerEl.src = 'https://files.catbox.moe/pdt55w.jpg';
|
| 2228 |
+
document.getElementById('bannerContainer').style.display = 'block';
|
| 2229 |
+
}
|
| 2230 |
+
|
| 2231 |
+
// Fetch user PFP
|
| 2232 |
+
const pfpRes = await fetch(`https://reaperxxxx-testldb.hf.space/user/${userId}/pfp`);
|
| 2233 |
+
const pfpData = await pfpRes.json();
|
| 2234 |
+
const imgEl = document.getElementById('pfp');
|
| 2235 |
+
|
| 2236 |
+
if (pfpData.status && pfpData.catboxUrl) {
|
| 2237 |
+
imgEl.src = pfpData.catboxUrl;
|
| 2238 |
+
} else {
|
| 2239 |
+
imgEl.src = 'https://files.catbox.moe/hmicys.jpeg';
|
| 2240 |
+
}
|
| 2241 |
+
|
| 2242 |
+
// Fetch user info
|
| 2243 |
+
const infoRes = await fetch(`https://reaperxxxx-testldb.hf.space/user/${userId}/info`);
|
| 2244 |
+
const infoData = await infoRes.json();
|
| 2245 |
+
|
| 2246 |
+
if (infoData.status) {
|
| 2247 |
+
const userInfo = infoData.groups[0] || {};
|
| 2248 |
+
|
| 2249 |
+
const fullName = userInfo.fullName || 'N/A';
|
| 2250 |
+
const username = userInfo.username || 'N/A';
|
| 2251 |
|
| 2252 |
+
if (fullName !== 'N/A') {
|
| 2253 |
+
document.getElementById('userName').textContent = fullName;
|
| 2254 |
+
document.getElementById('userName').style.display = 'block';
|
| 2255 |
}
|
| 2256 |
+
|
| 2257 |
+
// Update floating widget
|
| 2258 |
+
document.getElementById('widgetName').textContent = fullName;
|
| 2259 |
+
document.getElementById('widgetId').textContent = `ID: ${userId}`;
|
| 2260 |
+
document.getElementById('widgetAvatar').src = document.getElementById('pfp').src;
|
| 2261 |
+
updateGlobalRank(infoData.totalLevel);
|
| 2262 |
+
document.getElementById('floatingWidget').style.display = 'block';
|
| 2263 |
+
|
| 2264 |
+
// Display basic stats
|
| 2265 |
+
document.getElementById('fullName').textContent = fullName;
|
| 2266 |
+
document.getElementById('username').textContent = username;
|
| 2267 |
+
document.getElementById('totalXP').textContent = infoData.totalXP.toLocaleString();
|
| 2268 |
+
document.getElementById('totalLevel').textContent = infoData.totalLevel;
|
| 2269 |
+
document.getElementById('totalRoyalties').textContent = infoData.totalRoyalties.toLocaleString();
|
| 2270 |
+
document.getElementById('totalDailyMessages').textContent = infoData.totalDailyMessages;
|
| 2271 |
+
document.getElementById('groupCount').textContent = infoData.groups.length;
|
| 2272 |
+
|
| 2273 |
+
// Show stats grid
|
| 2274 |
+
document.getElementById('statsGrid').style.display = 'grid';
|
| 2275 |
+
|
| 2276 |
+
// Group unique groups by groupId
|
| 2277 |
+
const uniqueGroups = {};
|
| 2278 |
+
|
| 2279 |
+
for (const group of infoData.groups) {
|
| 2280 |
+
const groupId = group.groupId || group.id;
|
| 2281 |
+
|
| 2282 |
+
if (!uniqueGroups[groupId]) {
|
| 2283 |
+
uniqueGroups[groupId] = {
|
| 2284 |
+
groupId: groupId,
|
| 2285 |
+
fullName: group.fullName,
|
| 2286 |
+
username: group.username,
|
| 2287 |
+
totalLevel: 0,
|
| 2288 |
+
totalXP: 0,
|
| 2289 |
+
totalRoyalties: 0,
|
| 2290 |
+
totalDailyMessages: 0,
|
| 2291 |
+
entries: []
|
| 2292 |
+
};
|
| 2293 |
+
}
|
| 2294 |
+
|
| 2295 |
+
uniqueGroups[groupId].totalLevel += group.level || 0;
|
| 2296 |
+
uniqueGroups[groupId].totalXP += group.xp || 0;
|
| 2297 |
+
uniqueGroups[groupId].totalRoyalties += group.royalties || 0;
|
| 2298 |
+
uniqueGroups[groupId].totalDailyMessages += group.dailyMessages || 0;
|
| 2299 |
+
uniqueGroups[groupId].entries.push({
|
| 2300 |
+
level: group.level,
|
| 2301 |
+
xp: group.xp,
|
| 2302 |
+
royalties: group.royalties,
|
| 2303 |
+
dailyMessages: group.dailyMessages
|
| 2304 |
+
});
|
| 2305 |
+
}
|
| 2306 |
+
|
| 2307 |
+
|
| 2308 |
+
document.getElementById('groupsContainer').innerHTML = '';
|
| 2309 |
+
|
| 2310 |
+
// Display group stats
|
| 2311 |
+
const groupsContainer = document.getElementById('groupsContainer');
|
| 2312 |
+
|
| 2313 |
+
for (const groupId in uniqueGroups) {
|
| 2314 |
+
const group = uniqueGroups[groupId];
|
| 2315 |
+
|
| 2316 |
+
let groupMeta = null;
|
| 2317 |
+
let metaError = null;
|
| 2318 |
+
|
| 2319 |
+
try {
|
| 2320 |
+
const groupMetaRes = await fetch(`https://reaperxxxx-testldb.hf.space/group/${groupId}/meta`);
|
| 2321 |
+
|
| 2322 |
+
if (groupMetaRes.ok) {
|
| 2323 |
+
groupMeta = await groupMetaRes.json();
|
| 2324 |
+
} else {
|
| 2325 |
+
const errorText = await groupMetaRes.text();
|
| 2326 |
+
metaError = `API Error: ${groupMetaRes.status}`;
|
| 2327 |
+
}
|
| 2328 |
+
} catch (err) {
|
| 2329 |
+
metaError = `Fetch Error: ${err.message}`;
|
| 2330 |
+
}
|
| 2331 |
+
|
| 2332 |
+
const div = document.createElement('div');
|
| 2333 |
+
div.className = 'group-box';
|
| 2334 |
+
|
| 2335 |
+
const displayName = (groupMeta && groupMeta.status && groupMeta.groupName)
|
| 2336 |
+
? groupMeta.groupName
|
| 2337 |
+
: group.fullName || 'Unknown Group';
|
| 2338 |
+
|
| 2339 |
+
const groupPic = (groupMeta && groupMeta.status && groupMeta.groupPic)
|
| 2340 |
+
? groupMeta.groupPic
|
| 2341 |
+
: null;
|
| 2342 |
+
|
| 2343 |
+
const admins = (groupMeta && groupMeta.status && groupMeta.admins)
|
| 2344 |
+
? groupMeta.admins
|
| 2345 |
+
: null;
|
| 2346 |
+
|
| 2347 |
+
div.innerHTML = `
|
| 2348 |
+
<div class="group-header">
|
| 2349 |
+
${groupPic ? `<img class="group-pic" src="${groupPic}" alt="Group Picture">` : '<div class="group-pic" style="background: linear-gradient(45deg, #00bcd4, #87ceeb); display: flex; align-items: center; justify-content: center; color: #0a0a0a; font-weight: bold;">👥</div>'}
|
| 2350 |
+
<div class="group-info">
|
| 2351 |
+
<div class="group-name">${displayName}</div>
|
| 2352 |
+
<div class="group-id">ID: ${groupId}</div>
|
| 2353 |
+
</div>
|
| 2354 |
+
</div>
|
| 2355 |
+
|
| 2356 |
+
<div class="group-stats">
|
| 2357 |
+
<div class="group-stat-item">
|
| 2358 |
+
<span class="group-stat-value">${group.totalLevel}</span>
|
| 2359 |
+
<span class="group-stat-label">Level</span>
|
| 2360 |
+
</div>
|
| 2361 |
+
<div class="group-stat-item">
|
| 2362 |
+
<span class="group-stat-value">${group.totalXP.toLocaleString()}</span>
|
| 2363 |
+
<span class="group-stat-label">XP</span>
|
| 2364 |
+
</div>
|
| 2365 |
+
<div class="group-stat-item">
|
| 2366 |
+
<span class="group-stat-value">${group.totalRoyalties.toLocaleString()}</span>
|
| 2367 |
+
<span class="group-stat-label">Royalties</span>
|
| 2368 |
+
</div>
|
| 2369 |
+
<div class="group-stat-item">
|
| 2370 |
+
<span class="group-stat-value">${group.totalDailyMessages}</span>
|
| 2371 |
+
<span class="group-stat-label">Daily</span>
|
| 2372 |
+
</div>
|
| 2373 |
+
</div>
|
| 2374 |
+
|
| 2375 |
+
${metaError ? `<div class="error">⚠️ ${metaError}</div>` : ''}
|
| 2376 |
+
|
| 2377 |
+
${admins && admins.length > 0 ? `
|
| 2378 |
+
<div class="group-admins">
|
| 2379 |
+
<details>
|
| 2380 |
+
<summary>👑 Admins (${admins.length})</summary>
|
| 2381 |
+
<div class="admin-list">
|
| 2382 |
+
${admins.slice(0, 5).map(a => `<span class="admin-tag" onclick="window.open('https://t.me/finralxbot/info?startapp=${a.id}', '_blank')">${a.name || 'Unknown'}</span>`).join('')}
|
| 2383 |
+
${admins.length > 5 ? `<span class="admin-tag">+${admins.length - 5} more</span>` : ''}
|
| 2384 |
+
</div>
|
| 2385 |
+
</details>
|
| 2386 |
+
</div>` : ''}
|
| 2387 |
+
`;
|
| 2388 |
+
|
| 2389 |
+
groupsContainer.appendChild(div);
|
| 2390 |
+
}
|
| 2391 |
+
|
| 2392 |
+
document.getElementById('groupsSection').style.display = 'block';
|
| 2393 |
+
}
|
| 2394 |
|
| 2395 |
+
try {
|
| 2396 |
+
const nftsRes = await fetch(`https://reaperxxxx-testldb.hf.space/user/${userId}/nfts`);
|
| 2397 |
+
const nftsData = await nftsRes.json();
|
| 2398 |
+
|
| 2399 |
+
const nftsContainer = document.getElementById('nftsContainer');
|
| 2400 |
+
const showAllBtn = document.getElementById('showAllNftsBtn');
|
| 2401 |
+
const remainingCount = document.getElementById('remainingCount');
|
| 2402 |
+
const nftStats = document.getElementById('nftStats');
|
| 2403 |
+
|
| 2404 |
+
if (nftsData.status && nftsData.nfts && nftsData.nfts.length > 0) {
|
| 2405 |
+
// Sort NFTs by holders (ascending) to show rarest first
|
| 2406 |
+
const sortedNfts = nftsData.nfts.sort((a, b) => a.holders - b.holders);
|
| 2407 |
+
|
| 2408 |
+
// Calculate NFT statistics
|
| 2409 |
+
const totalNfts = sortedNfts.length;
|
| 2410 |
+
const avgQuality = Math.round(sortedNfts.reduce((sum, nft) => sum + nft.nftquality, 0) / totalNfts);
|
| 2411 |
+
const rarestHolders = Math.min(...sortedNfts.map(nft => nft.holders));
|
| 2412 |
+
const highestQuality = Math.max(...sortedNfts.map(nft => nft.nftquality));
|
| 2413 |
+
|
| 2414 |
+
// Update NFT stats
|
| 2415 |
+
document.getElementById('totalNfts').textContent = totalNfts;
|
| 2416 |
+
document.getElementById('avgQuality').textContent = avgQuality;
|
| 2417 |
+
document.getElementById('rarestHolders').textContent = rarestHolders;
|
| 2418 |
+
document.getElementById('highestQuality').textContent = highestQuality;
|
| 2419 |
+
nftStats.style.display = 'block';
|
| 2420 |
+
|
| 2421 |
+
function getQualityClass(quality) {
|
| 2422 |
+
if (quality >= 81) return 'legendary';
|
| 2423 |
+
if (quality >= 61) return 'way-better';
|
| 2424 |
+
if (quality >= 41) return 'even-better';
|
| 2425 |
+
if (quality >= 21) return 'better';
|
| 2426 |
+
return 'basic';
|
| 2427 |
+
}
|
| 2428 |
+
|
| 2429 |
+
function getQualityBadgeClass(quality) {
|
| 2430 |
+
if (quality >= 81) return 'quality-legendary';
|
| 2431 |
+
if (quality >= 61) return 'quality-way-better';
|
| 2432 |
+
if (quality >= 41) return 'quality-even-better';
|
| 2433 |
+
if (quality >= 21) return 'quality-better';
|
| 2434 |
+
return 'quality-basic';
|
| 2435 |
+
}
|
| 2436 |
+
|
| 2437 |
+
function getRarityClass(rarity) {
|
| 2438 |
+
const rarityLower = rarity.toLowerCase();
|
| 2439 |
+
if (rarityLower.includes('mythic')) return 'rarity-mythic';
|
| 2440 |
+
if (rarityLower.includes('legendary')) return 'rarity-legendary';
|
| 2441 |
+
if (rarityLower.includes('epic')) return 'rarity-epic';
|
| 2442 |
+
if (rarityLower.includes('rare')) return 'rarity-rare';
|
| 2443 |
+
if (rarityLower.includes('uncommon')) return 'rarity-uncommon';
|
| 2444 |
+
return 'rarity-common';
|
| 2445 |
+
}
|
| 2446 |
+
|
| 2447 |
+
function formatDate(dateString) {
|
| 2448 |
+
const date = new Date(dateString);
|
| 2449 |
+
return date.toLocaleDateString('en-US', {
|
| 2450 |
+
month: 'short',
|
| 2451 |
+
day: 'numeric',
|
| 2452 |
+
year: 'numeric'
|
| 2453 |
+
});
|
| 2454 |
+
}
|
| 2455 |
+
|
| 2456 |
+
function formatDateTime(dateString) {
|
| 2457 |
+
const date = new Date(dateString);
|
| 2458 |
+
return date.toLocaleString('en-US', {
|
| 2459 |
+
month: 'short',
|
| 2460 |
+
day: 'numeric',
|
| 2461 |
+
year: 'numeric',
|
| 2462 |
+
hour: '2-digit',
|
| 2463 |
+
minute: '2-digit'
|
| 2464 |
+
});
|
| 2465 |
+
}
|
| 2466 |
+
|
| 2467 |
+
function createNftCard(nft) {
|
| 2468 |
+
const qualityClass = getQualityClass(nft.nftquality);
|
| 2469 |
+
const qualityBadgeClass = getQualityBadgeClass(nft.nftquality);
|
| 2470 |
+
const rarityClass = getRarityClass(nft.rarity);
|
| 2471 |
+
const uniqueId = `details-${nft.nftid}`;
|
| 2472 |
+
|
| 2473 |
+
return `
|
| 2474 |
+
<div class="nft-card ${qualityClass}" style="animation: fadeInUp 0.6s ease forwards; opacity: 0;">
|
| 2475 |
+
<div class="quality-badge ${qualityBadgeClass}">${nft.nftquality}</div>
|
| 2476 |
+
<img src="${nft.nftimage}" alt="${nft.name}" class="nft-image" loading="lazy">
|
| 2477 |
+
<div class="nft-info">
|
| 2478 |
+
<div class="nft-header">
|
| 2479 |
+
<div class="nft-name" title="${nft.name}">${nft.name}</div>
|
| 2480 |
+
<div class="nft-id">#${nft.nftid}</div>
|
| 2481 |
+
</div>
|
| 2482 |
+
<div class="nft-rarity ${rarityClass}">${nft.rarity}</div>
|
| 2483 |
+
<button class="toggle-details" onclick="toggleDetails('${uniqueId}', this)">▼ Show Details</button>
|
| 2484 |
+
<div class="nft-details-wrapper" id="${uniqueId}" style="display: none;">
|
| 2485 |
+
<div class="nft-details">
|
| 2486 |
+
<div class="nft-detail">
|
| 2487 |
+
<span class="nft-detail-label">Quality</span>
|
| 2488 |
+
<span class="nft-detail-value">${nft.nftquality}/100</span>
|
| 2489 |
+
</div>
|
| 2490 |
+
<div class="nft-detail">
|
| 2491 |
+
<span class="nft-detail-label">Holders</span>
|
| 2492 |
+
<span class="nft-detail-value">${nft.holders}</span>
|
| 2493 |
+
</div>
|
| 2494 |
+
</div>
|
| 2495 |
+
<div class="nft-obtained">
|
| 2496 |
+
<span class="nft-obtained-label">Obtained On</span>
|
| 2497 |
+
<span class="nft-obtained-value">${formatDateTime(nft.gotten_on)}</span>
|
| 2498 |
+
</div>
|
| 2499 |
+
</div>
|
| 2500 |
+
</div>
|
| 2501 |
+
</div>
|
| 2502 |
+
`;
|
| 2503 |
+
}
|
| 2504 |
+
|
| 2505 |
+
// Show first 5 NFTs initially
|
| 2506 |
+
const initialNfts = sortedNfts.slice(0, 5);
|
| 2507 |
+
const remainingNfts = sortedNfts.slice(5);
|
| 2508 |
+
|
| 2509 |
+
nftsContainer.innerHTML = `
|
| 2510 |
+
<div class="nfts-grid">
|
| 2511 |
+
${initialNfts.map(nft => createNftCard(nft)).join('')}
|
| 2512 |
+
</div>
|
| 2513 |
+
`;
|
| 2514 |
+
|
| 2515 |
+
// Show "Show All" button if there are more NFTs
|
| 2516 |
+
if (remainingNfts.length > 0) {
|
| 2517 |
+
remainingCount.textContent = remainingNfts.length;
|
| 2518 |
+
showAllBtn.style.display = 'block';
|
| 2519 |
+
|
| 2520 |
+
let allShown = false;
|
| 2521 |
+
showAllBtn.addEventListener('click', () => {
|
| 2522 |
+
if (!allShown) {
|
| 2523 |
+
const nftsGrid = nftsContainer.querySelector('.nfts-grid');
|
| 2524 |
+
nftsGrid.innerHTML += remainingNfts.map(nft => createNftCard(nft)).join('');
|
| 2525 |
+
showAllBtn.textContent = 'Show Less';
|
| 2526 |
+
allShown = true;
|
| 2527 |
+
} else {
|
| 2528 |
+
const nftsGrid = nftsContainer.querySelector('.nfts-grid');
|
| 2529 |
+
nftsGrid.innerHTML = initialNfts.map(nft => createNftCard(nft)).join('');
|
| 2530 |
+
showAllBtn.innerHTML = `Show All NFTs (<span id="remainingCount">${remainingNfts.length}</span> more)`;
|
| 2531 |
+
allShown = false;
|
| 2532 |
+
}
|
| 2533 |
+
});
|
| 2534 |
+
}
|
| 2535 |
+
|
| 2536 |
+
setTimeout(() => {
|
| 2537 |
+
const nftCards = document.querySelectorAll('.nft-card');
|
| 2538 |
+
nftCards.forEach((card, index) => {
|
| 2539 |
+
setTimeout(() => {
|
| 2540 |
+
card.style.opacity = '1';
|
| 2541 |
+
}, index * 100);
|
| 2542 |
+
});
|
| 2543 |
+
}, 100);
|
| 2544 |
+
|
| 2545 |
+
document.getElementById('nftsSection').style.display = 'block';
|
| 2546 |
+
} else {
|
| 2547 |
+
// No NFTs found
|
| 2548 |
+
nftsContainer.innerHTML = `
|
| 2549 |
+
<div class="no-nfts">
|
| 2550 |
+
<div class="no-nfts-icon">🎨</div>
|
| 2551 |
+
<h4>No NFTs Found</h4>
|
| 2552 |
+
<p>This user hasn't collected any NFTs yet.</p>
|
| 2553 |
+
<p>Start your digital art journey today!</p>
|
| 2554 |
+
</div>
|
| 2555 |
+
`;
|
| 2556 |
+
document.getElementById('nftsSection').style.display = 'block';
|
| 2557 |
+
}
|
| 2558 |
+
} catch (err) {
|
| 2559 |
+
console.error('Error fetching NFTs:', err);
|
| 2560 |
+
const nftsContainer = document.getElementById('nftsContainer');
|
| 2561 |
+
nftsContainer.innerHTML = `
|
| 2562 |
+
<div class="no-nfts">
|
| 2563 |
+
<div class="no-nfts-icon">⚠️</div>
|
| 2564 |
+
<h4>Failed to Load NFTs</h4>
|
| 2565 |
+
<p>Unable to fetch NFT collection data.</p>
|
| 2566 |
+
<p>Please try again later.</p>
|
| 2567 |
+
</div>
|
| 2568 |
+
`;
|
| 2569 |
+
document.getElementById('nftsSection').style.display = 'block';
|
| 2570 |
+
}
|
| 2571 |
+
} catch (err) {
|
| 2572 |
+
console.error('Error fetching user data:', err);
|
| 2573 |
+
document.getElementById('chatId').innerHTML = '<div class="error">❌ Failed to load user info</div>';
|
| 2574 |
+
}
|
| 2575 |
});
|
| 2576 |
|
| 2577 |
function toggleDetails(id, button) {
|