From ef3a1cc12ceec7ac50ccaec6cf3be71128243427 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 30 Jan 2026 14:32:19 +0000 Subject: [PATCH] Auto commit: 2026-01-30T14:32:19.673Z --- admin.php | 97 +++---- assessments.php | 250 ++++++++++++++++++ .../002_add_users_and_assessments.sql | 73 +++++ includes/header.php | 53 ++-- index.php | 210 ++++----------- learners.php | 81 +++--- login.php | 95 +++++++ logout.php | 5 + parent.php | 45 ++-- register.php | 112 ++++++++ super-admin.php | 68 ++--- sw.js | 21 +- teacher.php | 179 +++++++++++++ 13 files changed, 978 insertions(+), 311 deletions(-) create mode 100644 assessments.php create mode 100644 db/migrations/002_add_users_and_assessments.sql create mode 100644 login.php create mode 100644 logout.php create mode 100644 register.php create mode 100644 teacher.php diff --git a/admin.php b/admin.php index 02c9192..ff469a1 100644 --- a/admin.php +++ b/admin.php @@ -1,31 +1,43 @@ query("SELECT COUNT(*) FROM learners")->fetchColumn(); +// Fetch Some Stats for this school +$total_learners_stmt = $db->prepare("SELECT COUNT(*) FROM learners WHERE school_id = ?"); +$total_learners_stmt->execute([$school_id]); +$total_learners = $total_learners_stmt->fetchColumn(); // Attendance for today $today = date('Y-m-d'); -$present_today = $db->prepare("SELECT COUNT(*) FROM attendance WHERE date = ? AND status = 'present'"); -$present_today->execute([$today]); +$present_today = $db->prepare("SELECT COUNT(*) FROM attendance WHERE date = ? AND status = 'present' AND school_id = ?"); +$present_today->execute([$today, $school_id]); $present_today_count = $present_today->fetchColumn(); $presence_rate = $total_learners > 0 ? round(($present_today_count / $total_learners) * 100) : 0; // Analytics: Attendance by Grade -$grade_stats = $db->query(" +$grade_stats = $db->prepare(" SELECT l.grade, COUNT(l.id) as total, SUM(CASE WHEN a.status = 'present' THEN 1 ELSE 0 END) as present FROM learners l - LEFT JOIN attendance a ON l.id = a.learner_id AND a.date = '$today' + LEFT JOIN attendance a ON l.id = a.learner_id AND a.date = :today + WHERE l.school_id = :school_id GROUP BY l.grade ORDER BY l.grade -")->fetchAll(); +"); +$grade_stats->execute(['today' => $today, 'school_id' => $school_id]); +$grade_stats = $grade_stats->fetchAll(); include 'includes/header.php'; ?> @@ -34,45 +46,48 @@ include 'includes/header.php';

School Admin Dashboard

-

Overview of school operations

+

Overview of operations for School ID:

-
-

Total Learners

-

+
+

Total Learners

+

-
-

Today's Presence

-

%

+
+

Today's Presence

+

%

-
-

Total Staff

-

12

+
+

Total Staff

+

...

-
-

SGB Meetings

-

1

+
+

Pending Tasks

+

3

-
+
-
Attendance Analytics by Grade (Today)
+
Attendance Analytics by Grade (Today)
+ +

No attendance data recorded today.

+ 0 ? round(($stat['present'] / $stat['total']) * 100) : 0; @@ -80,8 +95,8 @@ include 'includes/header.php'; ?>
- - % (/) + Grade + % (/)
@@ -91,28 +106,19 @@ include 'includes/header.php';
-
+
-
Recent Activity
+
Recent Activity
  • -
    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';
-
+
-
Quick Actions
+
Quick Actions
- Register New Learner + Manage Learners
@@ -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

+
+ +
+
+ + + + + +
+
+
+
+
Assessments
+
+
+ +
No assessments created.
+ + + +
+
+ +
+
+ ( pts) + +
+
+ +
+
+
+ +
+ +
+
+
+
Capture Marks:
+ Grade | Max Marks: +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + +
Learner NameScore /
No learners found for Grade in this school.
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+ +

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'; - 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

-
-
+ - - - - - -
-
-
-

Total Learners

-

-
-
-
-
-

Presence Rate

-

%

-
-
-
-
-

Pending Reports

-

0

-
-
-
- - -
-
-
Class Register
-
- - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - -
Learner NameGradeStudent IDStatus
- - -
- required> - - - > - -
-
-
-
- -
-
+
+
+

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: learners

+

Total: learners in this school

-
-