This commit is contained in:
Flatlogic Bot 2025-11-15 09:26:39 +00:00
parent 98db9c4cf7
commit e44c880941
4 changed files with 173 additions and 4 deletions

68
api/ticker.php Normal file
View File

@ -0,0 +1,68 @@
<?php
header('Content-Type: application/json');
// --- Configuration ---
$symbol = 'BTCUSDT_SPBL'; // Bitget symbol for BTC/USDT spot market
$api_url = "https://api.bitget.com/api/v2/spot/market/tickers?symbol=" . $symbol;
// --- cURL Execution ---
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $api_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Accept: application/json'
],
// It's good practice to set a user-agent
CURLOPT_USERAGENT => 'FlatlogicMarketDetector/1.0'
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// --- Response Handling ---
if ($error) {
http_response_code(500);
echo json_encode(['error' => 'cURL Error: ' . $error]);
exit;
}
if ($http_code !== 200) {
http_response_code($http_code);
echo json_encode(['error' => 'Bitget API returned non-200 status', 'details' => json_decode($response)]);
exit;
}
$data = json_decode($response, true);
// --- Data Validation & Output ---
if (json_last_error() !== JSON_ERROR_NONE || empty($data['data'])) {
http_response_code(500);
echo json_encode(['error' => 'Failed to parse JSON response or data is empty']);
exit;
}
// Extract the first ticker object from the response data array
$ticker_data = $data['data'][0] ?? null;
if (!$ticker_data) {
http_response_code(404);
echo json_encode(['error' => 'Ticker data for symbol not found in API response']);
exit;
}
// --- Sanitize and Structure Output ---
// We select and sanitize the fields we want to send to the frontend.
$output = [
'exchange' => 'Bitget',
'symbol' => $ticker_data['symbol'] ?? 'N/A',
'price' => $ticker_data['lastPr'] ?? '0.00',
// Bitget provides the 24h change as a decimal, e.g., 0.025 for +2.5%
'change_24h_percent' => isset($ticker_data['priceChangePercent']) ? (float)$ticker_data['priceChangePercent'] * 100 : 0,
'signal' => '-' // Placeholder for future signal detection
];
echo json_encode($output);

View File

@ -1,4 +1,3 @@
/* Import Google Fonts */ /* Import Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
@ -45,3 +44,22 @@ body {
.badge { .badge {
font-weight: 600; font-weight: 600;
} }
/* Price flash animations */
@keyframes flash-success-anim {
from { background-color: rgba(25, 135, 84, 0.2); }
to { background-color: transparent; }
}
.flash-success {
animation: flash-success-anim 0.75s ease-out;
}
@keyframes flash-danger-anim {
from { background-color: rgba(220, 53, 69, 0.2); }
to { background-color: transparent; }
}
.flash-danger {
animation: flash-danger-anim 0.75s ease-out;
}

View File

@ -1,3 +1,68 @@
document.addEventListener('DOMContentLoaded', function () {
const POLLING_INTERVAL = 3000; // 3 seconds
// No custom JavaScript needed for the initial static dashboard. const liveRow = document.getElementById('live-crypto-row');
// This file is ready for future interactivity. if (!liveRow) {
console.error('Live crypto row with ID #live-crypto-row not found.');
return;
}
// Select cells to update
const priceCell = liveRow.querySelector('.price');
const changeCell = liveRow.querySelector('.change');
const symbolCell = liveRow.querySelector('.symbol');
const exchangeCell = liveRow.querySelector('.exchange');
let lastPrice = 0;
async function fetchLivePrice() {
try {
const response = await fetch('api/ticker.php');
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
if (data.error) {
throw new Error(`API Error: ${data.error}`);
}
updateRow(data);
} catch (error) {
console.error('Failed to fetch live price:', error);
// Optionally, display an error state in the UI
priceCell.textContent = 'Error';
changeCell.textContent = '--';
}
}
function updateRow(data) {
const currentPrice = parseFloat(data.price);
const priceChange = currentPrice - lastPrice;
// Update text content
priceCell.textContent = `$${currentPrice.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
symbolCell.textContent = data.symbol.replace('_SPBL', ''); // Clean up symbol name
exchangeCell.textContent = data.exchange;
// Update 24h change
const changePercent = parseFloat(data.change_24h_percent);
changeCell.textContent = `${changePercent.toFixed(2)}%`;
changeCell.classList.toggle('text-success', changePercent >= 0);
changeCell.classList.toggle('text-danger', changePercent < 0);
// Visual flash on price change
if (lastPrice !== 0 && priceChange !== 0) {
const flashClass = priceChange > 0 ? 'flash-success' : 'flash-danger';
priceCell.classList.add(flashClass);
setTimeout(() => priceCell.classList.remove(flashClass), 750);
}
lastPrice = currentPrice;
}
// Initial fetch and start polling
fetchLivePrice();
setInterval(fetchLivePrice, POLLING_INTERVAL);
});

View File

@ -54,9 +54,27 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<!-- Live Row (Updated by JavaScript) -->
<tr id="live-crypto-row">
<td class="fw-medium text-muted exchange">Bitget</td>
<td>
<div class="d-flex align-items-center">
<img src="https://via.placeholder.com/24/0d6efd/FFFFFF?Text=B" class="symbol-logo rounded-circle" alt="">
<span class="fw-bold symbol">BTC/USDT</span>
</div>
</td>
<td class="fw-bold fs-5 price">$0.00</td>
<td class="text-center">
<span class="fw-bold change">
--%
</span>
</td>
<td class="text-end signal">-</td>
</tr>
<?php <?php
// Static mock data for UI variety
$mock_data = [ $mock_data = [
['exchange' => 'KCEX', 'symbol' => 'BTC/USDT', 'price' => '68,123.45', 'change' => 2.5, 'signal' => null],
['exchange' => 'Bitget', 'symbol' => 'ETH/USDT', 'price' => '3,789.12', 'change' => -21.8, 'signal' => 'Crash Alert'], ['exchange' => 'Bitget', 'symbol' => 'ETH/USDT', 'price' => '3,789.12', 'change' => -21.8, 'signal' => 'Crash Alert'],
['exchange' => 'WEEX', 'symbol' => 'PEPE/USDT', 'price' => '0.00001234', 'change' => 255.1, 'signal' => 'Pump Alert'], ['exchange' => 'WEEX', 'symbol' => 'PEPE/USDT', 'price' => '0.00001234', 'change' => 255.1, 'signal' => 'Pump Alert'],
['exchange' => 'KuCoin', 'symbol' => 'SOL/USDT', 'price' => '165.80', 'change' => -1.2, 'signal' => 'Bearish Reversal'], ['exchange' => 'KuCoin', 'symbol' => 'SOL/USDT', 'price' => '165.80', 'change' => -1.2, 'signal' => 'Bearish Reversal'],