Files
sistema_para_juego/discord/views/welcome/config.php

475 lines
21 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
session_start();
// Habilitar logging para depuración
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../../shared/utils/helpers.php';
require_once __DIR__ . '/../../../shared/auth/jwt.php';
require_once __DIR__ . '/../../../shared/database/connection.php';
$userData = JWTAuth::requireAuth();
// Verificar permiso para gestionar el mensaje de bienvenida
if (!hasPermission('manage_welcome', 'discord')) {
die('No tienes permiso para gestionar la configuración del mensaje de bienvenida de Discord.');
}
$db = getDB();
// Manejar guardado
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Verificar permiso para la acción de guardar
if (!hasPermission('manage_welcome', 'discord')) {
jsonResponse(['success' => false, 'error' => 'No tienes permiso para guardar la configuración del mensaje de bienvenida.'], 403);
}
$input = json_decode(file_get_contents('php://input'), true);
try {
// Verificar si ya existe configuración (solo debe haber una por ahora, o una por servidor si escalamos)
// Por simplicidad asumimos una configuración global única (id=1) o la creamos
$canal_id = $input['canal_id'] ?? '';
$texto = $input['texto'] ?? '';
$imagen_id = !empty($input['imagen_id']) ? $input['imagen_id'] : null;
$idiomas_habilitados = json_encode($input['idiomas_habilitados'] ?? []);
$registrar = isset($input['registrar_usuario']) ? (int)$input['registrar_usuario'] : 1;
$activo = isset($input['activo']) ? (int)$input['activo'] : 1;
// Intentar actualizar primero
$stmt = $db->prepare("SELECT id FROM bienvenida_discord LIMIT 1");
$stmt->execute();
$exists = $stmt->fetchColumn();
if ($exists) {
$stmt = $db->prepare("
UPDATE bienvenida_discord
SET canal_id = ?, texto = ?, imagen_id = ?, idiomas_habilitados = ?, registrar_usuario = ?, activo = ?
WHERE id = ?
");
$stmt->execute([$canal_id, $texto, $imagen_id, $idiomas_habilitados, $registrar, $activo, $exists]);
} else {
$stmt = $db->prepare("
INSERT INTO bienvenida_discord (canal_id, texto, imagen_id, idiomas_habilitados, registrar_usuario, activo)
VALUES (?, ?, ?, ?, ?, ?)
");
$stmt->execute([$canal_id, $texto, $imagen_id, $idiomas_habilitados, $registrar, $activo]);
}
jsonResponse(['success' => true]);
} catch (Exception $e) {
jsonResponse(['success' => false, 'error' => $e->getMessage()], 500);
}
exit;
}
// Obtener configuración actual
$stmt = $db->query("
SELECT b.*, g.ruta as imagen_ruta
FROM bienvenida_discord b
LEFT JOIN gallery g ON b.imagen_id = g.id
LIMIT 1
");
$config = $stmt->fetch(PDO::FETCH_ASSOC);
// Obtener canales destinatarios
$stmt = $db->query("SELECT discord_id, nombre FROM destinatarios_discord WHERE tipo = 'canal' ORDER BY nombre ASC");
$canales = $stmt->fetchAll();
// Obtener idiomas activos
$stmt = $db->query("SELECT id, codigo, nombre FROM idiomas WHERE activo = 1 ORDER BY nombre ASC");
$idiomas = $stmt->fetchAll();
// Decodificar idiomas seleccionados
$idiomasSeleccionados = [];
if ($config && $config['idiomas_habilitados']) {
$idiomasSeleccionados = json_decode($config['idiomas_habilitados'], true) ?? [];
}
?>
<!DOCTYPE html>
<html lang="<?php echo $userData->idioma ?? 'es'; ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bienvenida Discord - Sistema de Bots</title>
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Summernote CSS -->
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.css" rel="stylesheet">
<!-- Select2 CSS -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<style>
:root {
--discord-color: #5865F2;
--discord-dark: #4752C4;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, var(--discord-color) 0%, var(--discord-dark) 100%);
min-height: 100vh;
padding: 20px;
}
.header {
background: white;
border-radius: 15px;
padding: 20px 30px;
margin-bottom: 30px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
}
.header h1 { color: var(--discord-color); font-size: 24px; }
.container { max-width: 1000px; margin: 0 auto; }
.card {
background: white;
border-radius: 15px;
padding: 30px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.form-group { margin-bottom: 20px; }
.form-group label { display: block; margin-bottom: 8px; font-weight: 600; }
.form-control { width: 100%; padding: 10px; border: 2px solid #eee; border-radius: 8px; }
.btn {
padding: 10px 20px;
border-radius: 8px;
text-decoration: none;
border: none;
cursor: pointer;
font-weight: 600;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary { background: var(--discord-color); color: white; }
.btn-secondary { background: #6c757d; color: white; }
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
background-color: #ccc; transition: .4s; border-radius: 34px;
}
.slider:before {
position: absolute; content: ""; height: 16px; width: 16px; left: 4px; bottom: 4px;
background-color: white; transition: .4s; border-radius: 50%;
}
input:checked + .slider { background-color: var(--discord-color); }
input:checked + .slider:before { transform: translateX(26px); }
/* Modal Galería */
.modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); }
.modal-content { background: white; margin: 5% auto; padding: 20px; width: 80%; max-width: 900px; border-radius: 15px; max-height: 80vh; overflow-y: auto; }
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; margin-top: 20px; }
.gallery-item { border: 2px solid #eee; border-radius: 8px; overflow: hidden; cursor: pointer; transition: all 0.2s; position: relative; }
.gallery-item:hover { border-color: var(--discord-color); transform: translateY(-2px); }
.gallery-item img { width: 100%; height: 120px; object-fit: cover; }
.gallery-item.selected { border-color: var(--discord-color); box-shadow: 0 0 0 3px rgba(88, 101, 242, 0.3); }
.image-preview {
width: 100%;
height: 200px;
background: #f8f9fa;
border: 2px dashed #ddd;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
overflow: hidden;
position: relative;
}
.image-preview img { width: 100%; height: 100%; object-fit: contain; }
.remove-image {
position: absolute; top: 10px; right: 10px;
background: rgba(255,0,0,0.8); color: white;
border: none; border-radius: 50%; width: 30px; height: 30px;
cursor: pointer; display: none;
}
</style>
</head>
<body>
<div class="header">
<h1><i class="fas fa-handshake"></i> Configuración de Bienvenida</h1>
<a href="/discord/dashboard_discord.php" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Volver
</a>
</div>
<div class="container">
<div class="card">
<form id="welcomeForm">
<div style="display: flex; justify-content: space-between; margin-bottom: 20px;">
<div class="form-group" style="margin-bottom: 0;">
<label>Activar Bienvenida</label>
<label class="switch">
<input type="checkbox" name="activo" <?php echo ($config['activo'] ?? 1) ? 'checked' : ''; ?>>
<span class="slider"></span>
</label>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label>Registrar Usuario en BD</label>
<label class="switch">
<input type="checkbox" name="registrar_usuario" <?php echo ($config['registrar_usuario'] ?? 1) ? 'checked' : ''; ?>>
<span class="slider"></span>
</label>
</div>
</div>
<div class="form-group">
<label>Canal de Bienvenida</label>
<select name="canal_id" class="form-control select2" required>
<option value="">-- Seleccionar Canal --</option>
<?php foreach ($canales as $canal): ?>
<option value="<?php echo $canal['discord_id']; ?>"
<?php echo ($config['canal_id'] ?? '') == $canal['discord_id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($canal['nombre']); ?>
</option>
<?php endforeach; ?>
</select>
<small style="color: #666;">Si no aparece, agrégalo en "Destinatarios".</small>
</div>
<div class="form-group">
<label>Idiomas Disponibles (Botones Automáticos)</label>
<select name="idiomas_habilitados[]" id="idiomas_habilitados_select" class="form-control" multiple="multiple">
<?php foreach ($idiomas as $lang): ?>
<option value="<?php echo $lang['codigo']; ?>"
<?php echo in_array($lang['codigo'], $idiomasSeleccionados) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($lang['nombre']); ?>
</option>
<?php endforeach; ?>
</select>
<small style="color: #666;">Selecciona los idiomas que se mostrarán como botones en el mensaje de bienvenida.</small>
<div style="margin-top: 10px;">
<a href="/shared/languages/manager.php" style="font-size: 12px; color: var(--discord-color); text-decoration: none;">
<i class="fas fa-cog"></i> Gestionar idiomas
</a>
</div>
</div>
<div class="form-group">
<label>Mensaje de Bienvenida</label>
<textarea id="summernote" name="texto"><?php echo htmlspecialchars($config['texto'] ?? ''); ?></textarea>
<small style="color: #666;">Puedes usar {usuario} para mencionar al nuevo miembro.</small>
</div>
<div class="form-group">
<label>Imagen Opcional</label>
<input type="hidden" id="imagen_id" name="imagen_id" value="<?php echo htmlspecialchars($config['imagen_id'] ?? ''); ?>">
<button type="button" onclick="openGallery()" class="btn btn-secondary" style="margin-bottom: 10px;">
<i class="fas fa-image"></i> Seleccionar Imagen
</button>
<div id="imagePreview" class="image-preview">
<?php if (!empty($config['imagen_id']) && !empty($config['imagen_ruta'])): ?>
<img src="/gallery/uploads/<?php echo basename($config['imagen_ruta']); ?>" alt="Imagen de bienvenida">
<button type="button" class="remove-image" style="display:block" onclick="removeImage()">×</button>
<?php else: ?>
<span style="color: #ccc;">Sin imagen seleccionada</span>
<?php endif; ?>
</div>
</div>
<div style="display: flex; gap: 10px; margin-top: 20px;">
<?php if (hasPermission('manage_welcome', 'discord')): ?>
<button type="submit" class="btn btn-primary" style="flex: 1; justify-content: center;">
<i class="fas fa-save"></i> Guardar Configuración
</button>
<?php endif; ?>
<?php if (hasPermission('manage_welcome', 'discord')): ?>
<button type="button" onclick="sendTestMessage()" class="btn btn-success" style="flex: 1; justify-content: center; background: #28a745;">
<i class="fas fa-paper-plane"></i> Probar Mensaje
</button>
<?php endif; ?>
</div>
</form>
</div>
</div>
<!-- Modal Galería -->
<div id="galleryModal" class="modal">
<div class="modal-content">
<span style="float:right; cursor:pointer; font-size:24px;" onclick="closeGallery()">&times;</span>
<h2>Seleccionar Imagen</h2>
<div id="galleryContainer" class="gallery-grid">
<!-- Se carga vía AJAX -->
</div>
</div>
</div>
<!-- Librerías JS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
$('#summernote').summernote({
height: 200,
toolbar: [
['style', ['bold', 'italic', 'underline', 'clear']],
['para', ['ul', 'ol']],
['insert', ['link']],
['view', ['codeview']]
]
});
$('.select2').select2();
$('#idiomas_habilitados_select').select2(); // Inicializar el select2 para idiomas
// Galería
function openGallery() {
document.getElementById('galleryModal').style.display = 'block';
loadGalleryImages();
}
function closeGallery() {
document.getElementById('galleryModal').style.display = 'none';
}
async function loadGalleryImages() {
const container = document.getElementById('galleryContainer');
container.innerHTML = '<p>Cargando...</p>';
try {
const response = await fetch('/gallery/api/list.php');
const data = await response.json();
container.innerHTML = '';
if (data.images && data.images.length > 0) {
data.images.forEach(img => {
const div = document.createElement('div');
div.className = 'gallery-item';
// La API devuelve url_thumbnail (ruta completa) y nombre_original
div.innerHTML = `<img src="${img.url_thumbnail}" alt="${img.nombre_original}">`;
// Pasamos img.nombre que es el nombre del archivo físico
div.onclick = () => selectImage(img.id, img.nombre, img.ruta); // Pasar también la ruta completa para preview
container.appendChild(div);
});
} else {
container.innerHTML = '<p>No hay imágenes en la galería.</p>';
}
} catch (error) {
console.error(error);
container.innerHTML = '<p>Error cargando imágenes.</p>';
}
}
function selectImage(id, filename, ruta_completa) {
document.getElementById('imagen_id').value = id;
const preview = document.getElementById('imagePreview');
preview.innerHTML = `
<img src="${ruta_completa}" alt="Imagen de bienvenida">
<button type="button" class="remove-image" style="display:block" onclick="removeImage()">×</button>
`;
closeGallery();
}
function removeImage() {
document.getElementById('imagen_id').value = '';
document.getElementById('imagePreview').innerHTML = `
<span style="color: #ccc;">Sin imagen seleccionada</span>
`;
}
// Guardar
document.getElementById('welcomeForm').onsubmit = async function(e) {
e.preventDefault();
const formData = new FormData(e.target);
// Recolectar datos del formulario
const activo = $('input[name="activo"]').is(':checked') ? 1 : 0;
const registrar_usuario = $('input[name="registrar_usuario"]').is(':checked') ? 1 : 0;
const canal_id = $('select[name="canal_id"]').val();
const texto = $('#summernote').summernote('code');
const imagen_id = $('#imagen_id').val();
const idiomas_habilitados = $('#idiomas_habilitados_select').val(); // Array de códigos de idioma
const data = {
activo: activo,
registrar_usuario: registrar_usuario,
canal_id: canal_id,
texto: texto,
imagen_id: imagen_id === '' ? null : imagen_id,
idiomas_habilitados: idiomas_habilitados
};
try {
const response = await fetch(window.location.href, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
alert('Configuración guardada correctamente');
} else {
alert('Error: ' + result.error);
}
} catch (error) {
console.error(error);
alert('Error de conexión');
}
};
async function sendTestMessage() {
if (!confirm('¿Enviar mensaje de prueba al canal configurado?')) return;
const btn = document.querySelector('.btn-success');
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Enviando...';
btn.disabled = true;
try {
const response = await fetch('/discord/api/welcome/send_test.php', {
method: 'POST'
});
const result = await response.json();
if (result.success) {
alert('Mensaje de prueba enviado con éxito a Discord!');
} else {
alert('Error: ' + result.error);
}
} catch (error) {
console.error(error);
alert('Error de conexión');
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
}
window.onclick = function(event) {
if (event.target == document.getElementById('galleryModal')) {
closeGallery();
}
}
});
</script>
</body>
</html>