226 lines
11 KiB
PHP
226 lines
11 KiB
PHP
<?= $this->extend('layout/management_layout') ?>
|
||
<?= $this->section('content') ?>
|
||
<div class="container-fluid">
|
||
<div class="wrapper">
|
||
<div class="content"></div>
|
||
|
||
<h2 class="text-center mt-4 mb-3">Class Preparation</h2>
|
||
|
||
<!-- School Year Selector + Calculate Button -->
|
||
<form method="get" action="<?= site_url('class-prep') ?>" class="mb-4 d-flex align-items-center gap-2 flex-wrap">
|
||
<label for="school_year" class="form-label mb-0">School Year:</label>
|
||
<select name="school_year" id="school_year" class="form-select form-select-sm w-auto">
|
||
<?php for ($y = date('Y'); $y >= 2020; $y--): ?>
|
||
<?php $sy = $y . '-' . ($y + 1); ?>
|
||
<option value="<?= $sy ?>" <?= $schoolYear === $sy ? 'selected' : '' ?>><?= $sy ?></option>
|
||
<?php endfor; ?>
|
||
</select>
|
||
<?php $semVal = (string)($semester ?? ($_GET['semester'] ?? '')); ?>
|
||
<label for="semester" class="form-label mb-0">Semester:</label>
|
||
<select name="semester" id="semester" class="form-select form-select-sm w-auto">
|
||
<option value="">—</option>
|
||
<option value="Fall" <?= (strcasecmp($semVal,'Fall')===0?'selected':'') ?>>Fall</option>
|
||
<option value="Spring" <?= (strcasecmp($semVal,'Spring')===0?'selected':'') ?>>Spring</option>
|
||
</select>
|
||
<button class="btn btn-sm btn-primary">Calculate Items</button>
|
||
</form>
|
||
|
||
<!-- Class Cards -->
|
||
<div class="row g-3">
|
||
<?php foreach ($prepResults as $prep): ?>
|
||
<?php $adjMap = $prep['adjustments'] ?? []; ?>
|
||
<div class="col-12 col-lg-6">
|
||
<div class="card shadow-sm border-0 h-100">
|
||
<div class="card-header d-flex justify-content-between align-items-center bg-light border-0">
|
||
<div>
|
||
<div class="fw-semibold mb-1">
|
||
<?= esc($prep['class_section']) ?>
|
||
</div>
|
||
<?php if (!empty($prep['needs_print'])): ?>
|
||
<span class="badge bg-danger">Updated since last print</span>
|
||
<?php else: ?>
|
||
<span class="badge bg-success">Up-to-date</span>
|
||
<?php endif; ?>
|
||
<?php if (!empty($prep['last_printed_at'])): ?>
|
||
<small class="text-muted ms-2">Last printed: <?= esc($prep['last_printed_at']) ?></small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="small text-muted text-end">
|
||
Students:<br>
|
||
<span class="badge bg-secondary"><?= (int)$prep['student_count'] ?></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-body">
|
||
<div class="row g-3">
|
||
<!-- Prep Items -->
|
||
<div class="col-12 col-md-7">
|
||
<div class="fw-semibold mb-2">Prep Items</div>
|
||
<ul class="list-group list-group-flush small border rounded overflow-hidden">
|
||
<?php foreach (($prep['prep_items'] ?? []) as $item => $qty): ?>
|
||
<li class="list-group-item d-flex justify-content-between align-items-center <?= (int)$qty === 0 ? 'text-muted-50' : '' ?>">
|
||
<span><?= esc($item) ?></span>
|
||
<span class="badge <?= (int)$qty > 0 ? 'bg-primary' : 'bg-secondary' ?> rounded-pill">
|
||
<?= (int)$qty ?>
|
||
</span>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- Adjustments -->
|
||
<div class="col-12 col-md-5">
|
||
<div class="fw-semibold mb-2">Adjustments (Tables)</div>
|
||
<form method="post" action="<?= site_url('class-prep/save-adjustment') ?>" class="d-grid gap-2">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="class_section_id" value="<?= esc($prep['class_section_id']) ?>">
|
||
<input type="hidden" name="school_year" value="<?= esc($schoolYear) ?>">
|
||
|
||
<?php foreach ($adjMap as $item => $value): ?>
|
||
<div>
|
||
<label class="form-label mb-1 small text-muted d-block"><?= esc($item) ?></label>
|
||
<div class="input-group input-group-sm">
|
||
<button type="button" class="btn btn-outline-secondary" onclick="adjustQty(this, -1)" aria-label="Decrease <?= esc($item) ?>">−</button>
|
||
<input type="number"
|
||
class="form-control text-center"
|
||
name="adjustments[<?= esc($item) ?>]"
|
||
value="<?= (int)$value ?>"
|
||
readonly>
|
||
<button type="button" class="btn btn-outline-secondary" onclick="adjustQty(this, 1)" aria-label="Increase <?= esc($item) ?>">+</button>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
|
||
<div class="d-flex justify-content-end">
|
||
<button type="submit" class="btn btn-sm btn-primary">Save</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-footer bg-transparent border-0 d-flex justify-content-end">
|
||
<?php
|
||
$printUrl = site_url('class-prep/print/' . urlencode($prep['class_section_id']) . '/' . $schoolYear);
|
||
if ($semVal !== '') {
|
||
$printUrl .= '?semester=' . urlencode($semVal);
|
||
}
|
||
?>
|
||
<a href="<?= $printUrl ?>"
|
||
class="btn btn-lg btn-print-class <?= !empty($prep['needs_print']) ? 'btn-danger' : 'btn-success' ?>" target="_blank" rel="noopener noreferrer"
|
||
onclick="window.open(this.href, '_blank'); return false;">
|
||
Print
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- Totals Section -->
|
||
<div class="mt-5">
|
||
<h5 class="mb-3">📦 Totals for All Used Items</h5>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-bordered align-middle no-mgmt-sticky">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th>Item</th>
|
||
<th class="text-end">Total Needed</th>
|
||
<th class="text-end">In Inventory</th>
|
||
<th class="text-end">Short By</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($totalNeeded as $item => $needed): ?>
|
||
<?php
|
||
$have = (int)($available[$item] ?? 0);
|
||
$short = max(0, (int)$needed - $have);
|
||
$rowCls = $short > 0 ? 'table-warning' : '';
|
||
?>
|
||
<tr class="<?= $rowCls ?>">
|
||
<td><?= esc($item) ?></td>
|
||
<td class="text-end"><?= (int)$needed ?></td>
|
||
<td class="text-end"><?= $have ?></td>
|
||
<td class="text-end <?= $short > 0 ? 'text-danger fw-bold' : 'text-success' ?>">
|
||
<?= $short ?>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Shortage Warning -->
|
||
<?php if (!empty($shortages)): ?>
|
||
<div class="alert alert-danger mt-3">
|
||
<strong>Shortages Detected</strong>
|
||
<ul class="mb-0">
|
||
<?php foreach ($shortages as $item => $short): ?>
|
||
<li><?= esc($item) ?>: short by <?= (int)$short ?> pcs</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="alert alert-success mt-3">✅ All items are available in stock.</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?= $this->endSection() ?>
|
||
|
||
<?= $this->section('scripts') ?>
|
||
<style>
|
||
.text-muted-50 {
|
||
opacity: .55;
|
||
}
|
||
|
||
.card {
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.card-header {
|
||
border-top-left-radius: 12px;
|
||
border-top-right-radius: 12px;
|
||
}
|
||
|
||
.card-footer {
|
||
border-bottom-left-radius: 12px;
|
||
border-bottom-right-radius: 12px;
|
||
}
|
||
|
||
.list-group-item {
|
||
padding-top: .5rem;
|
||
padding-bottom: .5rem;
|
||
}
|
||
|
||
@media (max-width: 575.98px) {
|
||
.card .input-group {
|
||
max-width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<script>
|
||
function adjustQty(btn, delta) {
|
||
const input = btn.parentElement.querySelector('input[type="number"]');
|
||
const curr = parseInt(input.value, 10) || 0;
|
||
input.value = curr + delta; // clamp if you want: input.value = Math.max(0, curr + delta);
|
||
}
|
||
|
||
// Force print links to open in a new tab even if other handlers intercept
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('.btn-print-class').forEach(function(el) {
|
||
el.addEventListener('click', function(ev) {
|
||
ev.preventDefault();
|
||
try {
|
||
window.open(this.href, '_blank', 'noopener');
|
||
} catch (e) {
|
||
this.setAttribute('target', '_blank');
|
||
window.location.assign(this.href);
|
||
}
|
||
}, { capture: true });
|
||
});
|
||
});
|
||
</script>
|
||
<?= $this->endSection() ?>
|