recreate project

This commit is contained in:
root
2026-02-10 22:11:06 -05:00
commit 663c0cdbda
10149 changed files with 1379710 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
<?= $this->extend('layout/management_layout') ?>
<?= $this->section('content') ?>
<div class="container my-4">
<h2 class="mb-3">Family Communications</h2>
<?= view('partials/flash_messages') ?>
<?php
$prefillStudentId = isset($_GET['student_id']) ? (int)$_GET['student_id'] : 0;
$prefillTemplate = isset($_GET['template_key']) ? trim((string)$_GET['template_key']) : '';
?>
<div class="card">
<div class="card-header">Compose</div>
<div class="card-body">
<form id="comm-form" method="post" action="<?= site_url('communications/send') ?>">
<?= csrf_field() ?>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Student</label>
<select class="form-select" id="student_id" name="student_id" required>
<option value="">Select…</option>
<?php foreach ($students as $st): ?>
<?php $sid = (int)($st['id'] ?? 0); ?>
<option value="<?= esc($sid) ?>" <?= ($prefillStudentId === $sid ? 'selected' : '') ?>>
<?= esc(($st['lastname'] ?? '').', '.($st['firstname'] ?? '')) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Family (if multiple)</label>
<select class="form-select" id="family_id" name="family_id" required>
<option value="">Select a student first…</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Subject Category</label>
<select class="form-select" id="template_key" name="template_key" required>
<option value="">Select…</option>
<?php foreach ($templates as $t): ?>
<?php
$tkey = (string)($t['template_key'] ?? '');
$tname = (string)($t['name'] ?? '');
$label = $tname !== '' ? $tname : $tkey;
?>
<option value="<?= esc($tkey) ?>" <?= ($prefillTemplate !== '' && $prefillTemplate === $tkey ? 'selected' : '') ?>>
<?= esc($label) ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="mt-3">
<label class="form-label">Recipients (Guardians)</label>
<div id="recipientPills" class="d-flex flex-wrap gap-2"></div>
</div>
<hr/>
<div class="row g-3">
<div class="col-md-8">
<label class="form-label">Email Subject</label>
<input type="text" class="form-control" id="subject" name="subject" required>
</div>
<div class="col-md-4 d-flex align-items-end">
<button type="button" id="btnPreview" class="btn btn-outline-secondary ms-auto">Refresh Preview</button>
</div>
<div class="col-12">
<label class="form-label">Email Body (editable)</label>
<textarea class="form-control" id="body" name="body" rows="10" required></textarea>
</div>
</div>
<input type="hidden" name="recipients" id="recipients_json">
<input type="hidden" name="cc" id="cc_json">
<input type="hidden" name="bcc" id="bcc_json">
<div class="mt-3 d-flex gap-2">
<button type="submit" class="btn btn-primary">Send</button>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#previewModal">Preview</button>
</div>
</form>
</div>
</div>
</div>
<!-- Preview Modal -->
<div class="modal fade" id="previewModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Email Preview</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<h6 id="pvSubject" class="mb-3"></h6>
<div id="pvBody"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
(function(){
const $student = document.getElementById('student_id');
const $family = document.getElementById('family_id');
const $template = document.getElementById('template_key');
const $recipientPills = document.getElementById('recipientPills');
const $subject = document.getElementById('subject');
const $body = document.getElementById('body');
const $recipientsJson = document.getElementById('recipients_json');
let recipients = [];
function renderRecipients(){
$recipientPills.innerHTML = '';
recipients.forEach((em, idx) => {
const span = document.createElement('span');
span.className = 'badge bg-light text-dark border';
span.innerHTML = em + ' <button data-i="'+idx+'" type="button" class="btn btn-sm btn-link p-0 ms-1">×</button>';
$recipientPills.appendChild(span);
});
$recipientsJson.value = JSON.stringify(recipients);
}
$recipientPills.addEventListener('click', (e)=>{
if (e.target.tagName === 'BUTTON') {
recipients.splice(parseInt(e.target.getAttribute('data-i')),1);
renderRecipients();
}
});
async function loadFamilies(studentId){
$family.innerHTML = '<option value="">Loading…</option>';
recipients = []; renderRecipients();
if(!studentId){ $family.innerHTML = '<option value="">Select a student first…</option>'; return; }
const res = await fetch('<?= site_url('api/students') ?>/'+studentId+'/families');
const data = await res.json();
const list = data.data || [];
if (!list.length){ $family.innerHTML = '<option value="">No families found</option>'; return; }
let html = '';
list.forEach(f => {
const name = f.household_name || ('Family #' + f.id);
html += `<option value="${f.id}">${name}${f.is_primary_home ? ' (primary)' : ''}</option>`;
});
$family.innerHTML = '<option value="">Select…</option>' + html;
// Auto-select the first (primary) family
$family.selectedIndex = 1;
loadGuardians($family.value);
}
async function loadGuardians(familyId){
recipients = []; renderRecipients();
if(!familyId) return;
const res = await fetch('<?= site_url('api/families') ?>/'+familyId+'/guardians');
const data = await res.json();
(data.data || []).forEach(g => { if (g.receive_emails && g.email) recipients.push(g.email); });
recipients = Array.from(new Set(recipients));
renderRecipients();
}
async function refreshPreview(){
const student_id = $student.value;
const family_id = $family.value;
const template_key = $template.value;
if (!student_id || !family_id || !template_key) return;
const vars = {
school_name: 'Al Rahma Sunday School',
teacher_name: '<?= esc(session('display_name') ?? 'Teacher') ?>',
class_section: '',
student_grade: '',
attendance_message: '',
assessment_name: '',
score_obtained: '',
score_total: '',
teacher_comments: '',
behavior_summary: '',
actions_taken: '',
next_steps: ''
};
const form = new FormData();
form.append('<?= csrf_token() ?>', '<?= csrf_hash() ?>');
form.append('student_id', student_id);
form.append('family_id', family_id);
form.append('template_key', template_key);
form.append('vars', JSON.stringify(vars));
const res = await fetch('<?= site_url('communications/preview') ?>', { method: 'POST', body: form });
const data = await res.json();
if (data.subject) $subject.value = data.subject;
if (data.html) $body.value = data.html.replace(/<br\s*\/?>/g, "\n");
document.getElementById('pvSubject').textContent = $subject.value;
document.getElementById('pvBody').innerHTML = data.html || '';
}
document.getElementById('btnPreview').addEventListener('click', refreshPreview);
$student.addEventListener('change', e => loadFamilies(e.target.value));
$family.addEventListener('change', e => loadGuardians(e.target.value));
$template.addEventListener('change', refreshPreview);
// Init
if ($student.value) loadFamilies($student.value);
})();
</script>
<?= $this->endSection() ?>