251 lines
12 KiB
PHP
251 lines
12 KiB
PHP
<?php
|
|
require_once __DIR__ . '/db/config.php';
|
|
session_start();
|
|
|
|
// Auth Check
|
|
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'Teacher') {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
|
|
$db = db();
|
|
$school_id = $_SESSION['school_id'];
|
|
$pageTitle = 'Teacher Assessments | SOMS';
|
|
$message = '';
|
|
|
|
// Handle Assessment Creation
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|
if ($_POST['action'] === 'create') {
|
|
try {
|
|
$stmt = $db->prepare("INSERT INTO assessments (name, type, total_marks, grade, school_id) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$_POST['name'],
|
|
$_POST['type'],
|
|
$_POST['total_marks'],
|
|
$_POST['grade'],
|
|
$school_id
|
|
]);
|
|
$message = "Assessment created successfully.";
|
|
} catch (Exception $e) {
|
|
$message = "Error: " . $e->getMessage();
|
|
}
|
|
} elseif ($_POST['action'] === 'save_marks') {
|
|
try {
|
|
$db->beginTransaction();
|
|
$assessment_id = $_POST['assessment_id'];
|
|
$stmt = $db->prepare("INSERT INTO marks (assessment_id, learner_id, marks_obtained)
|
|
VALUES (:aid, :lid, :marks)
|
|
ON DUPLICATE KEY UPDATE marks_obtained = VALUES(marks_obtained)");
|
|
|
|
foreach ($_POST['marks'] as $learner_id => $marks) {
|
|
if ($marks !== '') {
|
|
$stmt->execute([
|
|
'aid' => $assessment_id,
|
|
'lid' => $learner_id,
|
|
'marks' => $marks
|
|
]);
|
|
}
|
|
}
|
|
$db->commit();
|
|
$message = "Marks saved successfully.";
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
$message = "Error: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fetch Assessments for this school
|
|
$stmt = $db->prepare("SELECT * FROM assessments WHERE school_id = ? ORDER BY created_at DESC");
|
|
$stmt->execute([$school_id]);
|
|
$assessments = $stmt->fetchAll();
|
|
|
|
// If an assessment is selected for grading
|
|
$selected_assessment = null;
|
|
$learners_to_grade = [];
|
|
if (isset($_GET['grade_id'])) {
|
|
$stmt = $db->prepare("SELECT * FROM assessments WHERE id = ? AND school_id = ?");
|
|
$stmt->execute([$_GET['grade_id'], $school_id]);
|
|
$selected_assessment = $stmt->fetch();
|
|
|
|
if ($selected_assessment) {
|
|
// Fetch learners in this grade and their existing marks
|
|
$stmt = $db->prepare("
|
|
SELECT l.*, m.marks_obtained
|
|
FROM learners l
|
|
LEFT JOIN marks m ON l.id = m.learner_id AND m.assessment_id = :aid
|
|
WHERE l.school_id = :sid AND l.grade = :grade
|
|
ORDER BY l.full_name ASC
|
|
");
|
|
$stmt->execute([
|
|
'aid' => $selected_assessment['id'],
|
|
'sid' => $school_id,
|
|
'grade' => $selected_assessment['grade']
|
|
]);
|
|
$learners_to_grade = $stmt->fetchAll();
|
|
}
|
|
}
|
|
|
|
include 'includes/header.php';
|
|
?>
|
|
|
|
<div class="container pb-5">
|
|
<div class="row mb-4">
|
|
<div class="col-12 d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h2 class="h4 mb-1">Assessment Tracking</h2>
|
|
<p class="text-muted small">Record and monitor learner performance</p>
|
|
</div>
|
|
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addAssessmentModal">
|
|
<i class="bi bi-plus-lg me-2"></i> New Assessment
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="alert alert-info alert-dismissible fade show shadow-sm" role="alert">
|
|
<?= htmlspecialchars($message) ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-md-4">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0 fw-bold">Assessments</h5>
|
|
</div>
|
|
<div class="list-group list-group-flush overflow-auto" style="max-height: 500px;">
|
|
<?php if (empty($assessments)): ?>
|
|
<div class="p-4 text-center text-muted">No assessments created.</div>
|
|
<?php endif; ?>
|
|
<?php foreach ($assessments as $a): ?>
|
|
<a href="?grade_id=<?= $a['id'] ?>" class="list-group-item list-group-item-action p-3 <?= ($selected_assessment && $selected_assessment['id'] == $a['id']) ? 'active' : '' ?>">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0 fw-bold"><?= htmlspecialchars($a['name']) ?></h6>
|
|
<span class="badge <?= ($selected_assessment && $selected_assessment['id'] == $a['id']) ? 'bg-light text-primary' : 'bg-primary' ?>"><?= htmlspecialchars($a['grade']) ?></span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mt-2">
|
|
<small><?= htmlspecialchars($a['type']) ?> (<?= $a['total_marks'] ?> pts)</small>
|
|
<small><?= date('d M', strtotime($a['created_at'])) ?></small>
|
|
</div>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-8">
|
|
<?php if ($selected_assessment): ?>
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h5 class="mb-0 fw-bold">Capture Marks: <?= htmlspecialchars($selected_assessment['name']) ?></h5>
|
|
<small class="text-muted">Grade <?= htmlspecialchars($selected_assessment['grade']) ?> | Max Marks: <?= $selected_assessment['total_marks'] ?></small>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="save_marks">
|
|
<input type="hidden" name="assessment_id" value="<?= $selected_assessment['id'] ?>">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">Learner Name</th>
|
|
<th style="width: 150px;" class="text-end pe-4">Score / <?= $selected_assessment['total_marks'] ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($learners_to_grade)): ?>
|
|
<tr>
|
|
<td colspan="2" class="text-center py-4 text-muted">No learners found for Grade <?= htmlspecialchars($selected_assessment['grade']) ?> in this school.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
<?php foreach ($learners_to_grade as $l): ?>
|
|
<tr>
|
|
<td class="ps-4">
|
|
<strong><?= htmlspecialchars($l['full_name']) ?></strong>
|
|
<br><small class="text-muted"><?= htmlspecialchars($l['student_id']) ?></small>
|
|
</td>
|
|
<td class="text-end pe-4">
|
|
<div class="input-group input-group-sm">
|
|
<input type="number" name="marks[<?= $l['id'] ?>]" class="form-control text-end"
|
|
max="<?= $selected_assessment['total_marks'] ?>" min="0"
|
|
value="<?= $l['marks_obtained'] ?? '' ?>" placeholder="0">
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="p-3 text-end border-top">
|
|
<button type="submit" class="btn btn-primary px-4 fw-bold">
|
|
<i class="bi bi-save me-2"></i> Save Marks
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="h-100 d-flex flex-column align-items-center justify-content-center text-muted py-5 border rounded bg-white shadow-sm">
|
|
<i class="bi bi-journal-check mb-3" style="font-size: 3rem; opacity: 0.3;"></i>
|
|
<p>Select an assessment from the list to record marks.</p>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Add Assessment Modal -->
|
|
<div class="modal fade" id="addAssessmentModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<form method="POST" class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title fw-bold">New Assessment</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body p-4">
|
|
<input type="hidden" name="action" value="create">
|
|
<div class="mb-3">
|
|
<label class="form-label small fw-bold">Assessment Name</label>
|
|
<input type="text" name="name" class="form-control" required placeholder="e.g. Term 1 Math Test">
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label small fw-bold">Type</label>
|
|
<select name="type" class="form-select" required>
|
|
<option value="Test">Test</option>
|
|
<option value="Exam">Exam</option>
|
|
<option value="Assignment">Assignment</option>
|
|
<option value="Project">Project</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label small fw-bold">Total Marks</label>
|
|
<input type="number" name="total_marks" class="form-control" required placeholder="e.g. 50">
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label small fw-bold">Grade</label>
|
|
<select name="grade" class="form-select" required>
|
|
<option value="">Select Grade</option>
|
|
<option value="8">Grade 8</option>
|
|
<option value="9">Grade 9</option>
|
|
<option value="10">Grade 10</option>
|
|
<option value="11">Grade 11</option>
|
|
<option value="12">Grade 12</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary px-4 fw-bold">Create Assessment</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<?php include 'includes/footer.php'; ?>
|