maintaince module
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
<?php include(__DIR__ . '/../../include/headscript.php'); ?>
|
||||
<?php
|
||||
require_once __DIR__ . '/../include/functions.php';
|
||||
|
||||
$pdo = mnt_pdo();
|
||||
|
||||
if (!userCan('maintenance.categories.view')) {
|
||||
http_response_code(403);
|
||||
exit('Permesso negato.');
|
||||
}
|
||||
|
||||
$canManage = userCan('maintenance.manage');
|
||||
|
||||
$categories = $pdo->query("
|
||||
SELECT c.*,
|
||||
(SELECT COUNT(*) FROM inv_equipment e WHERE e.category_id = c.id) AS equipment_count
|
||||
FROM inv_categories c
|
||||
ORDER BY c.sort_order ASC, c.name ASC
|
||||
")->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$MNT_TITLE = 'Categorie attrezzature';
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="it">
|
||||
|
||||
<head>
|
||||
<?php include __DIR__ . '/../include/page_head.php'; ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php include __DIR__ . '/../include/wrapper_open.php'; ?>
|
||||
<?php include(__DIR__ . '/../../include/navbar.php'); ?>
|
||||
<?php include(__DIR__ . '/../../include/topbar.php'); ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
|
||||
<nav aria-label="breadcrumb" class="mb-3">
|
||||
<ol class="breadcrumb" style="background:transparent;padding:0;margin:0;font-size:0.85rem">
|
||||
<li class="breadcrumb-item"><a href="manutenzioni/index.php">Registro attrezzature</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Categorie</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="card mnt-card">
|
||||
<div class="card-header d-flex align-items-center justify-content-between flex-wrap gap-2">
|
||||
<h5><i class="fa-solid fa-tags me-2"></i>Categorie attrezzature</h5>
|
||||
<div class="header-actions d-flex gap-2 flex-wrap">
|
||||
<a href="manutenzioni/index.php" class="btn btn-mnt-outline d-inline-flex align-items-center gap-2">
|
||||
<i class="fa-solid fa-arrow-left"></i><span>Registro</span>
|
||||
</a>
|
||||
<?php if ($canManage): ?>
|
||||
<button class="btn btn-mnt-primary d-inline-flex align-items-center gap-2" id="btnAddCategory">
|
||||
<i class="fa-solid fa-plus"></i><span>Nuova categoria</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<?php if (!$categories): ?>
|
||||
<div class="empty-state">
|
||||
<i class="fa-solid fa-tags"></i>
|
||||
<p>Nessuna categoria definita.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div id="categoryList">
|
||||
<!-- MOBILE -->
|
||||
<div class="d-md-none">
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<div class="mnt-item-card" style="--row-color: <?= mnt_h($category['color']) ?>"
|
||||
data-id="<?= (int)$category['id'] ?>"
|
||||
data-json="<?= mnt_h(json_encode($category, JSON_UNESCAPED_UNICODE)) ?>">
|
||||
<div class="ic-title"><?= mnt_h($category['name']) ?></div>
|
||||
<div class="ic-meta">
|
||||
Attrezzature: <strong><?= (int)$category['equipment_count'] ?></strong>
|
||||
<?php if ((int)$category['requires_line'] === 1): ?>
|
||||
· <span class="mnt-badge mnt-badge-soft">Richiede linea</span>
|
||||
<?php endif; ?>
|
||||
<?php if ((int)$category['is_active'] === 0): ?>
|
||||
· <span class="mnt-badge mnt-badge-none">Disattivata</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($canManage): ?>
|
||||
<div class="ic-actions">
|
||||
<button class="btn-action btn-action-edit btn-edit"><i class="fa-solid fa-pen"></i></button>
|
||||
<button class="btn-action btn-action-delete btn-delete"
|
||||
data-name="<?= mnt_h($category['name']) ?>"
|
||||
data-count="<?= (int)$category['equipment_count'] ?>">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<!-- DESKTOP -->
|
||||
<div class="d-none d-md-block table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:60px">Colore</th>
|
||||
<th>Nome</th>
|
||||
<th>Codice</th>
|
||||
<th class="text-center">Richiede linea</th>
|
||||
<th class="text-center">Ordine</th>
|
||||
<th class="text-center">Attrezzature</th>
|
||||
<th class="text-center">Stato</th>
|
||||
<?php if ($canManage): ?><th class="text-center" style="width:120px">Azioni</th><?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<tr data-id="<?= (int)$category['id'] ?>"
|
||||
data-json="<?= mnt_h(json_encode($category, JSON_UNESCAPED_UNICODE)) ?>">
|
||||
<td><span class="mnt-cat-dot" style="width:22px;height:22px;background: <?= mnt_h($category['color']) ?>"></span></td>
|
||||
<td class="fw-semibold" style="color:var(--mnt-heading)"><?= mnt_h($category['name']) ?></td>
|
||||
<td class="small text-muted"><?= mnt_h($category['code'] ?: '—') ?></td>
|
||||
<td class="text-center">
|
||||
<?= (int)$category['requires_line'] === 1
|
||||
? '<span class="mnt-badge mnt-badge-soft">Richiede linea</span>'
|
||||
: '<span class="text-muted">—</span>' ?>
|
||||
</td>
|
||||
<td class="text-center small"><?= (int)$category['sort_order'] ?></td>
|
||||
<td class="text-center"><?= (int)$category['equipment_count'] ?></td>
|
||||
<td class="text-center">
|
||||
<span class="mnt-badge <?= (int)$category['is_active'] === 1 ? 'mnt-badge-ok' : 'mnt-badge-none' ?>">
|
||||
<?= (int)$category['is_active'] === 1 ? 'Attiva' : 'Disattivata' ?>
|
||||
</span>
|
||||
</td>
|
||||
<?php if ($canManage): ?>
|
||||
<td class="text-center">
|
||||
<div class="d-inline-flex gap-1">
|
||||
<button class="btn-action btn-action-edit btn-edit" title="Modifica"><i class="fa-solid fa-pen"></i></button>
|
||||
<button class="btn-action btn-action-delete btn-delete" title="Elimina"
|
||||
data-name="<?= mnt_h($category['name']) ?>"
|
||||
data-count="<?= (int)$category['equipment_count'] ?>">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php include(__DIR__ . '/../../include/footer.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php if ($canManage): ?>
|
||||
<div class="modal fade" id="categoryModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-fullscreen-sm-down">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="categoryModalTitle">Nuova categoria</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
|
||||
</div>
|
||||
<form id="categoryForm">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="id" id="catId" value="">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-semibold">Nome <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="name" id="catName" maxlength="150" required>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label fw-semibold">Codice</label>
|
||||
<input type="text" class="form-control" name="code" id="catCode" maxlength="50">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label fw-semibold">Ordine</label>
|
||||
<input type="number" class="form-control" name="sort_order" id="catSort" min="0" max="9999" value="999">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label fw-semibold">Colore</label>
|
||||
<input type="color" class="form-control form-control-color" name="color" id="catColor" value="#6c757d">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label fw-semibold">Descrizione</label>
|
||||
<textarea class="form-control" name="description" id="catDescription" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-3">
|
||||
<input class="form-check-input" type="checkbox" name="requires_line" id="catRequiresLine" value="1">
|
||||
<label class="form-check-label fw-semibold" for="catRequiresLine">
|
||||
Richiede una linea di produzione
|
||||
</label>
|
||||
<div class="form-text">Le attrezzature di questa categoria devono indicare la linea.</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="checkbox" name="is_active" id="catActive" value="1" checked>
|
||||
<label class="form-check-label fw-semibold" for="catActive">Attiva</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Annulla</button>
|
||||
<button type="submit" class="btn btn-mnt-primary">Salva</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include(__DIR__ . '/../../jsinclude.php'); ?>
|
||||
<script>
|
||||
$(function () {
|
||||
<?php if ($canManage): ?>
|
||||
function openModal(data) {
|
||||
const isEdit = !!data;
|
||||
$('#categoryModalTitle').text(isEdit ? 'Modifica categoria' : 'Nuova categoria');
|
||||
$('#catId').val(isEdit ? data.id : '');
|
||||
$('#catName').val(isEdit ? data.name : '');
|
||||
$('#catCode').val(isEdit ? (data.code || '') : '');
|
||||
$('#catSort').val(isEdit ? data.sort_order : 999);
|
||||
$('#catColor').val(isEdit ? data.color : '#6c757d');
|
||||
$('#catDescription').val(isEdit ? (data.description || '') : '');
|
||||
$('#catRequiresLine').prop('checked', isEdit ? Number(data.requires_line) === 1 : false);
|
||||
$('#catActive').prop('checked', isEdit ? Number(data.is_active) === 1 : true);
|
||||
new bootstrap.Modal('#categoryModal').show();
|
||||
}
|
||||
|
||||
$('#btnAddCategory').on('click', () => openModal(null));
|
||||
|
||||
$('#categoryList').on('click', '.btn-edit', function () {
|
||||
openModal($(this).closest('[data-json]').data('json'));
|
||||
});
|
||||
|
||||
$('#categoryList').on('click', '.btn-delete', function () {
|
||||
const $btn = $(this);
|
||||
const count = parseInt($btn.data('count') || 0, 10);
|
||||
const id = $btn.closest('[data-id]').data('id');
|
||||
|
||||
if (count > 0) {
|
||||
Swal.fire({
|
||||
icon: 'warning', title: 'Impossibile eliminare',
|
||||
text: `La categoria "${$btn.data('name')}" è usata da ${count} attrezzature.`
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: `Eliminare "${$btn.data('name')}"?`, icon: 'warning', showCancelButton: true,
|
||||
confirmButtonText: 'Elimina', cancelButtonText: 'Annulla', confirmButtonColor: '#dc3545'
|
||||
}).then(r => {
|
||||
if (!r.isConfirmed) return;
|
||||
$.post('manutenzioni/ajax/delete_category.php', { id: id })
|
||||
.done(res => res.success ? location.reload() : Swal.fire({ icon: 'error', title: 'Errore', text: res.message }));
|
||||
});
|
||||
});
|
||||
|
||||
$('#categoryForm').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
if (!$('#catName').val().trim()) { Swal.fire({ icon: 'warning', title: 'Nome obbligatorio' }); return; }
|
||||
|
||||
$.post('manutenzioni/ajax/save_category.php', $(this).serialize())
|
||||
.done(res => res.success ? location.reload() : Swal.fire({ icon: 'error', title: 'Errore', text: res.message }))
|
||||
.fail(() => Swal.fire({ icon: 'error', title: 'Errore di rete' }));
|
||||
});
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user