recreate project
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
<style>
|
||||
/* Make the Parents multi-select significantly taller */
|
||||
#parentPicker .form-select[multiple] {
|
||||
height: clamp(420px, 65vh, 820px);
|
||||
/* min 420px, prefer 65% of viewport height, cap 820px */
|
||||
min-height: 420px;
|
||||
}
|
||||
|
||||
/* Slightly smaller option text helps fit more names on screen */
|
||||
#parentPicker .form-select[multiple] option {
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container my-4">
|
||||
<h2 class="mb-3">WhatsApp Group Links</h2>
|
||||
<?= view('partials/flash_messages') ?>
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
|
||||
<a href="<?= site_url('whatsapp/parent-contacts-by-class') ?>" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="bi bi-people"></i> Parent Contacts by Class
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<!-- Left: Link per Class -->
|
||||
<div class="col-lg-7">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Set / Update Links (<?= esc($schoolYear) ?><?= trim((string)$semester) !== '' ? ' - ' . esc($semester) : '' ?>)
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if (!empty($sections)): ?>
|
||||
<?php foreach ($sections as $sec):
|
||||
$sid = (int)($sec['class_section_id'] ?? $sec['id']);
|
||||
$sname = $sec['class_section_name'] ?? ($sec['name'] ?? ('Section ' . $sid));
|
||||
$existing = $linksBySection[$sid] ?? null;
|
||||
?>
|
||||
<form class="row gy-2 align-items-end border-bottom pb-3 mb-3"
|
||||
method="post"
|
||||
action="<?= site_url('whatsapp/saveLink') ?>">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="class_section_id" value="<?= esc($sid) ?>">
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Class / Section</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="class_section_name"
|
||||
value="<?= esc($sname) ?>"
|
||||
readonly>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Invite Link</label>
|
||||
<input type="url"
|
||||
class="form-control"
|
||||
name="invite_link"
|
||||
placeholder="https://chat.whatsapp.com/..."
|
||||
value="<?= esc($existing['invite_link'] ?? '') ?>"
|
||||
required>
|
||||
<?php if (!empty($existing['invite_link'])): ?>
|
||||
<small class="text-success d-block mt-1">Link set.</small>
|
||||
<?php else: ?>
|
||||
<small class="text-muted d-block mt-1">No link set yet.</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
name="active"
|
||||
id="active<?= $sid ?>"
|
||||
<?= !empty($existing) && (int)$existing['active'] === 1 ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="active<?= $sid ?>">Active</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 text-end">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<p class="text-muted">No sections found for this term.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: Send Invites -->
|
||||
<div class="col-lg-5">
|
||||
<div class="card">
|
||||
<div class="card-header">Send Invites</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="<?= site_url('whatsapp/sendInvites') ?>" id="sendInvitesForm">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Mode</label>
|
||||
|
||||
<select class="form-select" name="mode" id="modeSelect" required>
|
||||
<option value="all">All parents</option>
|
||||
<option value="class">Parents in a class</option>
|
||||
<option value="parents">Specific parent(s)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 d-none" id="classPicker">
|
||||
<label class="form-label">Class / Section</label>
|
||||
<select id="class_section_id_select"
|
||||
name="class_section_id"
|
||||
class="form-select">
|
||||
<option value="">-- Select Class / Section --</option>
|
||||
<?php foreach ($sections as $s): ?>
|
||||
<option value="<?= (int)$s['class_section_id'] ?>">
|
||||
<?= esc($s['class_section_name']) ?>
|
||||
<?php if (!empty($linksBySection[(int)$s['class_section_id']]['invite_link'])): ?>
|
||||
(has link)
|
||||
<?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 d-none" id="parentPicker">
|
||||
<label class="form-label">Parents</label>
|
||||
<select class="form-select" name="parent_ids[]" multiple size="25">
|
||||
<?php if (!empty($parents)): ?>
|
||||
<?php foreach ($parents as $p):
|
||||
$label = ($p['lastname'] ?? '') . ', ' . ($p['firstname'] ?? '');
|
||||
if (!empty($p['email'])) $label .= ' — ' . $p['email'];
|
||||
$label .= ($p['source'] ?? '') === 'parents' ? ' (Second Parent)' : ' (Primary)';
|
||||
?>
|
||||
<option value="<?= (int)$p['id'] ?>"><?= esc($label) ?></option>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<option disabled>No parents available</option>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<small class="text-muted">Hold Ctrl/Cmd to select multiple.</small>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-end">
|
||||
<button class="btn btn-success">Send Emails</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('scripts') ?>
|
||||
<script>
|
||||
(function() {
|
||||
const form = document.getElementById('sendInvitesForm');
|
||||
const mode = document.getElementById('modeSelect');
|
||||
const classPicker = document.getElementById('classPicker');
|
||||
const classSelect = document.getElementById('class_section_id_select');
|
||||
const parentPicker = document.getElementById('parentPicker');
|
||||
const parentSelect = parentPicker ? parentPicker.querySelector('select[name="parent_ids[]"]') : null;
|
||||
|
||||
function clearParentsSelection() {
|
||||
if (!parentSelect) return;
|
||||
for (const opt of parentSelect.options) opt.selected = false;
|
||||
}
|
||||
|
||||
function setRequired(el, on) {
|
||||
if (!el) return;
|
||||
if (on) el.setAttribute('required', 'required');
|
||||
else el.removeAttribute('required');
|
||||
}
|
||||
|
||||
function sync() {
|
||||
const v = mode.value;
|
||||
|
||||
// Hide both pickers by default
|
||||
classPicker.classList.add('d-none');
|
||||
parentPicker.classList.add('d-none');
|
||||
|
||||
// Not required by default
|
||||
setRequired(classSelect, false);
|
||||
setRequired(parentSelect, false);
|
||||
|
||||
if (v === 'class') {
|
||||
classPicker.classList.remove('d-none');
|
||||
setRequired(classSelect, true);
|
||||
// Default to first non-placeholder option if none chosen
|
||||
if (!classSelect.value && classSelect.options.length > 1) {
|
||||
classSelect.selectedIndex = 1;
|
||||
}
|
||||
if (parentSelect) clearParentsSelection();
|
||||
|
||||
} else if (v === 'parents') {
|
||||
parentPicker.classList.remove('d-none');
|
||||
setRequired(parentSelect, true);
|
||||
if (classSelect) classSelect.value = '';
|
||||
|
||||
} else { // 'all'
|
||||
if (classSelect) classSelect.value = '';
|
||||
if (parentSelect) clearParentsSelection();
|
||||
}
|
||||
}
|
||||
|
||||
mode.addEventListener('change', sync);
|
||||
document.addEventListener('DOMContentLoaded', sync);
|
||||
})();
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
Reference in New Issue
Block a user