Creating user roles version

This commit is contained in:
Flatlogic Bot 2025-11-26 07:02:50 +00:00
parent 851b3613d1
commit 4db23e4317
28 changed files with 813 additions and 154 deletions

View File

@ -4,6 +4,7 @@ require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$school_id = $_SESSION['school_id'];
// Handle POST request to add a new class
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['class_name'])) {
@ -13,8 +14,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['class_name'])) {
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO classes (name) VALUES (?)");
if ($stmt->execute([$className])) {
$stmt = $pdo->prepare("INSERT INTO classes (name, school_id) VALUES (?, ?)");
if ($stmt->execute([$className, $school_id])) {
$message = "Class '" . htmlspecialchars($className) . "' created successfully!";
} else {
$error = 'Failed to create class.';
@ -33,7 +34,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['class_name'])) {
$classes = [];
try {
$pdo = db();
$classes_stmt = $pdo->query("SELECT id, name, created_at FROM classes ORDER BY created_at DESC");
$classes_stmt = $pdo->prepare("SELECT id, name, created_at FROM classes WHERE school_id = ? ORDER BY created_at DESC");
$classes_stmt->execute([$school_id]);
$classes = $classes_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
@ -147,4 +149,4 @@ try {
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</html>

134
admin_edit_teacher.php Normal file
View File

@ -0,0 +1,134 @@
<?php
require_once __DIR__ . '/includes/auth_check.php';
require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$teacher = null;
$school_id = $_SESSION['school_id'];
if (!isset($_GET['id'])) {
header("Location: admin_teachers.php");
exit;
}
$teacher_id = $_GET['id'];
$pdo = db();
// Handle POST request to update teacher
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$can_edit_workload = isset($_POST['can_edit_workload']) ? 1 : 0;
try {
$stmt = $pdo->prepare("UPDATE teachers SET can_edit_workload = ? WHERE id = ? AND school_id = ?");
if ($stmt->execute([$can_edit_workload, $teacher_id, $school_id])) {
$message = 'Teacher updated successfully!';
} else {
$error = 'Failed to update teacher.';
}
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
}
}
// Fetch teacher data
try {
$stmt = $pdo->prepare("SELECT t.id, t.name, u.email, t.can_edit_workload FROM teachers t JOIN users u ON t.user_id = u.id WHERE t.id = ? AND t.school_id = ?");
$stmt->execute([$teacher_id, $school_id]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$teacher) {
header("Location: admin_teachers.php?error=not_found");
exit;
}
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin: Edit Teacher - Haki Schedule</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top shadow-sm">
<div class="container">
<a class="navbar-brand fw-bold" href="/">Haki Schedule</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle active" href="#" id="manageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Manage
</a>
<ul class="dropdown-menu" aria-labelledby="manageDropdown">
<li><a class="dropdown-item" href="/admin_classes.php">Classes</a></li>
<li><a class="dropdown-item" href="/admin_subjects.php">Subjects</a></li>
<li><a class="dropdown-item active" href="/admin_teachers.php">Teachers</a></li>
<li><a class="dropdown-item" href="/admin_workloads.php">Workloads</a></li>
<li><a class="dropdown-item" href="/admin_timeslots.php">Timeslots</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="/timetable.php">Class Timetable</a></li>
<li class="nav-item"><a class="nav-link" href="/teacher_timetable.php">Teacher Timetable</a></li>
<li class="nav-item"><a class="nav-link" href="/logout.php">Logout</a></li>
</ul>
</div>
</div>
</nav>
<main class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<h1 class="h2 fw-bold mb-4">Edit Teacher</h1>
<?php if ($message): ?>
<div class="alert alert-success"><?php echo $message; ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<form action="admin_edit_teacher.php?id=<?php echo $teacher['id']; ?>" method="POST">
<div class="mb-3">
<label for="teacher_name" class="form-label">Teacher Name</label>
<input type="text" class="form-control" id="teacher_name" name="teacher_name" value="<?php echo htmlspecialchars($teacher['name']); ?>" readonly>
</div>
<div class="mb-3">
<label for="teacher_email" class="form-label">Teacher Email</label>
<input type="email" class="form-control" id="teacher_email" name="teacher_email" value="<?php echo htmlspecialchars($teacher['email']); ?>" readonly>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="can_edit_workload" name="can_edit_workload" value="1" <?php echo $teacher['can_edit_workload'] ? 'checked' : ''; ?>>
<label class="form-check-label" for="can_edit_workload">Can edit their own workload</label>
</div>
<button type="submit" class="btn btn-primary">Update Teacher</button>
<a href="admin_teachers.php" class="btn btn-secondary">Back to Teachers</a>
</form>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white py-4 mt-5">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Haki Schedule. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -5,6 +5,7 @@ require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$editing_subject = null;
$school_id = $_SESSION['school_id'];
$pdo = db();
@ -12,8 +13,8 @@ $pdo = db();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
try {
$delete_id = $_POST['delete_id'];
$stmt = $pdo->prepare("DELETE FROM subjects WHERE id = ?");
$stmt->execute([$delete_id]);
$stmt = $pdo->prepare("DELETE FROM subjects WHERE id = ? AND school_id = ?");
$stmt->execute([$delete_id, $school_id]);
$message = "Subject deleted successfully.";
} catch (PDOException $e) {
$error = "Error deleting subject: " . $e->getMessage();
@ -24,7 +25,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
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;
$is_elective = isset($_POST['is_elective']) ? 1 : 0;
$subject_id = $_POST['subject_id'] ?? null;
if (empty($subjectName)) {
@ -33,13 +34,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['subject_name'])) {
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]);
$stmt = $pdo->prepare("UPDATE subjects SET name = ?, has_double_lesson = ?, is_elective = ? WHERE id = ? AND school_id = ?");
$stmt->execute([$subjectName, $has_double_lesson, $is_elective, $subject_id, $school_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]);
$stmt = $pdo->prepare("INSERT INTO subjects (name, has_double_lesson, is_elective, school_id) VALUES (?, ?, ?, ?)");
$stmt->execute([$subjectName, $has_double_lesson, $is_elective, $school_id]);
$message = "Subject created successfully!";
}
} catch (PDOException $e) {
@ -56,8 +57,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['subject_name'])) {
if (isset($_GET['edit_id'])) {
try {
$edit_id = $_GET['edit_id'];
$stmt = $pdo->prepare("SELECT * FROM subjects WHERE id = ?");
$stmt->execute([$edit_id]);
$stmt = $pdo->prepare("SELECT * FROM subjects WHERE id = ? AND school_id = ?");
$stmt->execute([$edit_id, $school_id]);
$editing_subject = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = "Error fetching subject: " . $e->getMessage();
@ -67,7 +68,8 @@ if (isset($_GET['edit_id'])) {
// Fetch all subjects to display
$subjects = [];
try {
$subjects_stmt = $pdo->query("SELECT * FROM subjects ORDER BY created_at DESC");
$subjects_stmt = $pdo->prepare("SELECT * FROM subjects WHERE school_id = ? ORDER BY name ASC");
$subjects_stmt->execute([$school_id]);
$subjects = $subjects_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
@ -143,15 +145,15 @@ try {
<label for="subject_name" class="form-label">Subject Name</label>
<input type="text" class="form-control" id="subject_name" name="subject_name" value="<?php echo htmlspecialchars($editing_subject['name'] ?? ''); ?>" placeholder="e.g., Mathematics" required>
</div>
<div class="col-md-6 mb-3">
<label for="elective_group" class="form-label">Elective Group (Optional)</label>
<input type="text" class="form-control" id="elective_group" name="elective_group" value="<?php echo htmlspecialchars($editing_subject['elective_group'] ?? ''); ?>" placeholder="e.g., Languages">
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="has_double_lesson" name="has_double_lesson" value="1" <?php echo !empty($editing_subject['has_double_lesson']) ? 'checked' : ''; ?>>
<label class="form-check-label" for="has_double_lesson">Has one double lesson per week</label>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="is_elective" name="is_elective" value="1" <?php echo !empty($editing_subject['is_elective']) ? 'checked' : ''; ?>>
<label class="form-check-label" for="is_elective">Is Elective</label>
</div>
<button type="submit" class="btn btn-primary"><?php echo $editing_subject ? 'Update Subject' : 'Create Subject'; ?></button>
<?php if ($editing_subject): ?>
<a href="admin_subjects.php" class="btn btn-secondary">Cancel Edit</a>
@ -173,7 +175,7 @@ try {
<tr>
<th>Name</th>
<th>Double Lesson</th>
<th>Elective Group</th>
<th>Is Elective</th>
<th>Actions</th>
</tr>
</thead>
@ -182,7 +184,7 @@ try {
<tr>
<td><?php echo htmlspecialchars($subject['name']); ?></td>
<td><?php echo $subject['has_double_lesson'] ? 'Yes' : 'No'; ?></td>
<td><?php echo htmlspecialchars($subject['elective_group'] ?? 'N/A'); ?></td>
<td><?php echo $subject['is_elective'] ? 'Yes' : 'No'; ?></td>
<td>
<a href="?edit_id=<?php echo $subject['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a>
<form action="admin_subjects.php" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this subject?');">
@ -211,4 +213,4 @@ try {
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</html>

View File

@ -4,11 +4,13 @@ require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$school_id = $_SESSION['school_id'];
// Handle POST request to add a new teacher
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$teacherName = trim($_POST['teacher_name'] ?? '');
$teacherEmail = trim($_POST['teacher_email'] ?? '');
$can_edit_workload = isset($_POST['can_edit_workload']) ? 1 : 0;
if (empty($teacherName) || empty($teacherEmail)) {
$error = 'Teacher name and email cannot be empty.';
@ -17,18 +19,43 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO teachers (name, email) VALUES (?, ?)");
if ($stmt->execute([$teacherName, $teacherEmail])) {
$message = 'Teacher "' . htmlspecialchars($teacherName) . '" created successfully!';
$pdo->beginTransaction();
// Check if user with this email already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$teacherEmail]);
if ($stmt->fetch()) {
$error = 'A user with this email already exists.';
$pdo->rollBack();
} else {
$error = 'Failed to create teacher.';
// Generate a random password
$password = bin2hex(random_bytes(8));
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// Create a user account for the teacher
$stmt = $pdo->prepare("INSERT INTO users (username, password, email, school_id, role) VALUES (?, ?, ?, ?, 'teacher')");
$stmt->execute([$teacherEmail, $hashed_password, $teacherEmail, $school_id]);
$user_id = $pdo->lastInsertId();
// Create the teacher
$stmt = $pdo->prepare("INSERT INTO teachers (name, user_id, school_id, can_edit_workload) VALUES (?, ?, ?, ?)");
if ($stmt->execute([$teacherName, $user_id, $school_id, $can_edit_workload])) {
$pdo->commit();
$message = 'Teacher "' . htmlspecialchars($teacherName) . '" created successfully! Their password is: ' . $password;
} else {
$error = 'Failed to create teacher.';
$pdo->rollBack();
}
}
} catch (PDOException $e) {
if ($e->errorInfo[1] == 1062) { // Duplicate entry
$error = 'Error: A teacher with the email "' . htmlspecialchars($teacherEmail) . '" already exists.';
$error = 'Error: A teacher with this email already exists.';
} else {
$error = 'Database error: ' . $e->getMessage();
}
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
}
}
}
@ -37,7 +64,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$teachers = [];
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, name, email, created_at FROM teachers ORDER BY created_at DESC");
$stmt = $pdo->prepare("SELECT t.id, t.name, u.email, t.can_edit_workload, t.created_at FROM teachers t JOIN users u ON t.user_id = u.id WHERE t.school_id = ? ORDER BY t.created_at DESC");
$stmt->execute([$school_id]);
$teachers = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
@ -115,6 +143,10 @@ try {
<label for="teacher_email" class="form-label">Teacher Email</label>
<input type="email" class="form-control" id="teacher_email" name="teacher_email" placeholder="e.g., john.doe@example.com" required>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="can_edit_workload" name="can_edit_workload" value="1">
<label class="form-check-label" for="can_edit_workload">Can edit their own workload</label>
</div>
<button type="submit" class="btn btn-primary">Create Teacher</button>
</form>
</div>
@ -128,17 +160,30 @@ try {
<p class="text-muted">No teachers have been created yet. Use the form above to add the first one.</p>
<?php else:
if(!empty($teachers)) : ?>
<ul class="list-group list-group-flush">
<?php foreach ($teachers as $teacher): ?>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<strong><?php echo htmlspecialchars($teacher['name']); ?></strong><br>
<small class="text-muted"><?php echo htmlspecialchars($teacher['email']); ?></small>
</div>
<small class="text-muted">Created: <?php echo date("M j, Y", strtotime($teacher['created_at'])); ?></small>
</li>
<?php endforeach; ?>
</ul>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Can Edit Workload</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($teachers as $teacher): ?>
<tr>
<td><?php echo htmlspecialchars($teacher['name']); ?></td>
<td><?php echo htmlspecialchars($teacher['email']); ?></td>
<td><?php echo $teacher['can_edit_workload'] ? 'Yes' : 'No'; ?></td>
<td><?php echo date("M j, Y", strtotime($teacher['created_at'])); ?></td>
<td><a href="admin_edit_teacher.php?id=<?php echo $teacher['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; endif; ?>
</div>
</div>
@ -155,4 +200,4 @@ try {
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</html>

View File

@ -6,12 +6,13 @@ $message = '';
$error = '';
$pdo = db();
$edit_workload = null;
$school_id = $_SESSION['school_id'];
// Handle Delete request
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
try {
$stmt = $pdo->prepare("DELETE FROM workloads WHERE id = ?");
if ($stmt->execute([$_POST['delete_id']])) {
$stmt = $pdo->prepare("DELETE FROM workloads WHERE id = ? AND school_id = ?");
if ($stmt->execute([$_POST['delete_id'], $school_id])) {
$message = 'Workload deleted successfully!';
} else {
$error = 'Failed to delete workload.';
@ -35,15 +36,15 @@ elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
} 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])) {
$stmt = $pdo->prepare("UPDATE workloads SET class_id = ?, subject_id = ?, teacher_id = ?, lessons_per_week = ? WHERE id = ? AND school_id = ?");
if ($stmt->execute([$class_id, $subject_id, $teacher_id, $lessons_per_week, $workload_id, $school_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])) {
$stmt = $pdo->prepare("INSERT INTO workloads (class_id, subject_id, teacher_id, lessons_per_week, school_id) VALUES (?, ?, ?, ?, ?)");
if ($stmt->execute([$class_id, $subject_id, $teacher_id, $lessons_per_week, $school_id])) {
$message = 'Workload created successfully!';
} else {
$error = 'Failed to create workload.';
@ -62,8 +63,8 @@ elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 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']]);
$stmt = $pdo->prepare("SELECT * FROM workloads WHERE id = ? AND school_id = ?");
$stmt->execute([$_GET['edit_id'], $school_id]);
$edit_workload = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
@ -72,9 +73,17 @@ if (isset($_GET['edit_id'])) {
// 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);
$classes_stmt = $pdo->prepare("SELECT id, name FROM classes WHERE school_id = ? ORDER BY name");
$classes_stmt->execute([$school_id]);
$classes = $classes_stmt->fetchAll(PDO::FETCH_ASSOC);
$subjects_stmt = $pdo->prepare("SELECT id, name FROM subjects WHERE school_id = ? ORDER BY name");
$subjects_stmt->execute([$school_id]);
$subjects = $subjects_stmt->fetchAll(PDO::FETCH_ASSOC);
$teachers_stmt = $pdo->prepare("SELECT id, name FROM teachers WHERE school_id = ? ORDER BY name");
$teachers_stmt->execute([$school_id]);
$teachers = $teachers_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error while fetching data: ' . $e->getMessage();
}
@ -82,14 +91,16 @@ try {
// Fetch all workloads to display
$workloads = [];
try {
$workloads_stmt = $pdo->query("
$workloads_stmt = $pdo->prepare("
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
WHERE w.school_id = ?
ORDER BY w.created_at DESC
");
$workloads_stmt->execute([$school_id]);
$workloads = $workloads_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error while fetching workloads: ' . $e->getMessage();
@ -126,7 +137,7 @@ try {
<li><a class="dropdown-item" href="/admin_classes.php">Classes</a></li>
<li><a class="dropdown-item" href="/admin_subjects.php">Subjects</a></li>
<li><a class="dropdown-item" href="/admin_teachers.php">Teachers</a></li>
<li><a class="dropdown-item" href="/admin_workloads.php">Workloads</a></li>
<li><a class="dropdown-item active" href="/admin_workloads.php">Workloads</a></li>
<li><a class="dropdown-item" href="/admin_timeslots.php">Timeslots</a></li>
</ul>
</li>
@ -231,4 +242,4 @@ try {
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</html>

81
dashboard.php Normal file
View File

@ -0,0 +1,81 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
require_once __DIR__ . '/db/config.php';
$role = $_SESSION['role'] ?? 'teacher';
$user_id = $_SESSION['user_id'];
$can_edit_workload = false;
if ($role === 'teacher') {
$pdo = db();
$stmt = $pdo->prepare("SELECT can_edit_workload FROM teachers WHERE user_id = ?");
$stmt->execute([$user_id]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
if ($teacher && $teacher['can_edit_workload']) {
$can_edit_workload = true;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - Haki Schedule</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top shadow-sm">
<div class="container">
<a class="navbar-brand fw-bold" href="dashboard.php">Haki Schedule</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<?php if ($role === 'admin'): ?>
<li class="nav-item"><a class="nav-link" href="admin_classes.php">Classes</a></li>
<li class="nav-item"><a class="nav-link" href="admin_subjects.php">Subjects</a></li>
<li class="nav-item"><a class="nav-link" href="admin_teachers.php">Teachers</a></li>
<li class="nav-item"><a class="nav-link" href="admin_workloads.php">Workloads</a></li>
<li class="nav-item"><a class="nav-link" href="admin_timeslots.php">Timeslots</a></li>
<li class="nav-item"><a class="nav-link" href="timetable.php">Class Timetable</a></li>
<li class="nav-item"><a class="nav-link" href="teacher_timetable.php">Teacher Timetable</a></li>
<?php else: ?>
<li class="nav-item"><a class="nav-link" href="teacher_timetable.php">My Timetable</a></li>
<?php if ($can_edit_workload): ?>
<li class="nav-item"><a class="nav-link" href="teacher_workload.php">My Workload</a></li>
<?php endif; ?>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
</ul>
</div>
</div>
</nav>
<main class="container py-5">
<h1 class="h3 fw-bold">Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?>!</h1>
<p>You are logged in as a <?php echo htmlspecialchars($role); ?>.</p>
<?php if ($role === 'admin'): ?>
<p>You can manage the school's data using the links in the navigation.</p>
<?php else: ?>
<p>You can view your timetable using the link in the navigation.</p>
<?php if ($can_edit_workload): ?>
<p>You can also <a href="teacher_workload.php">manage your workload</a>.</p>
<?php endif; ?>
<?php endif; ?>
</main>
<footer class="bg-dark text-white py-4 mt-5"><div class="container text-center"><p>&copy; <?php echo date("Y"); ?> Haki Schedule. All Rights Reserved.</p></div></footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -4,17 +4,22 @@ require_once __DIR__ . '/config.php';
try {
$pdo = db();
// Check if PDO connection is valid
if (!$pdo) {
throw new Exception("PDO connection is not valid. Check db/config.php");
}
// Create migrations table if it doesn't exist
$pdo->exec("CREATE TABLE IF NOT EXISTS `migrations` (
`migration` VARCHAR(255) NOT NULL,
PRIMARY KEY (`migration`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
// Get all migration files
$migrationsDir = __DIR__ . '/migrations';
if (!is_dir($migrationsDir)) {
echo "No migrations directory found. Nothing to do.\n";
exit(0);
}
$files = glob($migrationsDir . '/*.sql');
sort($files);
@ -23,10 +28,23 @@ try {
exit(0);
}
// Get already run migrations
$stmt = $pdo->query("SELECT `migration` FROM `migrations`");
$runMigrations = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach ($files as $file) {
echo "Running migration: " . basename($file) . "\n";
$migrationName = basename($file);
if (in_array($migrationName, $runMigrations)) {
continue; // Skip already run migration
}
echo "Running migration: " . $migrationName . "\n";
$sql = file_get_contents($file);
$pdo->exec($sql);
// Record the migration
$stmt = $pdo->prepare("INSERT INTO `migrations` (`migration`) VALUES (?)");
$stmt->execute([$migrationName]);
}
echo "Migrations completed successfully.\n";
@ -37,5 +55,4 @@ try {
} catch (Exception $e) {
http_response_code(500);
die("An error occurred: " . $e->getMessage() . "\n");
}
}

View File

@ -1,6 +0,0 @@
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;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS `schools` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,5 +0,0 @@
CREATE TABLE IF NOT EXISTS subjects (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`school_id` INT,
`role` VARCHAR(255) NOT NULL DEFAULT 'teacher',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
CONSTRAINT `fk_users_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS `classes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`school_id` INT,
PRIMARY KEY (`id`),
CONSTRAINT `fk_classes_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,6 +0,0 @@
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
);

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS `subjects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`is_elective` tinyint(1) DEFAULT '0',
`has_double_lesson` tinyint(1) DEFAULT '0',
`school_id` INT,
PRIMARY KEY (`id`),
CONSTRAINT `fk_subjects_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,12 +0,0 @@
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)
);

View File

@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS `teachers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`school_id` INT,
`user_id` INT,
`can_edit_workload` BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (`id`),
CONSTRAINT `fk_teachers_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_teachers_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,7 +0,0 @@
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;

View File

@ -1,3 +0,0 @@
ALTER TABLE `subjects`
ADD COLUMN `has_double_lesson` BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN `elective_group` VARCHAR(255) NULL;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS `workloads` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`teacher_id` int(11) NOT NULL,
`subject_id` int(11) NOT NULL,
`class_id` int(11) NOT NULL,
`lessons_per_week` int(11) NOT NULL,
`school_id` INT,
PRIMARY KEY (`id`),
KEY `teacher_id` (`teacher_id`),
KEY `subject_id` (`subject_id`),
KEY `class_id` (`class_id`),
CONSTRAINT `workloads_ibfk_1` FOREIGN KEY (`teacher_id`) REFERENCES `teachers` (`id`),
CONSTRAINT `workloads_ibfk_2` FOREIGN KEY (`subject_id`) REFERENCES `subjects` (`id`),
CONSTRAINT `workloads_ibfk_3` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id`),
CONSTRAINT `fk_workloads_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,7 +1,7 @@
CREATE TABLE IF NOT EXISTS timeslots (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
is_break BOOLEAN NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS `timeslots` (
`id` INT NOT NULL AUTO_INCREMENT,
`day_of_week` VARCHAR(20) NOT NULL,
`start_time` TIME NOT NULL,
`end_time` TIME NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,18 +1,15 @@
CREATE TABLE IF NOT EXISTS `schedules` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`class_id` INT NOT NULL,
`day_of_week` INT NOT NULL,
`timeslot_id` INT NOT NULL,
`subject_id` INT,
`teacher_id` INT,
`lesson_display_name` VARCHAR(255) NOT NULL,
`teacher_display_name` VARCHAR(255) NOT NULL,
`is_double` BOOLEAN DEFAULT FALSE,
`is_elective` BOOLEAN DEFAULT FALSE,
`is_horizontal_elective` BOOLEAN DEFAULT FALSE,
UNIQUE KEY `unique_schedule_entry` (`class_id`, `day_of_week`, `timeslot_id`),
FOREIGN KEY (`class_id`) REFERENCES `classes`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`timeslot_id`) REFERENCES `timeslots`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`id`) ON DELETE SET NULL,
FOREIGN KEY (`teacher_id`) REFERENCES `teachers`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`id` INT NOT NULL AUTO_INCREMENT,
`class_id` INT NOT NULL,
`timeslot_id` INT NOT NULL,
`teacher_id` INT,
`subject_id` INT,
`subject_name_override` VARCHAR(255),
`school_id` INT,
PRIMARY KEY (`id`),
FOREIGN KEY (`class_id`) REFERENCES `classes`(`id`),
FOREIGN KEY (`timeslot_id`) REFERENCES `timeslots`(`id`),
FOREIGN KEY (`teacher_id`) REFERENCES `teachers`(`id`),
FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`id`),
CONSTRAINT `fk_schedules_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -0,0 +1,23 @@
-- Add school_id and role to users table
ALTER TABLE `users`
ADD COLUMN `school_id` INT(11) NULL,
ADD COLUMN `role` VARCHAR(50) NOT NULL DEFAULT 'teacher';
-- Add workload_editable to users table
ALTER TABLE `users`
ADD COLUMN `workload_editable` BOOLEAN NOT NULL DEFAULT FALSE;
-- Add school_id to other tables
ALTER TABLE `classes` ADD COLUMN `school_id` INT(11) NULL;
ALTER TABLE `subjects` ADD COLUMN `school_id` INT(11) NULL;
ALTER TABLE `teachers` ADD COLUMN `school_id` INT(11) NULL;
ALTER TABLE `workloads` ADD COLUMN `school_id` INT(11) NULL;
ALTER TABLE `schedules` ADD COLUMN `school_id` INT(11) NULL;
-- Add foreign key constraints
ALTER TABLE `users` ADD CONSTRAINT `fk_users_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;
ALTER TABLE `classes` ADD CONSTRAINT `fk_classes_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;
ALTER TABLE `subjects` ADD CONSTRAINT `fk_subjects_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;
ALTER TABLE `teachers` ADD CONSTRAINT `fk_teachers_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;
ALTER TABLE `workloads` ADD CONSTRAINT `fk_workloads_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;
ALTER TABLE `schedules` ADD CONSTRAINT `fk_schedules_school_id` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE;

View File

@ -0,0 +1,8 @@
<?php
session_start();
// If user is not logged in, redirect to login page
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}

View File

@ -0,0 +1,26 @@
<?php
session_start();
require_once __DIR__ . '/db/config.php';
// If user is not logged in, redirect to login page
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
// Check if user is a teacher and can edit their workload
if ($_SESSION['role'] !== 'teacher') {
header("Location: dashboard.php");
exit;
}
$pdo = db();
$stmt = $pdo->prepare("SELECT can_edit_workload FROM teachers WHERE user_id = ?");
$stmt->execute([$_SESSION['user_id']]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$teacher || !$teacher['can_edit_workload']) {
header("Location: dashboard.php?error=workload_not_editable");
exit;
}

View File

@ -29,9 +29,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
$_SESSION['school_id'] = $user['school_id'];
// Redirect to the main page
header("Location: index.php");
header("Location: dashboard.php");
exit;
} else {
$error = 'Invalid username or password.';
@ -63,7 +64,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<div class="col-lg-5">
<div class="card">
<div class="card-body p-4">
<h1 class="h3 fw-bold text-center mb-4">Admin Login</h1>
<h1 class="h3 fw-bold text-center mb-4">Login</h1>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
@ -93,4 +94,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<footer class="bg-dark text-white py-4 mt-5"><div class="container text-center"><p>&copy; <?php echo date("Y"); ?> Haki Schedule. All Rights Reserved.</p></div></footer>
</body>
</html>
</html>

View File

@ -3,35 +3,68 @@ require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$registration_open = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$pdo = db();
$stmt = $pdo->query("SELECT COUNT(*) FROM schools");
if ($stmt->fetchColumn() == 0) {
$registration_open = true;
}
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
}
if ($registration_open && $_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? null;
$password = $_POST['password'] ?? null;
$school_name = $_POST['school_name'] ?? null;
$email = $_POST['email'] ?? null;
if (empty($username) || empty($password)) {
$error = 'Username and password are required.';
if (empty($username) || empty($password) || empty($school_name) || empty($email)) {
$error = 'All fields are required.';
} else {
try {
$pdo = db();
// Check if username already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$username]);
if ($stmt->fetch()) {
$error = 'Username already taken. Please choose another one.';
} else {
// Hash the password
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$pdo->beginTransaction();
// Insert new user
$stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, 'admin')");
if ($stmt->execute([$username, $hashed_password])) {
$message = 'Registration successful! You can now <a href="login.php">login</a>.';
// Check if school name already exists
$stmt = $pdo->prepare("SELECT id FROM schools WHERE name = ?");
$stmt->execute([$school_name]);
if ($stmt->fetch()) {
$error = 'School name already taken. Please choose another one.';
$pdo->rollBack();
} else {
// Insert new school
$stmt = $pdo->prepare("INSERT INTO schools (name) VALUES (?)");
$stmt->execute([$school_name]);
$school_id = $pdo->lastInsertId();
// Check if username already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$username]);
if ($stmt->fetch()) {
$error = 'Username already taken. Please choose another one.';
$pdo->rollBack();
} else {
$error = 'Failed to register user.';
// Hash the password
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// Insert new user
$stmt = $pdo->prepare("INSERT INTO users (username, password, email, school_id, role) VALUES (?, ?, ?, ?, 'admin')");
if ($stmt->execute([$username, $hashed_password, $email, $school_id])) {
$pdo->commit();
$message = 'Registration successful! You can now <a href="login.php">login</a>.';
} else {
$error = 'Failed to register user.';
$pdo->rollBack();
}
}
}
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
}
}
}
@ -66,11 +99,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<?php if (!$message): ?>
<?php if (!$message && $registration_open): ?>
<form action="register.php" method="POST">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<label for="school_name" class="form-label">School Name</label>
<input type="text" class="form-control" id="school_name" name="school_name" required>
</div>
<div class="mb-3">
<label for="username" class="form-label">Admin Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Admin Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
@ -83,6 +124,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<div class="text-center mt-3">
<p>Already have an account? <a href="login.php">Login here</a>.</p>
</div>
<?php elseif (!$message): ?>
<div class="alert alert-info">
Registration is currently closed. Only one school can be registered.
<p class="mt-3"><a href="login.php" class="btn btn-primary">Go to Login</a></p>
</div>
<?php endif; ?>
</div>
</div>
@ -92,4 +138,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<footer class="bg-dark text-white py-4 mt-5"><div class="container text-center"><p>&copy; <?php echo date("Y"); ?> Haki Schedule. All Rights Reserved.</p></div></footer>
</body>
</html>
</html>

View File

@ -1,18 +1,18 @@
<?php
session_start();
require_once 'includes/auth_check.php';
require_once 'includes/auth_check_teacher.php';
require_once 'db/config.php';
// --- Database Fetch Functions ---
function get_teachers($pdo) {
return $pdo->query("SELECT * FROM teachers ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
function get_teachers($pdo, $school_id) {
return $pdo->prepare("SELECT * FROM teachers WHERE school_id = ? ORDER BY name")->execute([$school_id])->fetchAll(PDO::FETCH_ASSOC);
}
function get_timeslots($pdo) {
return $pdo->query("SELECT * FROM timeslots ORDER BY start_time")->fetchAll(PDO::FETCH_ASSOC);
}
function get_teacher_schedule($pdo, $teacher_id) {
function get_teacher_schedule($pdo, $teacher_id, $school_id) {
$stmt = $pdo->prepare("
SELECT
s.day_of_week,
@ -24,19 +24,41 @@ function get_teacher_schedule($pdo, $teacher_id) {
s.is_horizontal_elective
FROM schedules s
JOIN classes c ON s.class_id = c.id
WHERE s.teacher_id = :teacher_id
WHERE s.teacher_id = :teacher_id AND s.school_id = :school_id
");
$stmt->execute([':teacher_id' => $teacher_id]);
$stmt->execute([':teacher_id' => $teacher_id, ':school_id' => $school_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// --- Main Logic ---
$pdoconn = db();
$teachers = get_teachers($pdoconn);
$school_id = $_SESSION['school_id'];
$role = $_SESSION['role'];
$user_id = $_SESSION['user_id'];
$teachers = [];
if ($role === 'admin') {
$stmt = $pdoconn->prepare("SELECT * FROM teachers WHERE school_id = ? ORDER BY name");
$stmt->execute([$school_id]);
$teachers = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else { // Teacher
$stmt = $pdoconn->prepare("SELECT * FROM teachers WHERE user_id = ? AND school_id = ?");
$stmt->execute([$user_id, $school_id]);
$teachers = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
$timeslots = get_timeslots($pdoconn);
$days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
$selected_teacher_id = isset($_GET['teacher_id']) ? $_GET['teacher_id'] : null;
$selected_teacher_id = null;
if ($role === 'admin') {
$selected_teacher_id = isset($_GET['teacher_id']) ? $_GET['teacher_id'] : null;
} else { // Teacher
if (!empty($teachers)) {
$selected_teacher_id = $teachers[0]['id'];
}
}
$selected_teacher_name = '';
$teacher_schedule_raw = [];
if ($selected_teacher_id) {
@ -46,7 +68,7 @@ if ($selected_teacher_id) {
break;
}
}
$teacher_schedule_raw = get_teacher_schedule($pdoconn, $selected_teacher_id);
$teacher_schedule_raw = get_teacher_schedule($pdoconn, $selected_teacher_id, $school_id);
}
// Organize schedule for easy display
@ -110,6 +132,7 @@ foreach ($teacher_schedule_raw as $lesson) {
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
<?php if (isset($_SESSION['user_id'])): ?>
<?php if ($role === 'admin'): ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="manageDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Manage
@ -123,6 +146,7 @@ foreach ($teacher_schedule_raw as $lesson) {
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="/timetable.php">Class Timetable</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link active" href="/teacher_timetable.php">Teacher Timetable</a></li>
<li class="nav-item"><a class="nav-link" href="/logout.php">Logout</a></li>
<?php else: ?>
@ -146,6 +170,7 @@ foreach ($teacher_schedule_raw as $lesson) {
<?php endif; ?>
</div>
<?php if ($role === 'admin'): ?>
<form method="GET" action="" class="mb-4">
<div class="row">
<div class="col-md-4">
@ -153,7 +178,7 @@ foreach ($teacher_schedule_raw as $lesson) {
<select name="teacher_id" id="teacher_id" class="form-select" onchange="this.form.submit()">
<option value="">-- Select a Teacher --</option>
<?php foreach ($teachers as $teacher): ?>
<option value="<?php echo $teacher['id']; ?>" <?php echo ($selected_teacher_id == $teacher['id']) ? 'selected' : ''; ?>>
<option value="<?php echo $teacher['id']; ?>" <?php echo ($selected_teacher_id == $teacher['id']['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($teacher['name']); ?>
</option>
<?php endforeach; ?>
@ -161,6 +186,7 @@ foreach ($teacher_schedule_raw as $lesson) {
</div>
</div>
</form>
<?php endif; ?>
<div id="timetable-container">
<?php if ($selected_teacher_id && !empty($teacher_schedule_raw)): ?>

219
teacher_workload.php Normal file
View File

@ -0,0 +1,219 @@
<?php
require_once __DIR__ . '/includes/auth_check_workload.php';
require_once __DIR__ . '/db/config.php';
$message = '';
$error = '';
$pdo = db();
$edit_workload = null;
$school_id = $_SESSION['school_id'];
$user_id = $_SESSION['user_id'];
// Get teacher_id from user_id
$stmt = $pdo->prepare("SELECT id FROM teachers WHERE user_id = ?");
$stmt->execute([$user_id]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
$teacher_id = $teacher['id'];
// Handle Delete request
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_id'])) {
try {
$stmt = $pdo->prepare("DELETE FROM workloads WHERE id = ? AND teacher_id = ? AND school_id = ?");
if ($stmt->execute([$_POST['delete_id'], $teacher_id, $school_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;
$lessons_per_week = $_POST['lessons_per_week'] ?? null;
if (empty($class_id) || empty($subject_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 = ?, lessons_per_week = ? WHERE id = ? AND teacher_id = ? AND school_id = ?");
if ($stmt->execute([$class_id, $subject_id, $lessons_per_week, $workload_id, $teacher_id, $school_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, school_id) VALUES (?, ?, ?, ?, ?)");
if ($stmt->execute([$class_id, $subject_id, $teacher_id, $lessons_per_week, $school_id])) {
$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) already exists for you.';
} 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 = ? AND teacher_id = ? AND school_id = ?");
$stmt->execute([$_GET['edit_id'], $teacher_id, $school_id]);
$edit_workload = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error: ' . $e->getMessage();
}
}
// Fetch related data for dropdowns
try {
$classes_stmt = $pdo->prepare("SELECT id, name FROM classes WHERE school_id = ? ORDER BY name");
$classes_stmt->execute([$school_id]);
$classes = $classes_stmt->fetchAll(PDO::FETCH_ASSOC);
$subjects_stmt = $pdo->prepare("SELECT id, name FROM subjects WHERE school_id = ? ORDER BY name");
$subjects_stmt->execute([$school_id]);
$subjects = $subjects_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error while fetching data: ' . $e->getMessage();
}
// Fetch all workloads for this teacher to display
$workloads = [];
try {
$workloads_stmt = $pdo->prepare("
SELECT w.id, c.name as class_name, s.name as subject_name, w.lessons_per_week, w.created_at, w.class_id, w.subject_id
FROM workloads w
JOIN classes c ON w.class_id = c.id
JOIN subjects s ON w.subject_id = s.id
WHERE w.teacher_id = ? AND w.school_id = ?
ORDER BY w.created_at DESC
");
$workloads_stmt->execute([$teacher_id, $school_id]);
$workloads = $workloads_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error = 'Database error while fetching workloads: ' . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Workload - Haki Schedule</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.10.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top shadow-sm">
<div class="container">
<a class="navbar-brand fw-bold" href="dashboard.php">Haki Schedule</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="dashboard.php">Dashboard</a></li>
<li class="nav-item"><a class="nav-link active" href="teacher_workload.php">My Workload</a></li>
<li class="nav-item"><a class="nav-link" href="teacher_timetable.php">My Timetable</a></li>
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
</ul>
</div>
</div>
</nav>
<main class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-10">
<h1 class="h2 fw-bold mb-4">My Workload</h1>
<?php if ($message): ?><div class="alert alert-success"><?php echo $message; ?></div><?php endif; ?>
<?php if ($error): ?><div class="alert alert-danger"><?php echo $error; ?></div><?php endif; ?>
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title"><?php echo $edit_workload ? 'Edit Workload' : 'Add New Workload'; ?></h5>
<form action="teacher_workload.php" method="POST">
<input type="hidden" name="workload_id" value="<?php echo $edit_workload['id'] ?? ''; ?>">
<div class="row">
<div class="col-md-6 mb-3">
<label for="class_id" class="form-label">Class</label>
<select class="form-select" id="class_id" name="class_id" required>
<?php foreach ($classes as $class): ?>
<option value="<?php echo $class['id']; ?>" <?php echo (isset($edit_workload) && $edit_workload['class_id'] == $class['id']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($class['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="subject_id" class="form-label">Subject</label>
<select class="form-select" id="subject_id" name="subject_id" required>
<?php foreach ($subjects as $subject): ?>
<option value="<?php echo $subject['id']; ?>" <?php echo (isset($edit_workload) && $edit_workload['subject_id'] == $subject['id']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($subject['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="lessons_per_week" class="form-label">Lessons Per Week</label>
<input type="number" class="form-control" id="lessons_per_week" name="lessons_per_week" min="1" value="<?php echo $edit_workload['lessons_per_week'] ?? ''; ?>" required>
</div>
</div>
<button type="submit" class="btn btn-primary"><?php echo $edit_workload ? 'Update Workload' : 'Add Workload'; ?></button>
<?php if ($edit_workload): ?>
<a href="teacher_workload.php" class="btn btn-secondary">Cancel Edit</a>
<?php endif; ?>
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title">My Existing Workloads</h5>
<div class="table-responsive">
<table class="table table-striped">
<thead><tr><th>Class</th><th>Subject</th><th class="text-center">Lessons/Week</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($workloads as $workload): ?>
<tr>
<td><?php echo htmlspecialchars($workload['class_name']); ?></td>
<td><?php echo htmlspecialchars($workload['subject_name']); ?></td>
<td class="text-center"><?php echo htmlspecialchars($workload['lessons_per_week']); ?></td>
<td>
<a href="?edit_id=<?php echo $workload['id']; ?>" class="btn btn-sm btn-outline-primary"><i class="bi bi-pencil-fill"></i></a>
<form action="teacher_workload.php" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this workload?');">
<input type="hidden" name="delete_id" value="<?php echo $workload['id']; ?>">
<button type="submit" class="btn btn-sm btn-outline-danger"><i class="bi bi-trash-fill"></i></button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-dark text-white py-4 mt-5"><div class="container text-center"><p>&copy; <?php echo date("Y"); ?> Haki Schedule. All Rights Reserved.</p></div></footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>