From 386664137b3b2a5e7e65db9c45e1e36bbd43574d Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 25 Nov 2025 17:23:56 +0000 Subject: [PATCH] kiveu new version --- admin_classes.php | 148 +++++++ admin_subjects.php | 212 +++++++++ admin_teachers.php | 156 +++++++ admin_workloads.php | 232 ++++++++++ assets/css/custom.css | 49 +++ db/migrate.php | 41 ++ db/migrations/001_create_classes_table.sql | 6 + db/migrations/002_create_subjects_table.sql | 5 + db/migrations/003_create_teachers_table.sql | 6 + db/migrations/004_create_workloads_table.sql | 12 + db/migrations/005_create_users_table.sql | 7 + db/migrations/006_add_subject_options.sql | 3 + demo.php | 220 ++++++---- includes/auth_check.php | 8 + index.php | 55 ++- login.php | 96 ++++ logout.php | 6 + register.php | 95 ++++ timetable.php | 434 +++++++++++++++++++ 19 files changed, 1679 insertions(+), 112 deletions(-) create mode 100644 admin_classes.php create mode 100644 admin_subjects.php create mode 100644 admin_teachers.php create mode 100644 admin_workloads.php create mode 100644 db/migrate.php create mode 100644 db/migrations/001_create_classes_table.sql create mode 100644 db/migrations/002_create_subjects_table.sql create mode 100644 db/migrations/003_create_teachers_table.sql create mode 100644 db/migrations/004_create_workloads_table.sql create mode 100644 db/migrations/005_create_users_table.sql create mode 100644 db/migrations/006_add_subject_options.sql create mode 100644 includes/auth_check.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 register.php create mode 100644 timetable.php diff --git a/admin_classes.php b/admin_classes.php new file mode 100644 index 0000000..33d65f9 --- /dev/null +++ b/admin_classes.php @@ -0,0 +1,148 @@ +prepare("INSERT INTO classes (name) VALUES (?)"); + if ($stmt->execute([$className])) { + $message = "Class '" . htmlspecialchars($className) . "' created successfully!"; + } else { + $error = 'Failed to create class.'; + } + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + $error = "Error: Class '" . htmlspecialchars($className) . "' already exists."; + } else { + $error = 'Database error: ' . $e->getMessage(); + } + } + } +} + +// Fetch all classes to display +$classes = []; +try { + $pdo = db(); + $classes_stmt = $pdo->query("SELECT id, name, created_at FROM classes ORDER BY created_at DESC"); + $classes = $classes_stmt->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + $error = 'Database error: ' . $e->getMessage(); +} + +?> + + + + + + Admin: Manage Classes - Haki Schedule + + + + + + + +
+
+
+

Manage Classes

+ + +
+ + +
+ + + +
+
+
Create a New Class
+
+
+ + +
+ +
+
+
+ + +
+
+
Existing Classes
+ +

No classes have been created yet. Use the form above to add the first one.

+ +
    + +
  • + + Created: +
  • + +
+ +
+
+ +
+
+
+ + + + + + \ No newline at end of file diff --git a/admin_subjects.php b/admin_subjects.php new file mode 100644 index 0000000..331504e --- /dev/null +++ b/admin_subjects.php @@ -0,0 +1,212 @@ +prepare("DELETE FROM subjects WHERE id = ?"); + $stmt->execute([$delete_id]); + $message = "Subject deleted successfully."; + } catch (PDOException $e) { + $error = "Error deleting subject: " . $e->getMessage(); + } +} + +// Handle POST request to add or update a subject +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['subject_name'])) { + $subjectName = trim($_POST['subject_name']); + $has_double_lesson = isset($_POST['has_double_lesson']) ? 1 : 0; + $elective_group = !empty($_POST['elective_group']) ? trim($_POST['elective_group']) : null; + $subject_id = $_POST['subject_id'] ?? null; + + if (empty($subjectName)) { + $error = 'Subject name cannot be empty.'; + } else { + try { + if ($subject_id) { + // Update existing subject + $stmt = $pdo->prepare("UPDATE subjects SET name = ?, has_double_lesson = ?, elective_group = ? WHERE id = ?"); + $stmt->execute([$subjectName, $has_double_lesson, $elective_group, $subject_id]); + $message = "Subject updated successfully!"; + } else { + // Insert new subject + $stmt = $pdo->prepare("INSERT INTO subjects (name, has_double_lesson, elective_group) VALUES (?, ?, ?)"); + $stmt->execute([$subjectName, $has_double_lesson, $elective_group]); + $message = "Subject created successfully!"; + } + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + $error = "Error: Subject '" . htmlspecialchars($subjectName) . "' already exists."; + } else { + $error = 'Database error: ' . $e->getMessage(); + } + } + } +} + +// Handle Edit request +if (isset($_GET['edit_id'])) { + try { + $edit_id = $_GET['edit_id']; + $stmt = $pdo->prepare("SELECT * FROM subjects WHERE id = ?"); + $stmt->execute([$edit_id]); + $editing_subject = $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + $error = "Error fetching subject: " . $e->getMessage(); + } +} + +// Fetch all subjects to display +$subjects = []; +try { + $subjects_stmt = $pdo->query("SELECT * FROM subjects ORDER BY created_at DESC"); + $subjects = $subjects_stmt->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + $error = 'Database error: ' . $e->getMessage(); +} + +?> + + + + + + Admin: Manage Subjects - Haki Schedule + + + + + + + +
+
+
+

