530 lines
24 KiB
PHP
530 lines
24 KiB
PHP
<?php
|
||
ini_set('display_errors', 1);
|
||
error_reporting(E_ALL);
|
||
|
||
include('include/headscript.php');
|
||
|
||
$db = DBHandlerSelect::getInstance();
|
||
$pdo = $db->getConnection();
|
||
|
||
// AJAX HANDLERS
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] == '1') {
|
||
header('Content-Type: application/json');
|
||
|
||
$action = $_POST['action'] ?? '';
|
||
|
||
try {
|
||
if ($action === 'add') {
|
||
$name = trim($_POST['name'] ?? '');
|
||
$abbreviato = trim($_POST['abbreviato'] ?? '');
|
||
$ordinamento = (int)($_POST['ordinamento'] ?? 999);
|
||
$description = trim($_POST['description'] ?? '');
|
||
$production_line_id = $_POST['production_line_id'] !== '' ? (int)$_POST['production_line_id'] : null;
|
||
$tool_id = $_POST['tool_id'] !== '' ? (int)$_POST['tool_id'] : null;
|
||
$tool_note = trim($_POST['tool_note'] ?? '');
|
||
|
||
if ($name === '') {
|
||
echo json_encode(['success' => false, 'message' => 'Nome obbligatorio']);
|
||
exit;
|
||
}
|
||
|
||
$stmt = $pdo->prepare("
|
||
INSERT INTO skills
|
||
(name, abbreviato, ordinamento, description, production_line_id, tool_id, tool_note)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||
");
|
||
$stmt->execute([$name, $abbreviato, $ordinamento, $description, $production_line_id, $tool_id, $tool_note]);
|
||
|
||
echo json_encode(['success' => true]);
|
||
exit;
|
||
}
|
||
|
||
if ($action === 'edit') {
|
||
$id = (int)($_POST['id'] ?? 0);
|
||
$name = trim($_POST['name'] ?? '');
|
||
$abbreviato = trim($_POST['abbreviato'] ?? '');
|
||
$ordinamento = (int)($_POST['ordinamento'] ?? 999);
|
||
$description = trim($_POST['description'] ?? '');
|
||
$production_line_id = $_POST['production_line_id'] !== '' ? (int)$_POST['production_line_id'] : null;
|
||
$tool_id = $_POST['tool_id'] !== '' ? (int)$_POST['tool_id'] : null;
|
||
$tool_note = trim($_POST['tool_note'] ?? '');
|
||
|
||
if ($id <= 0 || $name === '') {
|
||
echo json_encode(['success' => false, 'message' => 'Dati non validi']);
|
||
exit;
|
||
}
|
||
|
||
$stmt = $pdo->prepare("
|
||
UPDATE skills SET
|
||
name = ?, abbreviato = ?, ordinamento = ?, description = ?,
|
||
production_line_id = ?, tool_id = ?, tool_note = ?
|
||
WHERE id = ?
|
||
");
|
||
$stmt->execute([$name, $abbreviato, $ordinamento, $description, $production_line_id, $tool_id, $tool_note, $id]);
|
||
|
||
echo json_encode(['success' => true]);
|
||
exit;
|
||
}
|
||
|
||
if ($action === 'delete') {
|
||
$id = (int)($_POST['id'] ?? 0);
|
||
if ($id <= 0) {
|
||
echo json_encode(['success' => false, 'message' => 'ID non valido']);
|
||
exit;
|
||
}
|
||
|
||
$stmt = $pdo->prepare("DELETE FROM skills WHERE id = ?");
|
||
$stmt->execute([$id]);
|
||
|
||
echo json_encode(['success' => true]);
|
||
exit;
|
||
}
|
||
|
||
echo json_encode(['success' => false, 'message' => 'Azione sconosciuta']);
|
||
exit;
|
||
} catch (Exception $e) {
|
||
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||
exit;
|
||
}
|
||
}
|
||
|
||
// Elenco skills con nome tool
|
||
$skills = $pdo->query("
|
||
SELECT
|
||
s.id,
|
||
s.name,
|
||
s.abbreviato,
|
||
s.ordinamento,
|
||
s.description,
|
||
s.tool_id,
|
||
s.tool_note,
|
||
s.production_line_id,
|
||
pl.name AS linea_name,
|
||
pt.name AS tool_name,
|
||
pt.registration_number
|
||
FROM skills s
|
||
LEFT JOIN production_lines pl ON s.production_line_id = pl.id
|
||
LEFT JOIN production_tools pt ON s.tool_id = pt.id
|
||
ORDER BY s.ordinamento ASC, s.id
|
||
")->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
// Linee produzione
|
||
$lines = $pdo->query("SELECT id, name FROM production_lines ORDER BY line_number")->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
// Attrezzature per tendina
|
||
$tools = $pdo->query("
|
||
SELECT id, name, registration_number
|
||
FROM production_tools
|
||
WHERE is_active = 1
|
||
ORDER BY name
|
||
")->fetchAll(PDO::FETCH_ASSOC);
|
||
?>
|
||
|
||
<!doctype html>
|
||
<html lang="it">
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<?php include('cssinclude.php'); ?>
|
||
<title>Gestione Skills</title>
|
||
|
||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.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: 0.95rem;
|
||
background: #f8fafc;
|
||
}
|
||
|
||
.card {
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.back-dashboard {
|
||
background: #cfe3ff !important;
|
||
color: #1f2d3d !important;
|
||
border: 1px solid #bcd4f4 !important;
|
||
border-radius: 10px;
|
||
font-weight: 600;
|
||
padding: 10px 18px;
|
||
}
|
||
|
||
.btn-add {
|
||
background: #0d6efd;
|
||
color: white;
|
||
border-radius: 8px;
|
||
padding: 10px 20px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.table thead {
|
||
background: #cfe3ff;
|
||
color: #1f2d3d;
|
||
}
|
||
|
||
.modal-content {
|
||
border-radius: 16px;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="wrapper toggled">
|
||
<?php include('include/navbar.php'); ?>
|
||
<?php include('include/topbar.php'); ?>
|
||
|
||
<div class="page-wrapper">
|
||
<div class="page-content">
|
||
<div class="card p-3">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0">Gestione Skills</h5>
|
||
<button class="btn back-dashboard" onclick="location.href='production_dashboard.php'">
|
||
↩️ Dashboard
|
||
</button>
|
||
</div>
|
||
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
<h6 class="fw-semibold mb-0">Elenco Skills</h6>
|
||
<button class="btn btn-add" data-bs-toggle="modal" data-bs-target="#addSkillModal">
|
||
➕ Aggiungi Skill
|
||
</button>
|
||
</div>
|
||
|
||
<div class="table-responsive">
|
||
<table id="tabellaSkills" class="table table-striped table-bordered">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Abbreviato</th>
|
||
<th>Ordinamento</th>
|
||
<th>Linea</th>
|
||
<th>Attrezzatura</th>
|
||
<th>Nota Tool</th>
|
||
<th>Azioni</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($skills as $s): ?>
|
||
<tr>
|
||
<td><?= htmlspecialchars($s['name']) ?></td>
|
||
<td><?= htmlspecialchars($s['abbreviato'] ?? '-') ?></td>
|
||
<td><?= (int)$s['ordinamento'] ?></td>
|
||
<td><?= htmlspecialchars($s['linea_name'] ?? '-') ?></td>
|
||
<td>
|
||
<?php if ($s['tool_name']): ?>
|
||
<?= htmlspecialchars($s['tool_name']) ?>
|
||
<?php if ($s['registration_number']): ?>
|
||
<small>(<?= htmlspecialchars($s['registration_number']) ?>)</small>
|
||
<?php endif; ?>
|
||
<?php else: ?>
|
||
-
|
||
<?php endif; ?>
|
||
</td>
|
||
<td><?= htmlspecialchars($s['tool_note'] ?? '-') ?></td>
|
||
<td>
|
||
<button class="btn btn-sm btn-outline-primary edit-skill"
|
||
data-id="<?= $s['id'] ?>"
|
||
data-name="<?= htmlspecialchars($s['name'], ENT_QUOTES) ?>"
|
||
data-abbreviato="<?= htmlspecialchars($s['abbreviato'] ?? '', ENT_QUOTES) ?>"
|
||
data-ordinamento="<?= (int)$s['ordinamento'] ?>"
|
||
data-description="<?= htmlspecialchars($s['description'] ?? '', ENT_QUOTES) ?>"
|
||
data-line="<?= $s['production_line_id'] ?? '' ?>"
|
||
data-tool_id="<?= $s['tool_id'] ?? '' ?>"
|
||
data-tool_note="<?= htmlspecialchars($s['tool_note'] ?? '', ENT_QUOTES) ?>">
|
||
✏️ Modifica
|
||
</button>
|
||
<button class="btn btn-sm btn-outline-danger delete-skill"
|
||
data-id="<?= $s['id'] ?>"
|
||
data-name="<?= htmlspecialchars($s['name'], ENT_QUOTES) ?>">
|
||
🗑️ Elimina
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php include('include/footer.php'); ?>
|
||
</div>
|
||
|
||
<!-- MODAL AGGIUNGI SKILL -->
|
||
<div class="modal fade" id="addSkillModal" tabindex="-1">
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header" style="background:#cfe3ff;">
|
||
<h5 class="modal-title">Aggiungi Nuova Skill</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<form id="addSkillForm">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Nome *</label>
|
||
<input type="text" class="form-control" name="name" required>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Abbreviato</label>
|
||
<input type="text" class="form-control" name="abbreviato">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label fw-semibold">Ordinamento</label>
|
||
<input type="number" class="form-control" name="ordinamento" value="999" min="1">
|
||
</div>
|
||
<div class="col-md-8 mb-3">
|
||
<label class="form-label fw-semibold">Linea di produzione</label>
|
||
<select class="form-select" name="production_line_id">
|
||
<option value="">-- Nessuna --</option>
|
||
<?php foreach ($lines as $line): ?>
|
||
<option value="<?= $line['id'] ?>"><?= htmlspecialchars($line['name']) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold">Descrizione</label>
|
||
<textarea class="form-control" name="description" rows="3"></textarea>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Attrezzatura / Tool</label>
|
||
<select class="form-select" name="tool_id">
|
||
<option value="">-- Nessuna --</option>
|
||
<?php foreach ($tools as $tool): ?>
|
||
<option value="<?= $tool['id'] ?>">
|
||
<?= htmlspecialchars($tool['name']) ?>
|
||
<?= $tool['registration_number'] ? ' (' . htmlspecialchars($tool['registration_number']) . ')' : '' ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Nota Tool</label>
|
||
<input type="text" class="form-control" name="tool_note">
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<button type="submit" class="btn btn-add">💾 Salva</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODAL MODIFICA SKILL -->
|
||
<div class="modal fade" id="editSkillModal" tabindex="-1">
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header" style="background:#cfe3ff;">
|
||
<h5 class="modal-title">Modifica Skill</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<form id="editSkillForm">
|
||
<input type="hidden" name="id" id="editId">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Nome *</label>
|
||
<input type="text" class="form-control" name="name" id="editName" required>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Abbreviato</label>
|
||
<input type="text" class="form-control" name="abbreviato" id="editAbbreviato">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-4 mb-3">
|
||
<label class="form-label fw-semibold">Ordinamento</label>
|
||
<input type="number" class="form-control" name="ordinamento" id="editOrdinamento" min="1">
|
||
</div>
|
||
<div class="col-md-8 mb-3">
|
||
<label class="form-label fw-semibold">Linea di produzione</label>
|
||
<select class="form-select" name="production_line_id" id="editLine">
|
||
<option value="">-- Nessuna --</option>
|
||
<?php foreach ($lines as $line): ?>
|
||
<option value="<?= $line['id'] ?>"><?= htmlspecialchars($line['name']) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold">Descrizione</label>
|
||
<textarea class="form-control" name="description" id="editDescription" rows="3"></textarea>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Attrezzatura / Tool</label>
|
||
<select class="form-select" name="tool_id" id="editToolId">
|
||
<option value="">-- Nessuna --</option>
|
||
<?php foreach ($tools as $tool): ?>
|
||
<option value="<?= $tool['id'] ?>">
|
||
<?= htmlspecialchars($tool['name']) ?>
|
||
<?= $tool['registration_number'] ? ' (' . htmlspecialchars($tool['registration_number']) . ')' : '' ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<label class="form-label fw-semibold">Nota Tool</label>
|
||
<input type="text" class="form-control" name="tool_note" id="editToolNote">
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<button type="submit" class="btn btn-add">💾 Salva Modifiche</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php include('jsinclude.php'); ?>
|
||
|
||
<script>
|
||
$(document).ready(function() {
|
||
$('#tabellaSkills').DataTable({
|
||
pageLength: 50,
|
||
lengthMenu: [10, 25, 50, 100],
|
||
order: [
|
||
[3, 'asc']
|
||
],
|
||
language: {
|
||
url: 'https://cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json'
|
||
}
|
||
});
|
||
|
||
// Aggiungi
|
||
$('#addSkillForm').on('submit', function(e) {
|
||
e.preventDefault();
|
||
const formData = new FormData(this);
|
||
formData.append('ajax', '1');
|
||
formData.append('action', 'add');
|
||
|
||
fetch('', {
|
||
method: 'POST',
|
||
body: new URLSearchParams(formData)
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
Swal.fire({
|
||
icon: 'success',
|
||
title: 'Aggiunta!',
|
||
timer: 1000
|
||
}).then(() => location.reload());
|
||
} else {
|
||
Swal.fire({
|
||
icon: 'error',
|
||
title: 'Errore',
|
||
text: data.message
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
// Modifica - apri modal
|
||
$(document).on('click', '.edit-skill', function() {
|
||
const btn = $(this);
|
||
$('#editId').val(btn.data('id'));
|
||
$('#editName').val(btn.data('name'));
|
||
$('#editAbbreviato').val(btn.data('abbreviato'));
|
||
$('#editOrdinamento').val(btn.data('ordinamento'));
|
||
$('#editDescription').val(btn.data('description'));
|
||
$('#editLine').val(btn.data('line'));
|
||
$('#editToolId').val(btn.data('tool_id'));
|
||
$('#editToolNote').val(btn.data('tool_note'));
|
||
$('#editSkillModal').modal('show');
|
||
});
|
||
|
||
// Salva modifica
|
||
$('#editSkillForm').on('submit', function(e) {
|
||
e.preventDefault();
|
||
const formData = new FormData(this);
|
||
formData.append('ajax', '1');
|
||
formData.append('action', 'edit');
|
||
|
||
fetch('', {
|
||
method: 'POST',
|
||
body: new URLSearchParams(formData)
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
Swal.fire({
|
||
icon: 'success',
|
||
title: 'Modificata!',
|
||
timer: 1000
|
||
}).then(() => location.reload());
|
||
} else {
|
||
Swal.fire({
|
||
icon: 'error',
|
||
title: 'Errore',
|
||
text: data.message
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
// Elimina
|
||
$(document).on('click', '.delete-skill', function() {
|
||
const id = $(this).data('id');
|
||
const name = $(this).data('name');
|
||
|
||
Swal.fire({
|
||
title: 'Confermi eliminazione?',
|
||
text: `Skill: ${name}`,
|
||
icon: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonColor: '#d33',
|
||
cancelButtonColor: '#6c757d',
|
||
confirmButtonText: 'Sì, elimina',
|
||
cancelButtonText: 'Annulla'
|
||
}).then(result => {
|
||
if (!result.isConfirmed) return;
|
||
|
||
fetch('', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: `ajax=1&action=delete&id=${id}`
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
Swal.fire({
|
||
icon: 'success',
|
||
title: 'Eliminata!',
|
||
timer: 1000
|
||
}).then(() => location.reload());
|
||
} else {
|
||
Swal.fire({
|
||
icon: 'error',
|
||
title: 'Errore',
|
||
text: data.message
|
||
});
|
||
}
|
||
});
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|