diff --git a/add_grade.php b/add_grade.php new file mode 100644 index 0000000..00a0d8f --- /dev/null +++ b/add_grade.php @@ -0,0 +1,48 @@ += $max_score) { + $_SESSION['error_message'] = 'Min score must be less than max score.'; + header('Location: school_settings.php'); + exit; + } + + try { + $pdo = db(); + $sql = "INSERT INTO grading_scales (section, grade_name, min_score, max_score) VALUES (?, ?, ?, ?)"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$section, $grade_name, $min_score, $max_score]); + + $_SESSION['success_message'] = 'Grade added successfully.'; + + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + $_SESSION['error_message'] = "A grade with the name '{$grade_name}' already exists in the '{$section}' section."; + } else { + $_SESSION['error_message'] = 'Database error: ' . $e->getMessage(); + } + } +} + +header('Location: school_settings.php'); +exit; diff --git a/add_user.php b/add_user.php new file mode 100644 index 0000000..7cef618 --- /dev/null +++ b/add_user.php @@ -0,0 +1,91 @@ + + + + + + + Add User - Admin Dashboard + + + + +
+ +
+
+

Add New User

+
+
+
+
+ +
+ +
+
+ + + +
+ +
+
+ + + +
+ +
+
+ + + +
+ +
+
+ + +
+ +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..a8eb2a9 --- /dev/null +++ b/admin.php @@ -0,0 +1,64 @@ + + + + + + + Admin Dashboard - School Management + + + + +
+ +
+
+

Welcome, !

+

Here is your school's summary.

+
+
+
+

Total Students

+

1,234

+ +
+
+

Total Teachers

+

56

+ +
+
+

Bursary Overview

+

$546,789

+ +
+
+

Pending Issues

+

12

