update mescole and photo diagram

This commit is contained in:
2025-12-03 08:35:59 +01:00
parent a1c9d9f789
commit dd9d109dee
375 changed files with 1394 additions and 541 deletions
+242 -69
View File
@@ -1,4 +1,7 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
include('include/headscript.php');
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
@@ -265,7 +268,12 @@ if (!empty($_GET['ajax'])) {
$sql = "SELECT
p.*,
m.nome AS matrice,
ms.nome AS mescola,
(
SELECT GROUP_CONCAT(m.nome ORDER BY m.nome SEPARATOR ' | ')
FROM productiondata_mescole pm
JOIN mescole m ON m.id = pm.id_mescola
WHERE pm.id_productiondata = p.id
) AS mescole_list,
l.name AS linea,
c.nome AS cliente,
s.nome AS status_nome,
@@ -274,7 +282,6 @@ if (!empty($_GET['ajax'])) {
p.tempo_totale_produzione
FROM productiondata p
LEFT JOIN matrice m ON p.idmatrice = m.id
LEFT JOIN mescole ms ON p.idmescola = ms.id
LEFT JOIN production_lines l ON p.id_linea = l.id
LEFT JOIN clients c ON p.id_cliente = c.id
LEFT JOIN production_status s ON p.id_status = s.id
@@ -287,14 +294,31 @@ if (!empty($_GET['ajax'])) {
$records = $stmt->fetchAll();
foreach ($records as $r) {
// --- PARAMETRI LINEA (slot dinamici)
$sqlParams = "SELECT position, short_label, icon
FROM production_line_params
WHERE line_id = :line
ORDER BY position ASC";
$stmtP = $pdo->prepare($sqlParams);
$stmtP->execute(['line' => $r['id_linea']]);
$paramsLinea = $stmtP->fetchAll();
$r['param_slots'] = $paramsLinea;
include __DIR__ . "/render_production_card.php";
}
// --- RECORD IN STATO 6 ORDINATI PER PRIORITY
$sql2 = "SELECT
p.*,
m.nome AS matrice,
ms.nome AS mescola,
m.nome AS matrice,
(
SELECT GROUP_CONCAT(m2.nome ORDER BY m2.nome SEPARATOR ' | ')
FROM productiondata_mescole pm
JOIN mescole m2 ON m2.id = pm.id_mescola
WHERE pm.id_productiondata = p.id
) AS mescole_list,
l.name AS linea,
c.nome AS cliente,
s.nome AS status_nome,
@@ -303,13 +327,13 @@ if (!empty($_GET['ajax'])) {
p.tempo_totale_produzione
FROM productiondata p
LEFT JOIN matrice m ON p.idmatrice = m.id
LEFT JOIN mescole ms ON p.idmescola = ms.id
LEFT JOIN production_lines l ON p.id_linea = l.id
LEFT JOIN clients c ON p.id_cliente = c.id
LEFT JOIN production_status s ON p.id_status = s.id
WHERE p.id_status = 6
" . (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "") . "
ORDER BY p.priority ASC";
" . (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "") . "
ORDER BY p.priority ASC
";
$stmt2 = $pdo->prepare($sql2);
$stmt2->execute();
@@ -790,6 +814,83 @@ if (!empty($_GET['ajax'])) {
max-width: 1200px !important;
width: 95% !important;
}
/* Mantiene stile identico ai bottoni delle foto */
/* Stesso stile dei photo-btn */
.qc-btn {
width: 42px;
height: 42px;
border-radius: 10px;
border: 1px solid #000000;
/* bordo nero */
background: #c8f3df;
/* verde pastello interno */
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.2s ease;
}
.qc-btn i {
font-size: 1.8rem;
color: #000000;
/* icona nera */
}
.qc-btn:hover {
background: #b3e9d3;
/* leggero scurimento */
transform: scale(1.07);
}
.param-grid {
display: grid;
gap: 10px;
margin-bottom: 15px;
}
@media (max-width: 900px) {
.param-grid {
grid-template-columns: repeat(3, 1fr);
}
}
.param-slot {
background: #ffffff;
border-radius: 12px;
padding: 10px;
text-align: center;
border: 2px solid #e2e8f0;
cursor: pointer;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.08);
transition: 0.2s ease;
}
.param-slot:hover {
border-color: #3b82f6;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}
.thumb {
width: 100%;
height: 75px;
background: #f1f5f9;
border-radius: 8px;
overflow: hidden;
}
.thumb-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.param-label {
margin-top: 6px;
font-weight: 700;
font-size: 1rem;
}
</style>
</head>
@@ -952,37 +1053,6 @@ if (!empty($_GET['ajax'])) {
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).on("mousedown", function(e) {
// 🔥 Se clicco sulla X, non chiudere altri modali
if ($(e.target).attr("id") === "previewCloseX") {
return;
}
// --- Se il PREVIEW è aperto ---
if ($("#imagePreviewModal").hasClass("active")) {
// click fuori → chiudi SOLO il preview
if ($(e.target).closest("#imagePreviewModal .modal-content").length === 0) {
$("#imagePreviewModal").removeClass("active");
}
return; // 🔥 BLOCCA la chiusura del photoModal
}
// --- Se è aperto solo il PHOTO MODAL ---
if ($("#photoModal").hasClass("active")) {
if ($(e.target).closest("#photoModal .modal-content").length === 0) {
$("#photoModal").removeClass("active");
}
}
});
function showPhotoSuccess() {
$("#photoMessageError").hide();
$("#photoMessageSuccess").fadeIn(150);
@@ -997,13 +1067,15 @@ if (!empty($_GET['ajax'])) {
$("#photoMessageError").text("⚠️ " + msg).fadeIn(150);
}
function loadPhotoGallery(productionId, type) {
function loadPhotoGallery(productionId, type, slot = null) {
$("#photoGallery").html('<div style="color:#64748b;">Caricamento foto...</div>');
$.getJSON("get_photos.php", {
production_id: productionId,
photo_type: type
photo_type: type,
param_position: slot
}, function(r) {
if (!r.success) {
$("#photoGallery").html(
'<div style="color:#b91c1c;">Errore nel caricamento delle foto.</div>'
@@ -1012,60 +1084,58 @@ if (!empty($_GET['ajax'])) {
}
const photos = r.photos || [];
if (photos.length === 0) {
$("#photoGallery").html(
'<div style="color:#64748b;">Nessuna foto registrata per questa tipologia.</div>'
'<div style="color:#64748b;">Nessuna foto per questa posizione.</div>'
);
return;
}
let html = "";
photos.forEach(p => {
const aiLabel = p.ai_processed == 1 ? ' (AI✔)' : '';
html += `
<div style="width:90px; text-align:center; font-size:0.7rem;">
<div class="photo-thumb"
data-full="photos/${p.filename}"
style="width:90px; height:70px; border-radius:8px; overflow:hidden; border:1px solid #e2e8f0; margin-bottom:4px; cursor:pointer;">
<img src="photos/${p.filename}"
alt="photo"
style="width:100%; height:100%; object-fit:cover;">
</div>
<div style="color:#475569; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
#${p.id}${aiLabel}
</div>
</div>
`;
<div style="width:90px; text-align:center; font-size:0.7rem;">
<div class="photo-thumb"
data-full="photos/${p.filename}"
style="width:90px; height:70px; border-radius:8px; overflow:hidden; border:1px solid #e2e8f0; margin-bottom:4px; cursor:pointer;">
<img src="photos/${p.filename}" alt="photo"
style="width:100%; height:100%; object-fit:cover;">
</div>
<div style="color:#475569;">#${p.id}</div>
</div>
`;
});
$("#photoGallery").html(html);
}).fail(function() {
$("#photoGallery").html(
'<div style="color:#b91c1c;">Errore di connessione nel caricamento delle foto.</div>'
);
});
}
// APRI PREVIEW — evento CLICK (non mousedown)
$(document).on("click", ".photo-thumb", function(e) {
e.stopPropagation(); // evita che il click chiuda subito il modale
const fullImage = $(this).data("full");
$("#previewImage").attr("src", fullImage);
$("#imagePreviewModal").addClass("active");
});
// chiusura preview con X
$("#previewCloseX").on("click", function(e) {
// 🔥 chiusura preview con X - DELEGATO
$(document).on("click", "#previewCloseX", function(e) {
e.preventDefault();
e.stopImmediatePropagation(); // 🔥 blocca davvero tutto
$("#imagePreviewModal").removeClass("active");
});
// opzionale: chiudi cliccando fuori dal contenuto (sulloverlay scuro)
$(document).on("click", "#imagePreviewModal", function(e) {
if ($(e.target).is("#imagePreviewModal")) {
$("#imagePreviewModal").removeClass("active");
}
});
// chiusura modale principale (upload foto)
@@ -1172,17 +1242,50 @@ if (!empty($_GET['ajax'])) {
$("#photoModal").addClass("active");
});
// FOTO PARAMETRI MACCHINA (7 posizioni)
$(document).on("click", ".param-slot", function(e) {
e.stopPropagation();
$("#photoCancel").on("click", () => {
$("#photoModal").removeClass("active");
const slot = $(this).data("slot");
const productionId = $(this).data("production");
$("#photoType").val("parametri_macchina");
$("#photoProductionId").val(productionId);
$("#photoParamPosition").val(slot);
$("#photoModalTitle").text("Foto Parametro P" + slot);
$("#photoModalSubtitle").text("Produzione ID: " + productionId);
loadPhotoGallery(productionId, "parametri_macchina", slot);
$("#photoModal").addClass("active");
});
$("#photoCancel").off("click").on("click", () => {
$("#photoModal").removeClass("active");
// 🔥 ricarica le card (e quindi le thumbnail) via AJAX
loadRecords();
});
$("#photoModalCloseX").off("click").on("click", function() {
$("#photoModal").removeClass("active");
// 🔥 stessa logica: al close ricarico le card
loadRecords();
});
// --- SUBMIT FORM FOTO ---
$("#photoForm").off("submit").on("submit", function(e) {
e.preventDefault();
let formData = new FormData(this);
// 🔥 mostra loader, disabilita submit
$("#photoMessageSuccess, #photoMessageError").hide();
$("#photoLoading").show();
$("#photoForm .modal-confirm").prop("disabled", true);
$.ajax({
url: "upload_photo.php",
type: "POST",
@@ -1191,18 +1294,23 @@ if (!empty($_GET['ajax'])) {
contentType: false,
dataType: "json",
success: function(r) {
$("#photoLoading").hide();
$("#photoForm .modal-confirm").prop("disabled", false);
if (r.success) {
// conferma + refresh galleria
showPhotoSuccess();
loadPhotoGallery(
$("#photoProductionId").val(),
$("#photoType").val()
$("#photoType").val(),
$("#photoParamPosition").val() || null
);
} else {
showPhotoError(r.message || "Errore durante il caricamento della foto.");
}
},
error: function() {
$("#photoLoading").hide();
$("#photoForm .modal-confirm").prop("disabled", false);
showPhotoError("Errore di comunicazione con il server.");
}
});
@@ -1210,6 +1318,7 @@ if (!empty($_GET['ajax'])) {
$('.record-card.in-production').each(function() {
const $card = $(this);
const $expanded = $card.find('.record-expanded');
@@ -1550,6 +1659,34 @@ if (!empty($_GET['ajax'])) {
loadRecords();
});
// --- MODALE MESCOLE ---
$(document).on("click", ".showMescole", function(e) {
e.stopPropagation();
// prendo la stringa grezza dallattributo, NON .data()
const raw = $(this).attr("data-list") || "[]";
let list = [];
try {
list = JSON.parse(raw);
} catch (err) {
console.error("Errore parsing mescole:", err, raw);
list = [];
}
let html = "";
list.forEach(m => {
html += `<li style="margin:6px 0;font-size:1.1rem;">${m}</li>`;
});
$("#mescoleList").html(html || '<li style="margin:6px 0;">Nessuna mescola</li>');
$("#mescoleModal").addClass("active");
});
$(document).on("click", "#closeMescole", function() {
$("#mescoleModal").removeClass("active");
});
</script>
<!-- MODALE PER PREVIEW IMMAGINE -->
@@ -1588,6 +1725,42 @@ if (!empty($_GET['ajax'])) {
</div>
</div>
<!-- MODALE MESCOLE -->
<div id="mescoleModal" class="modal">
<div class="modal-content" style="max-width:400px;">
<h3>Mescole utilizzate</h3>
<ul id="mescoleList" style="text-align:left; padding-left:1rem;"></ul>
<div class="modal-buttons">
<button class="modal-btn modal-cancel" id="closeMescole">Chiudi</button>
</div>
</div>
</div>
<script>
// apre il file picker sul campo interno al form
$(document).on("click", "#choosePhotoBtn", function(e) {
e.stopPropagation();
$("#photoInput").click();
});
// mostra solo il nome file scelto (opzionale)
$(document).on("change", "#photoInput", function() {
const file = this.files[0];
if (!file) return;
$("#selectedPhotoName").text(file.name);
});
</script>
</body>
</html>
</body>
</html>