38301-vm/assets/js/main.js
2026-02-09 07:44:01 +00:00

233 lines
11 KiB
JavaScript

// Global variables
let currentMarketData = {};
function getLang() {
return document.documentElement.lang || 'en';
}
// Market Data Fetching
async function fetchMarketData() {
try {
const resp = await fetch('api/market_api.php');
const result = await resp.json();
if (result.success) {
currentMarketData = result.data;
updateUI();
}
} catch (e) {
console.error('Market API error', e);
}
}
function updateUI() {
// Update Home Page Market List
const homeList = document.getElementById('market-trends'); // Fixed ID mismatch
if (homeList) {
let html = '';
const symbols = ['BTC', 'ETH', 'BNB', 'SOL', 'XRP', 'DOGE', 'ADA', 'TRX'];
symbols.forEach(symbol => {
const coin = currentMarketData[symbol];
if (coin) {
const changeClass = coin.change >= 0 ? 'text-success' : 'text-danger';
const changeSign = coin.change >= 0 ? '+' : '';
const iconClass = coin.change >= 0 ? 'fa-arrow-trend-up' : 'fa-arrow-trend-down';
html += `
<tr onclick="window.location.href='trade.php?symbol=${symbol}'" style="cursor: pointer;">
<td class="ps-4 py-3 border-0">
<div class="d-flex align-items-center">
<img src="${coin.icon}" class="me-3" width="28" height="28">
<div>
<div class="fw-bold text-white" style="font-size: 0.9rem;">${symbol}</div>
<div class="text-muted small" style="font-size: 0.75rem;">${coin.name}</div>
</div>
</div>
</td>
<td class="py-3 border-0 text-white fw-bold" style="font-size: 0.9rem;">$${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}</td>
<td class="py-3 border-0 ${changeClass} fw-bold" style="font-size: 0.9rem;">
<i class="fas ${iconClass} me-1"></i>
${changeSign}${coin.change.toFixed(2)}%
</td>
<td class="pe-4 py-3 border-0 text-end">
<a href="trade.php?symbol=${symbol}" class="btn btn-sm btn-outline-primary rounded-pill px-3" style="font-size: 0.75rem;">Trade</a>
</td>
</tr>
`;
}
});
homeList.innerHTML = html;
}
// Update Hero Ticker if exists
const heroTicker = document.getElementById('hero-market-ticker');
if (heroTicker) {
let html = '';
const symbols = ['BTC', 'ETH', 'SOL', 'BNB'];
symbols.forEach(symbol => {
const coin = currentMarketData[symbol];
if (coin) {
const changeClass = coin.change >= 0 ? 'text-success' : 'text-danger';
html += `
<div class="market-card-mini p-3 rounded-4 bg-white bg-opacity-5 border border-white border-opacity-10" onclick="window.location.href='trade.php?symbol=${symbol}'" style="cursor: pointer; min-width: 140px;">
<div class="d-flex justify-content-between mb-2">
<span class="fw-bold text-white">${symbol}</span>
<span class="${changeClass} small">${coin.change >= 0 ? '+' : ''}${coin.change.toFixed(2)}%</span>
</div>
<div class="fw-bold text-white fs-5">$${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}</div>
</div>
`;
}
});
heroTicker.innerHTML = html;
}
// Update Ticker
const ticker = document.getElementById('ticker-wrap');
if (ticker) {
let html = '';
Object.keys(currentMarketData).forEach(symbol => {
const coin = currentMarketData[symbol];
const changeClass = coin.change >= 0 ? 'text-success' : 'text-danger';
html += `
<div class="d-flex align-items-center gap-2">
<span class="text-muted small fw-bold">${symbol}/USDT</span>
<span class="text-white fw-bold">${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}</span>
<span class="${changeClass} small">${coin.change >= 0 ? '+' : ''}${coin.change.toFixed(2)}%</span>
</div>
`;
});
ticker.innerHTML = html + html;
}
// Update Trade Page if on it
if (document.getElementById('crypto-list-container')) {
updateTradePage();
}
}
function updateTradePage() {
const listContainer = document.getElementById('crypto-list-container');
const search = document.getElementById('market-search')?.value.toLowerCase() || '';
const currentSymbol = document.getElementById('current-symbol')?.value;
let html = '';
Object.keys(currentMarketData).forEach(symbol => {
if (symbol.toLowerCase().includes(search) || currentMarketData[symbol].name.toLowerCase().includes(search)) {
const coin = currentMarketData[symbol];
const active = symbol === currentSymbol ? 'active' : '';
const changeClass = coin.change >= 0 ? 'text-success' : 'text-danger';
html += `
<div class="crypto-item ${active}" onclick="window.location.href='trade.php?symbol=${symbol}'">
<div class="d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center">
<img src="${coin.icon}" class="crypto-icon">
<div>
<div class="text-white crypto-name-text">${symbol}</div>
<div class="crypto-sub-text">${coin.name}</div>
</div>
</div>
<div class="text-end">
<div class="text-white crypto-price-text">$${coin.price.toLocaleString(undefined, {minimumFractionDigits: 2})}</div>
<div class="${changeClass} crypto-change-text">${coin.change >= 0 ? '+' : ''}${coin.change.toFixed(2)}%</div>
</div>
</div>
</div>
`;
}
});
listContainer.innerHTML = html;
// Update header info
if (currentSymbol && currentMarketData[currentSymbol]) {
const coin = currentMarketData[currentSymbol];
const lastPriceEl = document.getElementById('last-price');
if (lastPriceEl) {
const oldPrice = parseFloat(lastPriceEl.innerText.replace(/[$,]/g, '')) || 0;
lastPriceEl.innerText = '$' + coin.price.toLocaleString(undefined, {minimumFractionDigits: 2});
lastPriceEl.className = coin.price >= oldPrice ? 'fw-bold text-success fs-5' : 'fw-bold text-danger fs-5';
const bookPriceEl = document.getElementById('book-price');
if (bookPriceEl) bookPriceEl.innerText = coin.price.toLocaleString(undefined, {minimumFractionDigits: 2});
// If Market tab is active and price field is empty, update it
const marketTab = document.getElementById('tab-market');
if (marketTab && marketTab.classList.contains('active')) {
const priceInput = document.getElementById('order-price');
if (priceInput && !priceInput.value) {
priceInput.value = coin.price;
}
}
}
const changeEl = document.getElementById('24h-change');
if (changeEl) {
changeEl.innerText = (coin.change >= 0 ? '+' : '') + coin.change.toFixed(2) + '%';
changeEl.className = 'fw-bold ' + (coin.change >= 0 ? 'text-success' : 'text-danger');
}
if (document.getElementById('24h-high')) document.getElementById('24h-high').innerText = '$' + (coin.price * 1.05).toLocaleString(undefined, {minimumFractionDigits: 2});
if (document.getElementById('24h-low')) document.getElementById('24h-low').innerText = '$' + (coin.price * 0.95).toLocaleString(undefined, {minimumFractionDigits: 2});
if (document.getElementById('price-fiat')) {
const isZh = document.documentElement.lang === 'zh';
const rate = isZh ? 7.2 : 1.0;
const symbol = isZh ? '¥' : '$';
document.getElementById('price-fiat').innerText = '≈ ' + symbol + (coin.price * rate).toLocaleString(undefined, {minimumFractionDigits: 2});
}
}
simulateOrderBook();
}
function simulateOrderBook() {
const symbol = document.getElementById('current-symbol')?.value;
if (!symbol || !currentMarketData[symbol]) return;
const basePrice = currentMarketData[symbol].price;
const askContainer = document.getElementById('order-book-asks');
const bidContainer = document.getElementById('order-book-bids');
if (!askContainer || !bidContainer) return;
let askHtml = '';
let bidHtml = '';
for (let i = 5; i > 0; i--) {
const price = basePrice * (1 + (i * 0.0002));
const amount = Math.random() * 2 + 0.1;
const depth = Math.random() * 80 + 10;
askHtml += `
<div class="order-book-row ask" onclick="document.getElementById('order-price').value = ${price.toFixed(2)}">
<div class="depth-bg ask" style="width: ${depth}%"></div>
<span class="price">${price.toFixed(2)}</span>
<span class="amount">${amount.toFixed(4)}</span>
</div>
`;
}
for (let i = 1; i <= 5; i++) {
const price = basePrice * (1 - (i * 0.0002));
const amount = Math.random() * 2 + 0.1;
const depth = Math.random() * 80 + 10;
bidHtml += `
<div class="order-book-row bid" onclick="document.getElementById('order-price').value = ${price.toFixed(2)}">
<div class="depth-bg bid" style="width: ${depth}%"></div>
<span class="price">${price.toFixed(2)}</span>
<span class="amount">${amount.toFixed(4)}</span>
</div>
`;
}
askContainer.innerHTML = askHtml;
bidContainer.innerHTML = bidHtml;
}
// Initialization
document.addEventListener('DOMContentLoaded', () => {
fetchMarketData();
setInterval(fetchMarketData, 3000);
const searchInput = document.getElementById('market-search');
if (searchInput) {
searchInput.addEventListener('input', updateUI);
}
});