Autosave: 20260215-185011
This commit is contained in:
parent
f86c3be51e
commit
af52e13f7c
@ -7,7 +7,7 @@ $method = $_SERVER['REQUEST_METHOD'];
|
|||||||
|
|
||||||
if ($method === 'GET') {
|
if ($method === 'GET') {
|
||||||
try {
|
try {
|
||||||
$stmt = db()->prepare("SELECT * FROM messages ORDER BY created_at DESC LIMIT 50");
|
$stmt = db()->prepare("SELECT m.*, ul.custom_color FROM messages m LEFT JOIN user_likes ul ON m.username = ul.username ORDER BY m.created_at DESC LIMIT 50");
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
echo json_encode(array_reverse($messages));
|
echo json_encode(array_reverse($messages));
|
||||||
|
|||||||
@ -5,7 +5,7 @@ header('Content-Type: application/json');
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$stmt = $pdo->query("SELECT username, total_likes FROM user_likes ORDER BY total_likes DESC LIMIT 5");
|
$stmt = $pdo->query("SELECT username, total_likes, custom_color FROM user_likes ORDER BY total_likes DESC LIMIT 5");
|
||||||
$fans = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$fans = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
echo json_encode(['success' => true, 'fans' => $fans]);
|
echo json_encode(['success' => true, 'fans' => $fans]);
|
||||||
|
|||||||
33
api/update_fan_color.php
Normal file
33
api/update_fan_color.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/../db/config.php";
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
|
||||||
|
echo json_encode(["success" => false, "error" => "Method not allowed"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = json_decode(file_get_contents("php://input"), true);
|
||||||
|
$userName = $input["username"] ?? "";
|
||||||
|
$color = $input["color"] ?? "";
|
||||||
|
|
||||||
|
if (empty($userName) || !preg_match("/^#[a-fA-F0-9]{6}$/", $color)) {
|
||||||
|
echo json_encode(["success" => false, "error" => "Invalid input"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = db();
|
||||||
|
// We only allow top 3 fans to change color, but we'll enforce that in the UI.
|
||||||
|
// Here we just update it if they exist in user_likes.
|
||||||
|
$stmt = $pdo->prepare("UPDATE user_likes SET custom_color = ? WHERE username = ?");
|
||||||
|
$stmt->execute([$color, $userName]);
|
||||||
|
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
echo json_encode(["success" => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode(["success" => false, "error" => "User not found or color already set"]);
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode(["success" => false, "error" => $e->getMessage()]);
|
||||||
|
}
|
||||||
83
index.php
83
index.php
@ -588,6 +588,32 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
.fan-2 { color: #cbd5e1 !important; font-weight: 700 !important; }
|
.fan-2 { color: #cbd5e1 !important; font-weight: 700 !important; }
|
||||||
.fan-3 { color: #fb923c !important; font-weight: 700 !important; }
|
.fan-3 { color: #fb923c !important; font-weight: 700 !important; }
|
||||||
|
|
||||||
|
.vip-badge {
|
||||||
|
background: linear-gradient(45deg, #facc15, #fbbf24);
|
||||||
|
color: #000;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 800;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-left: 5px;
|
||||||
|
box-shadow: 0 0 10px rgba(250, 204, 21, 0.5);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-picker-container {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: none; /* Hidden by default */
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
border: 1px solid rgba(250, 204, 21, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes fan-entry {
|
@keyframes fan-entry {
|
||||||
0% { transform: scale(0.8); opacity: 0; }
|
0% { transform: scale(0.8); opacity: 0; }
|
||||||
50% { transform: scale(1.1); }
|
50% { transform: scale(1.1); }
|
||||||
@ -743,6 +769,13 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: #facc15;">
|
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: #facc15;">
|
||||||
<i class="bi bi-trophy-fill"></i> TOP FANS
|
<i class="bi bi-trophy-fill"></i> TOP FANS
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
<div id="fan-customization" class="color-picker-container">
|
||||||
|
<span style="font-size: 0.8rem; font-weight: bold; color: #facc15;">🎨 COLOR VIP:</span>
|
||||||
|
<input type="color" id="vip-color-input" onchange="updateCustomColor(this.value)" style="border: none; background: none; cursor: pointer; width: 30px; height: 30px; padding: 0;">
|
||||||
|
<span style="font-size: 0.7rem; opacity: 0.8;">Elige tu color personalizado</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="top-fans-list" style="flex: 1; display: flex; flex-direction: column; gap: 1rem;">
|
<div id="top-fans-list" style="flex: 1; display: flex; flex-direction: column; gap: 1rem;">
|
||||||
<!-- Fans se cargarán aquí -->
|
<!-- Fans se cargarán aquí -->
|
||||||
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Calculando ranking...</div>
|
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Calculando ranking...</div>
|
||||||
@ -976,11 +1009,13 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
const response = await fetch('api/get_top_fans.php');
|
const response = await fetch('api/get_top_fans.php');
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
topFans = data.fans.map(f => f.username);
|
topFans = data.fans;
|
||||||
const list = document.getElementById('top-fans-list');
|
const list = document.getElementById('top-fans-list');
|
||||||
list.innerHTML = '';
|
list.innerHTML = '';
|
||||||
|
|
||||||
const currentUserName = document.getElementById('user-name').value.trim();
|
const currentUserName = document.getElementById('user-name').value.trim();
|
||||||
|
const customizationBox = document.getElementById('fan-customization');
|
||||||
|
let isTop3 = false;
|
||||||
|
|
||||||
data.fans.forEach((fan, index) => {
|
data.fans.forEach((fan, index) => {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
@ -988,6 +1023,14 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
const scale = index === 0 ? '1.1' : '1';
|
const scale = index === 0 ? '1.1' : '1';
|
||||||
const opacity = 1 - (index * 0.1);
|
const opacity = 1 - (index * 0.1);
|
||||||
|
|
||||||
|
// Check if current user is in Top 3
|
||||||
|
if (index < 3 && fan.username === currentUserName && currentUserName !== "") {
|
||||||
|
isTop3 = true;
|
||||||
|
if (fan.custom_color) {
|
||||||
|
document.getElementById('vip-color-input').value = fan.custom_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Welcome sound for #1 fan
|
// Welcome sound for #1 fan
|
||||||
if (index === 0 && fan.username === currentUserName && !welcomeSoundPlayed && currentUserName !== "") {
|
if (index === 0 && fan.username === currentUserName && !welcomeSoundPlayed && currentUserName !== "") {
|
||||||
document.getElementById('welcome-sound').play().catch(e => console.log("Audio play blocked"));
|
document.getElementById('welcome-sound').play().catch(e => console.log("Audio play blocked"));
|
||||||
@ -1005,21 +1048,46 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
div.style.border = index === 0 ? '1px solid #facc15' : '1px solid transparent';
|
div.style.border = index === 0 ? '1px solid #facc15' : '1px solid transparent';
|
||||||
div.style.animation = fan.username === currentUserName ? 'fan-entry 0.5s ease-out' : 'none';
|
div.style.animation = fan.username === currentUserName ? 'fan-entry 0.5s ease-out' : 'none';
|
||||||
|
|
||||||
|
const vipBadge = index === 0 ? '<span class="vip-badge">VIP</span>' : '';
|
||||||
|
const customColorStyle = fan.custom_color ? `color: ${fan.custom_color} !important;` : '';
|
||||||
|
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div style="font-size: 1.5rem;">${medal}</div>
|
<div style="font-size: 1.5rem;">${medal}</div>
|
||||||
<div style="flex: 1;">
|
<div style="flex: 1;">
|
||||||
<div style="font-weight: 700; font-size: 0.9rem; color: ${index === 0 ? '#facc15' : 'white'}">${fan.username}</div>
|
<div style="font-weight: 700; font-size: 0.9rem; ${customColorStyle || (index === 0 ? 'color: #facc15' : 'white')}">${fan.username}${vipBadge}</div>
|
||||||
<div style="font-size: 0.75rem; opacity: 0.6;">${fan.total_likes} Corazones repartidos</div>
|
<div style="font-size: 0.75rem; opacity: 0.6;">${fan.total_likes} Corazones repartidos</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
list.appendChild(div);
|
list.appendChild(div);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
customizationBox.style.display = isTop3 ? 'flex' : 'none';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ranking error:', error);
|
console.error('Ranking error:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateCustomColor(color) {
|
||||||
|
const userName = document.getElementById('user-name').value.trim();
|
||||||
|
if (!userName) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('api/update_fan_color.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ username: userName, color: color })
|
||||||
|
});
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success) {
|
||||||
|
fetchTopFans();
|
||||||
|
fetchMessages();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error updating color:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchMessages() {
|
async function fetchMessages() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('api/chat.php');
|
const response = await fetch('api/chat.php');
|
||||||
@ -1031,21 +1099,24 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
const isLike = msg.message.includes('❤️');
|
const isLike = msg.message.includes('❤️');
|
||||||
|
|
||||||
// Determine fan class
|
// Determine fan class and VIP status
|
||||||
let fanClass = '';
|
let fanClass = '';
|
||||||
const fanIndex = topFans.indexOf(msg.username);
|
const fanIndex = topFans.findIndex(f => f.username === msg.username);
|
||||||
if (fanIndex === 0) fanClass = 'fan-1';
|
if (fanIndex === 0) fanClass = 'fan-1';
|
||||||
else if (fanIndex === 1) fanClass = 'fan-2';
|
else if (fanIndex === 1) fanClass = 'fan-2';
|
||||||
else if (fanIndex === 2) fanClass = 'fan-3';
|
else if (fanIndex === 2) fanClass = 'fan-3';
|
||||||
|
|
||||||
|
const vipBadge = fanIndex === 0 ? '<span class="vip-badge">VIP</span>' : '';
|
||||||
|
const customColor = msg.custom_color ? `color: ${msg.custom_color} !important;` : '';
|
||||||
|
|
||||||
div.style.background = isLike ? 'rgba(255, 68, 68, 0.15)' : 'rgba(255,255,255,0.05)';
|
div.style.background = isLike ? 'rgba(255, 68, 68, 0.15)' : 'rgba(255,255,255,0.05)';
|
||||||
div.style.padding = '0.8rem';
|
div.style.padding = '0.8rem';
|
||||||
div.style.borderRadius = '12px';
|
div.style.borderRadius = '12px';
|
||||||
div.style.borderLeft = `4px solid ${isLike ? '#ff4444' : (msg.username === currentUserName ? 'var(--primary-color)' : 'rgba(255,255,255,0.2)')}`;
|
div.style.borderLeft = `4px solid ${isLike ? '#ff4444' : (msg.username === currentUserName ? 'var(--primary-color)' : 'rgba(255,255,255,0.2)')}`;
|
||||||
|
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="${fanClass}" style="font-size: 0.7rem; font-weight: bold; color: ${isLike ? '#ff4444' : 'var(--primary-color)'}; margin-bottom: 2px;">
|
<div class="${fanClass}" style="font-size: 0.7rem; font-weight: bold; ${customColor || (isLike ? 'color: #ff4444' : 'var(--primary-color)')}; margin-bottom: 2px;">
|
||||||
${fanIndex === 0 ? '👑 ' : ''}${msg.username}
|
${fanIndex === 0 ? '👑 ' : ''}${msg.username}${vipBadge}
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size: 0.85rem; line-height: 1.4; ${isLike ? 'font-weight: 600;' : ''}">${msg.message}</div>
|
<div style="font-size: 0.85rem; line-height: 1.4; ${isLike ? 'font-weight: 600;' : ''}">${msg.message}</div>
|
||||||
<div style="font-size: 0.6rem; opacity: 0.4; margin-top: 4px; text-align: right;">${new Date(msg.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div>
|
<div style="font-size: 0.6rem; opacity: 0.4; margin-top: 4px; text-align: right;">${new Date(msg.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user