Auto commit: 2026-01-31T14:43:39.337Z

This commit is contained in:
Flatlogic Bot 2026-01-31 14:43:39 +00:00
parent a8024ec263
commit 0927396783
3 changed files with 271 additions and 45 deletions

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS songs (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
artist VARCHAR(255) NOT NULL,
is_active TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

260
index.php
View File

@ -26,11 +26,22 @@ $promoImage = "assets/pasted-20260130-234122-115a4b49.png";
$qrImage = "assets/pasted-20260131-000858-4fff58f0.jpg";
$logoImage = "assets/pasted-20260131-002028-7985dfae.png";
// Fetch latest requests
// Fetch latest requests and songs
$requests = [];
$songs = [];
try {
$stmt = db()->query("SELECT name, phone, message, created_at FROM listener_requests ORDER BY created_at DESC LIMIT 20");
$requests = $stmt->fetchAll();
$stmtSongs = db()->query("SELECT * FROM songs ORDER BY created_at DESC");
$songs = $stmtSongs->fetchAll();
$activeSong = null;
foreach ($songs as $s) {
if ($s["is_active"]) {
$activeSong = $s;
break;
}
}
} catch (Exception $e) {
// Silently fail if table doesn't exist yet or other DB error
}
@ -406,6 +417,75 @@ try {
.qr-container:hover {
transform: scale(1.1);
}
/* New styles for Song Management */
.nav-pills-glass .nav-link {
color: rgba(255,255,255,0.6);
border-radius: 15px;
padding: 0.5rem 1.5rem;
font-weight: 600;
transition: all 0.3s ease;
}
.nav-pills-glass .nav-link.active {
background: var(--primary-color);
color: #fff;
box-shadow: 0 5px 15px rgba(255, 45, 85, 0.4);
}
.song-item {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 20px;
padding: 1rem 1.5rem;
margin-bottom: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
transition: all 0.3s ease;
}
.song-item:hover {
background: rgba(255,255,255,0.1);
}
.song-active {
border-color: var(--primary-color);
background: rgba(255, 45, 85, 0.1);
}
.song-title-text {
font-weight: 700;
display: block;
}
.song-artist-text {
font-size: 0.8rem;
opacity: 0.6;
}
.btn-toggle-song {
background: rgba(255,255,255,0.1);
color: #fff;
border: none;
border-radius: 12px;
padding: 5px 15px;
font-size: 0.8rem;
font-weight: 600;
transition: all 0.3s ease;
}
.btn-toggle-song.active {
background: var(--primary-color);
}
.btn-delete-song {
background: rgba(255,0,0,0.1);
color: #ff4444;
border: none;
border-radius: 50%;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.btn-delete-song:hover {
background: #ff4444;
color: #fff;
}
</style>
</head>
<body>
@ -422,8 +502,8 @@ try {
</div>
<div class="song-info mb-4">
<span class="d-block fw-bold fs-5" id="songTitle">Conectando...</span>
<span class="d-block opacity-50 small" id="artistName">Lili Records Radio</span>
<span class="d-block fw-bold fs-5" id="songTitle"><?= ($activeSong ? htmlspecialchars($activeSong["title"]) : "Conectando...") ?></span>
<span class="d-block opacity-50 small" id="artistName"><?= ($activeSong ? htmlspecialchars($activeSong["artist"]) : "Lili Records Radio") ?></span>
</div>
<div class="player-controls-row d-flex align-items-center gap-3 justify-content-center">
@ -462,45 +542,117 @@ try {
<?php endif; ?>
</div>
<!-- Right: Image + Comments -->
<!-- Right: Image + Content -->
<div class="right-content">
<img src="<?= $promoImage ?>" alt="Lili Records Promo" class="promo-image">
<div class="comments-window">
<?php if ($isAdmin): ?>
<div class="comments-header">
<div>
<h5 class="mb-1"><i class="fas fa-comments me-2 text-primary"></i>Mensajes de Oyentes</h5>
<p class="small opacity-50 mb-0">Gestiona las peticiones en tiempo real</p>
</div>
<div class="text-center qr-container" style="width: 90px;" data-bs-toggle="modal" data-bs-target="#qrModal">
<img src="<?= $qrImage ?>" alt="QR Pago" class="w-100 rounded-3 mb-1">
<p class="small fw-bold mb-0">APOYAR</p>
</div>
</div>
<div class="comments-list" id="commentsList">
<?php if (empty($requests)): ?>
<div class="text-center py-5 opacity-30">
<i class="fas fa-comment-slash fa-4x mb-3"></i>
<p>No hay mensajes todavía.</p>
</div>
<?php else: ?>
<?php foreach ($requests as $req): ?>
<div class="comment-item">
<span class="comment-user"><?= htmlspecialchars($req['name']) ?></span>
<p class="mb-2"><?= htmlspecialchars($req['message']) ?></p>
<div class="d-flex justify-content-between align-items-center">
<span class="small opacity-40"><?= date('d M, H:i', strtotime($req['created_at'])) ?></span>
<?php if (!empty($req['phone'])): ?>
<a href="https://wa.me/<?= preg_replace('/[^0-9]/', '', $req['phone']) ?>" class="btn-wa-reply" target="_blank">
<i class="fab fa-whatsapp"></i>
</a>
<?php endif; ?>
</div>
<ul class="nav nav-pills nav-pills-glass mb-4 justify-content-center gap-2" id="adminTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="requests-tab" data-bs-toggle="pill" data-bs-target="#requests-pane" type="button" role="tab">
<i class="fas fa-comments me-2"></i>Mensajes
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="songs-tab" data-bs-toggle="pill" data-bs-target="#songs-pane" type="button" role="tab">
<i class="fas fa-music me-2"></i>Canciones
</button>
</li>
</ul>
<div class="tab-content flex-1 overflow-hidden d-flex flex-column">
<!-- Tab: Requests -->
<div class="tab-pane fade show active flex-1 overflow-hidden d-flex flex-column" id="requests-pane" role="tabpanel" tabindex="0">
<div class="comments-header border-0 mb-3">
<div>
<h5 class="mb-1">Mensajes de Oyentes</h5>
<p class="small opacity-50 mb-0">Peticiones en tiempo real</p>
</div>
<?php endforeach; ?>
<?php endif; ?>
<div class="text-center qr-container" style="width: 80px;" data-bs-toggle="modal" data-bs-target="#qrModal">
<img src="<?= $qrImage ?>" alt="QR Pago" class="w-100 rounded-3 mb-1">
<p class="small fw-bold mb-0">QR</p>
</div>
</div>
<div class="comments-list" id="commentsList">
<?php if (empty($requests)): ?>
<div class="text-center py-5 opacity-30">
<i class="fas fa-comment-slash fa-4x mb-3"></i>
<p>No hay mensajes todavía.</p>
</div>
<?php else: ?>
<?php foreach ($requests as $req): ?>
<div class="comment-item">
<span class="comment-user"><?= htmlspecialchars($req['name']) ?></span>
<p class="mb-2"><?= htmlspecialchars($req['message']) ?></p>
<div class="d-flex justify-content-between align-items-center">
<span class="small opacity-40"><?= date('d M, H:i', strtotime($req['created_at'])) ?></span>
<?php if (!empty($req['phone'])): ?>
<a href="https://wa.me/<?= preg_replace('/[^0-9]/', '', $req['phone']) ?>" class="btn-wa-reply" target="_blank">
<i class="fab fa-whatsapp"></i>
</a>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<!-- Tab: Songs -->
<div class="tab-pane fade flex-1 overflow-hidden d-flex flex-column" id="songs-pane" role="tabpanel" tabindex="0">
<div class="mb-4">
<form action="manage_songs.php" method="POST" class="row g-2">
<input type="hidden" name="action" value="add">
<div class="col-sm-5">
<input type="text" name="title" class="form-control form-control-glass" placeholder="Título canción" required>
</div>
<div class="col-sm-5">
<input type="text" name="artist" class="form-control form-control-glass" placeholder="Artista" required>
</div>
<div class="col-sm-2">
<button type="submit" class="btn btn-send-request text-white w-100 h-100">
<i class="fas fa-plus"></i>
</button>
</div>
</form>
</div>
<div class="comments-list">
<?php if (empty($songs)): ?>
<div class="text-center py-5 opacity-30">
<i class="fas fa-music fa-4x mb-3"></i>
<p>No hay canciones en la lista.</p>
</div>
<?php else: ?>
<?php foreach ($songs as $song): ?>
<div class="song-item <?= $song['is_active'] ? 'song-active' : '' ?>">
<div>
<span class="song-title-text"><?= htmlspecialchars($song['title']) ?></span>
<span class="song-artist-text"><?= htmlspecialchars($song['artist']) ?></span>
</div>
<div class="d-flex align-items-center gap-2">
<form action="manage_songs.php" method="POST" class="m-0">
<input type="hidden" name="action" value="toggle_active">
<input type="hidden" name="id" value="<?= $song['id'] ?>">
<button type="submit" class="btn-toggle-song <?= $song['is_active'] ? 'active' : '' ?>">
<?= $song['is_active'] ? 'ACTIVA' : 'ACTIVAR' ?>
</button>
</form>
<form action="manage_songs.php" method="POST" class="m-0" onsubmit="return confirm('¿Eliminar canción?')">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= $song['id'] ?>">
<button type="submit" class="btn-delete-song">
<i class="fas fa-trash-alt"></i>
</button>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<?php else: ?>
<div class="comments-header border-0 mb-3">
<div>
@ -514,10 +666,29 @@ try {
</div>
<div class="comments-list" style="max-height: 250px;">
<!-- User Song List Section (Optional view) -->
<?php if (!empty($songs)): ?>
<div class="mb-4">
<h6 class="small fw-bold text-uppercase opacity-50 mb-3">Lista de Canciones</h6>
<?php foreach (array_slice($songs, 0, 5) as $song): ?>
<div class="d-flex justify-content-between align-items-center py-2 px-3 mb-2 bg-white bg-opacity-5 rounded-4">
<div>
<span class="d-block small fw-bold"><?= htmlspecialchars($song['title']) ?></span>
<span class="d-block tiny opacity-50" style="font-size: 0.7rem;"><?= htmlspecialchars($song['artist']) ?></span>
</div>
<?php if ($song['is_active']): ?>
<span class="badge rounded-pill bg-primary" style="font-size: 0.6rem;">SONANDO</span>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<h6 class="small fw-bold text-uppercase opacity-50 mb-3">Últimos Mensajes</h6>
<?php if (empty($requests)): ?>
<p class="text-center py-4 opacity-40 italic"> el primero en escribir...</p>
<?php else: ?>
<?php foreach (array_slice($requests, 0, 8) as $req): ?>
<?php foreach (array_slice($requests, 0, 5) as $req): ?>
<div class="comment-item py-2 px-3 mb-2 border-0 bg-white bg-opacity-5 rounded-4">
<span class="comment-user small"><?= htmlspecialchars($req['name']) ?></span>
<p class="mb-0 small"><?= htmlspecialchars($req['message']) ?></p>
@ -611,6 +782,7 @@ try {
const artistName = document.getElementById('artistName');
const canvas = document.getElementById('visualizer');
const ctx = canvas.getContext('2d');
const hasActiveSong = <?= json_encode(!empty($activeSong)) ?>;
let isPlaying = false;
let audioContext;
@ -627,7 +799,7 @@ try {
source = audioContext.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioContext.destination);
analyser.fftSize = 64; // Fewer bars for a cleaner, modern look
analyser.fftSize = 64;
const bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
} catch (e) {
@ -646,26 +818,23 @@ try {
const width = canvas.width;
const height = canvas.height;
// We only use the first half of the frequency data because the high end is often empty
const barCount = dataArray.length / 1.2;
const barWidth = (width / barCount);
let x = 0;
for (let i = 0; i < barCount; i++) {
let barHeight = (dataArray[i] / 255) * height * 0.8;
if (barHeight < 5) barHeight = 5; // Minimum bar height for visibility
if (barHeight < 5) barHeight = 5;
// Create a vibrant gradient for each bar
const gradient = ctx.createLinearGradient(0, height - barHeight, 0, height);
gradient.addColorStop(0, '#ff2d55'); // Hot Pink
gradient.addColorStop(0.5, '#ff512f'); // Vibrant Orange-Red
gradient.addColorStop(0, '#ff2d55');
gradient.addColorStop(0.5, '#ff512f');
gradient.addColorStop(1, 'rgba(255, 45, 85, 0.2)');
ctx.fillStyle = gradient;
// Draw stylized bars with rounded tops
const bx = x + 2; // small padding
const bw = barWidth - 4; // bar thickness
const bx = x + 2;
const bw = barWidth - 4;
const bh = barHeight;
const by = height - bh;
const radius = bw / 2;
@ -708,6 +877,7 @@ try {
});
async function fetchMetadata() {
if (hasActiveSong) return; {
try {
const response = await fetch('https://api.radioking.io/widget/radio/lili-record-s-radio/track/current');
const data = await response.json();

49
manage_songs.php Normal file
View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
session_start();
if (empty($_SESSION['is_admin'])) {
header('Location: index.php');
exit;
}
$action = $_POST['action'] ?? '';
if ($action === 'add') {
$title = $_POST['title'] ?? '';
$artist = $_POST['artist'] ?? '';
if ($title && $artist) {
$stmt = db()->prepare("INSERT INTO songs (title, artist) VALUES (?, ?)");
$stmt->execute([$title, $artist]);
}
} elseif ($action === 'delete') {
$id = $_POST['id'] ?? '';
if ($id) {
$stmt = db()->prepare("DELETE FROM songs WHERE id = ?");
$stmt->execute([$id]);
}
} elseif ($action === 'toggle_active') {
$id = $_POST['id'] ?? '';
if ($id) {
// First, check the current status
$stmt = db()->prepare("SELECT is_active FROM songs WHERE id = ?");
$stmt->execute([$id]);
$current = $stmt->fetchColumn();
if ($current) {
// Deactivate it
$stmt = db()->prepare("UPDATE songs SET is_active = 0 WHERE id = ?");
$stmt->execute([$id]);
} else {
// Activate this one and deactivate ALL others
$stmt = db()->prepare("UPDATE songs SET is_active = 0");
$stmt->execute();
$stmt = db()->prepare("UPDATE songs SET is_active = 1 WHERE id = ?");
$stmt->execute([$id]);
}
}
}
header('Location: index.php?admin=lili');
exit;