recreate project
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h1>Apply Discount Voucher</h1>
|
||||
<?= $this->include('partials/academic_filter') ?>
|
||||
|
||||
<form method="post" action="">
|
||||
<?= csrf_field() ?>
|
||||
<div class="d-flex gap-2 mb-3 justify-content-end">
|
||||
<div>
|
||||
<button type="submit" class="btn btn-success">Apply Voucher</button>
|
||||
<button type="button" class="btn btn-info" onclick="window.location.href='/discounts/list'">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="voucher_id" class="form-label">Select Voucher Code</label>
|
||||
<select name="voucher_id" id="voucher_id" class="form-select" required>
|
||||
<option value="">-- Select Voucher --</option>
|
||||
<?php foreach ($vouchers as $voucher): ?>
|
||||
<option value="<?= esc($voucher['id']) ?>">
|
||||
<?= esc($voucher['code']) ?> (<?= esc(ucfirst($voucher['discount_type'])) ?> - <?= esc($voucher['discount_value']) ?><?= $voucher['discount_type'] === 'percent' ? '%' : '$' ?>)
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-3">
|
||||
<input class="form-check-input" type="checkbox" id="allowAdditional" name="allow_additional" value="1" checked>
|
||||
<label class="form-check-label" for="allowAdditional">
|
||||
Allow additional discounts for parents who already have discounts
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Parents</label>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered" id="parentsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="checkAll"></th>
|
||||
<th>Parent ID</th>
|
||||
<th>Parent Name</th>
|
||||
<th>Email</th>
|
||||
<th>Has Discount?</th> <!-- NEW -->
|
||||
<th>Total Discount Amount</th> <!-- NEW -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($parents as $parent): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="parent_ids[]"
|
||||
value="<?= esc($parent['id']) ?>"
|
||||
class="parent-check"
|
||||
data-has-discount="<?= $parent['has_discount'] ? '1' : '0' ?>"
|
||||
<?= $parent['has_discount'] ? 'disabled' : '' ?>>
|
||||
</td>
|
||||
|
||||
<td><?= esc($parent['school_id'] ?? 'N/A') ?></td>
|
||||
<td><?= esc($parent['firstname'] . ' ' . $parent['lastname']) ?></td>
|
||||
<td><?= esc($parent['email']) ?></td>
|
||||
<td>
|
||||
<?= isset($parent['has_discount']) && $parent['has_discount'] ? 'Yes' : 'No' ?>
|
||||
</td>
|
||||
<td>
|
||||
$<?= number_format($parent['total_discount'] ?? 0, 2) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('scripts') ?>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const table = $('#parentsTable').DataTable();
|
||||
|
||||
function syncDiscountLocks() {
|
||||
const allowAdditional = $('#allowAdditional').is(':checked');
|
||||
$('.parent-check').each(function() {
|
||||
const hasDiscount = $(this).data('has-discount') === 1 || $(this).data('has-discount') === '1';
|
||||
if (hasDiscount) {
|
||||
if (allowAdditional) {
|
||||
$(this).prop('disabled', false);
|
||||
} else {
|
||||
$(this).prop('checked', false).prop('disabled', true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#allowAdditional').on('change', syncDiscountLocks);
|
||||
$('#allowAdditional').prop('checked', true);
|
||||
syncDiscountLocks();
|
||||
|
||||
table.on('draw', function() {
|
||||
syncDiscountLocks();
|
||||
});
|
||||
|
||||
$('#checkAll').click(function() {
|
||||
$('.parent-check:enabled').prop('checked', this.checked);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h1>Create Discount Voucher</h1>
|
||||
|
||||
<?php if (session()->getFlashdata('error')): ?>
|
||||
<div class="alert alert-danger"><?= session()->getFlashdata('error') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (session()->getFlashdata('success')): ?>
|
||||
<div class="alert alert-success"><?= session()->getFlashdata('success') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="code" class="form-label">Voucher Code</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="code" id="code" class="form-control"
|
||||
value="<?= esc($voucher['code'] ?? '') ?>"
|
||||
placeholder="Enter or generate a code (e.g. WELCOME10)" required>
|
||||
<button type="button" class="btn btn-outline-secondary" id="generateCodeBtn">Auto Generate</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NEW: Description / Reason -->
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description / Reason</label>
|
||||
<textarea name="description" id="description" class="form-control" rows="3"
|
||||
placeholder="Reason for this voucher."><?= esc($voucher['description'] ?? '') ?></textarea>
|
||||
<div class="form-text">Visible to admins only; not shown to parents.</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="discount_type" class="form-label">Discount Type</label>
|
||||
<select name="discount_type" id="discount_type" class="form-select" required>
|
||||
<option value="percent" <?= (isset($voucher) && $voucher['discount_type'] == 'percent') ? 'selected' : '' ?>>Percentage (%)</option>
|
||||
<option value="fixed" <?= (isset($voucher) && $voucher['discount_type'] == 'fixed') ? 'selected' : '' ?>>Fixed Amount ($)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="discount_value" class="form-label">Discount Value</label>
|
||||
<input type="number" name="discount_value" id="discount_value" class="form-control"
|
||||
step="0.01" min="0"
|
||||
value="<?= esc($voucher['discount_value'] ?? '') ?>"
|
||||
placeholder="Enter discount value (e.g. 10 for 10% or 50 for $50)" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="max_uses" class="form-label">Maximum Uses</label>
|
||||
<input type="number" name="max_uses" id="max_uses" class="form-control"
|
||||
value="<?= esc($voucher['max_uses'] ?? '') ?>"
|
||||
placeholder="Leave empty for unlimited">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="valid_from" class="form-label">Valid From</label>
|
||||
<input type="date" name="valid_from" id="valid_from" class="form-control"
|
||||
value="<?= esc($voucher['valid_from'] ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="valid_until" class="form-label">Valid Until</label>
|
||||
<input type="date" name="valid_until" id="valid_until" class="form-control"
|
||||
value="<?= esc($voucher['valid_until'] ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" name="is_active" id="is_active" class="form-check-input"
|
||||
<?= (isset($voucher) ? ($voucher['is_active'] ? 'checked' : '') : 'checked') ?>>
|
||||
<label for="is_active" class="form-check-label">Active</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-success">Save Voucher</button>
|
||||
<button type="button" class="btn btn-info" onclick="window.location.href='/discounts/list'">Cancel</button>
|
||||
</form>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('scripts') ?>
|
||||
<script>
|
||||
document.getElementById('generateCodeBtn').addEventListener('click', function() {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
let code = '';
|
||||
for (let i = 0; i < 10; i++) code += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
document.getElementById('code').value = code;
|
||||
|
||||
// Remove any existing auto-generated prefix from Description (if present)
|
||||
const desc = document.getElementById('description');
|
||||
if (desc) {
|
||||
desc.value = desc.value.replace(/^Auto-generated on \d{4}-\d{2}-\d{2}\s*[—-]\s*reason:\s*/i, '');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<h2 class="text-center mt-4 mb-3">Discounts</h2>
|
||||
<?= $this->include('partials/academic_filter') ?>
|
||||
<div class="d-flex gap-2 mb-3 justify-content-end">
|
||||
<div>
|
||||
<a href="/discount/create" class="btn btn-primary">Create New Voucher</a>
|
||||
<a href="/discount/apply" class="btn btn-success">Apply Voucher to Parents</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table id="discountsTable" class="table table-striped w-100" style="table-layout:auto;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Code</th>
|
||||
<th>Type</th>
|
||||
<th>Value</th>
|
||||
<th>Max Uses</th>
|
||||
<th>Times Used</th>
|
||||
<th>Validity</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$formatValidityDate = function ($value) {
|
||||
$value = (string)($value ?? '');
|
||||
if ($value === '') {
|
||||
return 'N/A';
|
||||
}
|
||||
if (preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})$/', $value, $m)) {
|
||||
return $m[2] . '-' . $m[3] . '-' . $m[1];
|
||||
}
|
||||
try {
|
||||
return local_date($value, 'm-d-Y');
|
||||
} catch (Throwable $e) {
|
||||
return $value;
|
||||
}
|
||||
};
|
||||
?>
|
||||
<?php foreach ($vouchers as $v): ?>
|
||||
<tr>
|
||||
<td><?= esc($v['code']) ?></td>
|
||||
<td><?= esc(ucfirst($v['discount_type'])) ?></td>
|
||||
<td>
|
||||
<?= esc($v['discount_type'] === 'percent' ? $v['discount_value'] . '%' : '$' . number_format($v['discount_value'], 2)) ?>
|
||||
</td>
|
||||
<td><?= esc($v['max_uses'] ?? '∞') ?></td>
|
||||
<td><?= esc($v['times_used']) ?></td>
|
||||
<td>
|
||||
<?= esc($formatValidityDate($v['valid_from'] ?? '')) ?> → <?= esc($formatValidityDate($v['valid_until'] ?? '')) ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge <?= $v['is_active'] ? 'bg-success' : 'bg-secondary' ?>">
|
||||
<?= $v['is_active'] ? 'Active' : 'Inactive' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/discount/editVoucher/<?= $v['id'] ?>" class="btn btn-sm btn-warning">Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('scripts') ?>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#discountsTable').DataTable({
|
||||
pageLength: 100,
|
||||
order: [
|
||||
[0, 'asc']
|
||||
],
|
||||
autoWidth: false,
|
||||
responsive: true,
|
||||
columns: [
|
||||
null, null, null, null, null, {
|
||||
width: '20%'
|
||||
},
|
||||
null, {
|
||||
orderable: false,
|
||||
width: '120px'
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
Reference in New Issue
Block a user