<script>
// Añadir clase logged-in al body si el usuario está logueado
document.addEventListener('DOMContentLoaded', function() {
{% if app.user %}
document.body.classList.add('logged-in');
{% endif %}
// Configurar validación de fecha de inicio
const fechaInicioInput = document.querySelector('input[name="solicitud_accion_formativa_search[fechaInicio]"]');
if (fechaInicioInput) {
// Establecer fecha mínima como hoy
const today = new Date().toISOString().split('T')[0];
fechaInicioInput.setAttribute('min', today);
// Validación en tiempo real
fechaInicioInput.addEventListener('change', function() {
const selectedDate = new Date(this.value);
const todayDate = new Date();
todayDate.setHours(0, 0, 0, 0);
if (selectedDate < todayDate) {
this.setCustomValidity('{{ "validation.start_date_future"|trans({}, "courses") }}');
this.reportValidity();
} else {
this.setCustomValidity('');
}
});
}
});
document.addEventListener('DOMContentLoaded', function() {
// Handle empresa course enrollment buttons
{% if app.user and constant('App\\Enum\\RolEnum::EMPRESA') in app.user.roles %}
const solicitarCursoButtons = document.querySelectorAll('.solicitar-curso-empresa');
solicitarCursoButtons.forEach(function(button) {
button.addEventListener('click', function(e) {
e.preventDefault();
mostrarModalSeleccionEmpleados(button, 'solicitarCurso');
});
});
{% endif %}
});
/**
* Show employee selection modal for company actions
*/
function mostrarModalSeleccionEmpleados(button, accion) {
const actividadId = button.dataset.actividadId;
const actividadTipo = button.dataset.actividadTipo;
const cursoNombre = button.dataset.cursoNombre || 'curso';
const modalId = 'modalSeleccionEmpleados' + actividadTipo + actividadId + accion;
let modal = document.getElementById(modalId);
if (!modal) {
// Create the modal
modal = document.createElement('div');
modal.id = modalId;
modal.className = 'modal fade';
modal.setAttribute('role', 'dialog');
const tituloAccion = accion === 'mostrarInteres' ? '{{ "course.action.show_interest"|trans({}, "courses") }}' : '{{ "course.action.request_course"|trans({}, "courses") }}';
modal.innerHTML = `
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ "course.modal.select_employees"|trans({}, "courses") }} ${tituloAccion} "${cursoNombre}"</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="empleados-loading-${modalId}" class="text-center">
<i class="fa fa-spinner fa-spin"></i> {{ "course.modal.loading_employees"|trans({}, "courses") }}
</div>
<div id="empleados-error-${modalId}" style="display: none;" class="alert alert-danger">
<!-- Error messages will be shown here -->
</div>
<div id="empleados-content-${modalId}" style="display: none;">
<div class="form-group">
<input type="text" class="form-control" id="buscar-empleado-${modalId}" placeholder="{{ "course.modal.search_placeholder"|trans({}, "courses") }}" style="max-width: 100%; width: 100%; box-sizing: border-box;">
</div>
<div class="empleados-list" id="empleados-list-${modalId}">
<!-- Employee list will be populated here -->
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ "common.cancel"|trans }}</button>
<button type="button" class="btn btn-primary" id="confirmar-accion-${modalId}" disabled>
${accion === 'mostrarInteres' ? '{{ "course.modal.update_interests"|trans({}, "courses") }}' : '{{ "course.modal.update_enrollments"|trans({}, "courses") }}'}
</button>
</div>
</div>
</div>
`;
document.body.appendChild(modal);
// Add event listeners
const confirmarBtn = modal.querySelector('#confirmar-accion-' + modalId);
confirmarBtn.addEventListener('click', function() {
confirmarAccionEmpresa(modalId, actividadId, actividadTipo, accion);
});
const searchInput = modal.querySelector('#buscar-empleado-' + modalId);
searchInput.addEventListener('input', function() {
filtrarEmpleados(modalId, this.value);
});
}
// Show modal
$(modal).modal('show');
// Load employees
cargarEmpleadosAutorizados(modalId, actividadId, actividadTipo, accion);
}
/**
* Load authorized employees
*/
function cargarEmpleadosAutorizados(modalId, actividadId, actividadTipo, accion) {
const url = new URL('/es/empresa/mi-equipo/empleados-autorizados-cursos', window.location.origin);
if (actividadId) url.searchParams.append('actividadId', actividadId);
if (actividadTipo) url.searchParams.append('actividadTipo', actividadTipo);
if (accion) url.searchParams.append('accion', accion);
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.success) {
mostrarListaEmpleados(modalId, data.empleados);
} else {
mostrarErrorEmpleados(modalId, data.message || '{{ "course.modal.error_loading_employees"|trans({}, "courses") }}');
}
})
.catch(error => {
console.error('Error:', error);
mostrarErrorEmpleados(modalId, '{{ "course.modal.connection_error"|trans({}, "courses") }}');
});
}
/**
* Show employees list
*/
function mostrarListaEmpleados(modalId, empleados) {
const loadingDiv = document.getElementById('empleados-loading-' + modalId);
const contentDiv = document.getElementById('empleados-content-' + modalId);
const listDiv = document.getElementById('empleados-list-' + modalId);
loadingDiv.style.display = 'none';
contentDiv.style.display = 'block';
if (empleados.length === 0) {
listDiv.innerHTML = '<div class="alert alert-info">{{ "course.modal.no_authorized_employees"|trans({}, "courses") }}</div>';
return;
}
let html = '<table class="table table-striped" style="margin-top: 15px;"><thead><tr>' +
'<th><input type="checkbox" id="select-all-' + modalId + '"> {{ "course.modal.select_all"|trans({}, "courses") }}</th>' +
'<th>{{ "course.modal.full_name"|trans({}, "courses") }}</th>' +
'<th>{{ "course.modal.email"|trans({}, "courses") }}</th>' +
'<th>{{ "course.modal.phone"|trans({}, "courses") }}</th>' +
'</tr></thead><tbody>';
empleados.forEach(function(empleado) {
const isChecked = empleado.isPreseleccionado ? 'checked' : '';
const initiallyChecked = empleado.isPreseleccionado ? 'true' : 'false';
html += `
<tr class="empleado-row" data-nombre="${empleado.nombreCompleto.toLowerCase()}" data-email="${empleado.email.toLowerCase()}">
<td><input type="checkbox" class="empleado-checkbox" value="${empleado.id}" ${isChecked} data-initially-checked="${initiallyChecked}"></td>
<td>${empleado.nombreCompleto}</td>
<td>${empleado.email}</td>
<td>${empleado.telefono || '-'}</td>
</tr>
`;
});
html += '</tbody></table>';
listDiv.innerHTML = html;
// Add event listeners
const selectAllCheckbox = document.getElementById('select-all-' + modalId);
const empleadoCheckboxes = listDiv.querySelectorAll('.empleado-checkbox');
const confirmarBtn = document.getElementById('confirmar-accion-' + modalId);
selectAllCheckbox.addEventListener('change', function() {
empleadoCheckboxes.forEach(function(checkbox) {
if (checkbox.closest('.empleado-row').style.display !== 'none') {
checkbox.checked = selectAllCheckbox.checked;
}
});
updateConfirmarButton(modalId);
});
/*empleadoCheckboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', function() {
updateConfirmarButton(modalId);
});
});*/
$(document).on("change", ".empleado-checkbox", function(event)
{
var $table = $(this).closest("table");
var $checkboxes = $table.find("tbody .empleado-checkbox");
var $headerCheckbox = $table.find("thead input[type='checkbox']");
var allChecked = $checkboxes.length === $checkboxes.filter(":checked").length;
$headerCheckbox.prop("checked", allChecked);
updateConfirmarButton(modalId);
});
// Update button state initially (in case some employees are preselected)
updateConfirmarButton(modalId);
}
/**
* Show employees error
*/
function mostrarErrorEmpleados(modalId, message) {
const loadingDiv = document.getElementById('empleados-loading-' + modalId);
const errorDiv = document.getElementById('empleados-error-' + modalId);
loadingDiv.style.display = 'none';
errorDiv.style.display = 'block';
errorDiv.textContent = message;
}
/**
* Filter employees
*/
function filtrarEmpleados(modalId, searchTerm) {
const listDiv = document.getElementById('empleados-list-' + modalId);
const rows = listDiv.querySelectorAll('.empleado-row');
searchTerm = searchTerm.toLowerCase();
rows.forEach(function(row) {
const nombre = row.dataset.nombre;
const email = row.dataset.email;
if (nombre.includes(searchTerm) || email.includes(searchTerm)) {
row.style.display = '';
} else {
row.style.display = 'none';
// Uncheck hidden rows
const checkbox = row.querySelector('.empleado-checkbox');
checkbox.checked = false;
}
});
updateConfirmarButton(modalId);
}
/**
* Update confirm button state
*/
function updateConfirmarButton(modalId) {
const listDiv = document.getElementById('empleados-list-' + modalId);
const visibleCheckboxes = Array.from(listDiv.querySelectorAll('.empleado-checkbox')).filter(function(checkbox) {
return checkbox.closest('.empleado-row').style.display !== 'none';
});
const confirmarBtn = document.getElementById('confirmar-accion-' + modalId);
// Check if there's any change from the initial state (preselected employees)
const initiallySelected = visibleCheckboxes.filter(function(checkbox) {
return checkbox.dataset.initiallyChecked === 'true';
});
const currentlySelected = visibleCheckboxes.filter(function(checkbox) {
return checkbox.checked;
});
// Enable button if there's any change from initial state
const hasChanges = initiallySelected.length !== currentlySelected.length ||
!initiallySelected.every(checkbox => checkbox.checked) ||
!currentlySelected.every(checkbox => checkbox.dataset.initiallyChecked === 'true');
confirmarBtn.disabled = !hasChanges;
}
/**
* Confirm company action
*/
function confirmarAccionEmpresa(modalId, actividadId, actividadTipo, accion) {
const listDiv = document.getElementById('empleados-list-' + modalId);
const checkedCheckboxes = listDiv.querySelectorAll('.empleado-checkbox:checked');
const empleadosIds = Array.from(checkedCheckboxes).map(function(checkbox) {
return parseInt(checkbox.value);
});
// Send AJAX request
const url = '/es/courses/ajax/accion-curso-empresa';
const requestData = {
empleadosIds: empleadosIds,
actividadId: actividadId,
actividadTipo: actividadTipo,
accion: accion
};
// Disable confirm button
const confirmarBtn = document.getElementById('confirmar-accion-' + modalId);
confirmarBtn.disabled = true;
confirmarBtn.textContent = '{{ "course.modal.processing"|trans({}, "courses") }}';
let modalTitle = $('#' + modalId + ' h5.modal-title').html();
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify(requestData),
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.success) {console.log(data.details);
if(data.details.inscritoAll)
{
if($("button[data-actividad-id=" + actividadId + "]").parent().hasClass('footer') || // LIST
$("button[data-actividad-id=" + actividadId + "]").parent().hasClass('actions')) // DETALLE
{
$("button[data-actividad-id=" + actividadId + "]").parent().prepend('<span class="btn btn-secondary disabled">{{ 'courses.already_enrolled'|trans({}, 'courses')|default('Ya inscrito en este curso') }}</span>');
$("button[data-actividad-id=" + actividadId + "]").remove();
}
}
else if (data.details.interes || data.details.inscrito) {
$("button[data-actividad-id=" + actividadId + "]").removeClass(["btn-secondary", "btn-primary"]).addClass("btn-primary");
}
else if(data.details.interes === false || data.details.inscrito === false)
{
$("button[data-actividad-id=" + actividadId + "]").removeClass(["btn-secondary", "btn-primary"]).addClass("btn-secondary");
}
var richMsg = data.message || '{{ "course.modal.action_completed"|trans({}, "courses") }}';
if (data.breakdown) {
var b = data.breakdown;
var lines = [];
if (b.added) lines.push('✓ ' + b.added + ' marcat' + (b.added > 1 ? 's' : '') + ' correctament');
if (b.already) lines.push('• ' + b.already + ' ja ' + (b.already > 1 ? 'tenien' : 'tenia') + ' interès');
if (b.no_account) lines.push('✕ ' + b.no_account + ' sense compte (no registrats al sistema)');
if (b.errors && b.errors.length) {
b.errors.forEach(function(e) { lines.push('✕ ' + e); });
}
if (lines.length) richMsg = lines.join('<br>');
}
AlertUtils.success(modalTitle, richMsg, {html: true}, AlertUtils.Buttons.simple);
// Close modal
$('#' + modalId).modal('hide');
$("#" + modalId + " .empleados-list").html(null);
$("#" + modalId + " div.alert").html(null);
// Show success message
{#alert(data.message || '{{ "course.modal.action_completed"|trans({}, "courses") }}');#}
// Optionally reload page or update UI
// window.location.reload();
} else {
{#alert(data.message || '{{ "course.modal.error_processing_action"|trans({}, "courses") }}');#}
AlertUtils.danger(modalTitle, data.message || '{{ "course.modal.error_processing_action"|trans({}, "courses") }}', {}, AlertUtils.Buttons.simple);
}
})
.catch(error => {
console.error('Error:', error);
{#alert('{{ "course.modal.connection_error_processing"|trans({}, "courses") }}');#}
AlertUtils.danger(modalTitle, data.message || '{{ "course.modal.connection_error_processing"|trans({}, "courses") }}', {}, AlertUtils.Buttons.simple);
})
.finally(function() {
// Re-enable confirm button
confirmarBtn.disabled = false;
confirmarBtn.textContent = accion === 'mostrarInteres' ? '{{ "course.modal.update_interests"|trans({}, "courses") }}' : '{{ "course.modal.update_enrollments"|trans({}, "courses") }}';
});
}
</script>