From 70b712ff3bdacd3e93392fd7c9f337a82b4d3352 Mon Sep 17 00:00:00 2001 From: solocla Date: Tue, 26 May 2026 16:55:04 +0200 Subject: [PATCH] trainings changed details --- public/userarea/production_dashboard.php | 102 ++++- public/userarea/training_calendar.php | 211 ++++++++-- public/userarea/training_topics.php | 298 +++++++++++--- public/userarea/trainings.php | 485 +++++++++++++++++++---- 4 files changed, 913 insertions(+), 183 deletions(-) diff --git a/public/userarea/production_dashboard.php b/public/userarea/production_dashboard.php index ce821aa..ddd747e 100644 --- a/public/userarea/production_dashboard.php +++ b/public/userarea/production_dashboard.php @@ -150,7 +150,7 @@ $dashboardSections = [ [ 'id' => 'secPersonale', 'title' => 'Personale', - 'subtitle' => 'Dipendenti, skill', + 'subtitle' => 'Dipendenti, formazione, skill', 'icon' => 'đŸ‘Ĩ', 'open' => false, 'buttons' => [ @@ -168,6 +168,20 @@ $dashboardSections = [ 'url' => 'departments.php', 'permission' => 'hr.departments.view', ], + [ + 'label' => 'Corsi Formazione', + 'icon' => '📚', + 'class' => 'btn-setup', + 'url' => 'training_topics.php', + 'permission' => 'hr.training_topics.view', + ], + [ + 'label' => 'Storico Formazione', + 'icon' => '🎓', + 'class' => 'btn-setup', + 'url' => 'trainings.php', + 'permission' => 'hr.trainings.view', + ], [ 'label' => 'Skills', 'icon' => '🧠', @@ -494,45 +508,97 @@ $dashboardSections = [ margin-bottom: 1rem; width: 100%; } - .my-deadlines-widgets:empty { display: none; } + + .my-deadlines-widgets:empty { + display: none; + } + /* Each widget wraps itself in .my-deadlines-widgets; collapse the nested wrapper so all cards flow into the outer flex (single row). */ .my-deadlines-widgets .my-deadlines-widgets { display: contents; } + .my-deadlines-widgets .mdw { flex: 1 1 0; min-width: 0; - display: flex; align-items: center; gap: 0.75rem; + display: flex; + align-items: center; + gap: 0.75rem; padding: 0.8rem 0.9rem; border-radius: 0.6rem; text-decoration: none; color: #fff; - box-shadow: 0 2px 6px rgba(0,0,0,0.08); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); transition: transform 0.15s, box-shadow 0.15s; } + @media (max-width: 991.98px) { - .my-deadlines-widgets .mdw { flex: 1 1 calc(50% - 0.375rem); } + .my-deadlines-widgets .mdw { + flex: 1 1 calc(50% - 0.375rem); + } } + @media (max-width: 575.98px) { - .my-deadlines-widgets .mdw { flex: 1 1 100%; } + .my-deadlines-widgets .mdw { + flex: 1 1 100%; + } } - .my-deadlines-widgets .mdw:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); color: #fff; } - .my-deadlines-widgets .mdw-red { background: linear-gradient(135deg, #dc3545 0%, #b02a37 100%); } - .my-deadlines-widgets .mdw-orange { background: linear-gradient(135deg, #e8930c 0%, #c77a00 100%); } - .my-deadlines-widgets .mdw-gray { background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%); } + + .my-deadlines-widgets .mdw:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + color: #fff; + } + + .my-deadlines-widgets .mdw-red { + background: linear-gradient(135deg, #dc3545 0%, #b02a37 100%); + } + + .my-deadlines-widgets .mdw-orange { + background: linear-gradient(135deg, #e8930c 0%, #c77a00 100%); + } + + .my-deadlines-widgets .mdw-gray { + background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%); + } + .my-deadlines-widgets .mdw-icon { - width: 38px; height: 38px; border-radius: 50%; - display: flex; align-items: center; justify-content: center; - background: rgba(255,255,255,0.22); font-size: 1.05rem; flex-shrink: 0; + width: 38px; + height: 38px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.22); + font-size: 1.05rem; + flex-shrink: 0; } - .my-deadlines-widgets .mdw-body { flex: 1; line-height: 1.2; min-width: 0; } - .my-deadlines-widgets .mdw-count { font-size: 1.5rem; font-weight: 700; } + + .my-deadlines-widgets .mdw-body { + flex: 1; + line-height: 1.2; + min-width: 0; + } + + .my-deadlines-widgets .mdw-count { + font-size: 1.5rem; + font-weight: 700; + } + .my-deadlines-widgets .mdw-label { - font-size: 0.78rem; opacity: 0.95; - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + font-size: 0.78rem; + opacity: 0.95; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .my-deadlines-widgets .mdw-arrow { + opacity: 0.7; + font-size: 0.85rem; + flex-shrink: 0; } - .my-deadlines-widgets .mdw-arrow { opacity: 0.7; font-size: 0.85rem; flex-shrink: 0; }
diff --git a/public/userarea/training_calendar.php b/public/userarea/training_calendar.php index 42cfb5e..e818436 100644 --- a/public/userarea/training_calendar.php +++ b/public/userarea/training_calendar.php @@ -43,37 +43,172 @@ $departments = $pdo->query(" Calendario Formazione - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> @@ -88,10 +223,20 @@ $departments = $pdo->query("
📅 Calendario Formazione
-
- - 📚 Storico Formazione - + +
+ + + 📘 Corsi Formazione + + + + + + 📚 Gestione Formazione + + + @@ -201,7 +346,9 @@ $departments = $pdo->query(" calendar.render(); document.querySelectorAll('#filterStatus, #filterTopic, #filterDepartment, #filterEmployee').forEach(function(el) { - el.addEventListener('change', function() { calendar.refetchEvents(); }); + el.addEventListener('change', function() { + calendar.refetchEvents(); + }); }); document.getElementById('btnResetFilters').addEventListener('click', function() { @@ -214,4 +361,4 @@ $departments = $pdo->query(" - + \ No newline at end of file diff --git a/public/userarea/training_topics.php b/public/userarea/training_topics.php index ea19018..8aacc31 100644 --- a/public/userarea/training_topics.php +++ b/public/userarea/training_topics.php @@ -33,36 +33,193 @@ $topics = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC); @@ -246,11 +481,25 @@ function fmtDate(?string $d): string {
-
📚 Storico Formazione
-
+
📚 Gestione Formazione
+ +
+ + + + 📘 Corsi Formazione + + + + + + 📅 Calendario Formazione + + + @@ -323,7 +572,7 @@ function fmtDate(?string $d): string {
@@ -387,7 +636,7 @@ function fmtDate(?string $d): string { - — + — @@ -396,11 +645,11 @@ function fmtDate(?string $d): string { — - - - - + - + + + + + + @@ -514,7 +763,9 @@ function fmtDate(?string $d): string {
-

+
+
+
@@ -600,7 +851,9 @@ function fmtDate(?string $d): string { }); document.getElementById('bulkSelectAll').addEventListener('click', function() { - var all = $emp.find('option').map(function() { return this.value; }).get(); + var all = $emp.find('option').map(function() { + return this.value; + }).get(); $emp.val(all).trigger('change'); }); document.getElementById('bulkClear').addEventListener('click', function() { @@ -613,9 +866,18 @@ function fmtDate(?string $d): string { var completed = document.getElementById('bulkCompletedDate').value; var emps = $emp.val() || []; - if (!topicId) { Swal.fire('Attenzione', 'Selezionare un corso.', 'warning'); return; } - if (!completed) { Swal.fire('Attenzione', 'Indicare la data di completamento.', 'warning'); return; } - if (emps.length === 0) { Swal.fire('Attenzione', 'Selezionare almeno un dipendente.', 'warning'); return; } + if (!topicId) { + Swal.fire('Attenzione', 'Selezionare un corso.', 'warning'); + return; + } + if (!completed) { + Swal.fire('Attenzione', 'Indicare la data di completamento.', 'warning'); + return; + } + if (emps.length === 0) { + Swal.fire('Attenzione', 'Selezionare almeno un dipendente.', 'warning'); + return; + } var btn = document.getElementById('bulkSaveBtn'); btn.disabled = true; @@ -630,22 +892,39 @@ function fmtDate(?string $d): string { fd.append('description', document.getElementById('bulkDescription').value); fd.append('update_frequency_months', document.getElementById('bulkFreq').value); fd.append('reminder_days', document.getElementById('bulkRem').value); - emps.forEach(function(id) { fd.append('employee_ids[]', id); }); + emps.forEach(function(id) { + fd.append('employee_ids[]', id); + }); - fetch('ajax/trainings/save_bulk_training.php', { method: 'POST', body: fd }) - .then(function(r) { return r.json(); }) + fetch('ajax/trainings/save_bulk_training.php', { + method: 'POST', + body: fd + }) + .then(function(r) { + return r.json(); + }) .then(function(data) { if (data.success) { bulkModal.hide(); - Swal.fire({ icon: 'success', title: 'Fatto', text: data.message, timer: 1800, showConfirmButton: false }) - .then(function() { location.reload(); }); + Swal.fire({ + icon: 'success', + title: 'Fatto', + text: data.message, + timer: 1800, + showConfirmButton: false + }) + .then(function() { + location.reload(); + }); } else { - btn.disabled = false; btn.innerHTML = orig; + btn.disabled = false; + btn.innerHTML = orig; Swal.fire('Errore', data.message || 'Errore.', 'error'); } }) .catch(function() { - btn.disabled = false; btn.innerHTML = orig; + btn.disabled = false; + btn.innerHTML = orig; Swal.fire('Errore', 'Errore di connessione.', 'error'); }); }); @@ -682,14 +961,22 @@ function fmtDate(?string $d): string { function checkedIds() { return Array.prototype.slice.call(document.querySelectorAll('.row-check:checked')) - .map(function(c) { return c.value; }); + .map(function(c) { + return c.value; + }); } + function refreshBulkBar() { var ids = checkedIds(); var bar = document.getElementById('bulkBar'); document.getElementById('bulkSelCount').textContent = ids.length; - if (ids.length > 0) { bar.classList.remove('d-none'); bar.classList.add('d-flex'); } - else { bar.classList.add('d-none'); bar.classList.remove('d-flex'); } + if (ids.length > 0) { + bar.classList.remove('d-none'); + bar.classList.add('d-flex'); + } else { + bar.classList.add('d-none'); + bar.classList.remove('d-flex'); + } var all = document.querySelectorAll('.row-check'); if (checkAll) checkAll.checked = (all.length > 0 && ids.length === all.length); } @@ -698,11 +985,15 @@ function fmtDate(?string $d): string { if (e.target && e.target.classList && e.target.classList.contains('row-check')) refreshBulkBar(); }); if (checkAll) checkAll.addEventListener('change', function() { - document.querySelectorAll('.row-check').forEach(function(c) { c.checked = checkAll.checked; }); + document.querySelectorAll('.row-check').forEach(function(c) { + c.checked = checkAll.checked; + }); refreshBulkBar(); }); document.getElementById('btnBulkDeselect').addEventListener('click', function() { - document.querySelectorAll('.row-check').forEach(function(c) { c.checked = false; }); + document.querySelectorAll('.row-check').forEach(function(c) { + c.checked = false; + }); if (checkAll) checkAll.checked = false; refreshBulkBar(); }); @@ -718,8 +1009,14 @@ function fmtDate(?string $d): string { e.preventDefault(); var ids = checkedIds(); var date = document.getElementById('renewDate').value; - if (ids.length === 0) { renewModal.hide(); return; } - if (!date) { Swal.fire('Attenzione', 'Indicare la data.', 'warning'); return; } + if (ids.length === 0) { + renewModal.hide(); + return; + } + if (!date) { + Swal.fire('Attenzione', 'Indicare la data.', 'warning'); + return; + } var btn = document.getElementById('renewSaveBtn'); btn.disabled = true; @@ -728,26 +1025,44 @@ function fmtDate(?string $d): string { var fd = new FormData(); fd.append('completed_date', date); - ids.forEach(function(id) { fd.append('training_ids[]', id); }); + ids.forEach(function(id) { + fd.append('training_ids[]', id); + }); - fetch('ajax/trainings/bulk_update_deadline.php', { method: 'POST', body: fd }) - .then(function(r) { return r.json(); }) + fetch('ajax/trainings/bulk_update_deadline.php', { + method: 'POST', + body: fd + }) + .then(function(r) { + return r.json(); + }) .then(function(data) { if (data.success) { renewModal.hide(); - Swal.fire({ icon: 'success', title: 'Fatto', text: data.message, timer: 1800, showConfirmButton: false }) - .then(function() { location.reload(); }); + Swal.fire({ + icon: 'success', + title: 'Fatto', + text: data.message, + timer: 1800, + showConfirmButton: false + }) + .then(function() { + location.reload(); + }); } else { - btn.disabled = false; btn.innerHTML = orig; + btn.disabled = false; + btn.innerHTML = orig; Swal.fire('Errore', data.message || 'Errore.', 'error'); } }) .catch(function() { - btn.disabled = false; btn.innerHTML = orig; + btn.disabled = false; + btn.innerHTML = orig; Swal.fire('Errore', 'Errore di connessione.', 'error'); }); }); }); - + + \ No newline at end of file