+ +
+
+
+
+ + \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..af65fce --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,296 @@ +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&family=Poppins:wght@600;700&display=swap'); + +:root { + --primary-color: #4A90E2; + --secondary-color: #50E3C2; + --background-color: #F4F7F6; + --surface-color: #FFFFFF; + --text-color: #333333; + --border-radius: 0.75rem; + --primary-font: 'Poppins', sans-serif; + --secondary-font: 'Open Sans', sans-serif; +} + +body { + background-color: var(--background-color); + font-family: var(--secondary-font); + color: var(--text-color); + margin: 0; +} + +h1, h2, h3, h4, h5, h6 { + font-family: var(--primary-font); + font-weight: 700; +} + +/* New Login Page Styles */ +.login-container { + display: flex; + min-height: 100vh; + width: 100%; +} + +.login-hero-split { + flex: 1; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + display: flex; + justify-content: center; + align-items: center; + color: white; + padding: 3rem; + text-align: center; +} + +.hero-content { + max-width: 400px; +} + +.hero-title { + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 1rem; +} + +.hero-subtitle { + font-size: 1.25rem; + font-family: var(--secondary-font); + opacity: 0.9; +} + +.login-form-area { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 3rem; + background-color: var(--surface-color); +} + +.login-card { + width: 100%; + max-width: 400px; + border: none; + box-shadow: 0 15px 40px rgba(0,0,0,0.08); + border-radius: var(--border-radius); + padding: 2.5rem; + background-color: var(--surface-color); +} + +.login-card .card-title { + color: var(--primary-color); + font-weight: 600; +} + +.form-label { + font-weight: 600; + color: #555; +} + +.form-control { + border-radius: var(--border-radius); + padding: 0.85rem 1.1rem; + border: 1px solid #ddd; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.form-control:focus { + box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.2); + border-color: var(--primary-color); +} + +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + border-radius: var(--border-radius); + padding: 0.85rem 1.5rem; + font-weight: 600; + font-size: 1.1rem; + transition: background-color 0.3s ease, transform 0.2s ease; +} + +.btn-primary:hover { + background-color: #357ABD; + border-color: #357ABD; + transform: translateY(-2px); +} + +.alert { + border-radius: var(--border-radius); +} + +/* Admin Dashboard Styles */ +.admin-container { + display: flex; + min-height: 100vh; +} + +.sidebar { + width: 250px; + background-color: var(--surface-color); + box-shadow: 2px 0 10px rgba(0,0,0,0.05); + display: flex; + flex-direction: column; +} + +.sidebar-header { + padding: 1.5rem; + text-align: center; + border-bottom: 1px solid var(--background-color); +} + +.sidebar-header h3 { + color: var(--primary-color); + margin: 0; +} + +.sidebar-nav ul { + list-style: none; + padding: 0; + margin: 1rem 0; +} + +.sidebar-nav li { + padding: 0.5rem 1.5rem; +} + +.sidebar-nav a { + text-decoration: none; + color: var(--text-color); + font-weight: 600; + display: block; + transition: color 0.2s ease; +} + +.sidebar-nav a:hover, +.sidebar-nav li.active a { + color: var(--primary-color); +} + +.main-content { + flex-grow: 1; + padding: 2rem; + background-color: var(--background-color); +} + +.main-header { + margin-bottom: 2rem; +} + +.dashboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1.5rem; +} + +.dashboard-card { + background-color: var(--surface-color); + border-radius: var(--border-radius); + padding: 1.5rem; + box-shadow: 0 4px 15px rgba(0,0,0,0.05); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.dashboard-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 25px rgba(0,0,0,0.08); +} + +.dashboard-card h4 { + color: var(--primary-color); + margin-top: 0; + margin-bottom: 0.5rem; +} + +.card-value { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 0.5rem; +} + +.card-footer { + color: #6c757d; + font-size: 0.9rem; +} + +/* User Management Table */ +.user-table { + width: 100%; + border-collapse: collapse; + margin-top: 1rem; +} + +.user-table th, .user-table td { + padding: 0.75rem 1rem; + text-align: left; + border-bottom: 1px solid #eee; +} + +.user-table thead th { + font-family: var(--primary-font); + font-weight: 600; + color: var(--primary-color); +} + +.user-table tbody tr:hover { + background-color: rgba(74, 144, 226, 0.05); +} + +.action-link { + color: var(--primary-color); + text-decoration: none; + margin-right: 1rem; + font-weight: 600; +} + +.action-link:hover { + text-decoration: underline; +} + +.full-width-card { + grid-column: 1 / -1; +} + +.content-grid { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; +} + +.form-group { + margin-bottom: 1.5rem; +} + +.error-message { + color: #dc3545; + font-size: 0.875em; + margin-top: 0.25rem; +} + +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} + +@media (max-width: 768px) { + .login-container { + flex-direction: column; + } + .login-hero-split { + padding: 2rem; + min-height: 200px; + } + .hero-title { + font-size: 2.5rem; + } + .login-form-area { + padding: 2rem 1rem; + } +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..bb10c0a --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,23 @@ +document.addEventListener('DOMContentLoaded', function() { + const loginForm = document.getElementById('loginForm'); + if (loginForm) { + loginForm.addEventListener('submit', function(e) { + e.preventDefault(); + + // --- SIMULATED LOGIN --- + // In a real application, you would send this to a server for validation. + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + // Basic validation + if (email && password) { + // Simulate a successful login and redirect to the admin dashboard + console.log('Simulating successful login...'); + window.location.href = 'admin.php'; + } else { + // In a real app, you'd show a more specific error. + alert('Please enter both email and password.'); + } + }); + } +}); \ No newline at end of file diff --git a/db/migrations/001_create_users_table.sql b/db/migrations/001_create_users_table.sql new file mode 100644 index 0000000..a0bef7d --- /dev/null +++ b/db/migrations/001_create_users_table.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `role` VARCHAR(50) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE, + `password` VARCHAR(255) NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=INNODB; \ No newline at end of file diff --git a/db/migrations/002_add_email_password_to_users.sql b/db/migrations/002_add_email_password_to_users.sql new file mode 100644 index 0000000..4daa661 --- /dev/null +++ b/db/migrations/002_add_email_password_to_users.sql @@ -0,0 +1,7 @@ +ALTER TABLE `users` +ADD COLUMN `email` VARCHAR(255) NOT NULL AFTER `name`, +ADD COLUMN `password` VARCHAR(255) NOT NULL AFTER `email`, +ADD COLUMN `role` VARCHAR(50) NOT NULL DEFAULT 'user' AFTER `password`; + +-- Add a unique constraint to the email column to prevent duplicate emails +ALTER TABLE `users` ADD UNIQUE (`email`); diff --git a/db/migrations/003_add_email_and_password_columns.sql b/db/migrations/003_add_email_and_password_columns.sql new file mode 100644 index 0000000..5878a8e --- /dev/null +++ b/db/migrations/003_add_email_and_password_columns.sql @@ -0,0 +1,6 @@ +ALTER TABLE `users` +ADD COLUMN `email` VARCHAR(255) NOT NULL AFTER `name`, +ADD COLUMN `password` VARCHAR(255) NOT NULL AFTER `email`; + +-- Add a unique constraint to the email column to prevent duplicate emails +ALTER TABLE `users` ADD UNIQUE (`email`); diff --git a/db/migrations/004_add_status_to_users.sql b/db/migrations/004_add_status_to_users.sql new file mode 100644 index 0000000..23661c3 --- /dev/null +++ b/db/migrations/004_add_status_to_users.sql @@ -0,0 +1,2 @@ +ALTER TABLE `users` +ADD COLUMN `status` VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT 'User account status: active or inactive' AFTER `role`; diff --git a/db/migrations/005_create_school_settings_table.sql b/db/migrations/005_create_school_settings_table.sql new file mode 100644 index 0000000..84bb9bc --- /dev/null +++ b/db/migrations/005_create_school_settings_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `school_settings` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `setting_key` VARCHAR(255) NOT NULL UNIQUE, + `setting_value` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=INNODB; + +-- Insert some default values +INSERT INTO `school_settings` (setting_key, setting_value) VALUES +('school_name', 'My School') ON DUPLICATE KEY UPDATE setting_key=setting_key; diff --git a/db/migrations/006_create_grading_scales_table.sql b/db/migrations/006_create_grading_scales_table.sql new file mode 100644 index 0000000..2fde841 --- /dev/null +++ b/db/migrations/006_create_grading_scales_table.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS `grading_scales` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `section` VARCHAR(50) NOT NULL, + `grade_name` VARCHAR(10) NOT NULL, + `min_score` INT NOT NULL, + `max_score` INT NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY `section_grade` (`section`, `grade_name`) +) ENGINE=INNODB; diff --git a/db/migrations/007_create_classes_table.sql b/db/migrations/007_create_classes_table.sql new file mode 100644 index 0000000..8678e99 --- /dev/null +++ b/db/migrations/007_create_classes_table.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS `classes` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL UNIQUE, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=INNODB; diff --git a/db/migrations/008_create_subjects_table.sql b/db/migrations/008_create_subjects_table.sql new file mode 100644 index 0000000..aea53b0 --- /dev/null +++ b/db/migrations/008_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 +) ENGINE=INNODB; diff --git a/delete_grade.php b/delete_grade.php new file mode 100644 index 0000000..64d48b1 --- /dev/null +++ b/delete_grade.php @@ -0,0 +1,28 @@ +prepare($sql); + $stmt->execute([$id]); + + $_SESSION['success_message'] = 'Grade deleted successfully.'; + + } catch (PDOException $e) { + $_SESSION['error_message'] = 'Database error: ' . $e->getMessage(); + } +} + +header('Location: school_settings.php'); +exit; diff --git a/delete_user.php b/delete_user.php new file mode 100644 index 0000000..32200bc --- /dev/null +++ b/delete_user.php @@ -0,0 +1,26 @@ +prepare($sql); + $stmt->execute([$id]); + $_SESSION['success_message'] = 'User deleted successfully.'; + } catch (PDOException $e) { + die("Database error: " . $e->getMessage()); + } +} + +header("Location: users.php"); +exit; \ No newline at end of file diff --git a/edit_grade.php b/edit_grade.php new file mode 100644 index 0000000..e467f82 --- /dev/null +++ b/edit_grade.php @@ -0,0 +1,89 @@ +prepare("SELECT id, section, grade_name, min_score, max_score FROM grading_scales WHERE id = ?"); + $stmt->execute([$id]); + $grade = $stmt->fetch(); +} catch (PDOException $e) { + die("Database error: " . $e->getMessage()); +} + +if (!$grade) { + die("Grade not found."); +} +?> + + + + + + Edit Grade - Admin Dashboard + + + + +
+ +
+
+

