Auto commit: 2026-02-15T18:22:05.866Z
This commit is contained in:
parent
5787fd1d5c
commit
eb92bd9033
40
admin.php
40
admin.php
@ -20,20 +20,34 @@ $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");
|
||||
$locations = $stmt->fetchAll();
|
||||
|
||||
// Handle Video Password Update
|
||||
if (isset($_POST['update_video_pass'])) {
|
||||
$new_pass = trim($_POST['video_pass']);
|
||||
$stmt = $db->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('video_room_password', ?) ON DUPLICATE KEY UPDATE setting_value = ?");
|
||||
$stmt->execute([$new_pass, $new_pass]);
|
||||
$success_msg = "Contraseña de la sala de video actualizada.";
|
||||
}
|
||||
|
||||
// Get current video password
|
||||
$stmt = $db->prepare("SELECT setting_value FROM settings WHERE setting_key = 'video_room_password'");
|
||||
$stmt->execute();
|
||||
$current_video_pass = $stmt->fetchColumn() ?: "lili123";
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="refresh" content="30">
|
||||
<title>Admin Dashboard - Lili Records</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<style>
|
||||
body { background: #0f172a; color: white; font-family: 'Inter', sans-serif; }
|
||||
.card { background: rgba(30, 41, 59, 0.7); border: 1px solid rgba(255,255,255,0.1); color: white; backdrop-filter: blur(10px); }
|
||||
#map { height: 500px; border-radius: 15px; margin-top: 20px; }
|
||||
.stat-value { font-size: 3rem; font-weight: bold; color: #00e676; }
|
||||
.btn-success { background: #00e676; border: none; color: #0f172a; font-weight: bold; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -46,6 +60,30 @@ $locations = $stmt->fetchAll();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (isset($success_msg)): ?>
|
||||
<div class="alert alert-success bg-success text-white border-0 mb-4"><?= $success_msg ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card p-4">
|
||||
<h5 class="mb-3"><i class="bi bi-camera-video-fill text-primary"></i> Control de Sala de Video</h5>
|
||||
<form method="POST" class="row g-3">
|
||||
<div class="col-auto">
|
||||
<label class="form-label">Contraseña actual para los usuarios:</label>
|
||||
<input type="text" name="video_pass" class="form-control bg-dark text-white border-secondary" value="<?= htmlspecialchars($current_video_pass) ?>" required>
|
||||
</div>
|
||||
<div class="col-auto d-flex align-items-end">
|
||||
<button type="submit" name="update_video_pass" class="btn btn-success">ACTUALIZAR CONTRASEÑA</button>
|
||||
</div>
|
||||
<div class="col-12 mt-2">
|
||||
<small class="text-secondary">Esta contraseña será solicitada a los usuarios que intenten activar su cámara en la web.</small>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
|
||||
34
api/chat.php
Normal file
34
api/chat.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
if ($method === 'GET') {
|
||||
try {
|
||||
$stmt = db()->prepare("SELECT * FROM messages ORDER BY created_at DESC LIMIT 50");
|
||||
$stmt->execute();
|
||||
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
echo json_encode(array_reverse($messages));
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
}
|
||||
} elseif ($method === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$username = $input['username'] ?? 'Anónimo';
|
||||
$message = $input['message'] ?? '';
|
||||
|
||||
if (empty($message)) {
|
||||
echo json_encode(['error' => 'Mensaje vacío']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = db()->prepare("INSERT INTO messages (username, message) VALUES (?, ?)");
|
||||
$stmt->execute([$username, $message]);
|
||||
echo json_encode(['success' => true]);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
6
db/migrations/002_create_settings_table.sql
Normal file
6
db/migrations/002_create_settings_table.sql
Normal file
@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
setting_key VARCHAR(50) PRIMARY KEY,
|
||||
setting_value TEXT
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO settings (setting_key, setting_value) VALUES ('video_room_password', 'lili123');
|
||||
160
index.php
160
index.php
@ -11,6 +11,12 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? 'assets/pasted-20260215-1646
|
||||
$whatsapp_link = "https://chat.whatsapp.com/DkG96pTzAFO3hvLqmzwmTY";
|
||||
$whatsapp_number = '+5359177041';
|
||||
$facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
|
||||
// Fetch video room password
|
||||
$db = db();
|
||||
$stmt = $db->prepare("SELECT setting_value FROM settings WHERE setting_key = 'video_room_password'");
|
||||
$stmt->execute();
|
||||
$video_room_pass = $stmt->fetchColumn() ?: "lili123";
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="es">
|
||||
@ -592,10 +598,13 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
overflow-y: auto;
|
||||
padding-top: 4rem;
|
||||
}
|
||||
.player-section {
|
||||
max-width: 100%;
|
||||
.player-section, .interaction-center {
|
||||
max-width: 100% !important;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.interaction-center {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
.image-section {
|
||||
padding-left: 0;
|
||||
width: 100%;
|
||||
@ -699,7 +708,47 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- Interaction Center: Live Chat & Video Calls -->
|
||||
<section class="interaction-center" style="width: 100%; max-width: 850px; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; z-index: 10;">
|
||||
<!-- Live Web Chat -->
|
||||
<div class="glass-card chat-window" style="height: 500px; display: flex; flex-direction: column;">
|
||||
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: var(--primary-color);">
|
||||
<i class="bi bi-chat-dots-fill"></i> CHAT EN VIVO
|
||||
</h3>
|
||||
<div id="chat-messages" style="flex: 1; overflow-y: auto; margin-bottom: 1rem; padding-right: 5px; display: flex; flex-direction: column; gap: 0.8rem;">
|
||||
<!-- Mensajes se cargarán aquí -->
|
||||
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Cargando mensajes...</div>
|
||||
</div>
|
||||
<div class="chat-input-area" style="display: flex; gap: 0.5rem;">
|
||||
<input type="text" id="chat-user" placeholder="Nombre" style="width: 80px; font-size: 0.8rem; padding: 0.5rem; border-radius: 8px; border: none; background: rgba(255,255,255,0.1); color: white;">
|
||||
<input type="text" id="chat-msg" placeholder="Escribe un mensaje..." style="flex: 1; font-size: 0.8rem; padding: 0.5rem; border-radius: 8px; border: none; background: rgba(255,255,255,0.1); color: white;">
|
||||
<button onclick="sendChatMessage()" style="background: var(--primary-color); border: none; border-radius: 8px; color: white; padding: 0 1rem; cursor: pointer;">
|
||||
<i class="bi bi-send-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Live Video Call Window (Jitsi Integration) -->
|
||||
<div class="glass-card video-window" style="height: 500px; display: flex; flex-direction: column; position: relative; overflow: hidden;">
|
||||
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: var(--accent-color); padding-left: 5px;">
|
||||
<i class="bi bi-camera-video-fill"></i> VIDEO EN VIVO
|
||||
</h3>
|
||||
<div id="video-container" style="flex: 1; background: rgba(0,0,0,0.4); border-radius: 16px; position: relative; overflow: hidden;">
|
||||
<!-- Jitsi Iframe will be loaded here -->
|
||||
<div id="jitsi-placeholder" style="width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 1rem;">
|
||||
<i class="bi bi-person-video3" style="font-size: 3rem; margin-bottom: 1rem; opacity: 0.5;"></i>
|
||||
<p style="font-size: 0.9rem; margin-bottom: 1.5rem;">Únete a la sala de video para que otros usuarios te vean en vivo.</p>
|
||||
<button onclick="startVideo()" class="send-whatsapp-btn" style="width: auto; padding: 0.8rem 1.5rem; background: var(--primary-color);">
|
||||
ACTIVAR MI CÁMARA
|
||||
</button>
|
||||
<p style="font-size: 0.7rem; opacity: 0.5; margin-top: 1rem;">Integrado con la comunidad Lili Records</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; top: 1rem; right: 1rem; z-index: 5;">
|
||||
<span style="background: red; color: white; font-size: 0.6rem; padding: 2px 6px; border-radius: 4px; font-weight: bold; animation: pulse 1s infinite;">LIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
@ -862,6 +911,71 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
window.open('<?= $whatsapp_link ?>', '_blank');
|
||||
}
|
||||
|
||||
// --- Chat Functionality ---
|
||||
const chatMessages = document.getElementById('chat-messages');
|
||||
const chatUser = document.getElementById('chat-user');
|
||||
const chatMsg = document.getElementById('chat-msg');
|
||||
let lastMessageCount = 0;
|
||||
|
||||
async function fetchMessages() {
|
||||
try {
|
||||
const response = await fetch('api/chat.php');
|
||||
const messages = await response.json();
|
||||
|
||||
if (messages.length !== lastMessageCount) {
|
||||
chatMessages.innerHTML = '';
|
||||
messages.forEach(msg => {
|
||||
const div = document.createElement('div');
|
||||
div.style.background = 'rgba(255,255,255,0.05)';
|
||||
div.style.padding = '0.8rem';
|
||||
div.style.borderRadius = '12px';
|
||||
div.style.borderLeft = `4px solid ${msg.username === chatUser.value ? 'var(--primary-color)' : 'rgba(255,255,255,0.2)'}`;
|
||||
|
||||
div.innerHTML = `
|
||||
<div style="font-size: 0.7rem; font-weight: bold; color: var(--primary-color); margin-bottom: 2px;">${msg.username}</div>
|
||||
<div style="font-size: 0.85rem; line-height: 1.4;">${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>
|
||||
`;
|
||||
chatMessages.appendChild(div);
|
||||
});
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
lastMessageCount = messages.length;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Chat error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendChatMessage() {
|
||||
const user = chatUser.value.trim() || 'Anónimo';
|
||||
const message = chatMsg.value.trim();
|
||||
if (!message) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('api/chat.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user, message: message })
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
chatMsg.value = '';
|
||||
fetchMessages();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error sending message:', error);
|
||||
}
|
||||
}
|
||||
|
||||
chatMsg.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter') sendChatMessage();
|
||||
});
|
||||
|
||||
// Initial fetch and poll
|
||||
fetchMessages();
|
||||
setInterval(fetchMessages, 3000);
|
||||
// --- End Chat Functionality ---
|
||||
|
||||
// Fetch Now Playing Metadata from RadioKing
|
||||
async function updateMetadata() {
|
||||
try {
|
||||
@ -921,6 +1035,48 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
updateMetadata();
|
||||
setInterval(updateMetadata, 30000);
|
||||
|
||||
// --- Video Call Functionality ---
|
||||
function startVideo() {
|
||||
const roomPassword = '<?= $video_room_pass ?>';
|
||||
const userPass = prompt("Introduce la contraseña de la sala (Solicítala en el grupo de WhatsApp):");
|
||||
|
||||
if (userPass !== roomPassword) {
|
||||
if (userPass !== null) alert("Contraseña incorrecta. Solo miembros autorizados pueden unirse.");
|
||||
return;
|
||||
}
|
||||
|
||||
const container = document.getElementById('video-container');
|
||||
const placeholder = document.getElementById('jitsi-placeholder');
|
||||
placeholder.style.display = 'none';
|
||||
|
||||
// Load Jitsi External API
|
||||
const script = document.createElement('script');
|
||||
script.src = "https://meet.jit.si/external_api.js";
|
||||
script.onload = () => {
|
||||
const domain = "meet.jit.si";
|
||||
const options = {
|
||||
roomName: "LiliRecordsLive_Sala_Privada_2026",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
parentNode: container,
|
||||
configOverwrite: {
|
||||
startWithAudioMuted: true,
|
||||
startWithVideoMuted: false,
|
||||
prejoinPageEnabled: false
|
||||
},
|
||||
interfaceConfigOverwrite: {
|
||||
TOOLBAR_BUTTONS: [
|
||||
'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
|
||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'tileview', 'videobackgroundblur'
|
||||
],
|
||||
}
|
||||
};
|
||||
const api = new JitsiMeetExternalAPI(domain, options);
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
// Handle possible audio interruptions
|
||||
audio.addEventListener('error', function(e) {
|
||||
console.error('Audio error:', e);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user