recreate project
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
<style>
|
||||
#adminProgressTable thead th {
|
||||
position: static !important;
|
||||
}
|
||||
</style>
|
||||
<div class="container py-4">
|
||||
<div class="mb-4 pb-3 border-bottom">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h3 class="mb-0">Class Progress Reports</h3>
|
||||
<div class="text-muted">Filter by week, class, and status</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="card shadow-sm mb-3" method="get" action="<?= base_url('admin/progress') ?>">
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">From</label>
|
||||
<input type="date" name="from" class="form-control" value="<?= esc($filters['from'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">To</label>
|
||||
<input type="date" name="to" class="form-control" value="<?= esc($filters['to'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Class/Section</label>
|
||||
<select name="class_section_id" class="form-select">
|
||||
<option value="">All</option>
|
||||
<?php foreach ($classSections as $cs): ?>
|
||||
<option value="<?= esc($cs['class_section_id']) ?>" <?= (isset($filters['class_section_id']) && $filters['class_section_id'] === (string) $cs['class_section_id']) ? 'selected' : '' ?>>
|
||||
<?= esc($cs['class_section_name']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Status</label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">All</option>
|
||||
<?php foreach ($statusOptions as $value => $label): ?>
|
||||
<option value="<?= esc($value) ?>" <?= (isset($filters['status']) && $filters['status'] === $value) ? 'selected' : '' ?>><?= esc($label) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-3">
|
||||
<button class="btn btn-primary" type="submit">Apply</button>
|
||||
<a class="btn btn-outline-secondary" href="<?= base_url('admin/progress') ?>">Reset</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="card shadow-sm mt-5">
|
||||
<div class="card-body pt-4 px-0">
|
||||
<div class="table-responsive px-4" style="margin-top: 1.5rem;">
|
||||
<table id="adminProgressTable" class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Week</th>
|
||||
<th>Subjects</th>
|
||||
<th>Teacher</th>
|
||||
<th class="text-end">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$reportGroups = $reportGroups ?? [];
|
||||
$subjectSections = $subjectSections ?? [];
|
||||
?>
|
||||
<?php if (empty($reportGroups)): ?>
|
||||
<tr><td colspan="4" class="text-center text-muted py-4">No reports found.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($reportGroups as $group): ?>
|
||||
<?php
|
||||
$weekLabel = $group['week_start'] ? date('M d, Y', strtotime($group['week_start'])) : '-';
|
||||
if (!empty($group['week_end'])) {
|
||||
$weekLabel .= ' – ' . date('M d, Y', strtotime($group['week_end']));
|
||||
}
|
||||
$reports = $group['reports'] ?? [];
|
||||
$teacherName = '';
|
||||
foreach ($reports as $report) {
|
||||
if (!empty($report['teacher_name'])) {
|
||||
$teacherName = $report['teacher_name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$exampleId = $reports ? reset($reports)['id'] : null;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold"><?= esc($weekLabel) ?></div>
|
||||
<?php if (!empty($group['class_section_name'])): ?>
|
||||
<div class="text-muted small">Class: <?= esc($group['class_section_name']) ?></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<?php foreach ($subjectSections as $slug => $section): ?>
|
||||
<?php
|
||||
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
|
||||
$report = $reports[$subjectName] ?? null;
|
||||
$statusTag = $report ? ($report['status_label'] ?? 'Unknown') : 'No entry';
|
||||
$badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted';
|
||||
?>
|
||||
<div class="border rounded-3 p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
|
||||
<span class="badge <?= $badgeClass ?>"><?= esc($statusTag) ?></span>
|
||||
</div>
|
||||
<div class="small text-muted"><?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td><?= esc($teacherName ?: '-') ?></td>
|
||||
<td class="text-end">
|
||||
<?php if ($exampleId): ?>
|
||||
<a class="btn btn-sm btn-outline-primary" href="<?= base_url('admin/progress/view/' . $exampleId) ?>">View</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,139 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
<div class="container py-4">
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<div>
|
||||
<h3 class="mb-0">Progress Report</h3>
|
||||
<div class="text-muted">
|
||||
<?= esc($row['class_section_name'] ?? '-') ?> • <?= esc($row['week_start']) ?> → <?= esc($row['week_end']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<a href="<?= base_url('admin/progress') ?>" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$flagLabels = [
|
||||
'homework_assigned' => 'Homework assigned',
|
||||
'quiz_done' => 'Quiz / check-in completed',
|
||||
'materials_missing' => 'Materials needed',
|
||||
];
|
||||
$weeklyReports = $weeklyReports ?? [];
|
||||
$subjectSections = $subjectSections ?? [];
|
||||
$reportsBySubject = [];
|
||||
$attachments = [];
|
||||
foreach ($weeklyReports as $report) {
|
||||
$reportsBySubject[$report['subject']] = $report;
|
||||
foreach (($report['attachments'] ?? []) as $attachment) {
|
||||
$attachments[] = [
|
||||
'subject' => $report['subject'] ?? 'Attachment',
|
||||
'attachment' => $attachment,
|
||||
'report_id' => $report['id'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-8">
|
||||
<?php foreach ($subjectSections as $slug => $section): ?>
|
||||
<?php
|
||||
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
|
||||
$isQuran = $subjectName === 'Quran/Arabic';
|
||||
$unitLabel = $isQuran ? 'Surah / Custom Arabic' : 'Unit / Chapter';
|
||||
$homeworkLabel = $isQuran ? 'Arabic Practice / Homework' : 'Assigned Homework';
|
||||
$report = $reportsBySubject[$subjectName] ?? null;
|
||||
?>
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header bg-white d-flex align-items-center justify-content-between">
|
||||
<strong class="mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if (! $report): ?>
|
||||
<div class="text-muted">No entry submitted for this subject this week.</div>
|
||||
<?php else: ?>
|
||||
<div class="mb-2"><strong><?= $unitLabel ?>:</strong> <?= esc($report['unit_title'] ?: '-') ?></div>
|
||||
<?php if (!empty($report['materials'])): ?>
|
||||
<div class="mb-2"><strong>Materials:</strong> <?= esc($report['materials']) ?></div>
|
||||
<?php endif; ?>
|
||||
<div class="mb-3">
|
||||
<strong>Activities</strong>
|
||||
<div class="mt-1"><?= nl2br(esc($report['covered'] ?? '-')) ?></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<strong><?= $homeworkLabel ?>:</strong>
|
||||
<div class="mt-1"><?= nl2br(esc($report['homework'] ?: '-')) ?></div>
|
||||
</div>
|
||||
<?php if (!empty($report['attachments'])): ?>
|
||||
<div class="mt-3">
|
||||
<strong>Attachments:</strong>
|
||||
<div class="d-flex flex-column gap-2 mt-2">
|
||||
<?php foreach ($report['attachments'] as $attachment): ?>
|
||||
<?php
|
||||
$linkId = $attachment['id'] ?? $report['id'];
|
||||
$link = !empty($attachment['legacy'])
|
||||
? base_url('admin/progress/attachment/' . $linkId)
|
||||
: base_url('admin/progress/attachment-file/' . $linkId);
|
||||
?>
|
||||
<a class="btn btn-sm btn-outline-secondary text-start" href="<?= $link ?>" target="_blank" rel="noreferrer">
|
||||
<?= esc($attachment['name'] ?? 'Attachment') ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header bg-white"><strong>Summary</strong></div>
|
||||
<div class="card-body">
|
||||
<div class="mb-2"><strong>Teacher:</strong> <?= esc(trim($row['teacher_name'] ?? '')) ?: '-' ?></div>
|
||||
<div class="mb-2"><strong>Submitted:</strong> <?= esc($row['created_at'] ? date('M d, Y g:i A', strtotime($row['created_at'])) : '-') ?></div>
|
||||
<div><strong>Status:</strong> <?= esc($row['status_label'] ?? 'Unknown') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($row['flags'])): ?>
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header bg-white"><strong>Checklist</strong></div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($row['flags'] as $flag): ?>
|
||||
<span class="badge bg-light text-dark border"><?= esc($flagLabels[$flag] ?? str_replace('_', ' ', $flag)) ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($attachments)): ?>
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white"><strong>Attachments</strong></div>
|
||||
<div class="card-body">
|
||||
<?php foreach ($attachments as $entry): ?>
|
||||
<?php
|
||||
$attachment = $entry['attachment'] ?? [];
|
||||
$linkId = $attachment['id'] ?? ($entry['report_id'] ?? null);
|
||||
if (!$linkId) {
|
||||
continue;
|
||||
}
|
||||
$link = !empty($attachment['legacy'])
|
||||
? base_url('admin/progress/attachment/' . $linkId)
|
||||
: base_url('admin/progress/attachment-file/' . $linkId);
|
||||
$label = trim(($entry['subject'] ?? 'Attachment') . ' • ' . ($attachment['name'] ?? 'Attachment'));
|
||||
?>
|
||||
<a class="btn btn-outline-primary w-100 text-start mb-2" href="<?= $link ?>" target="_blank" rel="noreferrer">
|
||||
<?= esc($label) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,157 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<?php $isEdit = ($mode ?? 'create') === 'edit'; ?>
|
||||
<?php $isLocked = $isEdit && !empty($competition['is_locked']); ?>
|
||||
<?php $lockedAttr = $isLocked ? 'disabled' : ''; ?>
|
||||
<h3><?= esc($isEdit ? 'Edit Competition' : 'Create Competition') ?></h3>
|
||||
|
||||
<?php if ($isLocked): ?>
|
||||
<div class="alert alert-warning">This competition is locked. Unlock it to make changes.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
<?php foreach ($errors as $e): ?><li><?= esc($e) ?></li><?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="<?= $isEdit ? '/admin/competition-winners/' . $competition['id'] . '/update' : '/admin/competition-winners/store' ?>" class="row g-3">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">Title *</label>
|
||||
<input class="form-control" name="title" value="<?= esc(old('title', $competition['title'] ?? '')) ?>" required <?= $lockedAttr ?>>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Class Section (optional)</label>
|
||||
<?php $oldSection = (string) old('class_section_id', (string) ($competition['class_section_id'] ?? '')); ?>
|
||||
<select class="form-select" name="class_section_id" <?= $lockedAttr ?>>
|
||||
<option value="">All classes</option>
|
||||
<?php foreach ($classSections as $section): ?>
|
||||
<?php
|
||||
$value = (string) ($section['class_section_id'] ?? '');
|
||||
$label = $section['class_section_name'] ?? $value;
|
||||
$selected = $value !== '' && $value === $oldSection ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($value) ?>" <?= $selected ?>><?= esc($label) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="form-text">Leave empty to manage winners for all classes.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Semester</label>
|
||||
<input class="form-control" name="semester" value="<?= esc(old('semester', $competition['semester'] ?? $defaultSemester ?? '')) ?>" <?= $lockedAttr ?>>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">School Year</label>
|
||||
<input class="form-control" name="school_year" value="<?= esc(old('school_year', $competition['school_year'] ?? $defaultSchoolYear ?? '')) ?>" placeholder="2025-2026" <?= $lockedAttr ?>>
|
||||
<div class="form-text">Counts use the school year above.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Start Date</label>
|
||||
<input class="form-control" name="start_date" type="date" value="<?= esc(old('start_date', $competition['start_date'] ?? '')) ?>" <?= $lockedAttr ?>>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">End Date</label>
|
||||
<input class="form-control" name="end_date" type="date" value="<?= esc(old('end_date', $competition['end_date'] ?? '')) ?>" <?= $lockedAttr ?>>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h5 class="mt-2">Winners per Class</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-sm" data-no-mgmt-sticky>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th style="width:140px;">Students</th>
|
||||
<th style="width:140px;">Auto Winners</th>
|
||||
<th style="width:150px;">Questions</th>
|
||||
<th style="width:120px;">1st</th>
|
||||
<th style="width:120px;">2nd</th>
|
||||
<th style="width:120px;">3rd</th>
|
||||
<th style="width:120px;">4th</th>
|
||||
<th style="width:120px;">5th</th>
|
||||
<th style="width:120px;">6th</th>
|
||||
<th style="width:160px;">Override</th>
|
||||
<th style="width:140px;">Final Winners</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($classRows as $row): ?>
|
||||
<tr>
|
||||
<td><?= esc($row['class_section_name']) ?></td>
|
||||
<td><?= esc($row['student_count']) ?></td>
|
||||
<td><?= esc($row['auto_winners']) ?></td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" min="1"
|
||||
name="question_counts[<?= esc($row['class_section_id']) ?>]"
|
||||
value="<?= esc($row['question_count'] ?? '') ?>"
|
||||
placeholder="Questions" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][1]"
|
||||
value="<?= esc($row['prize_1'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][2]"
|
||||
value="<?= esc($row['prize_2'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][3]"
|
||||
value="<?= esc($row['prize_3'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][4]"
|
||||
value="<?= esc($row['prize_4'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][5]"
|
||||
value="<?= esc($row['prize_5'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" step="0.01" min="0"
|
||||
name="prizes[<?= esc($row['class_section_id']) ?>][6]"
|
||||
value="<?= esc($row['prize_6'] ?? '') ?>"
|
||||
placeholder="$" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control form-control-sm" type="number" min="1"
|
||||
name="winner_overrides[<?= esc($row['class_section_id']) ?>]"
|
||||
value="<?= esc($row['override_winners'] ?? '') ?>"
|
||||
placeholder="Auto" <?= $lockedAttr ?>>
|
||||
</td>
|
||||
<td><?= esc($row['final_winners']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary" <?= $lockedAttr ?>><?= esc($isEdit ? 'Update' : 'Create') ?></button>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="mb-0">Competition Winners</h3>
|
||||
<a class="btn btn-primary" href="/admin/competition-winners/create">+ New Competition</a>
|
||||
</div>
|
||||
|
||||
<?php if (session('success')): ?>
|
||||
<div class="alert alert-success"><?= esc(session('success')) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (session('error')): ?>
|
||||
<div class="alert alert-danger"><?= esc(session('error')) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="table table-bordered table-sm" data-no-mgmt-sticky>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Title</th>
|
||||
<th>Class Section</th>
|
||||
<th>Winners Rule</th>
|
||||
<th>Published</th>
|
||||
<th>Locked</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($competitions as $c): ?>
|
||||
<?php
|
||||
$sectionId = (int) ($c['class_section_id'] ?? 0);
|
||||
$sectionName = $sectionId > 0 ? ($sectionMap[$sectionId] ?? $sectionId) : 'All';
|
||||
$isLocked = !empty($c['is_locked']);
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($c['id']) ?></td>
|
||||
<td><?= esc($c['title']) ?></td>
|
||||
<td><?= esc($sectionName) ?></td>
|
||||
<td>Tiered per class</td>
|
||||
<td><?= $c['is_published'] ? 'Yes' : 'No' ?></td>
|
||||
<td><?= $isLocked ? 'Yes' : 'No' ?></td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="/admin/competition-winners/<?= $c['id'] ?>/settings">Settings</a>
|
||||
<a class="btn btn-sm btn-outline-primary" href="/admin/competition-winners/<?= $c['id'] ?>">Enter Scores</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="/admin/competition-winners/<?= $c['id'] ?>/preview">Preview</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="/admin/competition-winners/<?= $c['id'] ?>/winners">Winners</a>
|
||||
<form method="post" action="/admin/competition-winners/<?= $c['id'] ?>/export-quiz" class="d-inline">
|
||||
<?= csrf_field() ?>
|
||||
<button class="btn btn-sm btn-outline-success" type="submit">Export Scores to Quiz</button>
|
||||
</form>
|
||||
<?php if ($isLocked): ?>
|
||||
<form method="post" action="/admin/competition-winners/<?= $c['id'] ?>/unlock" class="d-inline">
|
||||
<?= csrf_field() ?>
|
||||
<button class="btn btn-sm btn-outline-warning" type="submit" onclick="return confirm('Unlock this competition to allow edits?')">Unlock</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<form method="post" action="/admin/competition-winners/<?= $c['id'] ?>/lock" class="d-inline">
|
||||
<?= csrf_field() ?>
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit" onclick="return confirm('Lock this competition to prevent edits?')">Lock</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h3 class="mb-0">Preview Winners</h3>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners/<?= $competition['id'] ?>">Edit Scores</a>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners/<?= $competition['id'] ?>/settings">Settings</a>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners">Back</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div><strong>Competition:</strong> <?= esc($competition['title']) ?></div>
|
||||
<div><strong>School Year:</strong> <?= esc($competition['school_year'] ?? '-') ?></div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($rankedByClass)): ?>
|
||||
<div class="alert alert-warning">No scores entered yet.</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($rankedByClass as $classId => $rows): ?>
|
||||
<?php
|
||||
$classLabel = $classMap[$classId] ?? ('Class ' . $classId);
|
||||
$topRows = $topByClass[$classId] ?? [];
|
||||
$winnerPrizeByStudent = [];
|
||||
foreach ($topRows as $winnerRow) {
|
||||
$studentId = $winnerRow['student_id'] ?? null;
|
||||
if ($studentId !== null) {
|
||||
$winnerPrizeByStudent[(int) $studentId] = $winnerRow['prize_amount'] ?? null;
|
||||
}
|
||||
}
|
||||
$studentCount = $classCounts[$classId] ?? count($rows);
|
||||
$override = $overrideMap[$classId] ?? null;
|
||||
$questions = $questionCounts[$classId] ?? null;
|
||||
$prizes = $prizeMap[$classId] ?? [];
|
||||
$finalWinners = $winnersCountByClass[$classId] ?? 0;
|
||||
?>
|
||||
<h5 class="mt-4">Top Winners - <?= esc($classLabel) ?></h5>
|
||||
<div class="text-muted mb-2">
|
||||
Students: <?= esc($studentCount) ?> | Questions: <?= esc($questions ?? '-') ?> | Override: <?= esc($override ?? '-') ?> | Final Winners: <?= esc($finalWinners) ?>
|
||||
</div>
|
||||
<table class="table table-bordered table-sm" data-no-mgmt-sticky>
|
||||
<thead class="table-light">
|
||||
<tr><th>Rank</th><th>Student</th><th>Score</th><th>Prize</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($topRows as $row): ?>
|
||||
<tr>
|
||||
<td><?= esc($row['rank']) ?></td>
|
||||
<td><?= esc($row['name']) ?></td>
|
||||
<td><?= esc($row['score']) ?></td>
|
||||
<td><?= esc(!empty($row['prize_amount']) ? $row['prize_amount'] : '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h6>All Ranked Scores - <?= esc($classLabel) ?></h6>
|
||||
<table class="table table-striped table-sm" data-no-mgmt-sticky>
|
||||
<thead><tr><th>#</th><th>Student</th><th>Score</th><th>Prize</th></tr></thead>
|
||||
<tbody>
|
||||
<?php $i = 1; foreach ($rows as $row): ?>
|
||||
<?php
|
||||
$studentId = (int) ($row['student_id'] ?? 0);
|
||||
$prizeVal = $winnerPrizeByStudent[$studentId] ?? null;
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $i++ ?></td>
|
||||
<td><?= esc($row['name']) ?></td>
|
||||
<td><?= esc($row['score']) ?></td>
|
||||
<td><?= esc(!empty($prizeVal) ? $prizeVal : '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="/admin/competition-winners/<?= $competition['id'] ?>/publish" class="mt-3">
|
||||
<?= csrf_field() ?>
|
||||
<button class="btn btn-success">Publish Winners</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,135 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h3 class="mb-0">Enter Scores</h3>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners">Back</a>
|
||||
</div>
|
||||
|
||||
<?php $isLocked = !empty($competition['is_locked']); ?>
|
||||
<?php $lockedAttr = $isLocked ? 'disabled' : ''; ?>
|
||||
|
||||
<?php if ($isLocked): ?>
|
||||
<div class="alert alert-warning">This competition is locked. Unlock it to update scores.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mb-3">
|
||||
<div><strong>Competition:</strong> <?= esc($competition['title']) ?></div>
|
||||
<?php if (!empty($classSectionName)): ?>
|
||||
<div><strong>Class Section:</strong> <?= esc($classSectionName) ?></div>
|
||||
<div>
|
||||
<strong>Students:</strong> <?= esc($classStudentCount ?? 0) ?> |
|
||||
<strong>Auto Winners:</strong> <?= esc($classAutoWinners ?? 0) ?> |
|
||||
<strong>Override:</strong> <?= esc($classOverrideWinners ?? '-') ?> |
|
||||
<strong>Final Winners:</strong> <?= esc($classFinalWinners ?? 0) ?> |
|
||||
<strong>Questions:</strong> <?= esc($classQuestionCount ?? '-') ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!$classSelectionLocked): ?>
|
||||
<form method="get" class="row g-2 align-items-end mb-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Select Class Section</label>
|
||||
<select class="form-select" name="class_section_id" onchange="this.form.submit()" <?= $lockedAttr ?>>
|
||||
<option value="">Choose a class</option>
|
||||
<?php foreach ($classSections as $section): ?>
|
||||
<?php
|
||||
$value = (string) ($section['class_section_id'] ?? '');
|
||||
$label = $section['class_section_name'] ?? $value;
|
||||
$selected = $value !== '' && (int) $value === (int) $activeClassSectionId ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($value) ?>" <?= $selected ?>><?= esc($label) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-text">Pick a class to load its students for score entry.</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (session('success')): ?>
|
||||
<div class="alert alert-success"><?= esc(session('success')) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="/admin/competition-winners/<?= $competition['id'] ?>/scores">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="class_section_id" value="<?= esc($activeClassSectionId ?? '') ?>">
|
||||
|
||||
<?php if (empty($activeClassSectionId)): ?>
|
||||
<div class="alert alert-warning">Select a class section to load students.</div>
|
||||
<?php else: ?>
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/v/bs5/dt-2.1.8/r-3.0.3/datatables.min.css">
|
||||
<?php $scoreMax = ($classQuestionCount !== null && (int) $classQuestionCount > 0) ? (int) $classQuestionCount : null; ?>
|
||||
<table class="table table-bordered table-sm" data-no-mgmt-sticky id="scoresTable">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width:140px;">School ID</th>
|
||||
<th>Student</th>
|
||||
<th style="width:180px;">
|
||||
Score<?= $scoreMax !== null ? ' (max ' . esc($scoreMax) . ')' : '' ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $s):
|
||||
$name = trim(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''));
|
||||
$studentId = $s['id'] ?? $s['student_id'] ?? null;
|
||||
$schoolId = $s['school_id'] ?? null;
|
||||
$val = $studentId !== null ? ($scoreMap[$studentId] ?? '') : '';
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($schoolId ?: $studentId) ?></td>
|
||||
<td><?= esc($name !== '' ? $name : ('Student #' . $studentId)) ?></td>
|
||||
<td data-order="<?= esc($val) ?>">
|
||||
<input class="form-control form-control-sm"
|
||||
name="scores[<?= esc($studentId) ?>]"
|
||||
type="number" step="0.01" min="0"
|
||||
value="<?= esc($val) ?>"
|
||||
<?= $scoreMax !== null ? 'max="' . esc($scoreMax) . '"' : '' ?>
|
||||
<?= $lockedAttr ?>>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-primary" <?= $lockedAttr ?>>Save Scores</button>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners/<?= $competition['id'] ?>/preview">Preview Winners</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.datatables.net/v/bs5/dt-2.1.8/r-3.0.3/datatables.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const tableEl = document.getElementById('scoresTable');
|
||||
if (!tableEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
new DataTable(tableEl, {
|
||||
responsive: true,
|
||||
paging: false,
|
||||
searching: false,
|
||||
info: false,
|
||||
order: [[1, 'asc']],
|
||||
});
|
||||
|
||||
tableEl.addEventListener('input', function (event) {
|
||||
const target = event.target;
|
||||
if (target && target.matches('input')) {
|
||||
const cell = target.closest('td');
|
||||
if (cell) {
|
||||
cell.setAttribute('data-order', target.value.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,110 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h3 class="mb-0">School Winners</h3>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners/<?= $competition['id'] ?>/preview">Preview</a>
|
||||
<a class="btn btn-outline-secondary" href="/admin/competition-winners">Back</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div><strong>Competition:</strong> <?= esc($competition['title']) ?></div>
|
||||
<div><strong>School Year:</strong> <?= esc($competition['school_year'] ?? '-') ?></div>
|
||||
<div><strong>Published:</strong> <?= !empty($competition['is_published']) ? 'Yes' : 'No' ?></div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$palette = [
|
||||
['bg' => '#fde2c2', 'hover' => '#f8c996'],
|
||||
['bg' => '#cfe6ff', 'hover' => '#b5d6ff'],
|
||||
['bg' => '#c9f2e7', 'hover' => '#a6e6d4'],
|
||||
['bg' => '#f7c8c7', 'hover' => '#f1a6a3'],
|
||||
['bg' => '#fff1a8', 'hover' => '#ffe38a'],
|
||||
['bg' => '#e4c7f2', 'hover' => '#d1a9e8'],
|
||||
['bg' => '#d6d9de', 'hover' => '#c2c8cf'],
|
||||
['bg' => '#c9efc5', 'hover' => '#aee3a9'],
|
||||
];
|
||||
$paletteCount = count($palette);
|
||||
?>
|
||||
|
||||
<style>
|
||||
<?php foreach ($palette as $index => $colors): ?>
|
||||
.class-color-<?= $index ?> td { background-color: <?= $colors['bg'] ?>; }
|
||||
.class-color-<?= $index ?>:hover td { background-color: <?= $colors['hover'] ?>; }
|
||||
<?php endforeach; ?>
|
||||
</style>
|
||||
|
||||
<?php if (empty($rows)): ?>
|
||||
<div class="alert alert-warning">No published winners yet. Publish winners to see the list.</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-bordered table-sm" data-no-mgmt-sticky>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>School ID</th>
|
||||
<th>Student</th>
|
||||
<th>Photo Consent</th>
|
||||
<th>Rank</th>
|
||||
<th>Score</th>
|
||||
<th>Prize</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalPrize = 0.0; ?>
|
||||
<?php foreach ($rows as $row): ?>
|
||||
<?php
|
||||
$classId = (int) ($row['class_section_id'] ?? 0);
|
||||
$classLabel = $row['class_section_name'] ?? ($classMap[$classId] ?? ('Class ' . $classId));
|
||||
$name = trim(($row['firstname'] ?? '') . ' ' . ($row['lastname'] ?? ''));
|
||||
$studentLabel = $name !== '' ? $name : ('Student #' . ($row['student_id'] ?? ''));
|
||||
$colorIndex = $paletteCount > 0 ? ($classId % $paletteCount) : 0;
|
||||
$questionCount = $questionCounts[$classId] ?? null;
|
||||
$scoreValue = $row['score'] ?? null;
|
||||
$scoreLabel = '-';
|
||||
$prizeValue = null;
|
||||
$photoConsentLabel = '-';
|
||||
if (array_key_exists('photo_consent', $row)) {
|
||||
$photoConsentLabel = ((int) $row['photo_consent'] === 1) ? 'Yes' : 'No';
|
||||
}
|
||||
if (isset($row['prize_amount']) && $row['prize_amount'] !== '' && is_numeric($row['prize_amount'])) {
|
||||
$prizeValue = (float) $row['prize_amount'];
|
||||
$totalPrize += $prizeValue;
|
||||
}
|
||||
if ($scoreValue !== null && $scoreValue !== '' && is_numeric($scoreValue)) {
|
||||
$scoreDisplay = number_format((float) $scoreValue, 0, '.', '');
|
||||
$scoreLabel = $scoreDisplay;
|
||||
if ($questionCount !== null) {
|
||||
$scoreLabel = $scoreDisplay . '/' . $questionCount;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr class="class-color-<?= esc((string) $colorIndex) ?>">
|
||||
<td><?= esc($classLabel) ?></td>
|
||||
<td><?= esc($row['school_id'] ?? $row['student_id'] ?? '-') ?></td>
|
||||
<td><?= esc($studentLabel) ?></td>
|
||||
<td><?= esc($photoConsentLabel) ?></td>
|
||||
<td><?= esc($row['rank'] ?? '-') ?></td>
|
||||
<td><?= esc($scoreLabel) ?></td>
|
||||
<td><?= esc($prizeValue !== null ? $prizeValue : '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="6" class="text-end">Total Prizes</th>
|
||||
<th><?= esc(number_format($totalPrize, 2, '.', '')) ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<a class="btn btn-primary external-link" href="/admin/competition-winners/<?= $competition['id'] ?>/recognition-pdf" target="_blank" rel="noopener">
|
||||
Generate Recognition PDF
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,145 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container-fluid py-4">
|
||||
<style>
|
||||
.admin-score-table { margin-top: 4px; }
|
||||
.admin-score-table thead th { position: static; }
|
||||
</style>
|
||||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
|
||||
<div>
|
||||
<h2 class="mb-0">Student Score Card (Admin)</h2>
|
||||
<div class="text-muted small">Search for a student, then open their score card.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-body">
|
||||
<form id="studentSearchForm" method="get" action="<?= site_url('administrator/student-score-card') ?>">
|
||||
<div class="row g-2 justify-content-center">
|
||||
<div class="col-12 col-md-8 col-lg-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Search Student</span>
|
||||
<input id="globalStudentSearch"
|
||||
class="form-control"
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="Type School ID or Student Name"
|
||||
list="studentSuggestions"
|
||||
autocomplete="off"
|
||||
value="<?= esc($query ?? '') ?>" />
|
||||
<button id="globalStudentSearchClear" class="btn btn-outline-secondary" type="button" title="Clear search">Clear</button>
|
||||
</div>
|
||||
<small class="text-muted">Searches all grades.</small>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="d-none">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<datalist id="studentSuggestions">
|
||||
<?php
|
||||
$seen = [];
|
||||
foreach (($suggestions ?? []) as $stu):
|
||||
$sid = (int)($stu['id'] ?? 0);
|
||||
if ($sid <= 0) continue;
|
||||
$schoolId = trim((string)($stu['school_id'] ?? ''));
|
||||
$label = trim(($stu['firstname'] ?? '') . ' ' . ($stu['lastname'] ?? ''));
|
||||
$value = trim(($schoolId !== '' ? $schoolId . ' - ' : '') . $label);
|
||||
if ($value === '' || isset($seen[$value])) continue;
|
||||
$seen[$value] = true;
|
||||
?>
|
||||
<option value="<?= esc($value) ?>"></option>
|
||||
<?php endforeach; ?>
|
||||
</datalist>
|
||||
|
||||
<?php if (!empty($query) && empty($students)): ?>
|
||||
<div class="alert alert-warning">No students found.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($students)): ?>
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<strong>Results</strong>
|
||||
<span class="text-muted small">Showing up to 50</span>
|
||||
</div>
|
||||
<div class="card-body table-responsive pt-2">
|
||||
<table class="table table-striped table-hover align-middle admin-score-table no-mgmt-sticky" data-no-mgmt-sticky="1">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>School ID</th>
|
||||
<th>Student</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $s): ?>
|
||||
<tr>
|
||||
<td><?= esc($s['school_id'] ?? '') ?></td>
|
||||
<td><?= esc(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? '')) ?></td>
|
||||
<td>
|
||||
<?php if ((int)($s['is_active'] ?? 0) === 1): ?>
|
||||
<span class="badge text-bg-success">Active</span>
|
||||
<?php else: ?>
|
||||
<span class="badge text-bg-secondary">Inactive</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<form method="post" action="<?= site_url('student/score-card') ?>" class="d-inline">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="student_id" value="<?= (int)($s['id'] ?? 0) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary">Open Score Card</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const form = document.getElementById('studentSearchForm');
|
||||
const input = document.getElementById('globalStudentSearch');
|
||||
const clr = document.getElementById('globalStudentSearchClear');
|
||||
const dlist = document.getElementById('studentSuggestions');
|
||||
const suggestionSet = new Set(Array.from(dlist?.options || []).map(o => (o.value || '').trim()));
|
||||
let lastAutoQuery = '';
|
||||
|
||||
function submitSearch() {
|
||||
if (!form) return;
|
||||
form.submit();
|
||||
}
|
||||
|
||||
input?.addEventListener('keydown', e => {
|
||||
if (e.key === 'Enter') { e.preventDefault(); submitSearch(); }
|
||||
});
|
||||
|
||||
clr?.addEventListener('click', () => {
|
||||
if (input) input.value = '';
|
||||
input?.focus();
|
||||
});
|
||||
|
||||
function tryAutoRun() {
|
||||
const val = (input?.value || '').trim();
|
||||
if (!val) return;
|
||||
if (suggestionSet.has(val) && val !== lastAutoQuery) {
|
||||
lastAutoQuery = val;
|
||||
submitSearch();
|
||||
}
|
||||
}
|
||||
|
||||
input?.addEventListener('change', tryAutoRun);
|
||||
input?.addEventListener('input', () => {
|
||||
clearTimeout(input.__autoTimer);
|
||||
input.__autoTimer = setTimeout(tryAutoRun, 50);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
Reference in New Issue
Block a user