214 lines
9.5 KiB
PHP
Executable File
214 lines
9.5 KiB
PHP
Executable File
<?php
|
|
require_once __DIR__ . '/../includes/session_check.php';
|
|
require_once __DIR__ . '/../config/config.php';
|
|
require_once __DIR__ . '/../includes/db.php';
|
|
|
|
// Solo para administradores
|
|
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
|
|
header('Location: /login.php');
|
|
exit;
|
|
}
|
|
|
|
$pageTitle = 'Gestionar Idiomas de Traducción';
|
|
require_once __DIR__ . '/../templates/header.php';
|
|
|
|
try {
|
|
$stmt = $pdo->query("SELECT * FROM supported_languages ORDER BY language_name ASC");
|
|
$languages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
$languages = [];
|
|
$errorMessage = "Error al cargar los idiomas: " . $e->getMessage();
|
|
}
|
|
|
|
?>
|
|
|
|
<div class="container-fluid">
|
|
<h1 class="mt-4">Gestionar Idiomas de Traducción</h1>
|
|
<p class="text-muted">Activa o desactiva los idiomas a los que el bot traducirá automáticamente los mensajes.</p>
|
|
|
|
<?php if (isset($errorMessage)): ?>
|
|
<div class="alert alert-danger"><?= htmlspecialchars($errorMessage) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="card shadow-sm">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Idiomas Soportados</h5>
|
|
<button id="sync-languages-btn" class="btn btn-secondary btn-sm">
|
|
<i class="bi bi-arrow-repeat me-1"></i> Sincronizar con LibreTranslate
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="language-list" class="list-group">
|
|
<?php if (empty($languages)): ?>
|
|
<div class="list-group-item">No se encontraron idiomas.</div>
|
|
<?php else: ?>
|
|
<?php foreach ($languages as $lang): ?>
|
|
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<div class="d-flex align-items-center">
|
|
<div class="flag-container me-2" style="min-width: 40px;">
|
|
<span class="fs-4 flag-emoji"><?= htmlspecialchars($lang['flag_emoji'] ?? '') ?></span>
|
|
<div class="edit-flag-form d-none">
|
|
<div class="input-group input-group-sm">
|
|
<input type="text" class="form-control flag-input" value="<?= htmlspecialchars($lang['flag_emoji'] ?? '') ?>" placeholder=" पेस्ट">
|
|
<button class="btn btn-success btn-sm save-flag-btn" data-lang-id="<?= $lang['id'] ?>">✓</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<i class="bi bi-pencil-square edit-flag-btn me-2" style="cursor: pointer;" data-lang-id="<?= $lang['id'] ?>"></i>
|
|
<div>
|
|
<span class="fw-bold"><?= htmlspecialchars($lang['language_name']) ?></span>
|
|
<small class="text-muted">(<?= htmlspecialchars($lang['language_code']) ?>)</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input language-toggle" type="checkbox" role="switch"
|
|
id="lang-toggle-<?= $lang['id'] ?>"
|
|
data-lang-id="<?= $lang['id'] ?>"
|
|
<?= $lang['is_active'] ? 'checked' : '' ?>>
|
|
<label class="form-check-label" for="lang-toggle-<?= $lang['id'] ?>"></label>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="alert-container" class="position-fixed bottom-0 end-0 p-3" style="z-index: 11"></div>
|
|
</div>
|
|
|
|
<?php require_once __DIR__ . '/../templates/footer.php'; ?>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const languageToggles = document.querySelectorAll('.language-toggle');
|
|
const syncBtn = document.getElementById('sync-languages-btn');
|
|
|
|
if (syncBtn) {
|
|
syncBtn.addEventListener('click', function () {
|
|
const originalHtml = this.innerHTML;
|
|
this.disabled = true;
|
|
this.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sincronizando...';
|
|
|
|
fetch('sync_languages.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showAlert(`Sincronización completada. Se añadieron ${data.new_languages} nuevos idiomas.`, 'success');
|
|
setTimeout(() => window.location.reload(), 2000);
|
|
} else {
|
|
showAlert('Error en la sincronización: ' + data.error, 'danger');
|
|
this.disabled = false;
|
|
this.innerHTML = originalHtml;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error de red durante la sincronización.', 'danger');
|
|
this.disabled = false;
|
|
this.innerHTML = originalHtml;
|
|
});
|
|
});
|
|
}
|
|
|
|
languageToggles.forEach(toggle => {
|
|
toggle.addEventListener('change', function () {
|
|
const langId = this.dataset.langId;
|
|
const isActive = this.checked;
|
|
|
|
fetch('update_language_status.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify({ id: langId, is_active: isActive })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showAlert('Estado del idioma actualizado con éxito.', 'success');
|
|
} else {
|
|
showAlert('Error: ' + data.error, 'danger');
|
|
// Revertir el cambio visual si falla la actualización
|
|
this.checked = !isActive;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error de red al actualizar el idioma.', 'danger');
|
|
this.checked = !isActive;
|
|
});
|
|
});
|
|
});
|
|
|
|
// Lógica para editar la bandera
|
|
const languageList = document.getElementById('language-list');
|
|
if (languageList) {
|
|
languageList.addEventListener('click', function(e) {
|
|
// Botón de editar
|
|
if (e.target.classList.contains('edit-flag-btn')) {
|
|
const listItem = e.target.closest('.list-group-item');
|
|
listItem.querySelector('.flag-emoji').classList.add('d-none');
|
|
e.target.classList.add('d-none');
|
|
listItem.querySelector('.edit-flag-form').classList.remove('d-none');
|
|
listItem.querySelector('.flag-input').focus();
|
|
}
|
|
|
|
// Botón de guardar
|
|
if (e.target.classList.contains('save-flag-btn')) {
|
|
const langId = e.target.dataset.langId;
|
|
const listItem = e.target.closest('.list-group-item');
|
|
const input = listItem.querySelector('.flag-input');
|
|
const newEmoji = input.value;
|
|
|
|
fetch('update_language_flag.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify({ id: langId, flag_emoji: newEmoji })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
const flagEmojiSpan = listItem.querySelector('.flag-emoji');
|
|
flagEmojiSpan.textContent = newEmoji;
|
|
flagEmojiSpan.classList.remove('d-none');
|
|
listItem.querySelector('.edit-flag-form').classList.add('d-none');
|
|
listItem.querySelector('.edit-flag-btn').classList.remove('d-none');
|
|
showAlert('Bandera actualizada.', 'success');
|
|
} else {
|
|
showAlert('Error: ' + data.error, 'danger');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showAlert('Error de red al actualizar la bandera.', 'danger');
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function showAlert(message, type = 'success') {
|
|
const alertContainer = document.getElementById('alert-container');
|
|
const alert = document.createElement('div');
|
|
alert.className = `alert alert-${type} alert-dismissible fade show`;
|
|
alert.role = 'alert';
|
|
alert.innerHTML = `
|
|
${message}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
`;
|
|
alertContainer.appendChild(alert);
|
|
|
|
setTimeout(() => {
|
|
const bsAlert = new bootstrap.Alert(alert);
|
|
bsAlert.close();
|
|
}, 3000);
|
|
}
|
|
});
|
|
</script>
|