Edit Grade

+
+
+
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + diff --git a/edit_user.php b/edit_user.php new file mode 100644 index 0000000..be3a732 --- /dev/null +++ b/edit_user.php @@ -0,0 +1,117 @@ +prepare("SELECT id, name, role, email FROM users WHERE id = ?"); + $stmt->execute([$id]); + $user = $stmt->fetch(); + } catch (PDOException $e) { + die("Database error: " . $e->getMessage()); + } + } +} + +if (!$user) { + die("User not found."); +} +?> + + + + + + Edit User - Admin Dashboard + + + + +
+ +
+
+

Edit User

+
+
+
+
+ +
+ +
+ +
+ + + +
+ +
+
+ + + +
+ +
+
+ + + +
+ +
+
+ + +
+ +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..0dc2613 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,75 @@ - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + Welcome to SchoolAdmin + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ + -
- + + + diff --git a/login.php b/login.php new file mode 100644 index 0000000..e2df8a5 --- /dev/null +++ b/login.php @@ -0,0 +1,33 @@ +prepare("SELECT * FROM users WHERE email = ?"); + $stmt->execute([$email]); + $user = $stmt->fetch(); + + if ($user && password_verify($password, $user['password'])) { + // Add this block to check user status + if ($user['status'] !== 'active') { + $_SESSION['login_error'] = 'Your account is inactive. Please contact an administrator.'; + header('Location: index.php'); + exit; + } + + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_name'] = $user['name']; + $_SESSION['user_role'] = $user['role']; + header('Location: admin.php'); + exit; + } else { + $_SESSION['login_error'] = 'Invalid email or password.'; + header('Location: index.php'); + exit; + } +} \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..d9d3d93 --- /dev/null +++ b/logout.php @@ -0,0 +1,8 @@ +prepare($sql); + $stmt->execute([$school_name, $school_name]); + + $_SESSION['success_message'] = 'School settings saved successfully.'; + + } catch (PDOException $e) { + $_SESSION['error_message'] = 'Database error: ' . $e->getMessage(); + } +} + +header('Location: school_settings.php'); +exit; diff --git a/save_user.php b/save_user.php new file mode 100644 index 0000000..fb62f77 --- /dev/null +++ b/save_user.php @@ -0,0 +1,84 @@ +prepare("SELECT id FROM users WHERE email = ?"); + $stmt->execute([$email]); + if ($stmt->fetch()) { + $errors['email'] = 'Email already exists.'; + } + } catch (PDOException $e) { + $errors['db'] = "Database error: " . $e->getMessage(); + } + } + + if (empty($password)) { + $errors['password'] = 'Password is required.'; + } elseif (strlen($password) < 8) { + $errors['password'] = 'Password must be at least 8 characters long.'; + } + + // Check for role uniqueness: Bursar and Assistant Bursar + if ($role === 'Bursar' || $role === 'Assistant Bursar') { + try { + $pdo = db(); + $stmt = $pdo->prepare("SELECT id FROM users WHERE role = ?"); + $stmt->execute([$role]); + if ($stmt->fetch()) { + // Using 'db' to show a general form error, as there's no specific field for this. + $errors['db'] = "A user with the role '{$role}' already exists. Only one is allowed."; + } + } catch (PDOException $e) { + $errors['db'] = "Database error while checking role uniqueness: " . $e->getMessage(); + } + } + + if (empty($errors)) { + try { + $pdo = db(); + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + $sql = "INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$name, $email, $hashed_password, $role]); + + $_SESSION['success_message'] = 'User created successfully.'; + header("Location: users.php"); + exit; + } catch (PDOException $e) { + $errors['db'] = "Database error: " . $e->getMessage(); + } + } + + $_SESSION['errors'] = $errors; + $_SESSION['old_input'] = $_POST; + header("Location: add_user.php"); + exit; +} + +header("Location: add_user.php"); +exit; diff --git a/school_settings.php b/school_settings.php new file mode 100644 index 0000000..acc0358 --- /dev/null +++ b/school_settings.php @@ -0,0 +1,162 @@ +exec(file_get_contents('db/migrations/005_create_school_settings_table.sql')); + } + if (file_exists('db/migrations/006_create_grading_scales_table.sql')) { + $pdo->exec(file_get_contents('db/migrations/006_create_grading_scales_table.sql')); + } + + $stmt = $pdo->query("SELECT setting_key, setting_value FROM school_settings"); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $settings[$row['setting_key']] = $row['setting_value']; + } +} catch (Exception $e) { + die("Could not connect to the database: " . $e->getMessage()); +} +$school_name = $settings['school_name'] ?? ''; + +// Grading Scales +$grading_scales = []; +try { + $stmt = $pdo->query("SELECT id, section, grade_name, min_score, max_score FROM grading_scales ORDER BY section, min_score DESC"); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $grading_scales[$row['section']][] = $row; + } +} catch (Exception $e) { + die("Could not fetch grading scales: " . $e->getMessage()); +} + +$sections = ['Nursery', 'Primary', 'Secondary']; + +?> + + + + + + School Settings - Admin Dashboard + + + + +
+ +
+
+

School Settings

+
+ + +
+ + + + +
+ + + +
+
+
+

General Settings

+
+
+
+
+ + +
+ +
+
+
+
+
+

Grading Scales

+
+
+ +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
GradeMin ScoreMax ScoreActions
+ Edit + Delete +
No grades defined for this section.
+
+ +
+ + +
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/subjects_classes.php b/subjects_classes.php new file mode 100644 index 0000000..3e52b85 --- /dev/null +++ b/subjects_classes.php @@ -0,0 +1,148 @@ +exec(file_get_contents('db/migrations/007_create_classes_table.sql')); + } + if (file_exists('db/migrations/008_create_subjects_table.sql')) { + $pdo->exec(file_get_contents('db/migrations/008_create_subjects_table.sql')); + } + + // Fetch classes + $stmt_classes = $pdo->query("SELECT id, name FROM classes ORDER BY name"); + $classes = $stmt_classes->fetchAll(); + + // Fetch subjects + $stmt_subjects = $pdo->query("SELECT id, name FROM subjects ORDER BY name"); + $subjects = $stmt_subjects->fetchAll(); + +} catch (Exception $e) { + die("Could not connect to the database: " . $e->getMessage()); +} + +?> + + + + + + Subjects & Classes - Admin Dashboard + + + + +
+ +
+
+

