Verificación de caracteres en gestión de cursos

This commit is contained in:
carlos.bonilla 2025-06-19 15:57:05 -06:00
parent 29ed4d7847
commit 272026f236
2 changed files with 122 additions and 54 deletions

View File

@ -7,38 +7,48 @@ if (!is_logged_in()) {
echo json_encode(['error' => 'No autenticado']);
exit;
}
try {
$profesorId = $_GET['profesor_id'] ?? null;
$query = "
SELECT d.*, a.nombre AS alumno_nombre, c.nombre AS curso_nombre
SELECT
d.codigo_unico,
d.fecha_emision,
a.nombre AS alumno_nombre,
a.email AS alumno_email,
c.nombre AS curso_nombre,
c.tipo AS curso_tipo
FROM diplomas d
JOIN alumnos_cursos ac ON d.alumno_curso_id = ac.id
JOIN alumnos a ON ac.alumno_id = a.id
JOIN cursos c ON ac.curso_id = c.id
";
$params = [];
if ($profesorId) {
$query .= " WHERE c.profesor_id = ?";
$params[] = $profesorId;
}
$query .= " ORDER BY d.fecha_emision DESC";
$stmt = $pdo->prepare($query);
$stmt->execute($params);
$diplomas = $stmt->fetchAll();
$diplomas = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$row['fecha_formateada'] = date("d/m/Y", strtotime($row['fecha_emision']));
$diplomas[] = $row;
}
echo json_encode([
'success' => true,
'data' => $diplomas,
'count' => count($diplomas)
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
?>

View File

@ -385,12 +385,16 @@ function loadProfessorCourses(container) {
<option value="archivado">Archivado</option>
</select>
<div class="action-buttons">
<button class="btn btn-success" type="submit">Guardar</button>
<button class="btn btn-outline" type="button" id="cancelCourseBtn" style="display:none; margin-left:8px; background-color: #f44336;">
<div class="form-actions">
<button type="button" class="btn btn-outline" id="cancelCourseBtn" style="display:none;">
Cancelar
</button>
<button type="submit" class="btn">
<span id="submitCourseText">Guardar</span>
<span class="spinner-border spinner-border-sm" id="submitCourseSpinner" style="display:none;"></span>
</button>
</div>
</form>
</div>
<div class="card">
@ -435,7 +439,7 @@ function loadProfessorCourses(container) {
<td>
<div class="action-buttons">
<button class="btn btn-sm" onclick="editCourse(${course.id})">Editar</button>
<button class="btn btn-sm btn-danger" onclick="deleteCourse(${course.id})">Eliminar</button>
<button class="btn btn-sm btn-danger" onclick="confirmDeleteCourse(${course.id})">Eliminar</button>
</div>
</td>
</tr>`;
@ -483,6 +487,46 @@ function formatCourseType(type) {
return types[type] || type;
}
window.createCourse = function (data, callback) {
fetch("api/cursos.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((res) => {
if (res.success) {
callback(true, "Curso creado correctamente");
} else {
callback(false, res.error || "Error al crear curso");
}
})
.catch(() => {
callback(false, "No se pudo conectar con el servidor");
});
};
window.updateCourse = function (id, data, callback) {
data.id = id;
fetch("api/cursos.php", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((res) => {
if (res.success) {
callback(true, "Curso actualizado correctamente");
} else {
callback(false, res.error || "Error al actualizar curso");
}
})
.catch(() => {
callback(false, "No se pudo conectar con el servidor");
});
};
function setupCourseForm() {
const courseTypeSelect = document.getElementById('courseType');
const competencesField = document.getElementById('competencesField');
@ -509,19 +553,30 @@ function setupCourseForm() {
if (!form) return;
const cancelBtn = document.getElementById("cancelCourseBtn");
const submitBtn = form.querySelector("button[type='submit']");
const submitText = document.getElementById("submitCourseText");
const spinner = document.getElementById("submitCourseSpinner");
if (cancelBtn) {
cancelBtn.addEventListener("click", function () {
form.reset();
competencesField.classList.add("oculto");
form.dataset.editing = "false";
delete form.dataset.courseId;
form.querySelector("button[type='submit']").textContent = "Guardar";
submitText.textContent = "Guardar";
spinner.style.display = "none";
submitBtn.disabled = false;
cancelBtn.style.display = "none";
});
}
form.addEventListener("submit", function (e) {
e.preventDefault();
submitText.textContent = "Procesando...";
spinner.style.display = "inline-block";
submitBtn.disabled = true;
const formData = new FormData(this);
const jsonData = {
nombre: formData.get("nombre"),
@ -535,46 +590,26 @@ function setupCourseForm() {
const isEdit = form.dataset.editing === "true";
const courseId = form.dataset.courseId;
const callback = (success, message) => {
if (success) {
showToast("success", message);
showSection("courses");
} else {
showToast("error", message);
}
submitText.textContent = isEdit ? "Actualizar Curso" : "Guardar";
spinner.style.display = "none";
submitBtn.disabled = false;
};
if (isEdit) {
updateCourse(courseId, jsonData);
updateCourse(courseId, jsonData, callback);
} else {
createCourse(jsonData);
createCourse(jsonData, callback);
}
});
}
window.createCourse = function (data) {
fetch("api/cursos.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
showSection("courses");
}
})
.catch((error) => console.error("Error:", error));
};
window.updateCourse = function (id, data) {
data.id = id;
fetch("api/cursos.php", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
showSection("courses");
}
})
.catch((error) => console.error("Error:", error));
};
window.editCourse = function (id) {
fetch(`api/cursos.php?profesor_id=${getProfesorId()}`)
.then((response) => response.json())
@ -609,19 +644,42 @@ window.editCourse = function (id) {
};
window.deleteCourse = function (id) {
if (!confirm("¿Estás seguro de eliminar este curso?")) return;
window.confirmDeleteCourse = function (id) {
showModal(
"Confirmar eliminación",
"¿Estás seguro de eliminar este curso? Esta acción no se puede deshacer.",
[
{
text: "Cancelar",
class: "btn-outline",
handler: "closeModal",
},
{
text: "Eliminar",
class: "btn-danger",
handler: `deleteCourse(${id})`,
},
]
);
};
window.deleteCourse = function (id) {
fetch(`api/cursos.php?id=${id}`, {
method: "DELETE",
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
showSection("courses");
showToast("success", "Curso eliminado correctamente");
closeModal();
loadProfessorCourses(document.querySelector("#courses-content"));
} else {
showToast("error", data.error || "No se pudo eliminar el curso");
}
})
.catch((error) => console.error("Error:", error));
.catch((error) => {
showToast("error", "Error al eliminar el curso");
});
};
// Gestión de alumnos
@ -1240,7 +1298,7 @@ window.unassignStudent = async function (alumnoId, cursoId) {
function loadDiplomasSection(container) {
container.innerHTML = '<div class="loader">Cargando diplomas...</div>';
fetch(`api/diplomas.php?profesor_id=${getProfesorId()}`)
fetch(`api/diploma.php?profesor_id=${getProfesorId()}`)
.then((response) => {
if (!response.ok) throw new Error("Error en la respuesta del servidor");
return response.json();