Manage Subjects

+ + +
+ + +
+ + + +
+
+
+
+ +
+
+ + +
+
+ + +
+
+
+ > + +
+ + + Cancel Edit + +
+
+
+ + +
+
+
Existing Subjects
+ +

No subjects have been created yet.

+ +
+ + + + + + + + + + + + + + + + + + + +
NameDouble LessonElective GroupActions
+ Edit +
+ + +
+
+
+ +
+
+ +
+
+
+ + + + + + diff --git a/admin_teachers.php b/admin_teachers.php new file mode 100644 index 0000000..01a3607 --- /dev/null +++ b/admin_teachers.php @@ -0,0 +1,156 @@ +prepare("INSERT INTO teachers (name, email) VALUES (?, ?)"); + if ($stmt->execute([$teacherName, $teacherEmail])) { + $message = 'Teacher "' . htmlspecialchars($teacherName) . '" created successfully!'; + } else { + $error = 'Failed to create teacher.'; + } + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + $error = 'Error: A teacher with the email "' . htmlspecialchars($teacherEmail) . '" already exists.'; + } else { + $error = 'Database error: ' . $e->getMessage(); + } + } + } +} + +// Fetch all teachers to display +$teachers = []; +try { + $pdo = db(); + $stmt = $pdo->query("SELECT id, name, email, created_at FROM teachers ORDER BY created_at DESC"); + $teachers = $stmt->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + $error = 'Database error: ' . $e->getMessage(); +} + +?> + + + + + + Admin: Manage Teachers - Haki Schedule + + + + + + + +
+
+
+

Manage Teachers

+ + +
+ + +
+ + + +
+
+
Create a New Teacher
+
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+
Existing Teachers
+ +

No teachers have been created yet. Use the form above to add the first one.

+ +
    + +
  • +
    +
    + +
    + Created: +
  • + +