Subjects & Classes

+
+ + +
+ + + + +
+ + + +
+ +
+
+

Manage Classes

+
+
+ + + + + + + + + + + + + + + +
Class NameActions
+ Edit + Delete +
+
+
+ + +
+ +
+
+
+ + +
+
+

Manage Subjects

+
+
+ + + + + + + + + + + + + + + +
Subject NameActions
+ Edit + Delete +
+
+
+ + +
+ +
+
+
+
+
+
+ + diff --git a/update_grade.php b/update_grade.php new file mode 100644 index 0000000..c442582 --- /dev/null +++ b/update_grade.php @@ -0,0 +1,48 @@ += $max_score) { + $_SESSION['error_message'] = 'Min score must be less than max score.'; + header('Location: school_settings.php'); + exit; + } + + try { + $pdo = db(); + $sql = "UPDATE grading_scales SET grade_name = ?, min_score = ?, max_score = ? WHERE id = ?"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$grade_name, $min_score, $max_score, $id]); + + $_SESSION['success_message'] = 'Grade updated successfully.'; + + } catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + $_SESSION['error_message'] = "A grade with that name already exists in this section."; + } else { + $_SESSION['error_message'] = 'Database error: ' . $e->getMessage(); + } + } +} + +header('Location: school_settings.php'); +exit; diff --git a/update_user.php b/update_user.php new file mode 100644 index 0000000..044eac0 --- /dev/null +++ b/update_user.php @@ -0,0 +1,74 @@ +prepare("SELECT id FROM users WHERE email = ? AND id != ?"); + $stmt->execute([$email, $id]); + if ($stmt->fetch()) { + $errors['email'] = 'Email already exists.'; + } + } catch (PDOException $e) { + $errors['db'] = "Database error: " . $e->getMessage(); + } + } + + if (!empty($password) && strlen($password) < 8) { + $errors['password'] = 'Password must be at least 8 characters long.'; + } + + if (empty($errors)) { + try { + $pdo = db(); + if ($password) { + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + $sql = "UPDATE users SET name = ?, email = ?, password = ?, role = ? WHERE id = ?"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$name, $email, $hashed_password, $role, $id]); + } else { + $sql = "UPDATE users SET name = ?, email = ?, role = ? WHERE id = ?"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$name, $email, $role, $id]); + } + + $_SESSION['success_message'] = 'User updated successfully.'; + header("Location: users.php"); + exit; + } catch (PDOException $e) { + $errors['db'] = "Database error: " . $e->getMessage(); + } + } + + $_SESSION['errors'] = $errors; + $_SESSION['old_input'] = $_POST; + header("Location: edit_user.php?id=" . $id); + exit; +} + +header("Location: users.php"); +exit; \ No newline at end of file diff --git a/update_user_status.php b/update_user_status.php new file mode 100644 index 0000000..485c98e --- /dev/null +++ b/update_user_status.php @@ -0,0 +1,43 @@ +prepare($sql); + $stmt->execute([$status, $id]); + + $_SESSION['success_message'] = 'User status updated successfully.'; + } catch (PDOException $e) { + $_SESSION['error_message'] = 'Database error: ' . $e->getMessage(); + } +} + +header('Location: users.php'); +exit; diff --git a/users.php b/users.php new file mode 100644 index 0000000..5eb3759 --- /dev/null +++ b/users.php @@ -0,0 +1,119 @@ +query("SELECT id, name, role, email, status FROM users"); + $users = $stmt->fetchAll(); + +} catch (PDOException $e) { + if (strpos($e->getMessage(), "Unknown column 'status'") !== false) { + try { + $sql = file_get_contents('db/migrations/004_add_status_to_users.sql'); + $pdo->exec($sql); + header("Location: users.php"); // Refresh the page after migration + exit; + } catch (Exception $me) { + die("Could not apply migration and connect to the database: " . $me->getMessage()); + } + } else { + die("Could not connect to the database: " . $e->getMessage()); + } +} +?> + + + + + + User Management - Admin Dashboard + + + + +
+ +
+
+

User Management

+ Add New User +
+ + +
+ + + +
+ + +
+
+
+

All Users

+
+
+ + + + + + + + + + + + + + + + + + + + + +
NameRoleEmailStatusActions
+ Edit + Delete + + Deactivate + + Activate + +
+
+
+
+
+
+ + \ No newline at end of file