recreate project
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
<?= $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() ?>
|
||||
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Class Prep Sheet</title>
|
||||
<link rel="icon" href="<?= base_url('assets/images/favicon.ico') ?>">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 5cm;
|
||||
}
|
||||
|
||||
.prep-label {
|
||||
border: 2px solid #000;
|
||||
padding: 2rem;
|
||||
width: 400px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.prep-label h2 {
|
||||
font-size: 5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.prep-label ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.prep-label {
|
||||
border: none;
|
||||
page-break-after: always;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="window.print()">
|
||||
|
||||
<?php
|
||||
// prefer friendly name if provided by controller
|
||||
$sectionTitle = isset($classSection) && $classSection ? $classSection : ($classSectionId ?? 'Class');
|
||||
|
||||
// make sure we have an array
|
||||
$prepItems = is_array($prepItems ?? null) ? $prepItems : [];
|
||||
|
||||
// optional: if you want a specific order, define it here.
|
||||
// otherwise we’ll just print in the array’s order.
|
||||
$preferredOrder = [
|
||||
'Grade Box',
|
||||
'Large Table',
|
||||
'Regular Chair',
|
||||
'Small Chair',
|
||||
'Small Table',
|
||||
'Teacher Chair',
|
||||
'Trash Bin',
|
||||
'White Board',
|
||||
];
|
||||
|
||||
// reorder $prepItems by $preferredOrder when present
|
||||
$ordered = [];
|
||||
foreach ($preferredOrder as $k) {
|
||||
if (array_key_exists($k, $prepItems)) {
|
||||
$ordered[$k] = $prepItems[$k];
|
||||
}
|
||||
}
|
||||
// include any remaining keys (if any)
|
||||
foreach ($prepItems as $k => $v) {
|
||||
if (!array_key_exists($k, $ordered)) {
|
||||
$ordered[$k] = $v;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="prep-label">
|
||||
<h2>Grade <?= esc($sectionTitle) ?></h2>
|
||||
<ul>
|
||||
<?php
|
||||
$printed = 0;
|
||||
foreach ($ordered as $name => $qty):
|
||||
$qty = (int)$qty;
|
||||
if ($qty > 0):
|
||||
$printed++;
|
||||
?>
|
||||
<li><strong><?= $qty ?></strong> <?= esc($name) ?></li>
|
||||
<?php
|
||||
endif;
|
||||
endforeach;
|
||||
|
||||
if ($printed === 0): ?>
|
||||
<li>No items needed</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user