Auto commit: 2026-02-16T22:52:33.215Z
This commit is contained in:
parent
1151eb2fd7
commit
e7beea1aa6
35
api/record_history.php
Normal file
35
api/record_history.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (!$input || empty($input['title']) || empty($input['artist'])) {
|
||||
echo json_encode(['success' => false, 'error' => 'Invalid input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$title = $input['title'];
|
||||
$artist = $input['artist'];
|
||||
$cover = $input['cover'] ?? null;
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Check if the last recorded song is the same to avoid duplicates on refresh
|
||||
$stmt = $db->prepare("SELECT title, artist FROM song_history ORDER BY played_at DESC LIMIT 1");
|
||||
$stmt->execute();
|
||||
$last = $stmt->fetch();
|
||||
|
||||
if ($last && $last['title'] === $title && $last['artist'] === $artist) {
|
||||
echo json_encode(['success' => true, 'message' => 'Already recorded']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO song_history (title, artist, cover) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$title, $artist, $cover]);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||
}
|
||||
7
db/migrations/001_create_song_history.sql
Normal file
7
db/migrations/001_create_song_history.sql
Normal file
@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS song_history (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
artist VARCHAR(255) NOT NULL,
|
||||
cover VARCHAR(500),
|
||||
played_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
263
history.php
Normal file
263
history.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Lili Records Radio - Historial de canciones.';
|
||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? 'assets/pasted-20260215-164611-6d2aee42.png';
|
||||
|
||||
$db = db();
|
||||
$stmt = $db->query("SELECT * FROM song_history WHERE played_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) ORDER BY played_at DESC LIMIT 50");
|
||||
$history = $stmt->fetchAll();
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Historial - Lili Records Radio</title>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--accent-color: #00c853;
|
||||
--primary-color: #38bdf8;
|
||||
--bg-overlay: rgba(0, 0, 0, 0.4);
|
||||
--glass-bg: rgba(255, 255, 255, 0.03);
|
||||
--glass-border: rgba(255, 255, 255, 0.2);
|
||||
--text-color: #ffffff;
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
--bg-overlay: rgba(255, 255, 255, 0.6);
|
||||
--glass-bg: rgba(255, 255, 255, 0.8);
|
||||
--glass-border: rgba(0, 0, 0, 0.1);
|
||||
--text-color: #1a1a1a;
|
||||
}
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: var(--text-color);
|
||||
background: #111;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url('assets/images/background.jpg') center/cover no-repeat;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.background::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--bg-overlay);
|
||||
}
|
||||
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
align-items: center;
|
||||
padding: 2rem 1.5rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 32px;
|
||||
padding: 2.5rem;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
box-shadow: 0 15px 45px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 800;
|
||||
margin: 0;
|
||||
background: linear-gradient(to right, #fff, var(--primary-color));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-weight: 600;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.history-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.history-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.history-item:hover {
|
||||
transform: translateX(10px);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.history-item img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.history-info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.history-title {
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.history-artist {
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.7;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.history-time {
|
||||
font-size: 0.7rem;
|
||||
opacity: 0.5;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
background: var(--glass-bg);
|
||||
border: 1px solid var(--glass-border);
|
||||
color: var(--text-color);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
backdrop-filter: blur(5px);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-theme="dark">
|
||||
<div class="background"></div>
|
||||
|
||||
<div class="app-container">
|
||||
<div class="glass-card">
|
||||
<div class="header">
|
||||
<a href="index.php" class="back-btn">
|
||||
<i class="bi bi-arrow-left"></i> VOLVER
|
||||
</a>
|
||||
<h1>HISTORIAL</h1>
|
||||
<button onclick="toggleTheme()" id="theme-toggle" class="theme-toggle">
|
||||
<i class="bi bi-moon-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="history-list">
|
||||
<?php if (empty($history)): ?>
|
||||
<div style="text-align: center; opacity: 0.5; padding: 2rem;">No hay canciones registradas en las últimas 24 horas.</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($history as $track): ?>
|
||||
<div class="history-item">
|
||||
<img src="<?= htmlspecialchars($track['cover'] ?: './assets/pasted-20260215-163754-def41f49.png') ?>" alt="Cover">
|
||||
<div class="history-info">
|
||||
<span class="history-title"><?= htmlspecialchars($track['title']) ?></span>
|
||||
<span class="history-artist"><?= htmlspecialchars($track['artist']) ?></span>
|
||||
</div>
|
||||
<div class="history-time">
|
||||
<?= date('H:i', strtotime($track['played_at'])) ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleTheme() {
|
||||
const body = document.body;
|
||||
const currentTheme = body.getAttribute('data-theme');
|
||||
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
||||
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
|
||||
|
||||
body.setAttribute('data-theme', newTheme);
|
||||
localStorage.setItem('theme', newTheme);
|
||||
|
||||
if (newTheme === 'light') {
|
||||
themeBtn.classList.remove('bi-moon-fill');
|
||||
themeBtn.classList.add('bi-sun-fill');
|
||||
} else {
|
||||
themeBtn.classList.remove('bi-sun-fill');
|
||||
themeBtn.classList.add('bi-moon-fill');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Theme
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('theme') || 'dark';
|
||||
if (savedTheme === 'light') {
|
||||
document.body.setAttribute('data-theme', 'light');
|
||||
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
|
||||
themeBtn.classList.remove('bi-moon-fill');
|
||||
themeBtn.classList.add('bi-sun-fill');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
71
index.php
71
index.php
@ -39,6 +39,16 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
--bg-overlay: rgba(0, 0, 0, 0.15); /* Even lighter for maximum transparency */
|
||||
--glass-bg: rgba(255, 255, 255, 0.03); /* Almost invisible glass */
|
||||
--glass-border: rgba(255, 255, 255, 0.2);
|
||||
--text-color: #ffffff;
|
||||
--card-shadow: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
--bg-overlay: rgba(255, 255, 255, 0.6);
|
||||
--glass-bg: rgba(255, 255, 255, 0.8);
|
||||
--glass-border: rgba(0, 0, 0, 0.1);
|
||||
--text-color: #1a1a1a;
|
||||
--card-shadow: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
body, html {
|
||||
@ -47,8 +57,9 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #ffffff;
|
||||
color: var(--text-color);
|
||||
background-color: transparent;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.background {
|
||||
@ -144,7 +155,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
font-size: 2.8rem;
|
||||
font-weight: 800;
|
||||
margin: 0 0 0.5rem;
|
||||
background: linear-gradient(to right, #fff, var(--primary-color), var(--accent-color));
|
||||
background: linear-gradient(to right, var(--text-color), var(--primary-color), var(--accent-color));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
letter-spacing: -1px;
|
||||
@ -248,7 +259,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color 0.05s ease, transform 0.05s ease, text-shadow 0.05s ease, opacity 0.5s ease;
|
||||
color: #ffffff;
|
||||
color: var(--text-color);
|
||||
text-shadow: 0 0 15px rgba(56, 189, 248, 0.6);
|
||||
display: block;
|
||||
margin-top: 0.2rem;
|
||||
@ -500,9 +511,9 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background-color: rgba(255, 255, 255, 0.05); /* Even more transparent */
|
||||
color: #ffffff;
|
||||
border: 1px solid var(--glass-border);
|
||||
background-color: var(--glass-bg);
|
||||
color: var(--text-color);
|
||||
font-family: inherit;
|
||||
font-size: 0.95rem;
|
||||
box-sizing: border-box;
|
||||
@ -518,7 +529,8 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
|
||||
.interaction-form input::placeholder,
|
||||
.interaction-form textarea::placeholder {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
color: var(--text-color);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.send-whatsapp-btn {
|
||||
@ -900,6 +912,14 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
<section class="player-section">
|
||||
<div class="glass-card">
|
||||
<header class="brand">
|
||||
<div style="position: absolute; top: 1rem; right: 1rem; display: flex; gap: 0.5rem; z-index: 100;">
|
||||
<button onclick="toggleTheme()" id="theme-toggle" style="background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-color); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; backdrop-filter: blur(5px); transition: all 0.3s;" title="Cambiar tema">
|
||||
<i class="bi bi-moon-fill"></i>
|
||||
</button>
|
||||
<a href="history.php" style="background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-color); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; backdrop-filter: blur(5px); transition: all 0.3s; text-decoration: none;" title="Historial de canciones">
|
||||
<i class="bi bi-clock-history"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="logo-wrapper">
|
||||
<img src="./assets/pasted-20260215-163754-def41f49.png" alt="Lili Records Logo" class="brand-logo">
|
||||
<img src="./assets/pasted-20260215-171328-d90df4ce.jpg" alt="Logo Secundario" class="brand-logo">
|
||||
@ -1929,6 +1949,13 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
if (coverPlaceholder) coverPlaceholder.style.display = 'none';
|
||||
trackCover.style.opacity = '1';
|
||||
|
||||
// Record History in Database
|
||||
fetch('api/record_history.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ title: title, artist: artist, cover: coverUrl })
|
||||
}).catch(err => console.error("Error recording history:", err));
|
||||
|
||||
// Dynamic Color Extraction
|
||||
trackCover.onload = function() {
|
||||
try {
|
||||
@ -2032,6 +2059,36 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
fetchTopSongs();
|
||||
}, 30000);
|
||||
|
||||
// Theme Toggle Functionality
|
||||
function toggleTheme() {
|
||||
const body = document.body;
|
||||
const currentTheme = body.getAttribute('data-theme');
|
||||
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
||||
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
|
||||
|
||||
body.setAttribute('data-theme', newTheme);
|
||||
localStorage.setItem('theme', newTheme);
|
||||
|
||||
if (newTheme === 'light') {
|
||||
themeBtn.classList.remove('bi-moon-fill');
|
||||
themeBtn.classList.add('bi-sun-fill');
|
||||
} else {
|
||||
themeBtn.classList.remove('bi-sun-fill');
|
||||
themeBtn.classList.add('bi-moon-fill');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Theme
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('theme') || 'dark';
|
||||
if (savedTheme === 'light') {
|
||||
document.body.setAttribute('data-theme', 'light');
|
||||
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
|
||||
themeBtn.classList.remove('bi-moon-fill');
|
||||
themeBtn.classList.add('bi-sun-fill');
|
||||
}
|
||||
})();
|
||||
|
||||
// Handle possible audio interruptions
|
||||
audio.addEventListener('error', function(e) {
|
||||
console.error('Audio error:', e);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user