added files for mescole

This commit is contained in:
2026-07-03 09:28:21 +02:00
parent c675eb766e
commit 376252e263
10 changed files with 955 additions and 20 deletions
+397
View File
@@ -0,0 +1,397 @@
<?php include('include/headscript.php'); ?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<title>Scheda Mescola - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<style>
body {
font-size: 1.05rem;
background: #f8fafc;
}
.card {
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.back-dashboard {
background-color: #cfe3ff !important;
color: #1f2d3d !important;
border: 1px solid #bcd4f4 !important;
border-radius: 10px;
font-weight: 600;
padding: 10px 18px;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease-in-out;
}
.back-dashboard:hover {
background-color: #b9d3ff !important;
transform: translateY(-2px);
}
.info-label {
font-size: .8rem;
text-transform: uppercase;
letter-spacing: .04em;
color: #6c757d;
margin-bottom: 2px;
}
.info-value {
font-size: 1.05rem;
font-weight: 600;
color: #1f2d3d;
}
.nav-tabs .nav-link.active {
background-color: #cfe3ff;
font-weight: 600;
}
.btn-add {
background-color: #0d6efd;
color: #fff;
border-radius: 8px;
font-weight: 500;
}
.btn-add:hover {
background-color: #0b5ed7;
}
</style>
</head>
<body>
<div class="wrapper" id="appWrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<!-- HEADER INFO GENERALI -->
<div class="card p-3 mb-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0" id="hNomeUscita">Scheda Mescola</h5>
<button type="button" class="btn back-dashboard" onclick="location.href='mescole.php'">
↩️ Torna a Gestione Mescole
</button>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-2">
<div class="info-label">ID</div>
<div class="info-value" id="hId">-</div>
</div>
<div class="col-md-3">
<div class="info-label">Nome Interno</div>
<div class="info-value" id="hNome">-</div>
</div>
<div class="col-md-3">
<div class="info-label">Q. Totale</div>
<div class="info-value" id="hQty">-</div>
</div>
<div class="col-md-2">
<div class="info-label">Stato</div>
<div class="info-value" id="hStato">-</div>
</div>
<div class="col-md-2">
<div class="info-label">Linee Associate</div>
<div class="info-value" id="hLinee">-</div>
</div>
</div>
</div>
</div>
<!-- TAB FILE PER CATEGORIA -->
<div class="card p-3">
<div class="card-body">
<ul class="nav nav-tabs" id="fileTabs" role="tablist"></ul>
<div class="tab-content pt-3" id="fileTabsContent"></div>
</div>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<!-- MODALE AGGIUNGI FILE -->
<div class="modal fade" id="addFileModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#cfe3ff;">
<h5 class="modal-title">Aggiungi File</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addFileForm">
<input type="hidden" id="fCategoria">
<div class="mb-3">
<label class="form-label fw-semibold">Titolo File</label>
<input type="text" class="form-control" id="fTitolo" required>
</div>
<div class="mb-3">
<label class="form-label fw-semibold">File</label>
<input type="file" class="form-control" id="fFile" required>
</div>
<div class="text-center">
<button type="submit" class="btn btn-add">💾 Carica File</button>
</div>
</form>
</div>
</div>
</div>
</div>
<?php include('jsinclude.php'); ?>
<script>
const idMescola = new URLSearchParams(window.location.search).get('id');
let CATEGORIE = {};
if (!idMescola) {
Swal.fire({
icon: 'error',
title: 'Errore',
text: 'ID mescola mancante'
}).then(() => location.href = 'mescole.php');
}
function fmtQty(n) {
return Number(n || 0).toLocaleString('it-IT', {
minimumFractionDigits: 3,
maximumFractionDigits: 3
});
}
function loadGeneral() {
fetch('get_mescola_general.php?id=' + encodeURIComponent(idMescola))
.then(r => r.json())
.then(res => {
if (!res.success) {
Swal.fire({
icon: 'error',
title: 'Errore',
text: res.message
}).then(() => location.href = 'mescole.php');
return;
}
const d = res.data;
document.title = 'Scheda Mescola - ' + d.nomeuscita;
$('#hNomeUscita').text('🧪 ' + d.nomeuscita);
$('#hId').text(d.id);
$('#hNome').text(d.nome || '-');
$('#hQty').text(fmtQty(d.qty_totale));
$('#hStato').html(
Number(d.is_active) === 1 ?
"<span class='badge bg-success'>Attiva</span>" :
"<span class='badge bg-secondary'>Inattiva</span>"
);
$('#hLinee').text(d.linee || 'Nessuna');
});
}
function buildTabs() {
fetch('get_mescola_files.php?id=' + encodeURIComponent(idMescola))
.then(r => r.json())
.then(res => {
if (!res.success) return;
CATEGORIE = res.categorie;
const tabsUl = $('#fileTabs');
const tabsContent = $('#fileTabsContent');
tabsUl.empty();
tabsContent.empty();
let first = true;
Object.keys(CATEGORIE).forEach(slug => {
const label = CATEGORIE[slug];
const activeTab = first ? 'active' : '';
const activePane = first ? 'show active' : '';
tabsUl.append(`
<li class="nav-item" role="presentation">
<button class="nav-link ${activeTab}" id="tab-${slug}" data-bs-toggle="tab"
data-bs-target="#pane-${slug}" type="button" role="tab">
${label}
</button>
</li>
`);
tabsContent.append(`
<div class="tab-pane fade ${activePane}" id="pane-${slug}" role="tabpanel">
<div class="d-flex justify-content-end mb-2">
<button class="btn btn-add btn-sm add-file-btn" data-categoria="${slug}">
Aggiungi File
</button>
</div>
<div class="table-responsive">
<table class="table table-striped align-middle text-center" id="table-${slug}">
<thead class="table-light">
<tr>
<th>Titolo</th>
<th>Nome File</th>
<th>Caricato il</th>
<th>Azioni</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
`);
first = false;
});
// popola ogni tab con i file già caricati
Object.keys(CATEGORIE).forEach(slug => loadFilesForCategory(slug));
});
}
function loadFilesForCategory(slug) {
fetch('get_mescola_files.php?id=' + encodeURIComponent(idMescola) + '&categoria=' + encodeURIComponent(slug))
.then(r => r.json())
.then(res => {
const tbody = $('#table-' + slug + ' tbody');
tbody.empty();
if (!res.success || res.rows.length === 0) {
tbody.append(`<tr>
<td class="text-muted" colspan="4">Nessun file caricato in questa categoria</td>
</tr>`);
return;
}
res.rows.forEach(f => {
tbody.append(`
<tr>
<td>${f.titolo}</td>
<td><a href="${f.url}" target="_blank" rel="noopener">${f.original_filename}</a></td>
<td>${f.uploaded_at}</td>
<td>
<a class="btn btn-sm btn-outline-primary" href="${f.url}" target="_blank" rel="noopener">⬇️ Scarica</a>
<button class="btn btn-sm btn-outline-danger del-file-btn" data-id="${f.id}" data-categoria="${slug}">🗑️ Elimina</button>
</td>
</tr>
`);
});
});
}
$(document).on('click', '.add-file-btn', function() {
$('#fCategoria').val($(this).data('categoria'));
$('#fTitolo').val('');
$('#fFile').val('');
$('#addFileModal').modal('show');
});
$('#addFileForm').on('submit', function(e) {
e.preventDefault();
const categoria = $('#fCategoria').val();
const titolo = $('#fTitolo').val().trim();
const fileInput = document.getElementById('fFile');
if (!fileInput.files.length) {
Swal.fire({
icon: 'warning',
title: 'Attenzione',
text: 'Seleziona un file'
});
return;
}
const formData = new FormData();
formData.append('idmescola', idMescola);
formData.append('categoria', categoria);
formData.append('titolo', titolo);
formData.append('file', fileInput.files[0]);
fetch('save_mescola_file.php', {
method: 'POST',
body: formData
})
.then(r => r.json())
.then(res => {
if (res.success) {
$('#addFileModal').modal('hide');
Swal.fire({
icon: 'success',
title: 'File caricato!'
});
loadFilesForCategory(categoria);
} else {
Swal.fire({
icon: 'error',
title: 'Errore',
text: res.message || 'Upload non riuscito'
});
}
});
});
$(document).on('click', '.del-file-btn', function() {
const id = $(this).data('id');
const categoria = $(this).data('categoria');
Swal.fire({
title: 'Eliminare il file?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Sì, elimina',
cancelButtonText: 'Annulla',
confirmButtonColor: '#d33'
}).then(res => {
if (!res.isConfirmed) return;
fetch('delete_mescola_file.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `id=${encodeURIComponent(id)}`
})
.then(r => r.json())
.then(data => {
if (data.success) {
loadFilesForCategory(categoria);
} else {
Swal.fire({
icon: 'error',
title: 'Errore',
text: data.message || 'Cancellazione non riuscita'
});
}
});
});
});
$(document).ready(function() {
loadGeneral();
buildTabs();
});
</script>
</body>
</html>