diff --git a/api/chat.php b/api/chat.php index 18e88d9..82739d3 100644 --- a/api/chat.php +++ b/api/chat.php @@ -46,19 +46,27 @@ if ($method === 'GET') { "); $topRequester = $topStmt->fetchColumn(); - $stmt = db()->prepare("SELECT m.*, f.points, f.loyalty_points, f.is_fan_of_month FROM messages m LEFT JOIN fans f ON m.username = f.name ORDER BY m.created_at DESC LIMIT 50"); + $stmt = db()->prepare("SELECT m.*, f.points, f.loyalty_points, f.is_fan_of_month, f.chat_color, f.dj_day_until FROM messages m LEFT JOIN fans f ON m.username = f.name ORDER BY m.created_at DESC LIMIT 50"); $stmt->execute(); $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($messages as &$msg) { $points = $msg['points'] ?? 0; $loyalty = $msg['loyalty_points'] ?? 0; - $msg['level_color'] = '#94a3b8'; + $chatColor = $msg['chat_color'] ?? null; + $djDayUntil = $msg['dj_day_until'] ?? null; + $isDjDay = $djDayUntil && strtotime($djDayUntil) > time(); + + $msg['level_color'] = $chatColor ?: '#94a3b8'; $msg['level_emoji'] = ''; if ($msg['username'] === 'Lili Bot 🤖') { $msg['level_color'] = '#00e676'; $msg['level_emoji'] = '🤖'; + } elseif ($isDjDay) { + $msg['level_color'] = '#facc15'; + $msg['level_emoji'] = '🎧'; + $msg['is_guest_dj'] = true; } elseif ($msg['username'] === $topRequester) { $msg['level_color'] = '#facc15'; $msg['level_emoji'] = '👑'; diff --git a/api/get_online_users.php b/api/get_online_users.php index 28b199b..babea09 100644 --- a/api/get_online_users.php +++ b/api/get_online_users.php @@ -13,7 +13,9 @@ $stmt = $db->prepare(" v.last_activity, f.points, f.loyalty_points, - f.is_fan_of_month + f.is_fan_of_month, + f.chat_color, + f.dj_day_until FROM visitor_logs v LEFT JOIN fans f ON v.username = f.name WHERE v.last_activity > DATE_SUB(NOW(), INTERVAL 15 MINUTE) diff --git a/api/get_top_fans.php b/api/get_top_fans.php index 20609bb..90e29e6 100644 --- a/api/get_top_fans.php +++ b/api/get_top_fans.php @@ -8,7 +8,7 @@ try { $username = $_GET['username'] ?? null; // Get top fans from the fans table - $stmt = $pdo->query("SELECT name as username, points as total_likes, photo, is_fan_of_month FROM fans ORDER BY points DESC LIMIT 5"); + $stmt = $pdo->query("SELECT name as username, points as total_likes, photo, is_fan_of_month, loyalty_points, chat_color, dj_day_until FROM fans ORDER BY points DESC LIMIT 5"); $fans = $stmt->fetchAll(PDO::FETCH_ASSOC); // If username provided and not in top 5, fetch it specifically @@ -21,7 +21,7 @@ try { } } if (!$found) { - $stmt = $pdo->prepare("SELECT name as username, points as total_likes, photo, is_fan_of_month FROM fans WHERE name = ?"); + $stmt = $pdo->prepare("SELECT name as username, points as total_likes, photo, is_fan_of_month, loyalty_points, chat_color, dj_day_until FROM fans WHERE name = ?"); $stmt->execute([$username]); $userFan = $stmt->fetch(PDO::FETCH_ASSOC); if ($userFan) { @@ -77,6 +77,18 @@ foreach ($fans as &$fan) { if ($fan['is_fan_of_month']) { $fan['badges'][] = ['icon' => 'bi-star-fill', 'color' => '#facc15', 'label' => 'Fan del Mes']; } + + $isDj = $fan['dj_day_until'] && strtotime($fan['dj_day_until']) > time(); + if ($isDj) { + $fan['badges'][] = ['icon' => 'bi-headphones', 'color' => '#facc15', 'label' => 'DJ INVITADO']; + $fan['level_color'] = '#facc15'; + $fan['level_name'] = 'DJ INVITADO'; + } + + if ($fan['loyalty_points'] > 0) { + $fan['badges'][] = ['icon' => 'bi-heart-fill', 'color' => '#00e676', 'label' => 'Fan Leal']; + } + if ($points >= 1000) { $fan['badges'][] = ['icon' => 'bi-gem', 'color' => '#38bdf8', 'label' => 'Diamante']; } elseif ($points >= 500) { diff --git a/api/redeem.php b/api/redeem.php new file mode 100644 index 0000000..d1688a8 --- /dev/null +++ b/api/redeem.php @@ -0,0 +1,73 @@ + false, 'error' => 'Datos incompletos']); + exit; +} + +try { + $pdo = db(); + $stmt = $pdo->prepare("SELECT loyalty_points, chat_color FROM fans WHERE name = ?"); + $stmt->execute([$username]); + $fan = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$fan) { + echo json_encode(['success' => false, 'error' => 'Usuario no encontrado']); + exit; + } + + $points = $fan['loyalty_points']; + $current_color = $fan['chat_color']; + + if ($item === 'god_mode') { + $cost = 500; + if ($points < $cost) { + echo json_encode(['success' => false, 'error' => "Puntos insuficientes ($points/$cost)"]); + exit; + } + + $new_color = $color ?: '#ffd700'; // Gold default + $stmt = $pdo->prepare("UPDATE fans SET loyalty_points = loyalty_points - ?, chat_color = ? WHERE name = ?"); + $stmt->execute([$cost, $new_color, $username]); + + echo json_encode(['success' => true, 'message' => '¡Modo Dios activado! Ahora tienes un color exclusivo.']); + } elseif ($item === 'dj_day') { + $cost = 2000; + if ($points < $cost) { + echo json_encode(['success' => false, 'error' => "Puntos insuficientes ($points/$cost)"]); + exit; + } + + $stmt = $pdo->prepare("UPDATE fans SET loyalty_points = loyalty_points - ?, dj_day_until = DATE_ADD(NOW(), INTERVAL 1 DAY) WHERE name = ?"); + $stmt->execute([$cost, $username]); + + echo json_encode(['success' => true, 'message' => '¡Eres DJ por un día! Tu nombre destacará en toda la sala.']); + } elseif ($item === 'change_color') { + // If they already have god mode, changing color might be cheaper or free? + // Let's say 100 points to change color if already bought, or free if we want. + if (!$current_color) { + echo json_encode(['success' => false, 'error' => 'Primero debes desbloquear el Modo Dios']); + exit; + } + $cost = 50; + if ($points < $cost) { + echo json_encode(['success' => false, 'error' => "Puntos insuficientes ($points/$cost)"]); + exit; + } + $stmt = $pdo->prepare("UPDATE fans SET loyalty_points = loyalty_points - ?, chat_color = ? WHERE name = ?"); + $stmt->execute([$cost, $color, $username]); + echo json_encode(['success' => true, 'message' => '¡Color actualizado!']); + } else { + echo json_encode(['success' => false, 'error' => 'Ítem no reconocido']); + } + +} catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/index.php b/index.php index f768bcf..82abd06 100644 --- a/index.php +++ b/index.php @@ -2226,8 +2226,13 @@ $twitter_link = "https://twitter.com/";

Tienda Radio

-
- 0 pts +
+
+ 0 PTS +
+
+ 0 LP +
@@ -2251,6 +2256,24 @@ $twitter_link = "https://twitter.com/";
1000
+
+
+
+
Modo Dios
+
Colores personalizados para tu nombre en el chat.
+
+
500
+
+ +
+
+
+
DJ por un día
+
Nombre dorado y estatus de DJ Invitado.
+
+
2000
+
+
@@ -2604,21 +2627,25 @@ $twitter_link = "https://twitter.com/"; const flagUrl = user.country_code ? `https://flagcdn.com/w20/${user.country_code.toLowerCase()}.png` : null; const isTopFan = user.points > 10 || user.is_fan_of_month == 1; const isLoyal = user.loyalty_points > 0; - const userColor = isLoyal ? "#00e676" : getUserColor(user.username); + const isGuestDj = user.dj_day_until && (new Date(user.dj_day_until) > new Date()); + + let userColor = user.chat_color || (isLoyal ? "#00e676" : getUserColor(user.username)); + if (isGuestDj) userColor = "#facc15"; return ` -
+
-
- ${user.username.charAt(0).toUpperCase()} +
+ ${isGuestDj ? '' : user.username.charAt(0).toUpperCase()} ${isVeryActive ? '' : ''}
- ${user.username} + ${user.username} ${flagUrl ? `` : ''} - ${isLoyal ? ` LEAL` : ""} - ${isTopFan && !isLoyal ? `TOP` : ''} + ${isGuestDj ? `DJ INVITADO` : ""} + ${isLoyal && !isGuestDj ? ` LEAL` : ""} + ${isTopFan && !isLoyal && !isGuestDj ? `TOP` : ''}
${timeAgo(user.last_activity)} @@ -3568,7 +3595,9 @@ $twitter_link = "https://twitter.com/"; // Update shop points display const shopPoints = document.getElementById('shop-user-points'); - if (shopPoints) shopPoints.innerText = `${parseInt(fan.total_likes).toLocaleString()} pts`; + const shopLoyalty = document.getElementById('shop-user-loyalty'); + if (shopPoints) shopPoints.innerText = `${parseInt(fan.total_likes).toLocaleString()} PTS`; + if (shopLoyalty) shopLoyalty.innerText = `${parseInt(fan.loyalty_points || 0).toLocaleString()} LP`; container.style.display = 'block'; badge.innerText = `Nivel ${fan.level}`; @@ -4070,6 +4099,55 @@ $twitter_link = "https://twitter.com/"; } } + async function redeemItem(item, color = null) { + const userName = document.getElementById('user-name').value.trim(); + if (!userName) return; + + try { + const response = await fetch('api/redeem.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: userName, item: item, color: color }) + }); + const result = await response.json(); + + if (result.success) { + confetti({ + particleCount: 200, + spread: 100, + origin: { y: 0.6 }, + colors: ['#facc15', '#f472b6', '#38bdf8', '#ffffff'] + }); + alert(result.message); + closeShopModal(); + fetchLeaderboard(); + if (typeof fetchMessages === 'function') fetchMessages(); + } else { + alert('Error: ' + result.error); + } + } catch (error) { + console.error('Redeem error:', error); + alert('Error de conexión al realizar el canje.'); + } + } + + function promptBuyGodMode() { + const color = prompt('MODO DIOS: Elige un color hexadecimal para tu nombre (ej: #FFD700 para Oro, #00FFFF para Cian):', '#FFD700'); + if (color) { + if (!/^#[0-9A-F]{6}$/i.test(color)) { + alert('Por favor, ingresa un código hexadecimal válido (ej: #FFD700).'); + return; + } + redeemItem('god_mode', color); + } + } + + function promptBuyDjDay() { + if (confirm('¿Quieres convertirte en DJ INVITADO por 2000 pts? Tu nombre destacará en toda la sala por 24 horas.')) { + redeemItem('dj_day'); + } + } + setInterval(fetchActivePerks, 10000); fetchActivePerks(); // --- End Radio Shop Functionality ---