+ +
+
+ +
+
+
+ + + + + + diff --git a/admin_workloads.php b/admin_workloads.php new file mode 100644 index 0000000..96721ab --- /dev/null +++ b/admin_workloads.php @@ -0,0 +1,232 @@ +prepare("DELETE FROM workloads WHERE id = ?"); + if ($stmt->execute([$_POST['delete_id']])) { + $message = 'Workload deleted successfully!'; + } else { + $error = 'Failed to delete workload.'; + } + } catch (PDOException $e) { + $error = 'Database error: ' . $e->getMessage(); + } +} +// Handle POST request to add or update a workload +elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { + $workload_id = $_POST['workload_id'] ?? null; + $class_id = $_POST['class_id'] ?? null; + $subject_id = $_POST['subject_id'] ?? null; + $teacher_id = $_POST['teacher_id'] ?? null; + $lessons_per_week = $_POST['lessons_per_week'] ?? null; + + if (empty($class_id) || empty($subject_id) || empty($teacher_id) || empty($lessons_per_week)) { + $error = 'All fields are required.'; + } elseif (!filter_var($lessons_per_week, FILTER_VALIDATE_INT, ["options" => ["min_range" => 1]])) { + $error = 'Lessons per week must be a positive number.'; + } else { + try { + if ($workload_id) { // Update + $stmt = $pdo->prepare("UPDATE workloads SET class_id = ?, subject_id = ?, teacher_id = ?, lessons_per_week = ? WHERE id = ?"); + if ($stmt->execute([$class_id, $subject_id, $teacher_id, $lessons_per_week, $workload_id])) { + $message = 'Workload updated successfully!'; + } else { + $error = 'Failed to update workload.'; + } + } else { // Insert + $stmt = $pdo->prepare("INSERT INTO workloads (class_id, subject_id, teacher_id, lessons_per_week) VALUES (?, ?, ?, ?)"); + if ($stmt->execute([$class_id, $subject_id, $teacher_id, $lessons_per_week])) { + $message = 'Workload created successfully!'; + } else { + $error = 'Failed to create workload.'; + } + } + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { + $error = 'Error: This workload assignment (Class, Subject, Teacher) already exists.'; + } else { + $error = 'Database error: ' . $e->getMessage(); + } + } + } +} + +// Handle Edit request (fetch workload to edit) +if (isset($_GET['edit_id'])) { + try { + $stmt = $pdo->prepare("SELECT * FROM workloads WHERE id = ?"); + $stmt->execute([$_GET['edit_id']]); + $edit_workload = $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + $error = 'Database error: ' . $e->getMessage(); + } +} + +// Fetch related data for dropdowns +try { + $classes = $pdo->query("SELECT id, name FROM classes ORDER BY name")->fetchAll(PDO::FETCH_ASSOC); + $subjects = $pdo->query("SELECT id, name FROM subjects ORDER BY name")->fetchAll(PDO::FETCH_ASSOC); + $teachers = $pdo->query("SELECT id, name FROM teachers ORDER BY name")->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + $error = 'Database error while fetching data: ' . $e->getMessage(); +} + +// Fetch all workloads to display +$workloads = []; +try { + $workloads_stmt = $pdo->query(" + SELECT w.id, c.name as class_name, s.name as subject_name, t.name as teacher_name, w.lessons_per_week, w.created_at, w.class_id, w.subject_id, w.teacher_id + FROM workloads w + JOIN classes c ON w.class_id = c.id + JOIN subjects s ON w.subject_id = s.id + JOIN teachers t ON w.teacher_id = t.id + ORDER BY w.created_at DESC + "); + $workloads = $workloads_stmt->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + $error = 'Database error while fetching workloads: ' . $e->getMessage(); +} + +?> + + + + + + Admin: Manage Workloads - Haki Schedule + + + + + + + + +
+
+
+

Manage Workloads

