fixed color
This commit is contained in:
@@ -51,10 +51,19 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
$approachDate = date('Y-m-d', strtotime($today . ' + ' . (int)$deadline['notification_days'] . ' days'));
|
$approachDate = date('Y-m-d', strtotime($today . ' + ' . (int)$deadline['notification_days'] . ' days'));
|
||||||
$isApproaching = !$isCompleted && !$isOverdue && $deadline['due_date'] <= $approachDate;
|
$isApproaching = !$isCompleted && !$isOverdue && $deadline['due_date'] <= $approachDate;
|
||||||
|
|
||||||
if ($isCompleted) { $statusLabel = 'Completata'; $statusClass = 'badge-completata'; }
|
if ($isCompleted) {
|
||||||
elseif ($isOverdue) { $statusLabel = 'Scaduta'; $statusClass = 'badge-scaduta'; }
|
$statusLabel = 'Completata';
|
||||||
elseif ($isApproaching) { $statusLabel = 'In scadenza'; $statusClass = 'badge-in-scadenza'; }
|
$statusClass = 'badge-completata';
|
||||||
else { $statusLabel = 'Attiva'; $statusClass = 'badge-attiva'; }
|
} elseif ($isOverdue) {
|
||||||
|
$statusLabel = 'Scaduta';
|
||||||
|
$statusClass = 'badge-scaduta';
|
||||||
|
} elseif ($isApproaching) {
|
||||||
|
$statusLabel = 'In scadenza';
|
||||||
|
$statusClass = 'badge-in-scadenza';
|
||||||
|
} else {
|
||||||
|
$statusLabel = 'Attiva';
|
||||||
|
$statusClass = 'badge-attiva';
|
||||||
|
}
|
||||||
|
|
||||||
$recurrenceLabels = ['once' => 'Una tantum', 'monthly' => 'Mensile', 'quarterly' => 'Trimestrale', 'semiannual' => 'Semestrale', 'annual' => 'Annuale', 'biennial' => 'Biennale', 'triennial' => 'Triennale', 'quadriennial' => 'Quadriennale', 'quinquennial' => 'Quinquennale', 'decennial' => 'Decennale', 'quindecennial' => 'Quindicennale'];
|
$recurrenceLabels = ['once' => 'Una tantum', 'monthly' => 'Mensile', 'quarterly' => 'Trimestrale', 'semiannual' => 'Semestrale', 'annual' => 'Annuale', 'biennial' => 'Biennale', 'triennial' => 'Triennale', 'quadriennial' => 'Quadriennale', 'quinquennial' => 'Quinquennale', 'decennial' => 'Decennale', 'quindecennial' => 'Quindicennale'];
|
||||||
$actionLabels = ['created' => 'Creata', 'updated' => 'Modificata', 'completed' => 'Completata', 'attachment_added' => 'Allegato aggiunto', 'attachment_removed' => 'Allegato rimosso', 'notification_sent' => 'Notifica inviata'];
|
$actionLabels = ['created' => 'Creata', 'updated' => 'Modificata', 'completed' => 'Completata', 'attachment_added' => 'Allegato aggiunto', 'attachment_removed' => 'Allegato rimosso', 'notification_sent' => 'Notifica inviata'];
|
||||||
@@ -65,6 +74,7 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -76,7 +86,11 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
<?php include('../cssinclude.php'); ?>
|
<?php include('../cssinclude.php'); ?>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<title><?= $deadline ? htmlspecialchars($deadline['topic'], ENT_QUOTES, 'UTF-8') . ' — ' : '' ?>Scadenzario</title>
|
<title><?= $deadline ? htmlspecialchars($deadline['topic'], ENT_QUOTES, 'UTF-8') . ' — ' : '' ?>Scadenzario</title>
|
||||||
<script>if(window.innerWidth>1024)document.addEventListener('DOMContentLoaded',function(){document.getElementById('appWrapper').classList.add('toggled')})</script>
|
<script>
|
||||||
|
if (window.innerWidth > 1024) document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
document.getElementById('appWrapper').classList.add('toggled')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--scad-primary: #5a8fd8;
|
--scad-primary: #5a8fd8;
|
||||||
@@ -88,136 +102,426 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
--scad-orange: #e8930c;
|
--scad-orange: #e8930c;
|
||||||
--scad-green: #198754;
|
--scad-green: #198754;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card {
|
.scad-card {
|
||||||
border: none; border-radius: 0.75rem;
|
border: none;
|
||||||
box-shadow: 0 2px 12px rgba(0,0,0,0.06); overflow: hidden;
|
border-radius: 0.75rem;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card .card-header {
|
.scad-card .card-header {
|
||||||
background: var(--scad-card-bg);
|
background: var(--scad-card-bg);
|
||||||
border-bottom: 1px solid var(--scad-card-border);
|
border-bottom: 1px solid var(--scad-card-border);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card .card-header h5 {
|
.scad-card .card-header h5 {
|
||||||
font-weight: 700; color: var(--scad-heading);
|
font-weight: 700;
|
||||||
margin: 0; font-size: 1.05rem;
|
color: var(--scad-heading);
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-card .card-body {
|
||||||
|
padding: 1.25rem;
|
||||||
}
|
}
|
||||||
.scad-card .card-body { padding: 1.25rem; }
|
|
||||||
|
|
||||||
.btn-scad-primary {
|
.btn-scad-primary {
|
||||||
background: var(--scad-primary); border: none; color: #fff;
|
background: var(--scad-primary);
|
||||||
font-weight: 600; font-size: 0.85rem; padding: 0.5rem 1rem;
|
border: none;
|
||||||
border-radius: 0.5rem; transition: all 0.2s;
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
.btn-scad-primary:hover { background: var(--scad-primary-hover); color: #fff; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(90,143,216,0.35); }
|
|
||||||
|
.btn-scad-primary:hover {
|
||||||
|
background: var(--scad-primary-hover);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(90, 143, 216, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
.btn-scad-outline {
|
.btn-scad-outline {
|
||||||
background: transparent; border: 1.5px solid var(--scad-primary); color: var(--scad-primary);
|
background: transparent;
|
||||||
font-weight: 600; font-size: 0.85rem; padding: 0.45rem 1rem; border-radius: 0.5rem; transition: all 0.2s;
|
border: 1.5px solid var(--scad-primary);
|
||||||
|
color: var(--scad-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding: 0.45rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
.btn-scad-outline:hover { background: var(--scad-primary); color: #fff; transform: translateY(-1px); }
|
|
||||||
|
.btn-scad-outline:hover {
|
||||||
|
background: var(--scad-primary);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
.btn-scad-green {
|
.btn-scad-green {
|
||||||
background: var(--scad-green); border: none; color: #fff;
|
background: var(--scad-green);
|
||||||
font-weight: 600; font-size: 0.85rem; padding: 0.5rem 1rem;
|
border: none;
|
||||||
border-radius: 0.5rem; transition: all 0.2s;
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scad-green:hover {
|
||||||
|
background: #157347;
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(25, 135, 84, 0.35);
|
||||||
}
|
}
|
||||||
.btn-scad-green:hover { background: #157347; color: #fff; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(25,135,84,0.35); }
|
|
||||||
|
|
||||||
.badge-status {
|
.badge-status {
|
||||||
font-weight: 600; font-size: 0.8rem; padding: 0.4em 0.75em;
|
font-weight: 600;
|
||||||
border-radius: 2rem; display: inline-block;
|
font-size: 0.8rem;
|
||||||
|
padding: 0.4em 0.75em;
|
||||||
|
border-radius: 2rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-attiva {
|
||||||
|
background: #e8eeff;
|
||||||
|
color: #3a6bb5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-scaduta {
|
||||||
|
background: #fde8e8;
|
||||||
|
color: #b91c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-in-scadenza {
|
||||||
|
background: #fef3cd;
|
||||||
|
color: #92600a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-completata {
|
||||||
|
background: #d1f2e0;
|
||||||
|
color: #0f5132;
|
||||||
}
|
}
|
||||||
.badge-attiva { background: #e8eeff; color: #3a6bb5; }
|
|
||||||
.badge-scaduta { background: #fde8e8; color: #b91c1c; }
|
|
||||||
.badge-in-scadenza{ background: #fef3cd; color: #92600a; }
|
|
||||||
.badge-completata { background: #d1f2e0; color: #0f5132; }
|
|
||||||
|
|
||||||
.detail-label {
|
.detail-label {
|
||||||
font-size: 0.75rem; font-weight: 700; text-transform: uppercase;
|
font-size: 0.75rem;
|
||||||
letter-spacing: 0.04em; color: #8e99b0; margin-bottom: 0.2rem;
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #8e99b0;
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-value {
|
.detail-value {
|
||||||
font-size: 0.95rem; color: var(--scad-heading); margin-bottom: 1rem;
|
font-size: 0.95rem;
|
||||||
|
color: var(--scad-heading);
|
||||||
|
margin-bottom: 1rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
.detail-value.text-danger-date { color: var(--scad-red); font-weight: 600; }
|
|
||||||
.detail-value.text-warning-date { color: var(--scad-orange); font-weight: 600; }
|
.detail-value.text-danger-date {
|
||||||
|
color: var(--scad-red);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.text-warning-date {
|
||||||
|
color: var(--scad-orange);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.person-chip {
|
.person-chip {
|
||||||
display: inline-flex; align-items: center; gap: 0.4rem;
|
display: inline-flex;
|
||||||
background: #f0f4ff; border: 1px solid #dde4f0; border-radius: 2rem;
|
align-items: center;
|
||||||
padding: 0.3rem 0.75rem 0.3rem 0.5rem; font-size: 0.85rem;
|
gap: 0.4rem;
|
||||||
margin: 0.2rem 0.15rem; color: var(--scad-heading);
|
background: #f0f4ff;
|
||||||
|
border: 1px solid #dde4f0;
|
||||||
|
border-radius: 2rem;
|
||||||
|
padding: 0.3rem 0.75rem 0.3rem 0.5rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin: 0.2rem 0.15rem;
|
||||||
|
color: var(--scad-heading);
|
||||||
}
|
}
|
||||||
.person-chip i { color: var(--scad-primary); font-size: 0.75rem; }
|
|
||||||
.person-chip .chip-dept { color: #8e99b0; font-size: 0.78rem; }
|
.person-chip i {
|
||||||
|
color: var(--scad-primary);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.person-chip .chip-dept {
|
||||||
|
color: #8e99b0;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
.dept-chip {
|
.dept-chip {
|
||||||
display: inline-flex; align-items: center; gap: 0.4rem;
|
display: inline-flex;
|
||||||
background: #eef6ee; border: 1px solid #c8e6c9; border-radius: 2rem;
|
align-items: center;
|
||||||
padding: 0.3rem 0.75rem 0.3rem 0.5rem; font-size: 0.85rem;
|
gap: 0.4rem;
|
||||||
margin: 0.2rem 0.15rem; color: #2e5e2e;
|
background: #eef6ee;
|
||||||
|
border: 1px solid #c8e6c9;
|
||||||
|
border-radius: 2rem;
|
||||||
|
padding: 0.3rem 0.75rem 0.3rem 0.5rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin: 0.2rem 0.15rem;
|
||||||
|
color: #2e5e2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-chip i {
|
||||||
|
color: #4caf50;
|
||||||
|
font-size: 0.75rem;
|
||||||
}
|
}
|
||||||
.dept-chip i { color: #4caf50; font-size: 0.75rem; }
|
|
||||||
|
|
||||||
/* Attachments */
|
/* Attachments */
|
||||||
.att-row {
|
.att-row {
|
||||||
display: flex; align-items: center; gap: 0.75rem;
|
display: flex;
|
||||||
padding: 0.65rem 0; border-bottom: 1px solid #f0f2f5;
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.65rem 0;
|
||||||
|
border-bottom: 1px solid #f0f2f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-icon-pdf {
|
||||||
|
background: #fde8e8;
|
||||||
|
color: #b91c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-icon-img {
|
||||||
|
background: #e8f5e9;
|
||||||
|
color: #2e7d32;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-icon-file {
|
||||||
|
background: #e8eeff;
|
||||||
|
color: #3a6bb5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-name {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--scad-heading);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-decoration: none;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-name:hover {
|
||||||
|
color: var(--scad-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-meta {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: #8e99b0;
|
||||||
}
|
}
|
||||||
.att-row:last-child { border-bottom: none; }
|
|
||||||
.att-icon { width: 36px; height: 36px; border-radius: 0.4rem; display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0; }
|
|
||||||
.att-icon-pdf { background: #fde8e8; color: #b91c1c; }
|
|
||||||
.att-icon-img { background: #e8f5e9; color: #2e7d32; }
|
|
||||||
.att-icon-file { background: #e8eeff; color: #3a6bb5; }
|
|
||||||
.att-info { flex: 1; min-width: 0; }
|
|
||||||
.att-name { font-weight: 600; color: var(--scad-heading); font-size: 0.9rem; text-decoration: none; word-break: break-all; }
|
|
||||||
.att-name:hover { color: var(--scad-primary); }
|
|
||||||
.att-meta { font-size: 0.78rem; color: #8e99b0; }
|
|
||||||
|
|
||||||
/* Timeline */
|
/* Timeline */
|
||||||
.timeline { position: relative; padding-left: 2rem; }
|
.timeline {
|
||||||
.timeline::before {
|
position: relative;
|
||||||
content: ''; position: absolute; left: 0.55rem; top: 0.5rem; bottom: 0.5rem;
|
padding-left: 2rem;
|
||||||
width: 2px; background: #e2e8f0;
|
|
||||||
}
|
}
|
||||||
.timeline-item { position: relative; padding-bottom: 1.25rem; }
|
|
||||||
.timeline-item:last-child { padding-bottom: 0; }
|
.timeline::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0.55rem;
|
||||||
|
top: 0.5rem;
|
||||||
|
bottom: 0.5rem;
|
||||||
|
width: 2px;
|
||||||
|
background: #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-dot {
|
.timeline-dot {
|
||||||
position: absolute; left: -1.7rem; top: 0.15rem;
|
position: absolute;
|
||||||
width: 22px; height: 22px; border-radius: 50%;
|
left: -1.7rem;
|
||||||
display: flex; align-items: center; justify-content: center;
|
top: 0.15rem;
|
||||||
font-size: 0.6rem; color: #fff; z-index: 1;
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 1;
|
||||||
box-shadow: 0 0 0 3px #fff;
|
box-shadow: 0 0 0 3px #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-header {
|
.timeline-header {
|
||||||
display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
margin-bottom: 0.15rem;
|
margin-bottom: 0.15rem;
|
||||||
}
|
}
|
||||||
.timeline-action { font-weight: 700; font-size: 0.88rem; color: var(--scad-heading); }
|
|
||||||
.timeline-user { font-size: 0.82rem; color: #6c757d; }
|
|
||||||
.timeline-date { font-size: 0.78rem; color: #adb5bd; }
|
|
||||||
.timeline-notes { font-size: 0.83rem; color: #6c757d; margin-top: 0.15rem; }
|
|
||||||
.timeline-changes { font-size: 0.82rem; margin-top: 0.3rem; background: #f8f9fb; border-radius: 0.4rem; padding: 0.5rem 0.75rem; }
|
|
||||||
.timeline-changes .change-field { font-weight: 600; color: var(--scad-heading); }
|
|
||||||
.timeline-changes .change-old { color: var(--scad-red); text-decoration: line-through; }
|
|
||||||
.timeline-changes .change-new { color: var(--scad-green); }
|
|
||||||
|
|
||||||
.scad-breadcrumb { background: transparent; padding: 0; margin-bottom: 1rem; }
|
.timeline-action {
|
||||||
.scad-breadcrumb .breadcrumb-item a { color: var(--scad-primary); text-decoration: none; font-weight: 500; transition: color 0.2s; }
|
font-weight: 700;
|
||||||
.scad-breadcrumb .breadcrumb-item a:hover { color: var(--scad-primary-hover); }
|
font-size: 0.88rem;
|
||||||
.scad-breadcrumb .breadcrumb-item.active { color: #6c757d; font-weight: 600; }
|
color: var(--scad-heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-user {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-date {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: #adb5bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-notes {
|
||||||
|
font-size: 0.83rem;
|
||||||
|
color: #6c757d;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-changes {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
background: #f8f9fb;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-changes .change-field {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--scad-heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-changes .change-old {
|
||||||
|
color: var(--scad-red);
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-changes .change-new {
|
||||||
|
color: var(--scad-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-breadcrumb {
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-breadcrumb .breadcrumb-item a {
|
||||||
|
color: var(--scad-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-breadcrumb .breadcrumb-item a:hover {
|
||||||
|
color: var(--scad-primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-breadcrumb .breadcrumb-item.active {
|
||||||
|
color: #6c757d;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
.action-bar { flex-direction: column; }
|
.action-bar {
|
||||||
.action-bar .btn { width: 100%; justify-content: center; }
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-bar .btn {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
.sidebar-wrapper, .topbar, .page-footer, .action-bar, .scad-breadcrumb { display: none !important; }
|
|
||||||
.page-wrapper { margin: 0 !important; }
|
.sidebar-wrapper,
|
||||||
.scad-card { box-shadow: none; border: 1px solid #ddd; }
|
.topbar,
|
||||||
@page { size: portrait; margin: 1cm; }
|
.page-footer,
|
||||||
|
.action-bar,
|
||||||
|
.scad-breadcrumb {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-wrapper {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scad-card {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
size: portrait;
|
||||||
|
margin: 1cm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-law-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
margin-left: 0.65rem;
|
||||||
|
padding: 0.42rem 0.85rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(90, 143, 216, 0.45);
|
||||||
|
background: linear-gradient(135deg, #5a8fd8 0%, #6f42c1 100%);
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: default;
|
||||||
|
user-select: none;
|
||||||
|
box-shadow: 0 4px 14px rgba(90, 143, 216, 0.35);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-law-btn i {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-law-btn:hover {
|
||||||
|
color: #ffffff !important;
|
||||||
|
background: linear-gradient(135deg, #4578c0 0%, #5b35a5 100%);
|
||||||
|
box-shadow: 0 6px 18px rgba(90, 143, 216, 0.45);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper" id="appWrapper">
|
<div class="wrapper" id="appWrapper">
|
||||||
<?php include('../include/navbar.php'); ?>
|
<?php include('../include/navbar.php'); ?>
|
||||||
@@ -284,7 +588,14 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
|
|
||||||
<?php if ($deadline['law_regulation']): ?>
|
<?php if ($deadline['law_regulation']): ?>
|
||||||
<div class="detail-label">Legge / Articolo</div>
|
<div class="detail-label">Legge / Articolo</div>
|
||||||
<div class="detail-value"><?= htmlspecialchars($deadline['law_regulation'], ENT_QUOTES, 'UTF-8') ?></div>
|
<div class="detail-value">
|
||||||
|
<?= htmlspecialchars($deadline['law_regulation'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
|
||||||
|
<span class="ai-law-btn" title="Funzione AI disponibile prossimamente">
|
||||||
|
<i class="fa-solid fa-wand-magic-sparkles"></i>
|
||||||
|
AI
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="detail-label">Periodicità</div>
|
<div class="detail-label">Periodicità</div>
|
||||||
@@ -369,9 +680,16 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php foreach ($attachments as $att):
|
<?php foreach ($attachments as $att):
|
||||||
$mime = $att['mime_type'] ?? '';
|
$mime = $att['mime_type'] ?? '';
|
||||||
if (strpos($mime, 'pdf') !== false) { $iconClass = 'att-icon-pdf'; $icon = 'fa-file-pdf'; }
|
if (strpos($mime, 'pdf') !== false) {
|
||||||
elseif (strpos($mime, 'image') !== false) { $iconClass = 'att-icon-img'; $icon = 'fa-file-image'; }
|
$iconClass = 'att-icon-pdf';
|
||||||
else { $iconClass = 'att-icon-file'; $icon = 'fa-file'; }
|
$icon = 'fa-file-pdf';
|
||||||
|
} elseif (strpos($mime, 'image') !== false) {
|
||||||
|
$iconClass = 'att-icon-img';
|
||||||
|
$icon = 'fa-file-image';
|
||||||
|
} else {
|
||||||
|
$iconClass = 'att-icon-file';
|
||||||
|
$icon = 'fa-file';
|
||||||
|
}
|
||||||
$sizeKB = round(($att['size'] ?? 0) / 1024, 1);
|
$sizeKB = round(($att['size'] ?? 0) / 1024, 1);
|
||||||
$sizeStr = $sizeKB >= 1024 ? round($sizeKB / 1024, 1) . ' MB' : $sizeKB . ' KB';
|
$sizeStr = $sizeKB >= 1024 ? round($sizeKB / 1024, 1) . ' MB' : $sizeKB . ' KB';
|
||||||
?>
|
?>
|
||||||
@@ -456,16 +774,28 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
fetch('scadenzario/ajax/complete_deadline.php?id=<?= (int)$deadline['id'] ?>')
|
fetch('scadenzario/ajax/complete_deadline.php?id=<?= (int)$deadline['id'] ?>')
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
Swal.fire({ icon: 'success', title: 'Completata', text: data.message, timer: 2500, showConfirmButton: false })
|
Swal.fire({
|
||||||
.then(function() { window.location.href = 'scadenzario/index.php'; });
|
icon: 'success',
|
||||||
|
title: 'Completata',
|
||||||
|
text: data.message,
|
||||||
|
timer: 2500,
|
||||||
|
showConfirmButton: false
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
window.location.href = 'scadenzario/index.php';
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() { Swal.fire('Errore', 'Errore di connessione.', 'error'); });
|
.catch(function() {
|
||||||
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -473,4 +803,5 @@ if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|||||||
</script>
|
</script>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -10,7 +10,9 @@ if ($filterSubjectId) {
|
|||||||
$s = $pdo->prepare("SELECT name FROM scad_subjects WHERE id = ?");
|
$s = $pdo->prepare("SELECT name FROM scad_subjects WHERE id = ?");
|
||||||
$s->execute([$filterSubjectId]);
|
$s->execute([$filterSubjectId]);
|
||||||
$filterSubjectName = $s->fetchColumn() ?: null;
|
$filterSubjectName = $s->fetchColumn() ?: null;
|
||||||
if (!$filterSubjectName) { $filterSubjectId = null; }
|
if (!$filterSubjectName) {
|
||||||
|
$filterSubjectId = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional filter: limit to deadlines assigned to the current user (directly OR via department)
|
// Optional filter: limit to deadlines assigned to the current user (directly OR via department)
|
||||||
@@ -20,7 +22,9 @@ if ($filterMy) {
|
|||||||
$st = $pdo->prepare("SELECT id, department FROM employees WHERE auth_user_id = ? LIMIT 1");
|
$st = $pdo->prepare("SELECT id, department FROM employees WHERE auth_user_id = ? LIMIT 1");
|
||||||
$st->execute([(int)$iduserlogin]);
|
$st->execute([(int)$iduserlogin]);
|
||||||
$filterMyEmployee = $st->fetch(PDO::FETCH_ASSOC) ?: null;
|
$filterMyEmployee = $st->fetch(PDO::FETCH_ASSOC) ?: null;
|
||||||
if (!$filterMyEmployee) { $filterMy = false; }
|
if (!$filterMyEmployee) {
|
||||||
|
$filterMy = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
@@ -65,9 +69,39 @@ $departments = $pdo->query("SELECT DISTINCT department FROM employees WHERE depa
|
|||||||
$subjects = $pdo->query("SELECT id, name, color FROM scad_subjects ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
|
$subjects = $pdo->query("SELECT id, name, color FROM scad_subjects ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$today = date('Y-m-d');
|
$today = date('Y-m-d');
|
||||||
|
|
||||||
|
function getContrastTextColor($hexColor)
|
||||||
|
{
|
||||||
|
$hexColor = trim($hexColor);
|
||||||
|
|
||||||
|
if ($hexColor === '') {
|
||||||
|
return '#ffffff';
|
||||||
|
}
|
||||||
|
|
||||||
|
$hexColor = ltrim($hexColor, '#');
|
||||||
|
|
||||||
|
if (strlen($hexColor) === 3) {
|
||||||
|
$hexColor = $hexColor[0] . $hexColor[0] .
|
||||||
|
$hexColor[1] . $hexColor[1] .
|
||||||
|
$hexColor[2] . $hexColor[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($hexColor) !== 6) {
|
||||||
|
return '#ffffff';
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = hexdec(substr($hexColor, 0, 2));
|
||||||
|
$g = hexdec(substr($hexColor, 2, 2));
|
||||||
|
$b = hexdec(substr($hexColor, 4, 2));
|
||||||
|
|
||||||
|
$brightness = (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
|
||||||
|
|
||||||
|
return ($brightness > 150) ? '#000000' : '#ffffff';
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="it">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -84,7 +118,11 @@ $today = date('Y-m-d');
|
|||||||
<link href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css" rel="stylesheet">
|
<link href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css" rel="stylesheet">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css" rel="stylesheet">
|
||||||
<title>Scadenzario - Lista Scadenze</title>
|
<title>Scadenzario - Lista Scadenze</title>
|
||||||
<script>if(window.innerWidth>1024)document.addEventListener('DOMContentLoaded',function(){document.getElementById('appWrapper').classList.add('toggled')})</script>
|
<script>
|
||||||
|
if (window.innerWidth > 1024) document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
document.getElementById('appWrapper').classList.add('toggled')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--scad-primary: #5a8fd8;
|
--scad-primary: #5a8fd8;
|
||||||
@@ -97,17 +135,20 @@ $today = date('Y-m-d');
|
|||||||
--scad-green: #198754;
|
--scad-green: #198754;
|
||||||
--scad-blue: #5a8fd8;
|
--scad-blue: #5a8fd8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card {
|
.scad-card {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card .card-header {
|
.scad-card .card-header {
|
||||||
background: var(--scad-card-bg);
|
background: var(--scad-card-bg);
|
||||||
border-bottom: 1px solid var(--scad-card-border);
|
border-bottom: 1px solid var(--scad-card-border);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scad-card .card-header h5 {
|
.scad-card .card-header h5 {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--scad-heading);
|
color: var(--scad-heading);
|
||||||
@@ -115,7 +156,10 @@ $today = date('Y-m-d');
|
|||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
}
|
}
|
||||||
.scad-card .card-body { padding: 1.25rem; }
|
|
||||||
|
.scad-card .card-body {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-scad-primary {
|
.btn-scad-primary {
|
||||||
background: var(--scad-primary);
|
background: var(--scad-primary);
|
||||||
@@ -127,12 +171,14 @@ $today = date('Y-m-d');
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-scad-primary:hover {
|
.btn-scad-primary:hover {
|
||||||
background: var(--scad-primary-hover);
|
background: var(--scad-primary-hover);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 12px rgba(90, 143, 216, 0.35);
|
box-shadow: 0 4px 12px rgba(90, 143, 216, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-scad-outline {
|
.btn-scad-outline {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1.5px solid var(--scad-primary);
|
border: 1.5px solid var(--scad-primary);
|
||||||
@@ -143,6 +189,7 @@ $today = date('Y-m-d');
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-scad-outline:hover {
|
.btn-scad-outline:hover {
|
||||||
background: var(--scad-primary);
|
background: var(--scad-primary);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -151,39 +198,114 @@ $today = date('Y-m-d');
|
|||||||
|
|
||||||
/* Action buttons */
|
/* Action buttons */
|
||||||
.btn-action {
|
.btn-action {
|
||||||
width: 32px; height: 32px;
|
width: 32px;
|
||||||
display: inline-flex; align-items: center; justify-content: center;
|
height: 32px;
|
||||||
border-radius: 0.4rem; border: none;
|
display: inline-flex;
|
||||||
transition: all 0.2s; font-size: 0.78rem;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
border: none;
|
||||||
|
transition: all 0.2s;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-edit {
|
||||||
|
background: #eef3ff;
|
||||||
|
color: var(--scad-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-edit:hover {
|
||||||
|
background: var(--scad-primary);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 3px 8px rgba(90, 143, 216, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-complete {
|
||||||
|
background: #e8f5e9;
|
||||||
|
color: var(--scad-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-complete:hover {
|
||||||
|
background: var(--scad-green);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 3px 8px rgba(25, 135, 84, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-delete {
|
||||||
|
background: #fff0f0;
|
||||||
|
color: var(--scad-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-action-delete:hover {
|
||||||
|
background: var(--scad-red);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 3px 8px rgba(220, 53, 69, 0.3);
|
||||||
}
|
}
|
||||||
.btn-action-edit { background: #eef3ff; color: var(--scad-primary); }
|
|
||||||
.btn-action-edit:hover { background: var(--scad-primary); color: #fff; transform: translateY(-1px); box-shadow: 0 3px 8px rgba(90,143,216,0.3); }
|
|
||||||
.btn-action-complete { background: #e8f5e9; color: var(--scad-green); }
|
|
||||||
.btn-action-complete:hover { background: var(--scad-green); color: #fff; transform: translateY(-1px); box-shadow: 0 3px 8px rgba(25,135,84,0.3); }
|
|
||||||
.btn-action-delete { background: #fff0f0; color: var(--scad-red); }
|
|
||||||
.btn-action-delete:hover { background: var(--scad-red); color: #fff; transform: translateY(-1px); box-shadow: 0 3px 8px rgba(220,53,69,0.3); }
|
|
||||||
|
|
||||||
/* Status badges */
|
/* Status badges */
|
||||||
.badge-status {
|
.badge-status {
|
||||||
font-weight: 600; font-size: 0.75rem;
|
font-weight: 600;
|
||||||
padding: 0.35em 0.65em; border-radius: 2rem;
|
font-size: 0.75rem;
|
||||||
display: inline-block; white-space: nowrap;
|
padding: 0.35em 0.65em;
|
||||||
|
border-radius: 2rem;
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-attiva {
|
||||||
|
background: #5a8fd8 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-scaduta {
|
||||||
|
background: #dc3545 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-in-scadenza {
|
||||||
|
background: #ffc107 !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-completata {
|
||||||
|
background: #198754 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
}
|
}
|
||||||
.badge-attiva { background: #e8eeff; color: #3a6bb5; }
|
|
||||||
.badge-scaduta { background: #fde8e8; color: #b91c1c; }
|
|
||||||
.badge-in-scadenza{ background: #fef3cd; color: #92600a; }
|
|
||||||
.badge-completata { background: #d1f2e0; color: #0f5132; }
|
|
||||||
|
|
||||||
/* Row coloring */
|
/* Row coloring */
|
||||||
#deadlinesTable tbody tr.row-overdue { background-color: #fff5f5; }
|
#deadlinesTable tbody tr.row-overdue {
|
||||||
#deadlinesTable tbody tr.row-approaching { background-color: #fffbeb; }
|
background-color: #fff5f5;
|
||||||
#deadlinesTable tbody tr.row-completed { opacity: 0.6; }
|
}
|
||||||
#deadlinesTable tbody tr:hover { filter: brightness(0.97); }
|
|
||||||
|
#deadlinesTable tbody tr.row-approaching {
|
||||||
|
background-color: #fffbeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
#deadlinesTable tbody tr.row-completed {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#deadlinesTable tbody tr:hover {
|
||||||
|
filter: brightness(0.97);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subject color full row - soft background */
|
||||||
|
#deadlinesTable tbody tr[data-subject-color] td {
|
||||||
|
background-color: var(--subject-row-bg, transparent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Subject color stripe */
|
|
||||||
#deadlinesTable tbody tr[data-subject-color] td:first-child {
|
#deadlinesTable tbody tr[data-subject-color] td:first-child {
|
||||||
border-left: 4px solid var(--subject-color, transparent);
|
border-left: 4px solid var(--subject-color, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Keep hover readable */
|
||||||
|
#deadlinesTable tbody tr[data-subject-color]:hover td {
|
||||||
|
background-color: var(--subject-row-bg-hover, var(--subject-row-bg, transparent)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.subject-chip {
|
.subject-chip {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.15rem 0.55rem;
|
padding: 0.15rem 0.55rem;
|
||||||
@@ -194,16 +316,23 @@ $today = date('Y-m-d');
|
|||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deadline-card[data-subject-color] {
|
.deadline-card[data-subject-color] {
|
||||||
border-left: 4px solid var(--subject-color, var(--scad-card-border));
|
border-left: 4px solid var(--subject-color, var(--scad-card-border));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter banner (subject history mode) */
|
/* Filter banner (subject history mode) */
|
||||||
.subject-filter-banner {
|
.subject-filter-banner {
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
display: flex;
|
||||||
gap: 0.75rem; padding: 0.75rem 1rem;
|
align-items: center;
|
||||||
background: var(--scad-card-bg); border: 1px solid var(--scad-card-border);
|
justify-content: space-between;
|
||||||
border-radius: 0.5rem; margin-bottom: 1rem; font-size: 0.9rem;
|
gap: 0.75rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: var(--scad-card-bg);
|
||||||
|
border: 1px solid var(--scad-card-border);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter bar */
|
/* Filter bar */
|
||||||
@@ -213,6 +342,7 @@ $today = date('Y-m-d');
|
|||||||
border-color: #d0d9e8;
|
border-color: #d0d9e8;
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-bar .form-select:focus {
|
.filter-bar .form-select:focus {
|
||||||
border-color: var(--scad-primary);
|
border-color: var(--scad-primary);
|
||||||
box-shadow: 0 0 0 0.2rem rgba(90, 143, 216, 0.15);
|
box-shadow: 0 0 0 0.2rem rgba(90, 143, 216, 0.15);
|
||||||
@@ -229,44 +359,131 @@ $today = date('Y-m-d');
|
|||||||
padding-bottom: 0.4rem;
|
padding-bottom: 0.4rem;
|
||||||
border-bottom: 2px solid #e8eeff;
|
border-bottom: 2px solid #e8eeff;
|
||||||
}
|
}
|
||||||
.modal-backdrop { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; }
|
|
||||||
.modal { position: fixed; }
|
.modal-backdrop {
|
||||||
.modal-content { background: #fff !important; }
|
position: fixed;
|
||||||
.modal-body { background: #fff !important; }
|
top: 0;
|
||||||
.modal-footer { background: #fff !important; }
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
background: var(--scad-card-bg);
|
background: var(--scad-card-bg);
|
||||||
border-bottom: 1px solid var(--scad-card-border);
|
border-bottom: 1px solid var(--scad-card-border);
|
||||||
}
|
}
|
||||||
.modal-title { font-weight: 700; color: var(--scad-heading); }
|
|
||||||
|
.modal-title {
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--scad-heading);
|
||||||
|
}
|
||||||
|
|
||||||
/* Empty state */
|
/* Empty state */
|
||||||
.empty-state { text-align: center; padding: 3rem 1rem; color: #8e99b0; }
|
.empty-state {
|
||||||
.empty-state i { font-size: 2.5rem; margin-bottom: 0.75rem; color: #c5cfe0; display: block; }
|
text-align: center;
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
color: #8e99b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
color: #c5cfe0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
/* Table text overflow */
|
/* Table text overflow */
|
||||||
#deadlinesTable td { max-width: 250px; overflow: hidden; text-overflow: ellipsis; }
|
#deadlinesTable td {
|
||||||
#deadlinesTable td:first-child { max-width: 150px; }
|
max-width: 250px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
#deadlinesTable td:first-child {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Attachment list in modal */
|
/* Attachment list in modal */
|
||||||
.att-item {
|
.att-item {
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
display: flex;
|
||||||
padding: 0.5rem 0.75rem; background: #f8f9fa; border-radius: 0.4rem;
|
align-items: center;
|
||||||
margin-bottom: 0.4rem; font-size: 0.85rem;
|
justify-content: space-between;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
.att-item .att-name { color: var(--scad-heading); font-weight: 500; word-break: break-all; }
|
|
||||||
.att-item .att-actions { display: flex; gap: 0.4rem; flex-shrink: 0; margin-left: 0.5rem; }
|
.att-item .att-name {
|
||||||
.att-item .att-actions a, .att-item .att-actions button {
|
color: var(--scad-heading);
|
||||||
width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
|
font-weight: 500;
|
||||||
border-radius: 0.3rem; border: none; font-size: 0.75rem; transition: all 0.15s;
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.4rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-actions a,
|
||||||
|
.att-item .att-actions button {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
border: none;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
transition: all 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-download {
|
||||||
|
background: #eef3ff;
|
||||||
|
color: var(--scad-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-download:hover {
|
||||||
|
background: var(--scad-primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-remove {
|
||||||
|
background: #fff0f0;
|
||||||
|
color: var(--scad-red);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.att-item .att-remove:hover {
|
||||||
|
background: var(--scad-red);
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
.att-item .att-download { background: #eef3ff; color: var(--scad-primary); text-decoration: none; }
|
|
||||||
.att-item .att-download:hover { background: var(--scad-primary); color: #fff; }
|
|
||||||
.att-item .att-remove { background: #fff0f0; color: var(--scad-red); cursor: pointer; }
|
|
||||||
.att-item .att-remove:hover { background: var(--scad-red); color: #fff; }
|
|
||||||
|
|
||||||
/* Select2 tweaks */
|
/* Select2 tweaks */
|
||||||
.select2-container--bootstrap-5 .select2-selection { min-height: 38px; border-color: #d0d9e8; }
|
.select2-container--bootstrap-5 .select2-selection {
|
||||||
|
min-height: 38px;
|
||||||
|
border-color: #d0d9e8;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mobile cards */
|
/* Mobile cards */
|
||||||
.deadline-card {
|
.deadline-card {
|
||||||
@@ -279,22 +496,55 @@ $today = date('Y-m-d');
|
|||||||
border-left: 5px solid var(--scad-blue);
|
border-left: 5px solid var(--scad-blue);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
.deadline-card:active { box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
||||||
.deadline-card.card-overdue { border-left-color: var(--scad-red); background: #fff8f8; border-color: #fcd5d5; }
|
.deadline-card:active {
|
||||||
.deadline-card.card-approaching { border-left-color: var(--scad-orange); background: #fffdf5; border-color: #fce9b8; }
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
.deadline-card.card-completed { border-left-color: #adb5bd; opacity: 0.55; border-color: #dee2e6; }
|
|
||||||
.deadline-card .card-topic {
|
|
||||||
font-weight: 700; font-size: 0.95rem; color: var(--scad-heading);
|
|
||||||
margin-bottom: 0.35rem; line-height: 1.3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deadline-card.card-overdue {
|
||||||
|
border-left-color: var(--scad-red);
|
||||||
|
background: #fff8f8;
|
||||||
|
border-color: #fcd5d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deadline-card.card-approaching {
|
||||||
|
border-left-color: var(--scad-orange);
|
||||||
|
background: #fffdf5;
|
||||||
|
border-color: #fce9b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deadline-card.card-completed {
|
||||||
|
border-left-color: #adb5bd;
|
||||||
|
opacity: 0.55;
|
||||||
|
border-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deadline-card .card-topic {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--scad-heading);
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
.deadline-card .card-meta {
|
.deadline-card .card-meta {
|
||||||
font-size: 0.8rem; color: #6c757d;
|
font-size: 0.8rem;
|
||||||
display: flex; flex-wrap: wrap; gap: 0.3rem 1rem;
|
color: #6c757d;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.3rem 1rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
.deadline-card .card-meta i { width: 14px; text-align: center; }
|
|
||||||
|
.deadline-card .card-meta i {
|
||||||
|
width: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.deadline-card .card-actions {
|
.deadline-card .card-actions {
|
||||||
display: flex; gap: 0.5rem; align-items: center;
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,22 +559,42 @@ $today = date('Y-m-d');
|
|||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-menu-btn i {
|
.header-menu-btn i {
|
||||||
display: block;
|
display: block;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
.header-menu-btn::after { display: none !important; }
|
|
||||||
|
.header-menu-btn::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
.scad-card .card-header { flex-direction: column; gap: 0.75rem; align-items: flex-start !important; }
|
.scad-card .card-header {
|
||||||
.header-actions { width: 100%; justify-content: flex-end; }
|
flex-direction: column;
|
||||||
.header-actions #btnAddDeadline { flex: 1; justify-content: center; }
|
gap: 0.75rem;
|
||||||
.filter-bar .form-select { width: 100%; }
|
align-items: flex-start !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions #btnAddDeadline {
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-bar .form-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper" id="appWrapper">
|
<div class="wrapper" id="appWrapper">
|
||||||
<?php include('../include/navbar.php'); ?>
|
<?php include('../include/navbar.php'); ?>
|
||||||
@@ -503,10 +773,31 @@ $today = date('Y-m-d');
|
|||||||
$isOverdue = !$isCompleted && $dueDate < $today;
|
$isOverdue = !$isCompleted && $dueDate < $today;
|
||||||
$isApproaching = !$isCompleted && !$isOverdue && $dueDate <= $approachDate;
|
$isApproaching = !$isCompleted && !$isOverdue && $dueDate <= $approachDate;
|
||||||
|
|
||||||
if ($isCompleted) { $statusLabel = 'Completata'; $statusClass = 'badge-completata'; $statusKey = 'completata'; $rowClass = 'row-completed'; $cardClass = 'card-completed'; }
|
if ($isCompleted) {
|
||||||
elseif ($isOverdue) { $statusLabel = 'Scaduta'; $statusClass = 'badge-scaduta'; $statusKey = 'scaduta'; $rowClass = 'row-overdue'; $cardClass = 'card-overdue'; }
|
$statusLabel = 'Completata';
|
||||||
elseif ($isApproaching) { $statusLabel = 'In scadenza'; $statusClass = 'badge-in-scadenza'; $statusKey = 'in-scadenza'; $rowClass = 'row-approaching'; $cardClass = 'card-approaching'; }
|
$statusClass = 'badge-completata';
|
||||||
else { $statusLabel = 'Attiva'; $statusClass = 'badge-attiva'; $statusKey = 'attiva'; $rowClass = ''; $cardClass = ''; }
|
$statusKey = 'completata';
|
||||||
|
$rowClass = 'row-completed';
|
||||||
|
$cardClass = 'card-completed';
|
||||||
|
} elseif ($isOverdue) {
|
||||||
|
$statusLabel = 'Scaduta';
|
||||||
|
$statusClass = 'badge-scaduta';
|
||||||
|
$statusKey = 'scaduta';
|
||||||
|
$rowClass = 'row-overdue';
|
||||||
|
$cardClass = 'card-overdue';
|
||||||
|
} elseif ($isApproaching) {
|
||||||
|
$statusLabel = 'In scadenza';
|
||||||
|
$statusClass = 'badge-in-scadenza';
|
||||||
|
$statusKey = 'in-scadenza';
|
||||||
|
$rowClass = 'row-approaching';
|
||||||
|
$cardClass = 'card-approaching';
|
||||||
|
} else {
|
||||||
|
$statusLabel = 'Attiva';
|
||||||
|
$statusClass = 'badge-attiva';
|
||||||
|
$statusKey = 'attiva';
|
||||||
|
$rowClass = '';
|
||||||
|
$cardClass = '';
|
||||||
|
}
|
||||||
|
|
||||||
$row['_dueFmt'] = date('d/m/Y', strtotime($dueDate));
|
$row['_dueFmt'] = date('d/m/Y', strtotime($dueDate));
|
||||||
$row['_checkFmt'] = $row['check_date'] ? date('d/m/Y', strtotime($row['check_date'])) : '—';
|
$row['_checkFmt'] = $row['check_date'] ? date('d/m/Y', strtotime($row['check_date'])) : '—';
|
||||||
@@ -540,7 +831,14 @@ $today = date('Y-m-d');
|
|||||||
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
||||||
<?php if (!empty($row['subject_name'])): ?>
|
<?php if (!empty($row['subject_name'])): ?>
|
||||||
<div class="mb-1"><span class="subject-chip" style="background: <?= htmlspecialchars($row['subject_color'] ?: '#6c757d', ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($row['subject_name'], ENT_QUOTES, 'UTF-8') ?></span></div>
|
<div class="mb-1"><?php
|
||||||
|
$subjectBadgeBg = $row['subject_color'] ?: '#6c757d';
|
||||||
|
$subjectBadgeText = getContrastTextColor($subjectBadgeBg);
|
||||||
|
?>
|
||||||
|
<span class="subject-chip" style="background: <?= htmlspecialchars($subjectBadgeBg, ENT_QUOTES, 'UTF-8') ?>; color: <?= $subjectBadgeText ?>;">
|
||||||
|
<?= htmlspecialchars($row['subject_name'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="d-flex justify-content-between align-items-start mb-1">
|
<div class="d-flex justify-content-between align-items-start mb-1">
|
||||||
<a href="scadenzario/detail.php?id=<?= (int)$row['id'] ?>" class="card-topic text-decoration-none"><?= htmlspecialchars($row['topic'], ENT_QUOTES, 'UTF-8') ?></a>
|
<a href="scadenzario/detail.php?id=<?= (int)$row['id'] ?>" class="card-topic text-decoration-none"><?= htmlspecialchars($row['topic'], ENT_QUOTES, 'UTF-8') ?></a>
|
||||||
@@ -596,14 +894,28 @@ $today = date('Y-m-d');
|
|||||||
data-id="<?= (int)$row['id'] ?>"
|
data-id="<?= (int)$row['id'] ?>"
|
||||||
data-status="<?= $row['_statusKey'] ?>"
|
data-status="<?= $row['_statusKey'] ?>"
|
||||||
data-subject-id="<?= (int)($row['subject_id'] ?? 0) ?>"
|
data-subject-id="<?= (int)($row['subject_id'] ?? 0) ?>"
|
||||||
<?php if (!empty($row['subject_color'])): ?>data-subject-color="<?= htmlspecialchars($row['subject_color'], ENT_QUOTES, 'UTF-8') ?>" style="--subject-color: <?= htmlspecialchars($row['subject_color'], ENT_QUOTES, 'UTF-8') ?>"<?php endif; ?>
|
<?php if (!empty($row['subject_color'])): ?>
|
||||||
|
<?php
|
||||||
|
$subjectColor = htmlspecialchars($row['subject_color'], ENT_QUOTES, 'UTF-8');
|
||||||
|
$subjectRowBg = $subjectColor . '1A'; // circa 10% opacity
|
||||||
|
$subjectRowBgHover = $subjectColor . '2A'; // circa 16% opacity
|
||||||
|
?>
|
||||||
|
data-subject-color="<?= $subjectColor ?>"
|
||||||
|
style="--subject-color: <?= $subjectColor ?>; --subject-row-bg: <?= $subjectRowBg ?>; --subject-row-bg-hover: <?= $subjectRowBgHover ?>;"
|
||||||
|
<?php endif; ?>
|
||||||
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-department="<?= htmlspecialchars($row['reparti'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-employees="<?= htmlspecialchars($row['responsabili'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
data-due-date="<?= htmlspecialchars($row['due_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
|
||||||
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
data-check-date="<?= htmlspecialchars($row['check_date'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
|
||||||
<td>
|
<td>
|
||||||
<?php if (!empty($row['subject_name'])): ?>
|
<?php if (!empty($row['subject_name'])): ?>
|
||||||
<span class="subject-chip" style="background: <?= htmlspecialchars($row['subject_color'] ?: '#6c757d', ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($row['subject_name'], ENT_QUOTES, 'UTF-8') ?></span>
|
<?php
|
||||||
|
$subjectBadgeBg = $row['subject_color'] ?: '#6c757d';
|
||||||
|
$subjectBadgeText = getContrastTextColor($subjectBadgeBg);
|
||||||
|
?>
|
||||||
|
<span class="subject-chip" style="background: <?= htmlspecialchars($subjectBadgeBg, ENT_QUOTES, 'UTF-8') ?>; color: <?= $subjectBadgeText ?>;">
|
||||||
|
<?= htmlspecialchars($row['subject_name'], ENT_QUOTES, 'UTF-8') ?>
|
||||||
|
</span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<span class="text-muted">—</span>
|
<span class="text-muted">—</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@@ -842,17 +1154,38 @@ $today = date('Y-m-d');
|
|||||||
|
|
||||||
// --- Auto-calc due_date from document_date + recurrence ---
|
// --- Auto-calc due_date from document_date + recurrence ---
|
||||||
var RECURRENCE_OFFSETS = {
|
var RECURRENCE_OFFSETS = {
|
||||||
monthly: { months: 1 },
|
monthly: {
|
||||||
quarterly: { months: 3 },
|
months: 1
|
||||||
semiannual: { months: 6 },
|
},
|
||||||
annual: { years: 1 },
|
quarterly: {
|
||||||
biennial: { years: 2 },
|
months: 3
|
||||||
triennial: { years: 3 },
|
},
|
||||||
quadriennial: { years: 4 },
|
semiannual: {
|
||||||
quinquennial: { years: 5 },
|
months: 6
|
||||||
decennial: { years: 10 },
|
},
|
||||||
quindecennial:{ years: 15 }
|
annual: {
|
||||||
|
years: 1
|
||||||
|
},
|
||||||
|
biennial: {
|
||||||
|
years: 2
|
||||||
|
},
|
||||||
|
triennial: {
|
||||||
|
years: 3
|
||||||
|
},
|
||||||
|
quadriennial: {
|
||||||
|
years: 4
|
||||||
|
},
|
||||||
|
quinquennial: {
|
||||||
|
years: 5
|
||||||
|
},
|
||||||
|
decennial: {
|
||||||
|
years: 10
|
||||||
|
},
|
||||||
|
quindecennial: {
|
||||||
|
years: 15
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function computeDueDate() {
|
function computeDueDate() {
|
||||||
var docVal = document.getElementById('dlDocDate').value;
|
var docVal = document.getElementById('dlDocDate').value;
|
||||||
var recurrence = document.getElementById('dlRecurrence').value;
|
var recurrence = document.getElementById('dlRecurrence').value;
|
||||||
@@ -876,8 +1209,9 @@ $today = date('Y-m-d');
|
|||||||
var statusFilter = $('#filterStatus').val();
|
var statusFilter = $('#filterStatus').val();
|
||||||
var deptFilter = $('#filterDepartment').val();
|
var deptFilter = $('#filterDepartment').val();
|
||||||
|
|
||||||
if (statusFilter === 'non-completata') { if (row.getAttribute('data-status') === 'completata') return false; }
|
if (statusFilter === 'non-completata') {
|
||||||
else if (statusFilter && row.getAttribute('data-status') !== statusFilter) return false;
|
if (row.getAttribute('data-status') === 'completata') return false;
|
||||||
|
} else if (statusFilter && row.getAttribute('data-status') !== statusFilter) return false;
|
||||||
if (deptFilter && (row.getAttribute('data-department') || '').indexOf(deptFilter) === -1) return false;
|
if (deptFilter && (row.getAttribute('data-department') || '').indexOf(deptFilter) === -1) return false;
|
||||||
var subjFilter = $('#filterSubject').val();
|
var subjFilter = $('#filterSubject').val();
|
||||||
if (subjFilter && String(row.getAttribute('data-subject-id')) !== String(subjFilter)) return false;
|
if (subjFilter && String(row.getAttribute('data-subject-id')) !== String(subjFilter)) return false;
|
||||||
@@ -898,14 +1232,17 @@ $today = date('Y-m-d');
|
|||||||
var table = null;
|
var table = null;
|
||||||
if ($('#deadlinesTable').length) {
|
if ($('#deadlinesTable').length) {
|
||||||
table = $('#deadlinesTable').DataTable({
|
table = $('#deadlinesTable').DataTable({
|
||||||
order: [[3, 'asc']],
|
order: [
|
||||||
|
[3, 'asc']
|
||||||
|
],
|
||||||
pageLength: 25,
|
pageLength: 25,
|
||||||
language: {
|
language: {
|
||||||
url: 'https://cdn.datatables.net/plug-ins/1.13.7/i18n/it-IT.json'
|
url: 'https://cdn.datatables.net/plug-ins/1.13.7/i18n/it-IT.json'
|
||||||
},
|
},
|
||||||
columnDefs: [
|
columnDefs: [{
|
||||||
{ orderable: false, targets: -1 }
|
orderable: false,
|
||||||
]
|
targets: -1
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -916,8 +1253,9 @@ $today = date('Y-m-d');
|
|||||||
var subjVal = $('#filterSubject').val();
|
var subjVal = $('#filterSubject').val();
|
||||||
$('#mobileCards .deadline-card').each(function() {
|
$('#mobileCards .deadline-card').each(function() {
|
||||||
var show = true;
|
var show = true;
|
||||||
if (statusVal === 'non-completata') { if ($(this).data('status') === 'completata') show = false; }
|
if (statusVal === 'non-completata') {
|
||||||
else if (statusVal && $(this).data('status') !== statusVal) show = false;
|
if ($(this).data('status') === 'completata') show = false;
|
||||||
|
} else if (statusVal && $(this).data('status') !== statusVal) show = false;
|
||||||
if (deptVal && ($(this).data('department') || '').indexOf(deptVal) === -1) show = false;
|
if (deptVal && ($(this).data('department') || '').indexOf(deptVal) === -1) show = false;
|
||||||
if (subjVal && String($(this).data('subject-id')) !== String(subjVal)) show = false;
|
if (subjVal && String($(this).data('subject-id')) !== String(subjVal)) show = false;
|
||||||
var empVal = $('#filterEmployee').val();
|
var empVal = $('#filterEmployee').val();
|
||||||
@@ -938,15 +1276,33 @@ $today = date('Y-m-d');
|
|||||||
var active = 0;
|
var active = 0;
|
||||||
var summary = [];
|
var summary = [];
|
||||||
var st = $('#filterStatus').val();
|
var st = $('#filterStatus').val();
|
||||||
if (st && st !== 'non-completata') { active++; summary.push($('#filterStatus option:selected').text()); }
|
if (st && st !== 'non-completata') {
|
||||||
|
active++;
|
||||||
|
summary.push($('#filterStatus option:selected').text());
|
||||||
|
}
|
||||||
var subj = $('#filterSubject').val();
|
var subj = $('#filterSubject').val();
|
||||||
if (subj) { active++; summary.push('Argomento: ' + $('#filterSubject option:selected').text()); }
|
if (subj) {
|
||||||
|
active++;
|
||||||
|
summary.push('Argomento: ' + $('#filterSubject option:selected').text());
|
||||||
|
}
|
||||||
var dept = $('#filterDepartment').val();
|
var dept = $('#filterDepartment').val();
|
||||||
if (dept) { active++; summary.push('Reparto: ' + dept); }
|
if (dept) {
|
||||||
|
active++;
|
||||||
|
summary.push('Reparto: ' + dept);
|
||||||
|
}
|
||||||
var emp = $('#filterEmployee').val();
|
var emp = $('#filterEmployee').val();
|
||||||
if (emp) { active++; summary.push('Responsabile: ' + emp); }
|
if (emp) {
|
||||||
if (fpDue.selectedDates.length) { active++; summary.push('Scadenza: ' + $('#filterDueRange').val()); }
|
active++;
|
||||||
if (fpCheck.selectedDates.length) { active++; summary.push('Controllo: ' + $('#filterCheckRange').val()); }
|
summary.push('Responsabile: ' + emp);
|
||||||
|
}
|
||||||
|
if (fpDue.selectedDates.length) {
|
||||||
|
active++;
|
||||||
|
summary.push('Scadenza: ' + $('#filterDueRange').val());
|
||||||
|
}
|
||||||
|
if (fpCheck.selectedDates.length) {
|
||||||
|
active++;
|
||||||
|
summary.push('Controllo: ' + $('#filterCheckRange').val());
|
||||||
|
}
|
||||||
|
|
||||||
var $badge = $('#filterCountBadge');
|
var $badge = $('#filterCountBadge');
|
||||||
if (active > 0) $badge.text(active).removeClass('d-none');
|
if (active > 0) $badge.text(active).removeClass('d-none');
|
||||||
@@ -961,6 +1317,7 @@ $today = date('Y-m-d');
|
|||||||
filterCards();
|
filterCards();
|
||||||
updateFilterBadge();
|
updateFilterBadge();
|
||||||
});
|
});
|
||||||
|
|
||||||
function resetFilters() {
|
function resetFilters() {
|
||||||
$('#filterStatus').val('non-completata');
|
$('#filterStatus').val('non-completata');
|
||||||
$('#filterDepartment').val('');
|
$('#filterDepartment').val('');
|
||||||
@@ -1019,7 +1376,9 @@ $today = date('Y-m-d');
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
})
|
})
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
var deadlineId = data.id;
|
var deadlineId = data.id;
|
||||||
@@ -1031,27 +1390,50 @@ $today = date('Y-m-d');
|
|||||||
for (var i = 0; i < fileInput.files.length; i++) {
|
for (var i = 0; i < fileInput.files.length; i++) {
|
||||||
fileData.append('files[]', fileInput.files[i]);
|
fileData.append('files[]', fileInput.files[i]);
|
||||||
}
|
}
|
||||||
return fetch('scadenzario/ajax/upload_attachment.php', { method: 'POST', body: fileData })
|
return fetch('scadenzario/ajax/upload_attachment.php', {
|
||||||
.then(function(r) { return r.json(); })
|
method: 'POST',
|
||||||
|
body: fileData
|
||||||
|
})
|
||||||
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(upData) {
|
.then(function(upData) {
|
||||||
modal.hide();
|
modal.hide();
|
||||||
Swal.fire({ icon: 'success', title: 'Salvato', text: data.message + ' ' + upData.message, timer: 2000, showConfirmButton: false })
|
Swal.fire({
|
||||||
.then(function() { location.reload(); });
|
icon: 'success',
|
||||||
|
title: 'Salvato',
|
||||||
|
text: data.message + ' ' + upData.message,
|
||||||
|
timer: 2000,
|
||||||
|
showConfirmButton: false
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
modal.hide();
|
modal.hide();
|
||||||
Swal.fire({ icon: 'success', title: 'Salvato', text: data.message, timer: 1500, showConfirmButton: false })
|
Swal.fire({
|
||||||
.then(function() { location.reload(); });
|
icon: 'success',
|
||||||
|
title: 'Salvato',
|
||||||
|
text: data.message,
|
||||||
|
timer: 1500,
|
||||||
|
showConfirmButton: false
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
isSaving = false; saveBtn.disabled = false;
|
isSaving = false;
|
||||||
|
saveBtn.disabled = false;
|
||||||
saveBtn.innerHTML = '<i class="fa-solid fa-check me-1"></i> Salva';
|
saveBtn.innerHTML = '<i class="fa-solid fa-check me-1"></i> Salva';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
isSaving = false; saveBtn.disabled = false;
|
isSaving = false;
|
||||||
|
saveBtn.disabled = false;
|
||||||
saveBtn.innerHTML = '<i class="fa-solid fa-check me-1"></i> Salva';
|
saveBtn.innerHTML = '<i class="fa-solid fa-check me-1"></i> Salva';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1088,7 +1470,9 @@ $today = date('Y-m-d');
|
|||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
fetch('scadenzario/ajax/delete_attachment.php?id=' + attId)
|
fetch('scadenzario/ajax/delete_attachment.php?id=' + attId)
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
btn.closest('.att-item').remove();
|
btn.closest('.att-item').remove();
|
||||||
@@ -1107,9 +1491,14 @@ $today = date('Y-m-d');
|
|||||||
$(document).on('click', '.btn-edit', function() {
|
$(document).on('click', '.btn-edit', function() {
|
||||||
var id = $(this).closest('[data-id]').data('id');
|
var id = $(this).closest('[data-id]').data('id');
|
||||||
fetch('scadenzario/ajax/get_deadline.php?id=' + id)
|
fetch('scadenzario/ajax/get_deadline.php?id=' + id)
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (!data.success) { Swal.fire('Errore', data.message, 'error'); return; }
|
if (!data.success) {
|
||||||
|
Swal.fire('Errore', data.message, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
var d = data.data;
|
var d = data.data;
|
||||||
document.getElementById('dlId').value = d.id;
|
document.getElementById('dlId').value = d.id;
|
||||||
$('#dlSubject').val(d.subject_id || '').trigger('change');
|
$('#dlSubject').val(d.subject_id || '').trigger('change');
|
||||||
@@ -1129,7 +1518,9 @@ $today = date('Y-m-d');
|
|||||||
renderAttachments(d.attachments || []);
|
renderAttachments(d.attachments || []);
|
||||||
modal.show();
|
modal.show();
|
||||||
})
|
})
|
||||||
.catch(function() { Swal.fire('Errore', 'Errore di connessione.', 'error'); });
|
.catch(function() {
|
||||||
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
@@ -1146,16 +1537,28 @@ $today = date('Y-m-d');
|
|||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
fetch('scadenzario/ajax/complete_deadline.php?id=' + id)
|
fetch('scadenzario/ajax/complete_deadline.php?id=' + id)
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
Swal.fire({ icon: 'success', title: 'Completata', text: data.message, timer: 2500, showConfirmButton: false })
|
Swal.fire({
|
||||||
.then(function() { location.reload(); });
|
icon: 'success',
|
||||||
|
title: 'Completata',
|
||||||
|
text: data.message,
|
||||||
|
timer: 2500,
|
||||||
|
showConfirmButton: false
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() { Swal.fire('Errore', 'Errore di connessione.', 'error'); });
|
.catch(function() {
|
||||||
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1175,16 +1578,28 @@ $today = date('Y-m-d');
|
|||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
fetch('scadenzario/ajax/delete_deadline.php?id=' + id)
|
fetch('scadenzario/ajax/delete_deadline.php?id=' + id)
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
Swal.fire({ icon: 'success', title: 'Eliminata', text: data.message, timer: 1500, showConfirmButton: false })
|
Swal.fire({
|
||||||
.then(function() { location.reload(); });
|
icon: 'success',
|
||||||
|
title: 'Eliminata',
|
||||||
|
text: data.message,
|
||||||
|
timer: 1500,
|
||||||
|
showConfirmButton: false
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire('Errore', data.message, 'error');
|
Swal.fire('Errore', data.message, 'error');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() { Swal.fire('Errore', 'Errore di connessione.', 'error'); });
|
.catch(function() {
|
||||||
|
Swal.fire('Errore', 'Errore di connessione.', 'error');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1195,7 +1610,9 @@ $today = date('Y-m-d');
|
|||||||
if (editId) {
|
if (editId) {
|
||||||
history.replaceState(null, '', 'scadenzario/index.php');
|
history.replaceState(null, '', 'scadenzario/index.php');
|
||||||
fetch('scadenzario/ajax/get_deadline.php?id=' + editId)
|
fetch('scadenzario/ajax/get_deadline.php?id=' + editId)
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) {
|
||||||
|
return r.json();
|
||||||
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (!data.success) return;
|
if (!data.success) return;
|
||||||
var d = data.data;
|
var d = data.data;
|
||||||
@@ -1242,4 +1659,5 @@ $today = date('Y-m-d');
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user