- Nueva tabla 'welcome_messages' en la base de datos - Panel web con página de configuración de bienvenida (/welcome) - Listar, crear, editar y eliminar mensajes por servidor - Vista previa del mensaje - Plantillas predefinidas - Bot Discord: - Nuevo intent 'members' para detectar nuevos usuarios - Evento on_member_join que envía mensaje de bienvenida - Botones de traducción en mensajes de bienvenida - Actualizada configuración de MySQL en docker-compose.yml - Añadido logging de debug para traducciones
259 lines
15 KiB
HTML
259 lines
15 KiB
HTML
{% set lang = request.cookies.get('panel_lang', 'es') %}
|
|
{% set is_admin = username == 'nickpons666' %}
|
|
<!DOCTYPE html>
|
|
<html lang="{{ lang }}">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ "Mensaje de Bienvenida - Bots de Traducción" | translate(lang) }}</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="/dashboard">
|
|
<i class="bi bi-translate"></i> {{ "Bots de Traducción" | translate(lang) }}
|
|
</a>
|
|
<div class="d-flex align-items-center">
|
|
<div class="dropdown me-3">
|
|
<button class="btn btn-outline-light btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
<i class="bi bi-translate"></i>
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><a class="dropdown-item {{ 'active' if lang == 'es' }}" href="/set-lang/es">Español</a></li>
|
|
<li><a class="dropdown-item {{ 'active' if lang == 'en' }}" href="/set-lang/en">English</a></li>
|
|
<li><a class="dropdown-item {{ 'active' if lang == 'pt' }}" href="/set-lang/pt">Português</a></li>
|
|
</ul>
|
|
</div>
|
|
<a href="/dashboard" class="btn btn-outline-light btn-sm me-2">{{ "Dashboard" | translate(lang) }}</a>
|
|
<a href="/logout" class="btn btn-outline-light btn-sm">{{ "Cerrar Sesión" | translate(lang) }}</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container mt-5">
|
|
<h2 class="mb-4">👋 {{ "Mensajes de Bienvenida" | translate(lang) }}</h2>
|
|
|
|
{% if success %}
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
<i class="bi bi-check-circle"></i> {{ "Configuración guardada correctamente." | translate(lang) }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if error %}
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
<i class="bi bi-exclamation-triangle"></i> {{ "Error al guardar. Verifica los datos." | translate(lang) }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="row">
|
|
<div class="col-lg-5">
|
|
{% if configs %}
|
|
<div class="card mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0"><i class="bi bi-list"></i> {{ "Servidores Configurados" | translate(lang) }}</h5>
|
|
<button class="btn btn-sm btn-primary" onclick="nuevoMensaje()">
|
|
<i class="bi bi-plus"></i> {{ "Nuevo" | translate(lang) }}
|
|
</button>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="list-group list-group-flush">
|
|
{% for guild_id, cfg in configs.items() %}
|
|
<div class="list-group-item {{ 'active' if selected_guild == guild_id else '' }}"
|
|
style="cursor: pointer;"
|
|
onclick="seleccionarGuild('{{ guild_id }}')">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<strong>Guild ID:</strong> {{ guild_id }}<br>
|
|
<small><i class="bi bi-chat-dots"></i> Channel: {{ cfg['channel_id'] }}</small>
|
|
</div>
|
|
<div class="text-end">
|
|
{% if cfg['enabled'] %}
|
|
<span class="badge bg-success">{{ "Activo" | translate(lang) }}</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">{{ "Inactivo" | translate(lang) }}</span>
|
|
{% endif %}
|
|
<form method="POST" action="/welcome/delete" class="d-inline"
|
|
onsubmit="return confirm('¿Eliminar esta configuración?')">
|
|
<input type="hidden" name="guild_id" value="{{ guild_id }}">
|
|
<button type="submit" class="btn btn-sm btn-outline-danger">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="mt-2">
|
|
<small class="text-muted">{{ cfg['message_content'][:50] if cfg['message_content'] else '' }}...</small>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="card mb-4">
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-inbox" style="font-size: 3rem; color: #ccc;"></i>
|
|
<p class="mt-3 text-muted">{{ "No hay mensajes de bienvenida configurados." | translate(lang) }}</p>
|
|
<button class="btn btn-primary" onclick="nuevoMensaje()">
|
|
<i class="bi bi-plus"></i> {{ "Crear primer mensaje" | translate(lang) }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="card" id="formularioCard" style="{{ 'display: none;' if not selected_guild and not new_form else '' }}">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-discord"></i>
|
|
{{ "Editar Mensaje" | translate(lang) if selected_guild else "Nuevo Mensaje" | translate(lang) }}
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" action="/welcome/save">
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ "Servidor (Guild ID)" | translate(lang) }}</label>
|
|
<input type="number" class="form-control" name="guild_id" id="guild_id"
|
|
value="{{ selected_cfg['guild_id'] if selected_cfg else '' }}" required
|
|
placeholder="{{ 'Ej: 123456789012345678' | translate(lang) }}">
|
|
<div class="form-text">{{ "Ingresa el ID del servidor de Discord" | translate(lang) }}</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ "Canal de Bienvenida (Channel ID)" | translate(lang) }}</label>
|
|
<input type="number" class="form-control" name="channel_id" id="channel_id"
|
|
value="{{ selected_cfg['channel_id'] if selected_cfg else '' }}" required
|
|
placeholder="{{ 'Ej: 123456789012345678' | translate(lang) }}">
|
|
<div class="form-text">{{ "ID del canal donde se enviarán los mensajes de bienvenida" | translate(lang) }}</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">{{ "Mensaje de Bienvenida" | translate(lang) }}</label>
|
|
<textarea class="form-control" name="message_content" id="message_content" rows="4" required>{{ selected_cfg['message_content'] if selected_cfg else '' }}</textarea>
|
|
<div class="form-text">
|
|
{{ "Placeholders:" | translate(lang) }}
|
|
<code>{user_mention}</code>, <code>{username}</code>, <code>{server_name}</code>, <code>{member_count}</code>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" name="enabled" id="enabled" value="1"
|
|
{% if selected_cfg and selected_cfg['enabled'] %}checked{% endif %}>
|
|
<label class="form-check-label" for="enabled">
|
|
{{ "Habilitar mensaje de bienvenida" | translate(lang) }}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-save"></i> {{ "Guardar" | translate(lang) }}
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" onclick="ocultarFormulario()">
|
|
{{ "Cancelar" | translate(lang) }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-7">
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="bi bi-eye"></i> {{ "Vista Previa" | translate(lang) }}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="discord-preview p-3 rounded" style="background-color: #36393f; color: #dcddde;">
|
|
<div id="preview_content">
|
|
{% if selected_cfg and selected_cfg['message_content'] %}
|
|
{{ selected_cfg['message_content'] }}
|
|
{% else %}
|
|
¡Bienvenido {user_mention} a {server_name}! Ahora somos {member_count} miembros.
|
|
{% endif %}
|
|
</div>
|
|
<hr style="border-color: #40444b; margin: 10px 0;">
|
|
<small style="color: #b9bbbe;">¿Traducir este mensaje?</small>
|
|
<div class="d-flex flex-wrap gap-1 mt-2">
|
|
<button class="btn btn-sm btn-secondary" disabled>🇬🇧 EN</button>
|
|
<button class="btn btn-sm btn-secondary" disabled>🇪🇸 ES</button>
|
|
<button class="btn btn-sm btn-secondary" disabled>🇫🇷 FR</button>
|
|
</div>
|
|
</div>
|
|
<small class="text-muted d-block mt-2">
|
|
<i class="bi bi-info-circle"></i> {{ "Vista previa en Discord" | translate(lang) }}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="bi bi-lightbulb"></i> {{ "Plantillas" | translate(lang) }}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-outline-secondary text-start" onclick="setExample(1)">
|
|
<i class="bi bi-star"></i> <strong>¡Bienvenido {user_mention} a {server_name}! 🎉</strong>
|
|
</button>
|
|
<button class="btn btn-outline-secondary text-start" onclick="setExample(2)">
|
|
<i class="bi bi-heart"></i> <strong>¡Hola {username}!</strong> Nos alegra que te hayas unido. {server_name} ahora tiene {member_count} miembros. ¡Disfruta!
|
|
</button>
|
|
<button class="btn btn-outline-secondary text-start" onclick="setExample(3)">
|
|
<i class="bi bi-info-circle"></i> <strong>👋 ¡Bienvenido/a {user_mention} a {server_name}!</strong><br>
|
|
<small>Actualmente somos {member_count} miembros.</small>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
const examples = {
|
|
1: '¡Bienvenido {user_mention} a {server_name}! 🎉',
|
|
2: '¡Hola {username}! Nos alegra que te hayas unido. {server_name} ahora tiene {member_count} miembros. ¡Disfruta tu estancia! 😊',
|
|
3: '👋 ¡Bienvenido/a {user_mention} a **{server_name}**!\n\nActualmente somos {member_count} miembros. Lee las reglas y presentate en #presentaciones.'
|
|
};
|
|
|
|
function setExample(num) {
|
|
document.getElementById('message_content').value = examples[num];
|
|
updatePreview();
|
|
}
|
|
|
|
function updatePreview() {
|
|
const content = document.getElementById('message_content').value || '¡Bienvenido {user_mention} a {server_name}! 🎉';
|
|
document.getElementById('preview_content').innerText = content;
|
|
}
|
|
|
|
document.getElementById('message_content').addEventListener('input', updatePreview);
|
|
|
|
function seleccionarGuild(guildId) {
|
|
window.location.href = '/welcome?guild=' + guildId;
|
|
}
|
|
|
|
function nuevoMensaje() {
|
|
document.getElementById('formularioCard').style.display = 'block';
|
|
document.getElementById('guild_id').value = '';
|
|
document.getElementById('channel_id').value = '';
|
|
document.getElementById('message_content').value = '';
|
|
document.getElementById('enabled').checked = true;
|
|
document.getElementById('preview_content').innerText = '¡Bienvenido {user_mention} a {server_name}! 🎉';
|
|
}
|
|
|
|
function ocultarFormulario() {
|
|
document.getElementById('formularioCard').style.display = 'none';
|
|
}
|
|
|
|
{% if selected_guild or new_form %}
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.getElementById('formularioCard').style.display = 'block';
|
|
});
|
|
{% endif %}
|
|
</script>
|
|
</body>
|
|
</html>
|