+ +
+
+ +
+
+
+
+ +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + + Cancel Edit + +
+
+
+ +
+
+
Existing Workloads
+
+ + + + + + + + + + + + + +
ClassSubjectTeacherLessons/WeekActions
+ +
+ + +
+
+
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css index 8e885df..8717987 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -153,3 +153,52 @@ body { display: none !important; } } + +/* New Timetable Styles */ +.timetable-table { + border-collapse: separate; + border-spacing: 5px; +} + +.time-col { + width: 100px; + font-weight: bold; + vertical-align: middle; +} + +.timetable-cell-container { + padding: 2px !important; + background-color: #F9FAFB; +} + +.timetable-cell { + border-radius: 8px; + padding: 12px 8px; + color: #111827; + height: 100%; + min-height: 80px; + display: flex; + flex-direction: column; + justify-content: center; + transition: transform 0.2s, box-shadow 0.2s; +} + +.timetable-cell:hover { + transform: translateY(-3px); + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +.subject-name { + font-weight: bold; + font-size: 0.9rem; +} + +.teacher-name { + font-size: 0.8rem; + opacity: 0.8; +} + +.break-cell { + background-color: #F3F4F6; + border-radius: 8px; +} diff --git a/db/migrate.php b/db/migrate.php new file mode 100644 index 0000000..501fb9d --- /dev/null +++ b/db/migrate.php @@ -0,0 +1,41 @@ +exec($sql); + } + + echo "Migrations completed successfully.\n"; + +} catch (PDOException $e) { + http_response_code(500); + die("Migration failed: " . $e->getMessage() . "\n"); +} catch (Exception $e) { + http_response_code(500); + die("An error occurred: " . $e->getMessage() . "\n"); +} + diff --git a/db/migrations/001_create_classes_table.sql b/db/migrations/001_create_classes_table.sql new file mode 100644 index 0000000..b8f96b3 --- /dev/null +++ b/db/migrations/001_create_classes_table.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS classes ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + school_id INT UNSIGNED DEFAULT 1, -- For future multi-tenancy + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=INNODB; diff --git a/db/migrations/002_create_subjects_table.sql b/db/migrations/002_create_subjects_table.sql new file mode 100644 index 0000000..14357f6 --- /dev/null +++ b/db/migrations/002_create_subjects_table.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS subjects ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/db/migrations/003_create_teachers_table.sql b/db/migrations/003_create_teachers_table.sql new file mode 100644 index 0000000..1ab5fa6 --- /dev/null +++ b/db/migrations/003_create_teachers_table.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS teachers ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + email VARCHAR(255) NOT NULL UNIQUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/db/migrations/004_create_workloads_table.sql b/db/migrations/004_create_workloads_table.sql new file mode 100644 index 0000000..be1f1ed --- /dev/null +++ b/db/migrations/004_create_workloads_table.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS workloads ( + id INT AUTO_INCREMENT PRIMARY KEY, + class_id INT NOT NULL, + subject_id INT NOT NULL, + teacher_id INT NOT NULL, + lessons_per_week INT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE CASCADE, + FOREIGN KEY (subject_id) REFERENCES subjects(id) ON DELETE CASCADE, + FOREIGN KEY (teacher_id) REFERENCES teachers(id) ON DELETE CASCADE, + UNIQUE KEY (class_id, subject_id, teacher_id) +); diff --git a/db/migrations/005_create_users_table.sql b/db/migrations/005_create_users_table.sql new file mode 100644 index 0000000..d7f4f66 --- /dev/null +++ b/db/migrations/005_create_users_table.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS users ( + id INT AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(255) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + role VARCHAR(50) NOT NULL DEFAULT 'admin', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=INNODB; diff --git a/db/migrations/006_add_subject_options.sql b/db/migrations/006_add_subject_options.sql new file mode 100644 index 0000000..77a3cf7 --- /dev/null +++ b/db/migrations/006_add_subject_options.sql @@ -0,0 +1,3 @@ +ALTER TABLE `subjects` +ADD COLUMN `has_double_lesson` BOOLEAN NOT NULL DEFAULT FALSE, +ADD COLUMN `elective_group` VARCHAR(255) NULL; diff --git a/demo.php b/demo.php index d130014..40452d2 100644 --- a/demo.php +++ b/demo.php @@ -16,92 +16,146 @@ - + -
-
-
-
-

Class Timetable: Grade 10A

-

A visual demonstration of a generated schedule.

-
-
- Back to Home - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Day08:00 - 09:0009:00 - 10:0010:00 - 10:3010:30 - 11:3011:30 - 12:3012:30 - 13:3013:30 - 14:30
MondayMathematicsMr. SmithPhysicsMs. JonesBreakEnglishMr. DoeHistoryMrs. DaneLunchBiologyMs. Jones
TuesdayChemistryMr. WhiteEnglishMr. DoeBreakMathematicsMr. SmithGeographyMr. GreenLunchArtMs. Black
WednesdayPhysics (Double)Ms. JonesPhysics (Double)Ms. JonesBreakHistoryMrs. DaneMathematicsMr. SmithLunchMusicMr. Brown
ThursdayEnglishMr. DoeBiologyMs. JonesBreakChemistryMr. WhitePhysical Ed.Mr. BlueLunchMathematicsMr. Smith
FridayHistoryMrs. DaneGeographyMr. GreenBreakEnglishMr. DoeMathematicsMr. SmithLunchElectiveVarious
+
+ + +
+
+
+
+
+

Class Timetable: Grade 10A

+

A visual demonstration of a generated schedule.

+
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Day08:00 - 09:0009:00 - 10:0010:00 - 10:3010:30 - 11:3011:30 - 12:3012:30 - 13:3013:30 - 14:30
MondayMathematicsMr. SmithPhysicsMs. JonesBreakEnglishMr. DoeHistoryMrs. DaneLunchBiologyMs. Jones
TuesdayChemistryMr. WhiteEnglishMr. DoeBreakMathematicsMr. SmithGeographyMr. GreenLunchArtMs. Black
WednesdayPhysics (Double)Ms. JonesPhysics (Double)Ms. JonesBreakHistoryMrs. DaneMathematicsMr. SmithLunchMusicMr. Brown
ThursdayEnglishMr. DoeBiologyMs. JonesBreakChemistryMr. WhitePhysical Ed.Mr. BlueLunchMathematicsMr. Smith
FridayHistoryMrs. DaneGeographyMr. GreenBreakEnglishMr. DoeMathematicsMr. SmithLunchElectiveVarious
+
+
+
+
+ +
+
+

© Haki Schedule. All Rights Reserved.

+
+
- + \ No newline at end of file diff --git a/includes/auth_check.php b/includes/auth_check.php new file mode 100644 index 0000000..404e4b0 --- /dev/null +++ b/includes/auth_check.php @@ -0,0 +1,8 @@ + - Haki Schedule - - - - - - - - + Haki Schedule - Automated Timetable Generator + + - -