added flag to photos

This commit is contained in:
Claudio 2026-03-12 10:20:22 +01:00
parent 1f27bc48d4
commit 817bbadf22
5 changed files with 287 additions and 16 deletions

File diff suppressed because one or more lines are too long

View File

@ -160,6 +160,7 @@ try {
"Matrice" => $matriceId,
"SottoMatrice" => null,
"SchemaCustomField" => $schemaId,
"Riferimento" => $part["part_description"] ?? "",
"NoteWeb" => $part["part_description"] ?? "",
"ConsegnaRichiesta" => $consegnaRichiesta,
];

View File

@ -349,6 +349,69 @@ document.addEventListener("DOMContentLoaded", function () {
});
});
document
.querySelectorAll(".photo-flag-checkbox")
.forEach((checkbox) => {
checkbox.addEventListener("change", async function () {
const photoId = this.getAttribute("data-photo-id");
const field = this.getAttribute("data-field");
const value = this.checked ? 1 : 0;
const currentCheckbox = this;
// Only one PrimaPagina visually in the current popup
if (field === "PrimaPagina" && value === 1) {
document
.querySelectorAll(
".photo-flag-checkbox[data-field='PrimaPagina']",
)
.forEach((cb) => {
if (cb !== currentCheckbox) {
cb.checked = false;
}
});
}
try {
const formData = new URLSearchParams();
formData.append("photo_id", photoId);
formData.append("field", field);
formData.append("value", value);
const response = await fetch("update_photo_flags.php", {
method: "POST",
headers: {
"Content-Type":
"application/x-www-form-urlencoded",
},
body: formData.toString(),
});
const result = await response.json();
if (!result.success) {
throw new Error(
result.message || "Errore salvataggio flag",
);
}
// Safety refresh for PrimaPagina to ensure UI matches DB
if (field === "PrimaPagina") {
loadPopupContent(iddatadb, idquotations);
}
} catch (error) {
alert(
"Errore durante il salvataggio del flag: " +
error.message,
);
// rollback current checkbox
currentCheckbox.checked = !currentCheckbox.checked;
// reload popup to restore coherent state
loadPopupContent(iddatadb, idquotations);
}
});
});
document.querySelectorAll(".thumbnail").forEach((img) => {
img.addEventListener("click", function () {
const enlargedImage = document.getElementById("enlargedImage");

View File

@ -117,12 +117,24 @@ $code = $row[$field] ?? 'Non disponibile';
// Recupera le foto associate alla riga
try {
$stmt = $pdo->prepare("SELECT id, file_path, file_name, description, uploaded_at FROM {$photoTable} WHERE {$photoParamName} = ? ORDER BY uploaded_at DESC");
$stmt = $pdo->prepare("
SELECT
id,
file_path,
file_name,
uploaded_at,
description,
StampaNelRapporto,
PrimaPagina
FROM {$photoTable}
WHERE {$photoParamName} = ?
ORDER BY uploaded_at DESC
");
$stmt->execute([$paramValue]);
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
error_log("Errore query foto: " . $e->getMessage());
$photos = []; // Imposta array vuoto in caso di errore
$photos = [];
}
// Definisci il percorso base per le foto
@ -134,7 +146,7 @@ $uploadUrl = $iddatadb
? $baseUrl . "/upload_photos_mobile.php?iddatadb=" . $iddatadb
: $baseUrl . "/upload_photos_mobile.php?idquotations=" . $idquotations;
// Genera il QR code con endroid/qr-code 6.0.6
// Genera il QR code con endroid/qr-code
$qrCodeDir = '../photostrf/qrcodes/';
if (!is_dir($qrCodeDir)) {
mkdir($qrCodeDir, 0755, true);
@ -164,6 +176,7 @@ $result->saveToFile($qrCodeFile);
<p>Caricamento in corso...</p>
</div>
</div>
<h3>Manage Photos</h3>
<p><strong>ID:</strong> <?= htmlspecialchars($id) ?></p>
<p><strong>Code:</strong> <?= htmlspecialchars($code) ?></p>
@ -182,6 +195,7 @@ $result->saveToFile($qrCodeFile);
<p>Drag the photo here or click to select</p>
<input type="file" id="photoInput" multiple accept="image/*" style="display: none;">
</div>
<!-- Area per la webcam -->
<div id="webcamArea" style="display: none; text-align: center; margin-bottom: 20px;">
<p>Webcam Preview</p>
@ -194,7 +208,9 @@ $result->saveToFile($qrCodeFile);
<button id="closeWebcamBtn" style="padding: 10px 20px; background: #dc3545; color: white; border: none; cursor: pointer;">Close Webcam</button>
</div>
</div>
<button id="openWebcamBtn" style="padding: 10px 20px; background: #007bff; color: white; border: none; cursor: pointer; margin-bottom: 20px;">Take Photo with Webcam</button>
<!-- Elenco delle foto -->
<div id="photosList">
<?php if (empty($photos)): ?>
@ -204,25 +220,57 @@ $result->saveToFile($qrCodeFile);
<?php
$filePath = $photoBasePath . $photo['file_path'];
$fileExists = file_exists($filePath);
$stampaNelRapporto = !empty($photo['StampaNelRapporto']) ? 1 : 0;
$primaPagina = !empty($photo['PrimaPagina']) ? 1 : 0;
?>
<div class="photo-item" data-photo-id="<?= $photo['id'] ?>" style="display: flex; align-items: center; margin-bottom: 10px; border-bottom: 1px solid #eee; padding-bottom: 10px;">
<div style="flex: 1;">
<div class="photo-item" data-photo-id="<?= (int)$photo['id'] ?>">
<div class="photo-thumb-area">
<?php if ($fileExists): ?>
<img src="../photostrf/<?= htmlspecialchars($photo['file_path']) ?>" alt="<?= htmlspecialchars($photo['file_name']) ?>" class="thumbnail" style="max-width: 100px; max-height: 100px; margin-right: 10px; cursor: pointer;">
<img src="../photostrf/<?= htmlspecialchars($photo['file_path']) ?>"
alt="<?= htmlspecialchars($photo['file_name']) ?>"
class="thumbnail"
style="max-width: 100px; max-height: 100px; cursor: pointer;">
<?php else: ?>
<p style="color: red;">[File non trovato]</p>
<div class="missing-file-box">[File non trovato]</div>
<?php endif; ?>
<p style="margin: 0;">
<strong>Nome:</strong> <?= htmlspecialchars($photo['file_name']) ?><br>
<strong>Caricata il:</strong> <?= htmlspecialchars($photo['uploaded_at']) ?><br>
<strong>Descrizione:</strong> <?= htmlspecialchars($photo['description'] ?? 'Nessuna descrizione') ?>
</p>
</div>
<button class="delete-photo-btn" data-photo-id="<?= $photo['id'] ?>" style="background: none; border: none; color: #dc3545; cursor: pointer;">
<i class="fas fa-trash"></i>
</button>
<div class="photo-info-area">
<p class="photo-name">
<strong>Name:</strong> <?= htmlspecialchars($photo['file_name']) ?>
</p>
<div class="photo-flags">
<label class="flag-label">
<input
type="checkbox"
class="photo-flag-checkbox"
data-photo-id="<?= (int)$photo['id'] ?>"
data-field="StampaNelRapporto"
<?= $stampaNelRapporto ? 'checked' : '' ?>>
Print in Report
</label>
<label class="flag-label">
<input
type="checkbox"
class="photo-flag-checkbox prima-pagina-checkbox"
data-photo-id="<?= (int)$photo['id'] ?>"
data-field="PrimaPagina"
<?= $primaPagina ? 'checked' : '' ?>>
First Page
</label>
</div>
</div>
<div class="photo-actions-area">
<button class="delete-photo-btn" data-photo-id="<?= (int)$photo['id'] ?>" type="button">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<?php endforeach; ?>
<!-- Bottone Crea Collage -->
<button id="createCollageBtn" style="padding: 10px 20px; background: #ffc107; color: white; border: none; cursor: pointer; margin-top: 20px;">Crea Collage</button>
<?php endif; ?>
@ -283,6 +331,12 @@ $result->saveToFile($qrCodeFile);
<style>
.photo-item {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 12px;
border-bottom: 1px solid #eee;
padding: 12px 0;
transition: background-color 0.3s;
}
@ -290,6 +344,68 @@ $result->saveToFile($qrCodeFile);
background-color: #f8f9fa;
}
.photo-thumb-area {
flex: 0 0 110px;
text-align: center;
}
.photo-info-area {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.photo-actions-area {
flex: 0 0 40px;
display: flex;
justify-content: center;
align-items: center;
}
.photo-name {
margin: 0;
word-break: break-word;
}
.photo-flags {
display: flex;
flex-wrap: wrap;
gap: 18px;
margin-top: 4px;
}
.flag-label {
display: flex;
align-items: center;
gap: 6px;
margin: 0;
font-size: 14px;
cursor: pointer;
}
.flag-label input[type="checkbox"] {
transform: scale(1.1);
cursor: pointer;
}
.delete-photo-btn {
background: none;
border: none;
color: #dc3545;
cursor: pointer;
font-size: 18px;
}
.delete-photo-btn:hover {
color: #b02a37;
}
.missing-file-box {
color: red;
font-size: 13px;
}
#dropArea.highlight {
border-color: #28a745;
background-color: #e9ecef;

View File

@ -0,0 +1,91 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json');
try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
throw new Exception('Metodo non valido');
}
$photoId = isset($_POST['photo_id']) ? (int)$_POST['photo_id'] : 0;
$field = isset($_POST['field']) ? trim($_POST['field']) : '';
$value = isset($_POST['value']) ? (int)$_POST['value'] : 0;
if ($photoId <= 0) {
throw new Exception('photo_id mancante o non valido');
}
$allowedFields = ['StampaNelRapporto', 'PrimaPagina'];
if (!in_array($field, $allowedFields, true)) {
throw new Exception('Campo non consentito');
}
$value = $value === 1 ? 1 : 0;
// Recupera la foto per sapere a quale record padre appartiene
$stmt = $pdo->prepare("
SELECT id, iddatadb, idquotations
FROM datadb_photos
WHERE id = ?
LIMIT 1
");
$stmt->execute([$photoId]);
$photo = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$photo) {
throw new Exception('Foto non trovata');
}
$iddatadb = !empty($photo['iddatadb']) ? (int)$photo['iddatadb'] : null;
$idquotations = !empty($photo['idquotations']) ? (int)$photo['idquotations'] : null;
$pdo->beginTransaction();
if ($field === 'PrimaPagina' && $value === 1) {
// Solo una foto può essere PrimaPagina per lo stesso record padre
if ($iddatadb) {
$stmtReset = $pdo->prepare("
UPDATE datadb_photos
SET PrimaPagina = 0
WHERE iddatadb = ?
");
$stmtReset->execute([$iddatadb]);
} elseif ($idquotations) {
$stmtReset = $pdo->prepare("
UPDATE datadb_photos
SET PrimaPagina = 0
WHERE idquotations = ?
");
$stmtReset->execute([$idquotations]);
}
}
$stmtUpdate = $pdo->prepare("
UPDATE datadb_photos
SET {$field} = ?
WHERE id = ?
");
$stmtUpdate->execute([$value, $photoId]);
$pdo->commit();
echo json_encode([
'success' => true,
'photo_id' => $photoId,
'field' => $field,
'value' => $value
]);
} catch (Exception $e) {
if (isset($pdo) && $pdo->inTransaction()) {
$pdo->rollBack();
}
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}