Verificación de caracteres en gestión de cursos
This commit is contained in:
parent
29ed4d7847
commit
272026f236
|
@ -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()]);
|
||||
}
|
||||
?>
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue