No attendance data recorded today.
+
0 ? round(($stat['present'] / $stat['total']) * 100) : 0;
@@ -80,8 +95,8 @@ include 'includes/header.php';
?>
+
-
Daily Register Completed
- Grade 10A - Mrs. Mdluli
+ System Online
+ School instance successfully initialized.
-
10 mins ago
-
-
-
-
-
-
New Learner Registered
- Sipho Zulu - Grade 8B
-
-
1 hour ago
+
Just now
@@ -120,14 +126,14 @@ include 'includes/header.php';
-
+
@@ -145,4 +148,4 @@ include 'includes/header.php';
-
\ No newline at end of file
+
diff --git a/assessments.php b/assessments.php
new file mode 100644
index 0000000..02353eb
--- /dev/null
+++ b/assessments.php
@@ -0,0 +1,250 @@
+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';
+?>
+
+
+
+
+
+
Assessment Tracking
+
Record and monitor learner performance
+
+
+ New Assessment
+
+
+
+
+
+
+ = htmlspecialchars($message) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Select an assessment from the list to record marks.
+
+
+
+
+
+
+
+
+
+
diff --git a/db/migrations/002_add_users_and_assessments.sql b/db/migrations/002_add_users_and_assessments.sql
new file mode 100644
index 0000000..34312d4
--- /dev/null
+++ b/db/migrations/002_add_users_and_assessments.sql
@@ -0,0 +1,73 @@
+-- Migration: Add users, assessments and school association
+CREATE TABLE IF NOT EXISTS users (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ email VARCHAR(255) NOT NULL UNIQUE,
+ password VARCHAR(255) NOT NULL,
+ role ENUM('Super Admin', 'Admin', 'Teacher', 'Parent') NOT NULL,
+ school_id INT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE SET NULL
+);
+
+-- Add school_id to learners if it doesn't exist
+SET @dbname = DATABASE();
+SET @tablename = 'learners';
+SET @columnname = 'school_id';
+SET @preparedStatement = (SELECT IF(
+ (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE TABLE_SCHEMA = @dbname
+ AND TABLE_NAME = @tablename
+ AND COLUMN_NAME = @columnname) > 0,
+ 'SELECT 1',
+ 'ALTER TABLE learners ADD COLUMN school_id INT, ADD FOREIGN KEY (school_id) REFERENCES schools(id)'
+));
+PREPARE stmt FROM @preparedStatement;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+-- Add school_id to attendance if it doesn't exist
+SET @tablename = 'attendance';
+SET @columnname = 'school_id';
+SET @preparedStatement = (SELECT IF(
+ (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE TABLE_SCHEMA = @dbname
+ AND TABLE_NAME = @tablename
+ AND COLUMN_NAME = @columnname) > 0,
+ 'SELECT 1',
+ 'ALTER TABLE attendance ADD COLUMN school_id INT, ADD FOREIGN KEY (school_id) REFERENCES schools(id)'
+));
+PREPARE stmt FROM @preparedStatement;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+CREATE TABLE IF NOT EXISTS assessments (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ type ENUM('Test', 'Exam', 'Assignment', 'Project') NOT NULL,
+ total_marks INT NOT NULL,
+ grade VARCHAR(20) NOT NULL,
+ school_id INT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS marks (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ assessment_id INT NOT NULL,
+ learner_id INT NOT NULL,
+ marks_obtained INT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (assessment_id) REFERENCES assessments(id) ON DELETE CASCADE,
+ FOREIGN KEY (learner_id) REFERENCES learners(id) ON DELETE CASCADE,
+ UNIQUE KEY unique_mark (assessment_id, learner_id)
+);
+
+-- Seed a default user (password: password123)
+-- Admin for 'Soweto High' (assuming id 1 from previous seeding if it exists)
+INSERT IGNORE INTO users (email, password, role, school_id) VALUES
+('admin@sowetohigh.edu.za', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'Admin', 1),
+('teacher@sowetohigh.edu.za', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'Teacher', 1);
+
+-- Assign existing learners to school 1 if they aren't assigned
+UPDATE learners SET school_id = 1 WHERE school_id IS NULL;
+UPDATE attendance SET school_id = 1 WHERE school_id IS NULL;
diff --git a/includes/header.php b/includes/header.php
index 979d878..3e53a30 100644
--- a/includes/header.php
+++ b/includes/header.php
@@ -1,7 +1,14 @@
@@ -23,30 +30,33 @@ $current_role = $current_role ?? 'Teacher';
-
+
-
\ No newline at end of file
+
diff --git a/index.php b/index.php
index bfe9452..4dd8320 100644
--- a/index.php
+++ b/index.php
@@ -1,164 +1,70 @@
beginTransaction();
- $stmt = $db->prepare("INSERT INTO attendance (learner_id, status, date)
- VALUES (:learner_id, :status, :date)
- ON DUPLICATE KEY UPDATE status = VALUES(status)");
-
- foreach ($_POST['attendance'] as $learner_id => $status) {
- $stmt->execute([
- 'learner_id' => $learner_id,
- 'status' => $status,
- 'date' => $date
- ]);
- }
- $db->commit();
- $message = "Attendance saved successfully for $date.";
- } catch (Exception $e) {
- $db->rollBack();
- $message = "Error: " . $e->getMessage();
- }
-}
-
-// Fetch Learners and their current attendance for today
-$query = "SELECT l.*, a.status as today_status
- FROM learners l
- LEFT JOIN attendance a ON l.id = a.learner_id AND a.date = :date
- ORDER BY l.full_name ASC";
-$stmt = $db->prepare($query);
-$stmt->execute(['date' => $date]);
-$learners = $stmt->fetchAll();
-
-// Stats
-$total_learners = count($learners);
-$present_count = 0;
-foreach ($learners as $l) {
- if ($l['today_status'] === 'present') $present_count++;
-}
-$presence_rate = $total_learners > 0 ? round(($present_count / $total_learners) * 100) : 0;
-
+$pageTitle = 'Welcome | Township Schools Platform';
include 'includes/header.php';
?>
-
-
-
-
Teacher Dashboard
-
Daily attendance for = date('l, d F Y') ?>
-
-
+
-
-
- = htmlspecialchars($message) ?>
-
-
-
-
-
-
-
-
-
Total Learners
-
= $total_learners ?>
-
-
-
-
-
Presence Rate
-
= $presence_rate ?>%
-
-
-
-
-
-
-
-
-
-
+
+
+
Empowering Township Schools Through Digital Excellence
+
A comprehensive school operations and management system designed for resilience, efficiency, and student success.
+
-
+
+
+
+
+
+
Teacher Productivity
+
Streamlined attendance tracking and assessment management to save teachers valuable time.
+
+
+
+
+
+
School Analytics
+
Real-time data for administrators to monitor school-wide performance and attendance trends.
+
+
+
+
+
+
Offline First
+
Built to work in low-bandwidth environments with robust offline synchronization capabilities.
+
+
+
+
diff --git a/learners.php b/learners.php
index 309c87e..1b5988a 100644
--- a/learners.php
+++ b/learners.php
@@ -1,20 +1,28 @@
prepare("INSERT INTO learners (full_name, grade, student_id) VALUES (?, ?, ?)");
+ $stmt = $db->prepare("INSERT INTO learners (full_name, grade, student_id, school_id) VALUES (?, ?, ?, ?)");
$stmt->execute([
$_POST['full_name'],
$_POST['grade'],
- $_POST['student_id']
+ $_POST['student_id'],
+ $school_id
]);
$message = "Learner registered successfully.";
} catch (Exception $e) {
@@ -22,8 +30,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
}
} elseif ($_POST['action'] === 'delete') {
try {
- $stmt = $db->prepare("DELETE FROM learners WHERE id = ?");
- $stmt->execute([$_POST['id']]);
+ // Ensure the learner belongs to this school before deleting
+ $stmt = $db->prepare("DELETE FROM learners WHERE id = ? AND school_id = ?");
+ $stmt->execute([$_POST['id'], $school_id]);
$message = "Learner record deleted.";
} catch (Exception $e) {
$message = "Error: " . $e->getMessage();
@@ -31,8 +40,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
}
}
-// Fetch Learners
-$learners = $db->query("SELECT * FROM learners ORDER BY full_name ASC")->fetchAll();
+// Fetch Learners for this specific school
+$stmt = $db->prepare("SELECT * FROM learners WHERE school_id = ? ORDER BY full_name ASC");
+$stmt->execute([$school_id]);
+$learners = $stmt->fetchAll();
include 'includes/header.php';
?>
@@ -41,26 +52,26 @@ include 'includes/header.php';
Learner Management
-
Total: = count($learners) ?> learners
+
Total: = count($learners) ?> learners in this school
-
+
Register New Learner
-
+
= htmlspecialchars($message) ?>
-
+
-
+
Full Name
Grade
@@ -69,13 +80,21 @@ include 'includes/header.php';
+
+
+
+
+ No learners registered yet.
+
+
+
= htmlspecialchars($l['full_name']) ?>
= htmlspecialchars($l['grade']) ?>
- = htmlspecialchars($l['student_id']) ?>
+ = htmlspecialchars($l['student_id']) ?>