175 lines
6.9 KiB
PHP
175 lines
6.9 KiB
PHP
<?= $this->extend('layout/management_layout') ?>
|
||
<?= $this->section('content') ?>
|
||
|
||
<div class="container my-4">
|
||
<?php $isEdit = !empty($item); ?>
|
||
<h3 class="mb-3"><?= $isEdit ? 'Edit' : 'Add' ?> Book</h3>
|
||
|
||
<?= view('partials/flash_messages') ?>
|
||
<?php
|
||
$isEdit = isset($isEdit) && $isEdit;
|
||
$itemId = $item['id'] ?? null;
|
||
$action = $isEdit ? site_url('inventory/update/'.$itemId) : site_url('inventory/store');
|
||
|
||
// Build a label function for categories with grade range
|
||
$catLabel = function(array $c): string {
|
||
$name = $c['name'] ?? '';
|
||
$gmin = $c['grade_min'] ?? null;
|
||
$gmax = $c['grade_max'] ?? null;
|
||
if ($gmin !== null || $gmax !== null) {
|
||
// Render compact: (Gmin–Gmax) supports one-sided ranges too
|
||
if ($gmin !== null && $gmax !== null) $name .= " (G{$gmin}–G{$gmax})";
|
||
elseif ($gmin !== null) $name .= " (G{$gmin}+)";
|
||
elseif ($gmax !== null) $name .= " (≤G{$gmax})";
|
||
}
|
||
return $name;
|
||
};
|
||
|
||
// ---- Classes preselection (supports array, CSV, or JSON) ----
|
||
$selectedClasses = [];
|
||
$rawClasses = $item['classes'] ?? $item['class_list'] ?? $item['class_ids'] ?? null;
|
||
|
||
if (is_array($rawClasses)) {
|
||
$selectedClasses = array_map('intval', $rawClasses);
|
||
} elseif (is_string($rawClasses) && $rawClasses !== '') {
|
||
$decoded = json_decode($rawClasses, true);
|
||
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
|
||
$selectedClasses = array_map('intval', $decoded);
|
||
} else {
|
||
$parts = preg_split('/[,\s]+/', $rawClasses);
|
||
$selectedClasses = array_map('intval', array_filter($parts, static fn($v) => $v !== ''));
|
||
}
|
||
}
|
||
// Keep only values 1..13
|
||
$selectedClasses = array_values(array_intersect(range(1,13), $selectedClasses));
|
||
?>
|
||
<form method="post" action="<?= $action ?>">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="type" value="book">
|
||
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label">Title</label>
|
||
<input class="form-control" name="name" required value="<?= esc($item['name'] ?? '') ?>">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label">Category</label>
|
||
<select class="form-select" name="category_id" id="bookCategorySelect">
|
||
<option value="">— None —</option>
|
||
<?php foreach ($categories as $c): ?>
|
||
<?php
|
||
$cid = (int)($c['id'] ?? 0);
|
||
$sel = isset($item['category_id']) && (int)$item['category_id'] === $cid ? 'selected' : '';
|
||
$gmin = $c['grade_min'] ?? '';
|
||
$gmax = $c['grade_max'] ?? '';
|
||
?>
|
||
<option value="<?= esc($cid) ?>"
|
||
data-gmin="<?= esc($gmin) ?>"
|
||
data-gmax="<?= esc($gmax) ?>"
|
||
<?= $sel ?>>
|
||
<?= esc($catLabel($c)) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<div class="form-text">
|
||
Grade Range:
|
||
<span id="catGradeRange">—</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== Classes (1–13) ===== -->
|
||
<div class="col-12">
|
||
<label class="form-label d-flex align-items-center gap-2">
|
||
Classes (1–13)
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" id="btnSelectAllClasses">Select All</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" id="btnClearClasses">Clear</button>
|
||
</label>
|
||
<div class="row g-2" id="classesGrid">
|
||
<?php for ($i = 1; $i <= 13; $i++): ?>
|
||
<?php $checked = in_array($i, $selectedClasses, true) ? 'checked' : ''; ?>
|
||
<div class="col-6 col-sm-4 col-md-3 col-lg-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input class-checkbox" type="checkbox"
|
||
id="class<?= $i ?>" name="classes[]" value="<?= $i ?>" <?= $checked ?>>
|
||
<label class="form-check-label" for="class<?= $i ?>">Class <?= $i ?></label>
|
||
</div>
|
||
</div>
|
||
<?php endfor; ?>
|
||
</div>
|
||
<div class="form-text">Choose all class numbers that use this book.</div>
|
||
</div>
|
||
<!-- ========================== -->
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label">Author</label>
|
||
<input class="form-control" name="author" value="<?= esc($item['author'] ?? '') ?>">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">ISBN</label>
|
||
<input class="form-control" name="isbn" value="<?= esc($item['isbn'] ?? '') ?>">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Edition</label>
|
||
<input class="form-control" name="edition" value="<?= esc($item['edition'] ?? '') ?>">
|
||
</div>
|
||
|
||
<div class="col-md-2">
|
||
<label class="form-label">Quantity</label>
|
||
<input type="number" min="0" class="form-control" name="quantity" value="<?= esc($item['quantity'] ?? 0) ?>">
|
||
</div>
|
||
<div class="col-md-2">
|
||
<label class="form-label">Unit</label>
|
||
<input class="form-control" name="unit" placeholder="pcs, set" value="<?= esc($item['unit'] ?? '') ?>">
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label">SKU</label>
|
||
<input class="form-control" name="sku" value="<?= esc($item['sku'] ?? '') ?>">
|
||
</div>
|
||
|
||
<div class="col-12">
|
||
<label class="form-label">Description / Notes</label>
|
||
<textarea class="form-control" rows="3" name="description"><?= esc($item['description'] ?? '') ?></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-3 d-flex gap-2">
|
||
<button class="btn btn-primary"><?= $isEdit ? 'Update' : 'Save' ?></button>
|
||
<a class="btn btn-outline-secondary" href="<?= site_url('inventory/book') ?>">Cancel</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<script>
|
||
(function() {
|
||
// Category grade range helper
|
||
const sel = document.getElementById('bookCategorySelect');
|
||
const out = document.getElementById('catGradeRange');
|
||
function label(opt) {
|
||
if (!opt) { out.textContent = '—'; return; }
|
||
const gmin = opt.getAttribute('data-gmin');
|
||
const gmax = opt.getAttribute('data-gmax');
|
||
if ((gmin && gmin !== '') && (gmax && gmax !== '')) out.textContent = `G${gmin}–G${gmax}`;
|
||
else if (gmin && gmin !== '') out.textContent = `G${gmin}+`;
|
||
else if (gmax && gmax !== '') out.textContent = `≤G${gmax}`;
|
||
else out.textContent = '—';
|
||
}
|
||
sel?.addEventListener('change', () => label(sel.options[sel.selectedIndex]));
|
||
if (sel) label(sel.options[sel.selectedIndex]); // init on load
|
||
|
||
// Classes select all / clear
|
||
const selectAllBtn = document.getElementById('btnSelectAllClasses');
|
||
const clearBtn = document.getElementById('btnClearClasses');
|
||
const checkboxes = document.querySelectorAll('.class-checkbox');
|
||
|
||
selectAllBtn?.addEventListener('click', () => {
|
||
checkboxes.forEach(cb => cb.checked = true);
|
||
});
|
||
clearBtn?.addEventListener('click', () => {
|
||
checkboxes.forEach(cb => cb.checked = false);
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
<?= $this->endSection() ?>
|