Auto commit: 2026-02-17T18:45:07.833Z

This commit is contained in:
Flatlogic Bot 2026-02-17 18:45:07 +00:00
parent 55ebbe45e6
commit cc5bd4931c
3 changed files with 123 additions and 8 deletions

View File

@ -48,6 +48,30 @@ $locations = $stmt->fetchAll();
</div>
</div>
<!-- Now Playing Header -->
<div class="row mb-4">
<div class="col-md-12">
<div class="card p-3 border-success" style="background: rgba(0, 230, 118, 0.05);">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<div class="position-relative me-3">
<img id="admin-track-cover" src="./assets/pasted-20260215-163754-def41f49.png" style="width: 60px; height: 60px; border-radius: 10px; object-fit: cover; border: 2px solid #00e676;">
<span class="position-absolute bottom-0 end-0 p-1 bg-success border border-light rounded-circle" style="width: 12px; height: 12px;"></span>
</div>
<div>
<span class="text-success fw-bold x-small" style="font-size: 0.7rem; letter-spacing: 1px;">SONANDO AHORA:</span>
<h4 id="admin-track-title" class="mb-0">Lili Records Radio</h4>
<p id="admin-track-artist" class="text-secondary mb-0">En vivo desde el estudio</p>
</div>
</div>
<div class="text-end">
<span id="admin-track-timer" class="badge bg-dark border border-secondary">00:00</span>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="card p-4 text-center">
@ -159,20 +183,47 @@ $locations = $stmt->fetchAll();
</div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>
<script>
const map = L.map('map').setView([20, 0], 2);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '&copy; OpenStreetMap contributors'
}).addTo(map);
const locations = <?= json_encode($locations) ?>;
locations.forEach(loc => {
if (loc.lat && loc.lon) {
L.marker([loc.lat, loc.lon])
.addTo(map)
.bindPopup(`<b>${loc.country}</b><br>${loc.count} usuario(s)`);
let heatmapLayer;
let markersGroup = L.layerGroup().addTo(map);
function updateMap(locations) {
markersGroup.clearLayers();
const heatData = [];
locations.forEach(loc => {
if (loc.lat && loc.lon) {
// Add marker
L.marker([loc.lat, loc.lon])
.addTo(markersGroup)
.bindPopup(`<b>${loc.country}</b><br>${loc.count} usuario(s)`);
// Add to heatmap data (lat, lon, intensity)
// We use the count as intensity, but capped/scaled for better visualization
heatData.push([loc.lat, loc.lon, Math.min(loc.count * 0.5, 1)]);
}
});
if (heatmapLayer) {
map.removeLayer(heatmapLayer);
}
});
heatmapLayer = L.heatLayer(heatData, {
radius: 25,
blur: 15,
maxZoom: 10,
gradient: {0.4: 'blue', 0.6: 'cyan', 0.7: 'lime', 0.8: 'yellow', 1: 'red'}
}).addTo(map);
}
// Initial map data
updateMap(<?= json_encode($locations) ?>);
let volumeChart;
function initChart() {
@ -292,6 +343,10 @@ $locations = $stmt->fetchAll();
volumeChart.data.datasets[0].data = hourlyData;
volumeChart.update();
}
if (data.locations) {
updateMap(data.locations);
}
}
} catch (error) {
console.error('Error fetching stats:', error);
@ -321,11 +376,40 @@ $locations = $stmt->fetchAll();
}
}
async function updateNowPlaying() {
try {
const response = await fetch('https://www.radioking.com/widgets/api/v1/radio/828046/track/current');
const data = await response.json();
if (data && data.title) {
document.getElementById('admin-track-title').textContent = data.title;
document.getElementById('admin-track-artist').textContent = data.artist || 'Lili Records';
if (data.cover) {
document.getElementById('admin-track-cover').src = data.cover;
}
if (data.started_at && data.end_at) {
const start = new Date(data.started_at).getTime();
const end = new Date(data.end_at).getTime();
const duration = end - start;
const now = new Date().getTime();
const elapsed = Math.max(0, now - start);
const m = Math.floor(elapsed / 60000);
const s = Math.floor((elapsed % 60000) / 1000);
document.getElementById('admin-track-timer').textContent = `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}
}
} catch (error) {
console.error('Error fetching now playing:', error);
}
}
fetchRequests();
fetchStats();
updateNowPlaying();
setInterval(() => {
fetchRequests();
fetchStats();
updateNowPlaying();
}, 15000);
</script>
</body>

View File

@ -69,11 +69,16 @@ if ($method === 'GET') {
$stmt = $db->query("SELECT HOUR(created_at) as hour, COUNT(*) as count FROM song_requests WHERE created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY hour ORDER BY hour ASC");
$volume_stats = $stmt->fetchAll();
// Visitor locations (last 10 minutes)
$stmt = $db->query("SELECT country, country_code, lat, lon, COUNT(*) as count FROM visitor_logs WHERE last_activity > DATE_SUB(NOW(), INTERVAL 10 MINUTE) GROUP BY country_code");
$locations = $stmt->fetchAll();
echo json_encode([
'success' => true,
'top_artists' => $top_artists,
'top_songs' => $top_songs,
'volume_stats' => $volume_stats
'volume_stats' => $volume_stats,
'locations' => $locations
]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);

View File

@ -1024,6 +1024,22 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
<body>
<div class="background"></div>
<!-- Sticky Top Marquee -->
<div id="sticky-now-playing" style="position: fixed; top: 0; left: 0; width: 100%; background: rgba(15, 23, 42, 0.85); backdrop-filter: blur(10px); z-index: 1000; padding: 10px 0; border-bottom: 1px solid rgba(56, 189, 248, 0.3); display: none; animation: slideDown 0.5s ease;">
<div style="max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: center; gap: 15px; padding: 0 20px;">
<div style="width: 40px; height: 40px; border-radius: 8px; overflow: hidden; flex-shrink: 0; border: 1px solid var(--primary-color);">
<img id="sticky-track-cover" src="./assets/pasted-20260215-163754-def41f49.png" style="width: 100%; height: 100%; object-fit: cover;">
</div>
<div style="overflow: hidden; white-space: nowrap; flex: 1; text-align: center;">
<span style="color: var(--primary-color); font-weight: 800; font-size: 0.75rem; text-transform: uppercase; margin-right: 10px;">SONANDO:</span>
<span id="sticky-track-info" style="font-weight: 700; font-size: 0.9rem; color: #fff;">Lili Records Radio</span>
</div>
</div>
</div>
<style>
@keyframes slideDown { from { transform: translateY(-100%); } to { transform: translateY(0); } }
</style>
<div class="app-container">
<!-- Left Section: Player -->
<section class="player-section">
@ -2394,6 +2410,16 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
trackTitle.classList.add('scrolling');
trackTitle.innerHTML = `<span>${title} &nbsp;&nbsp;&nbsp;&nbsp; ${title} &nbsp;&nbsp;&nbsp;&nbsp;</span>`;
}
// Update Sticky Bar
const stickyBar = document.getElementById('sticky-now-playing');
const stickyCover = document.getElementById('sticky-track-cover');
const stickyInfo = document.getElementById('sticky-track-info');
if (stickyBar && stickyCover && stickyInfo) {
stickyCover.src = coverUrl;
stickyInfo.textContent = `${artist} - ${title}`;
stickyBar.style.display = 'block';
}
}, 500);
}