Auto commit: 2026-02-18T23:08:21.896Z
This commit is contained in:
parent
9778f4d4ad
commit
c09fce8f06
155
admin.php
155
admin.php
@ -20,6 +20,18 @@ $active_phones = $stmt->fetchAll();
|
|||||||
$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");
|
$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();
|
$locations = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Get announcement history
|
||||||
|
$stmt = $db->query("SELECT * FROM announcements_history ORDER BY created_at DESC LIMIT 10");
|
||||||
|
$announcements = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Get announcement stats
|
||||||
|
$stmt = $db->query("SELECT COUNT(*) FROM announcements_history WHERE created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)");
|
||||||
|
$announcements_24h = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
// Get today's requests
|
||||||
|
$stmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE DATE(created_at) = CURDATE()");
|
||||||
|
$requests_today = $stmt->fetchColumn();
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
@ -64,7 +76,11 @@ $locations = $stmt->fetchAll();
|
|||||||
<p id="admin-track-artist" class="text-secondary mb-0">En vivo desde el estudio</p>
|
<p id="admin-track-artist" class="text-secondary mb-0">En vivo desde el estudio</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="text-end d-flex align-items-center gap-2">
|
||||||
|
<button class="btn btn-success btn-sm d-flex align-items-center gap-2" onclick="announceOnAir()" style="transition: all 0.3s; box-shadow: 0 0 10px rgba(0, 230, 118, 0.3);">
|
||||||
|
<i class="bi bi-whatsapp"></i> <span>ANUNCIAR AL AIRE</span>
|
||||||
|
<span class="spinner-grow spinner-grow-sm text-white" role="status" style="width: 8px; height: 8px;"></span>
|
||||||
|
</button>
|
||||||
<span id="admin-track-timer" class="badge bg-dark border border-secondary">00:00</span>
|
<span id="admin-track-timer" class="badge bg-dark border border-secondary">00:00</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -80,6 +96,18 @@ $locations = $stmt->fetchAll();
|
|||||||
<p class="text-secondary">En los últimos 10 minutos</p>
|
<p class="text-secondary">En los últimos 10 minutos</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card p-4 text-center mt-4 border-success" style="background: rgba(0, 230, 118, 0.05);">
|
||||||
|
<h5>Anuncios (24h)</h5>
|
||||||
|
<div id="announcements-24h-count" class="stat-value" style="color: #00e676;"><?= $announcements_24h ?></div>
|
||||||
|
<p class="text-secondary">Compartidos por WhatsApp</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card p-4 text-center mt-4 border-primary" style="background: rgba(13, 110, 253, 0.05);">
|
||||||
|
<h5>Peticiones Hoy</h5>
|
||||||
|
<div id="requests-today-count" class="stat-value" style="color: #0d6efd;"><?= $requests_today ?></div>
|
||||||
|
<p class="text-secondary">Canciones solicitadas</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card p-4 mt-4">
|
<div class="card p-4 mt-4">
|
||||||
<h5>Móviles Conectados</h5>
|
<h5>Móviles Conectados</h5>
|
||||||
<ul class="list-group list-group-flush bg-transparent">
|
<ul class="list-group list-group-flush bg-transparent">
|
||||||
@ -121,6 +149,43 @@ $locations = $stmt->fetchAll();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mt-4">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card p-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h5><i class="bi bi-history text-success"></i> Historial de Anuncios Recientes</h5>
|
||||||
|
<button class="btn btn-sm btn-outline-success" onclick="fetchAnnouncements()">Actualizar Historial</button>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-dark table-hover align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Fecha y Hora</th>
|
||||||
|
<th>Canción Anunciada</th>
|
||||||
|
<th>Plataforma</th>
|
||||||
|
<th>Anunciante</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="announcements-body">
|
||||||
|
<?php if (empty($announcements)): ?>
|
||||||
|
<tr><td colspan="4" class="text-center text-secondary">No hay anuncios registrados</td></tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($announcements as $ann): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= date('d/m/Y H:i', strtotime($ann['created_at'])) ?></td>
|
||||||
|
<td><span class="text-success fw-bold"><?= htmlspecialchars($ann['song_name']) ?></span></td>
|
||||||
|
<td><span class="badge bg-success"><i class="bi bi-whatsapp"></i> WhatsApp</span></td>
|
||||||
|
<td><?= htmlspecialchars($ann['announcer_name']) ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card p-4 h-100">
|
<div class="card p-4 h-100">
|
||||||
@ -274,7 +339,32 @@ $locations = $stmt->fetchAll();
|
|||||||
initChart();
|
initChart();
|
||||||
|
|
||||||
async function fetchRequests() {
|
async function fetchRequests() {
|
||||||
// ... (keeping existing logic)
|
try {
|
||||||
|
const response = await fetch('api/song_requests.php?status=pending');
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.success) {
|
||||||
|
const tbody = document.getElementById('requests-body');
|
||||||
|
if (data.requests.length === 0) {
|
||||||
|
tbody.innerHTML = '<tr><td colspan="6" class="text-center text-secondary">No hay peticiones pendientes</td></tr>';
|
||||||
|
} else {
|
||||||
|
tbody.innerHTML = data.requests.map(req => `
|
||||||
|
<tr>
|
||||||
|
<td>${req.artist}</td>
|
||||||
|
<td>${req.song}</td>
|
||||||
|
<td>${req.requester}</td>
|
||||||
|
<td>${new Date(req.created_at).toLocaleString()}</td>
|
||||||
|
<td><span class="badge bg-warning text-dark">${req.status}</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-success" onclick="updateStatus(${req.id}, 'mark_played')">Sonar</button>
|
||||||
|
<button class="btn btn-sm btn-danger" onclick="updateStatus(${req.id}, 'delete')">Eliminar</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`).join('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching requests:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchChatImages() {
|
async function fetchChatImages() {
|
||||||
@ -384,6 +474,11 @@ $locations = $stmt->fetchAll();
|
|||||||
if (data.locations) {
|
if (data.locations) {
|
||||||
updateMap(data.locations);
|
updateMap(data.locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.requests_today !== undefined) {
|
||||||
|
const reqCounter = document.getElementById('requests-today-count');
|
||||||
|
if (reqCounter) reqCounter.innerText = data.requests_today;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching stats:', error);
|
console.error('Error fetching stats:', error);
|
||||||
@ -413,6 +508,60 @@ $locations = $stmt->fetchAll();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function announceOnAir() {
|
||||||
|
const title = document.getElementById('admin-track-title').innerText.trim();
|
||||||
|
const artist = document.getElementById('admin-track-artist').innerText.trim();
|
||||||
|
const currentSong = artist !== 'Lili Records' ? `${artist} - ${title}` : title;
|
||||||
|
const shareUrl = window.location.origin; // Link to the main radio page
|
||||||
|
const text = `🔴 *¡ESTAMOS AL AIRE!* 🎙️📻\n\nSintoniza ahora *Lili Records Radio* para escuchar la mejor música en vivo.\n\n🎵 *Sonando:* ${currentSong}\n\n👉 *Escúchanos aquí:* ${shareUrl}\n\n¡Te esperamos! 💃🕺\n\n#LiliRecords #RadioEnVivo #LaQueTeGusta`;
|
||||||
|
|
||||||
|
// Log the announcement
|
||||||
|
try {
|
||||||
|
await fetch('api/log_announcement.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ song_name: currentSong })
|
||||||
|
});
|
||||||
|
fetchAnnouncements();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error logging announcement:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `https://wa.me/?text=${encodeURIComponent(text)}`;
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchAnnouncements() {
|
||||||
|
try {
|
||||||
|
// Since we don't have a dedicated API for fetching history yet, we'll reload the relevant part or create one.
|
||||||
|
// For simplicity and following the project style, I'll create api/get_announcements.php
|
||||||
|
const response = await fetch('api/get_announcements.php');
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.success) {
|
||||||
|
const tbody = document.getElementById('announcements-body');
|
||||||
|
if (data.announcements.length === 0) {
|
||||||
|
tbody.innerHTML = '<tr><td colspan="4" class="text-center text-secondary">No hay anuncios registrados</td></tr>';
|
||||||
|
} else {
|
||||||
|
tbody.innerHTML = data.announcements.map(ann => `
|
||||||
|
<tr>
|
||||||
|
<td>${new Date(ann.created_at).toLocaleString()}</td>
|
||||||
|
<td><span class="text-success fw-bold">${ann.song_name}</span></td>
|
||||||
|
<td><span class="badge bg-success"><i class="bi bi-whatsapp"></i> WhatsApp</span></td>
|
||||||
|
<td>${ann.announcer_name}</td>
|
||||||
|
</tr>
|
||||||
|
`).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.count_24h !== undefined) {
|
||||||
|
const counter = document.getElementById('announcements-24h-count');
|
||||||
|
if (counter) counter.innerText = data.count_24h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching announcements:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function updateNowPlaying() {
|
async function updateNowPlaying() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('https://www.radioking.com/widgets/api/v1/radio/828046/track/current');
|
const response = await fetch('https://www.radioking.com/widgets/api/v1/radio/828046/track/current');
|
||||||
@ -443,10 +592,12 @@ $locations = $stmt->fetchAll();
|
|||||||
fetchRequests();
|
fetchRequests();
|
||||||
fetchStats();
|
fetchStats();
|
||||||
updateNowPlaying();
|
updateNowPlaying();
|
||||||
|
fetchAnnouncements();
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
fetchRequests();
|
fetchRequests();
|
||||||
fetchStats();
|
fetchStats();
|
||||||
updateNowPlaying();
|
updateNowPlaying();
|
||||||
|
fetchAnnouncements();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
16
api/get_announcements.php
Normal file
16
api/get_announcements.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->query("SELECT * FROM announcements_history ORDER BY created_at DESC LIMIT 10");
|
||||||
|
$announcements = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$stmt = $db->query("SELECT COUNT(*) FROM announcements_history WHERE created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)");
|
||||||
|
$count_24h = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'announcements' => $announcements, 'count_24h' => $count_24h]);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
20
api/log_announcement.php
Normal file
20
api/log_announcement.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
$data = json_decode(file_get_contents('php://input'), true);
|
||||||
|
|
||||||
|
if (!$data || !isset($data['song_name'])) {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Datos incompletos']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = db();
|
||||||
|
$stmt = $db->prepare("INSERT INTO announcements_history (song_name) VALUES (?)");
|
||||||
|
$stmt->execute([$data['song_name']]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@ -88,12 +88,17 @@ if ($method === 'GET') {
|
|||||||
$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");
|
$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();
|
$locations = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Total requests today
|
||||||
|
$stmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE DATE(created_at) = CURDATE()");
|
||||||
|
$requests_today = $stmt->fetchColumn();
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'top_artists' => $top_artists,
|
'top_artists' => $top_artists,
|
||||||
'top_songs' => $top_songs,
|
'top_songs' => $top_songs,
|
||||||
'volume_stats' => $volume_stats,
|
'volume_stats' => $volume_stats,
|
||||||
'locations' => $locations
|
'locations' => $locations,
|
||||||
|
'requests_today' => $requests_today
|
||||||
]);
|
]);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||||
|
|||||||
7
db/migrations/20260218_create_announcements_history.sql
Normal file
7
db/migrations/20260218_create_announcements_history.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS announcements_history (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
song_name VARCHAR(255) NOT NULL,
|
||||||
|
announcer_name VARCHAR(100) DEFAULT 'Admin',
|
||||||
|
platform VARCHAR(50) DEFAULT 'WhatsApp',
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
Loading…
x
Reference in New Issue
Block a user