Compare commits

...

12 Commits

Author SHA1 Message Date
Flatlogic Bot
f9b7d8af32 Edit users.php via Editor 2025-12-09 01:19:46 +00:00
Flatlogic Bot
53b2eca493 Edit users.php via Editor 2025-12-09 01:19:09 +00:00
Flatlogic Bot
3d54aeb8f0 Edit attendance.php via Editor 2025-12-07 20:12:55 +00:00
Flatlogic Bot
7acb928eca Edit activities.php via Editor 2025-12-07 20:12:28 +00:00
Flatlogic Bot
4d076f05c2 Edit users.php via Editor 2025-12-07 20:06:27 +00:00
Flatlogic Bot
1839023496 Edit roles.php via Editor 2025-12-07 20:06:06 +00:00
Flatlogic Bot
93f530e4f6 t7 2025-12-07 19:58:10 +00:00
Flatlogic Bot
e15fa31a20 t6 2025-11-27 10:42:12 +00:00
Flatlogic Bot
082d14fa79 v5 2025-11-27 10:17:29 +00:00
Flatlogic Bot
a2059511fc t4 2025-11-27 10:08:20 +00:00
Flatlogic Bot
acd454b06b t3 2025-11-27 09:24:02 +00:00
Flatlogic Bot
4359789531 t1 2025-11-27 08:44:48 +00:00
27 changed files with 1862 additions and 146 deletions

32
activities.php Normal file
View File

@ -0,0 +1,32 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
//header('Location: login.php');
//exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Activities</title>
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<header>
<h1>Activities</h1>
<nav>
<ul>
<li><a href="teacher_dashboard.php">Dashboard</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</header>
<main>
<h2>Activity Management</h2>
<p>This page will contain student activity information.</p>
</main>
</body>
</html>

33
admin_dashboard.php Normal file
View File

@ -0,0 +1,33 @@
<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role_name'] !== 'admin') {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard</title>
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<header>
<h1>Admin Dashboard</h1>
<nav>
<ul>
<li><a href="users.php">Manage Users</a></li>
<li><a href="roles.php">Manage Roles</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</header>
<main>
<h2>Welcome, Admin!</h2>
<p>This is your dashboard. You can manage users and roles from here.</p>
</main>
</body>
</html>

74
assets/css/custom.css Normal file
View File

@ -0,0 +1,74 @@
:root {
--primary-color: #4a90e2;
--secondary-color: #50e3c2;
--background-color: #f9f9f9;
--surface-color: #ffffff;
--text-color: #333333;
}
body {
font-family: 'Vazirmatn', sans-serif;
direction: rtl;
background-color: var(--background-color);
color: var(--text-color);
}
.hero {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
color: white;
padding: 100px 0;
text-align: center;
}
.hero h1 {
font-size: 3rem;
font-weight: 700;
}
.hero p {
font-size: 1.25rem;
margin-bottom: 30px;
}
.feature-card {
background-color: var(--surface-color);
border-radius: 8px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-card i {
font-size: 3rem;
color: var(--primary-color);
margin-bottom: 20px;
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
border-radius: 8px;
padding: 10px 20px;
}
.btn-primary:hover {
background-color: #357ABD;
border-color: #357ABD;
}
.footer {
background-color: var(--surface-color);
padding: 20px 0;
text-align: center;
border-top: 1px solid #eee;
}
#loginModal .modal-content {
border-radius: 8px;
}

13
assets/js/main.js Normal file
View File

@ -0,0 +1,13 @@
document.addEventListener('DOMContentLoaded', function() {
// Smooth scroll for hero button
const heroBtn = document.querySelector('.hero .btn');
if (heroBtn) {
heroBtn.addEventListener('click', function(e) {
e.preventDefault();
document.querySelector('#features').scrollIntoView({
behavior: 'smooth'
});
});
}
});

216
attendance.php Normal file
View File

@ -0,0 +1,216 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
//header('Location: login.php');
//exit();
}
$role_name = $_SESSION['role_name'];
$user_id = $_SESSION['user_id'];
function get_students() {
$pdo = db();
$stmt = $pdo->prepare("SELECT u.id, u.first_name, u.last_name FROM users u JOIN roles r ON u.role_id = r.id WHERE r.role_name = 'student'");
$stmt->execute();
return $stmt->fetchAll();
}
function get_children_for_parent($parent_id) {
$pdo = db();
$stmt = $pdo->prepare("SELECT u.id, u.first_name, u.last_name FROM users u JOIN parent_child pc ON u.id = pc.child_id WHERE pc.parent_id = ?");
$stmt->execute([$parent_id]);
return $stmt->fetchAll();
}
function get_student_attendance($student_id) {
$pdo = db();
$stmt = $pdo->prepare("SELECT attendance_date, status FROM attendance WHERE student_id = ? ORDER BY attendance_date DESC");
$stmt->execute([$student_id]);
return $stmt->fetchAll();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $role_name === 'teacher') {
$attendance_date = $_POST['attendance_date'];
$students = $_POST['students'];
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO attendance (student_id, attendance_date, status) VALUES (?, ?, ?)");
foreach ($students as $student_id => $status) {
$stmt->execute([$student_id, $attendance_date, $status]);
}
$success_message = "Attendance for $attendance_date has been saved.";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Attendance</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">School Management</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<?php if ($role_name === 'teacher'): ?>
<li><a href="teacher_dashboard.php" class="nav-link px-2 link-dark">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-secondary">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
<?php elseif ($role_name === 'student'): ?>
<li><a href="student_dashboard.php" class="nav-link px-2 link-dark">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-secondary">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
<?php elseif ($role_name === 'parent'): ?>
<li><a href="parent_dashboard.php" class="nav-link px-2 link-dark">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-secondary">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
<?php endif; ?>
</ul>
<div class="text-end">
<a href="logout.php" class="btn btn-outline-primary">Logout</a>
</div>
</div>
</div>
</header>
<main class="container py-5">
<h1>Attendance</h1>
<?php if (isset($success_message)): ?>
<div class="alert alert-success"><?php echo $success_message; ?></div>
<?php endif; ?>
<?php if ($role_name === 'teacher'): ?>
<h2>Take Attendance</h2>
<form method="POST">
<div class="mb-3">
<label for="attendance_date" class="form-label">Date</label>
<input type="date" class="form-control" id="attendance_date" name="attendance_date" value="<?php echo date('Y-m-d'); ?>" required>
</div>
<table class="table">
<thead>
<tr>
<th>Student Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
$students = get_students();
foreach ($students as $student):
?>
<tr>
<td><?php echo htmlspecialchars($student['first_name'] . ' ' . $student['last_name']); ?></td>
<td>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="students[<?php echo $student['id']; ?>]" id="present_<?php echo $student['id']; ?>" value="present" checked>
<label class="form-check-label" for="present_<?php echo $student['id']; ?>">Present</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="students[<?php echo $student['id']; ?>]" id="absent_<?php echo $student['id']; ?>" value="absent">
<label class="form-check-label" for="absent_<?php echo $student['id']; ?>">Absent</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="students[<?php echo $student['id']; ?>]" id="late_<?php echo $student['id']; ?>" value="late">
<label class="form-check-label" for="late_<?php echo $student['id']; ?>">Late</label>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<button type="submit" class="btn btn-primary">Submit Attendance</button>
</form>
<?php elseif ($role_name === 'student'): ?>
<h2>My Attendance</h2>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
$attendance_records = get_student_attendance($user_id);
foreach ($attendance_records as $record):
?>
<tr>
<td><?php echo htmlspecialchars($record['attendance_date']); ?></td>
<td><?php echo htmlspecialchars($record['status']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($role_name === 'parent'): ?>
<h2>My Child's Attendance</h2>
<?php
$children = get_children_for_parent($user_id);
if (count($children) > 0):
?>
<form method="GET" class="mb-3">
<div class="row">
<div class="col-md-4">
<label for="child_id" class="form-label">Select Child</label>
<select class="form-select" id="child_id" name="child_id" onchange="this.form.submit()">
<option value="">Select a child</option>
<?php foreach ($children as $child): ?>
<option value="<?php echo $child['id']; ?>" <?php echo (isset($_GET['child_id']) && $_GET['child_id'] == $child['id']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($child['first_name'] . ' ' . $child['last_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
</form>
<?php if (isset($_GET['child_id'])):
$child_id = $_GET['child_id'];
// Make sure the selected child belongs to the parent
$is_child_of_parent = false;
foreach ($children as $child) {
if ($child['id'] == $child_id) {
$is_child_of_parent = true;
break;
}
}
if ($is_child_of_parent):
?>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
$attendance_records = get_student_attendance($child_id);
foreach ($attendance_records as $record):
?>
<tr>
<td><?php echo htmlspecialchars($record['attendance_date']); ?></td>
<td><?php echo htmlspecialchars($record['status']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<div class="alert alert-danger">Invalid child selected.</div>
<?php endif; ?>
<?php endif; ?>
<?php else: ?>
<p>You have no children linked to your account.</p>
<?php endif; ?>
<?php endif; ?>
</main>
</body>
</html>

34
database.sql Normal file
View File

@ -0,0 +1,34 @@
DROP TABLE IF EXISTS attendance, parent_child, users, roles;
CREATE TABLE IF NOT EXISTS roles (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role_id INT,
first_name VARCHAR(255),
last_name VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS attendance (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT NOT NULL,
attendance_date DATE NOT NULL,
status ENUM('present', 'absent', 'late') NOT NULL,
FOREIGN KEY (student_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS parent_child (
id INT AUTO_INCREMENT PRIMARY KEY,
parent_id INT NOT NULL,
child_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES users(id),
FOREIGN KEY (child_id) REFERENCES users(id)
);

21
db/migrate.php Normal file
View File

@ -0,0 +1,21 @@
<?php
require_once __DIR__ . '/config.php';
function run_migrations() {
$pdo = db();
$migrations_dir = __DIR__ . '/migrations';
$files = glob($migrations_dir . '/*.sql');
foreach ($files as $file) {
$sql = file_get_contents($file);
try {
$pdo->exec($sql);
echo "Migration from $file executed successfully.\n";
} catch (PDOException $e) {
echo "Error executing migration from $file: " . $e->getMessage() . "\n";
}
}
}
run_migrations();

View File

@ -0,0 +1 @@
DROP TABLE IF EXISTS attendance, parent_child, users, roles;

View File

@ -0,0 +1,4 @@
CREATE TABLE IF NOT EXISTS roles (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(255) NOT NULL UNIQUE
);

View File

@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role_id INT,
first_name VARCHAR(255),
last_name VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE SET NULL
);

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS attendance (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT NOT NULL,
attendance_date DATE NOT NULL,
status ENUM('present', 'absent', 'late') NOT NULL,
FOREIGN KEY (student_id) REFERENCES users(id)
);

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS parent_child (
id INT AUTO_INCREMENT PRIMARY KEY,
parent_id INT NOT NULL,
child_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES users(id),
FOREIGN KEY (child_id) REFERENCES users(id)
);

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS exams (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
created_by INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE
);

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS exam_questions (
id INT AUTO_INCREMENT PRIMARY KEY,
exam_id INT NOT NULL,
question_text TEXT NOT NULL,
question_type ENUM('multiple_choice', 'free_text') NOT NULL,
options JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (exam_id) REFERENCES exams(id) ON DELETE CASCADE
);

View File

@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS student_exams (
id INT AUTO_INCREMENT PRIMARY KEY,
exam_id INT NOT NULL,
student_id INT NOT NULL,
status ENUM('assigned', 'in-progress', 'completed') DEFAULT 'assigned',
score INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (exam_id) REFERENCES exams(id) ON DELETE CASCADE,
FOREIGN KEY (student_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE KEY (exam_id, student_id)
);

View File

@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS student_answers (
id INT AUTO_INCREMENT PRIMARY KEY,
student_exam_id INT NOT NULL,
question_id INT NOT NULL,
answer_text TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (student_exam_id) REFERENCES student_exams(id) ON DELETE CASCADE,
FOREIGN KEY (question_id) REFERENCES exam_questions(id) ON DELETE CASCADE,
UNIQUE KEY (student_exam_id, question_id)
);

180
exam_questions.php Normal file
View File

@ -0,0 +1,180 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
$user_id = $_SESSION['user_id'];
$role = $_SESSION['role'];
if ($role !== 'teacher') {
header('Location: ' . $role . '_dashboard.php');
exit();
}
if (!isset($_GET['exam_id'])) {
header('Location: exams.php');
exit();
}
$exam_id = $_GET['exam_id'];
$pdo = db();
// Verify the teacher owns the exam
$stmt = $pdo->prepare('SELECT * FROM exams WHERE id = ? AND created_by = ?');
$stmt->execute([$exam_id, $user_id]);
$exam = $stmt->fetch();
if (!$exam) {
echo "Exam not found or you don't have permission to edit it.";
exit();
}
// Handle question form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['question_text'])) {
$question_text = trim($_POST['question_text']);
$question_type = $_POST['question_type'];
$options = null;
if ($question_type === 'multiple_choice') {
$options_raw = trim($_POST['options']);
if (!empty($options_raw)) {
$options = json_encode(array_map('trim', explode("\n", $options_raw)));
}
}
if (!empty($question_text)) {
if (isset($_POST['question_id']) && !empty($_POST['question_id'])) {
// Update question
$stmt = $pdo->prepare('UPDATE exam_questions SET question_text = ?, question_type = ?, options = ? WHERE id = ? AND exam_id = ?');
$stmt->execute([$question_text, $question_type, $options, $_POST['question_id'], $exam_id]);
} else {
// Add new question
$stmt = $pdo->prepare('INSERT INTO exam_questions (exam_id, question_text, question_type, options) VALUES (?, ?, ?, ?)');
$stmt->execute([$exam_id, $question_text, $question_type, $options]);
}
}
header('Location: exam_questions.php?exam_id=' . $exam_id);
exit();
}
// Handle question deletion
if (isset($_GET['delete_question'])) {
$question_id = $_GET['delete_question'];
$stmt = $pdo->prepare('DELETE FROM exam_questions WHERE id = ? AND exam_id = ?');
$stmt->execute([$question_id, $exam_id]);
header('Location: exam_questions.php?exam_id=' . $exam_id);
exit();
}
// Fetch questions for the exam
$stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE exam_id = ? ORDER BY created_at ASC');
$stmt->execute([$exam_id]);
$questions = $stmt->fetchAll();
// Check if we are editing a question
$edit_question = null;
if (isset($_GET['edit_question'])) {
$stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE id = ? AND exam_id = ?');
$stmt->execute([$_GET['edit_question'], $exam_id]);
$edit_question = $stmt->fetch();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Questions for <?php echo htmlspecialchars($exam['name']); ?></title>
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<header>
<h1>Manage Questions for "<?php echo htmlspecialchars($exam['name']); ?>"</h1>
<nav>
<ul>
<li><a href="exams.php">Back to Exams</a></li>
<li><a href="teacher_dashboard.php">Dashboard</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2><?php echo $edit_question ? 'Edit' : 'Add'; ?> Question</h2>
<form action="exam_questions.php?exam_id=<?php echo $exam_id; ?>" method="POST">
<?php if ($edit_question): ?>
<input type="hidden" name="question_id" value="<?php echo htmlspecialchars($edit_question['id']); ?>">
<?php endif; ?>
<div>
<label for="question_text">Question:</label>
<textarea id="question_text" name="question_text" rows="3" required><?php echo $edit_question ? htmlspecialchars($edit_question['question_text']) : ''; ?></textarea>
</div>
<div>
<label for="question_type">Question Type:</label>
<select id="question_type" name="question_type">
<option value="free_text" <?php echo ($edit_question && $edit_question['question_type'] === 'free_text') ? 'selected' : ''; ?>>Free Text</option>
<option value="multiple_choice" <?php echo ($edit_question && $edit_question['question_type'] === 'multiple_choice') ? 'selected' : ''; ?>>Multiple Choice</option>
</select>
</div>
<div id="mc_options_container">
<label for="options">Options (one per line):</label>
<textarea id="options" name="options" rows="5"><?php echo ($edit_question && $edit_question['options']) ? htmlspecialchars(implode("\n", json_decode($edit_question['options']))) : ''; ?></textarea>
</div>
<button type="submit"><?php echo $edit_question ? 'Update' : 'Add'; ?> Question</button>
<?php if ($edit_question): ?>
<a href="exam_questions.php?exam_id=<?php echo $exam_id; ?>">Cancel Edit</a>
<?php endif; ?>
</form>
</section>
<section>
<h2>Questions</h2>
<table>
<thead>
<tr>
<th>Question</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($questions as $question):
?>
<tr>
<td><?php echo nl2br(htmlspecialchars($question['question_text'])); ?></td>
<td><?php echo htmlspecialchars(str_replace('_', ' ', $question['question_type'])); ?></td>
<td>
<a href="exam_questions.php?exam_id=<?php echo $exam_id; ?>&edit_question=<?php echo $question['id']; ?>">Edit</a> |
<a href="exam_questions.php?exam_id=<?php echo $exam_id; ?>&delete_question=<?php echo $question['id']; ?>" onclick="return confirm('Are you sure you want to delete this question?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($questions)):
?>
<tr>
<td colspan="3">No questions have been added to this exam yet.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</section>
</main>
<script>
// Show/hide multiple choice options based on question type selection
const questionType = document.getElementById('question_type');
const mcOptionsContainer = document.getElementById('mc_options_container');
function toggleMcOptions() {
mcOptionsContainer.style.display = questionType.value === 'multiple_choice' ? 'block' : 'none';
}
toggleMcOptions(); // Initial check
questionType.addEventListener('change', toggleMcOptions);
</script>
</body>
</html>

177
exams.php Normal file
View File

@ -0,0 +1,177 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
$user_id = $_SESSION['user_id'];
$role = $_SESSION['role'];
$pdo = db();
$page_title = 'Exams';
$header_links = '<a href="' . $role . '_dashboard.php">Dashboard</a>';
// Role-based logic
if ($role === 'teacher') {
$page_title = 'Manage Exams';
// Handle form submissions for creating/editing exams
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['exam_name'])) {
$exam_name = trim($_POST['exam_name']);
if (!empty($exam_name)) {
if (isset($_POST['exam_id']) && !empty($_POST['exam_id'])) {
$stmt = $pdo->prepare('UPDATE exams SET name = ? WHERE id = ? AND created_by = ?');
$stmt->execute([$exam_name, $_POST['exam_id'], $user_id]);
} else {
$stmt = $pdo->prepare('INSERT INTO exams (name, created_by) VALUES (?, ?)');
$stmt->execute([$exam_name, $user_id]);
}
}
header('Location: exams.php');
exit();
}
// Handle exam deletion
if (isset($_GET['delete_exam'])) {
$stmt = $pdo->prepare('DELETE FROM exams WHERE id = ? AND created_by = ?');
$stmt->execute([$_GET['delete_exam'], $user_id]);
header('Location: exams.php');
exit();
}
// Fetch exams for the teacher view
$stmt = $pdo->prepare('SELECT * FROM exams WHERE created_by = ? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
$exams = $stmt->fetchAll();
// Check if we are editing an exam
$edit_exam = null;
if (isset($_GET['edit_exam'])) {
$stmt = $pdo->prepare('SELECT * FROM exams WHERE id = ? AND created_by = ?');
$stmt->execute([$_GET['edit_exam'], $user_id]);
$edit_exam = $stmt->fetch();
}
} elseif ($role === 'student') {
$page_title = 'Your Exams';
// Fetch assigned exams for the student view
$stmt = $pdo->prepare('
SELECT e.name, se.status, se.score, se.id as student_exam_id
FROM student_exams se
JOIN exams e ON se.exam_id = e.id
WHERE se.student_id = ?
ORDER BY e.created_at DESC
');
$stmt->execute([$user_id]);
$assigned_exams = $stmt->fetchAll();
} else {
// Redirect other roles to their dashboard
header('Location: ' . $role . '_dashboard.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $page_title; ?></title>
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<header>
<h1><?php echo $page_title; ?></h1>
<nav>
<ul>
<li><?php echo $header_links; ?></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</header>
<main>
<?php if ($role === 'teacher'): ?>
<section>
<h2><?php echo $edit_exam ? 'Edit' : 'Create'; ?> Exam</h2>
<form action="exams.php" method="POST">
<?php if ($edit_exam): ?>
<input type="hidden" name="exam_id" value="<?php echo htmlspecialchars($edit_exam['id']); ?>">
<?php endif; ?>
<div>
<label for="exam_name">Exam Name:</label>
<input type="text" id="exam_name" name="exam_name" value="<?php echo $edit_exam ? htmlspecialchars($edit_exam['name']) : ''; ?>" required>
</div>
<button type="submit"><?php echo $edit_exam ? 'Update' : 'Create'; ?> Exam</button>
<?php if ($edit_exam): ?>
<a href="exams.php">Cancel Edit</a>
<?php endif; ?>
</form>
</section>
<section>
<h2>Your Exams</h2>
<table>
<thead>
<tr>
<th>Exam Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($exams as $exam): ?>
<tr>
<td><?php echo htmlspecialchars($exam['name']); ?></td>
<td>
<a href="view_submissions.php?exam_id=<?php echo $exam['id']; ?>">View Submissions</a> |
<a href="exams.php?edit_exam=<?php echo $exam['id']; ?>">Edit</a> |
<a href="exam_questions.php?exam_id=<?php echo $exam['id']; ?>">Manage Questions</a> |
<a href="exams.php?delete_exam=<?php echo $exam['id']; ?>" onclick="return confirm('Are you sure you want to delete this exam?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($exams)): ?>
<tr><td colspan="2">You have not created any exams yet.</td></tr>
<?php endif; ?>
</tbody>
</table>
</section>
<?php elseif ($role === 'student'): ?>
<section>
<h2>Assigned Exams</h2>
<table>
<thead>
<tr>
<th>Exam Name</th>
<th>Status</th>
<th>Score</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($assigned_exams as $exam): ?>
<tr>
<td><?php echo htmlspecialchars($exam['name']); ?></td>
<td><?php echo htmlspecialchars(ucfirst($exam['status'])); ?></td>
<td><?php echo $exam['score'] !== null ? $exam['score'] . '%' : 'Not graded'; ?></td>
<td>
<?php if ($exam['status'] === 'assigned' || $exam['status'] === 'in-progress'): ?>
<a href="take_exam.php?student_exam_id=<?php echo $exam['student_exam_id']; ?>">Take Exam</a>
<?php elseif ($exam['status'] === 'completed'): ?>
<a href="view_results.php?student_exam_id=<?php echo $exam['student_exam_id']; ?>">View Results</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($assigned_exams)): ?>
<tr><td colspan="4">You have no assigned exams.</td></tr>
<?php endif; ?>
</tbody>
</table>
</section>
<?php endif; ?>
</main>
</body>
</html>

251
index.php
View File

@ -1,150 +1,111 @@
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
?>
<!doctype html>
<html lang="en">
<?php session_start(); ?>
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<?php
// Read project preview data from environment
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>سیستم مدیریت مدرسه</title>
<meta name="description" content="<?php echo htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'سیستم جامع مدیریت مدرسه'); ?>">
<!-- Bootstrap RTL CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.rtl.min.css" rel="stylesheet">
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
<!-- Feather Icons -->
<script src="https://unpkg.com/feather-icons"></script>
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<meta property="og:title" content="School Management System">
<meta property="og:description" content="<?php echo htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A comprehensive school management system.'); ?>">
<meta property="og:image" content="<?php echo htmlspecialchars($_SERVER['PROJECT_IMAGE_URL'] ?? ''); ?>">
<meta name="twitter:card" content="summary_large_image">
</head>
<body>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
</div>
</main>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
</footer>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">مدیریت مدرسه</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="index.php" class="nav-link px-2 link-secondary">خانه</a></li>
<li><a href="roles.php" class="nav-link px-2 link-dark">مدیریت نقش‌ها</a></li>
<li><a href="users.php" class="nav-link px-2 link-dark">مدیریت کاربران</a></li>
<a href="activities.php">Activities</a>
<a href="exams.php">Exams</a>
<a href="attendance.php">Attendance</a>
</ul>
<div class="text-end">
<?php if (isset($_SESSION['user_id'])): ?>
<a href="logout.php" class="btn btn-outline-primary">خروج</a>
<?php else: ?>
<a href="login.php" class="btn btn-primary">ورود</a>
<?php endif; ?>
</div>
</div>
</div>
</header>
<main>
<section class="hero">
<div class="container">
<h1>سیستم مدیریت یکپارچه مدرسه</h1>
<p>راه حلی مدرن برای مدیریت تمام امور مدرسه شما</p>
<a href="#features" class="btn btn-light btn-lg">بیشتر بدانید</a>
</div>
</section>
<section id="features" class="py-5">
<div class="container">
<h2 class="text-center mb-5">امکانات سیستم</h2>
<div class="row text-center">
<div class="col-md-4">
<div class="feature-card">
<i data-feather="users"></i>
<h3>مدیریت دانش‌آموزان</h3>
<p>ثبت‌نام، اطلاعات تحصیلی و حضور و غیاب.</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i data-feather="briefcase"></i>
<h3>مدیریت معلمان</h3>
<p>اطلاعات پرسنلی، برنامه‌ریزی درسی و ارتباط با والدین.</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i data-feather="book-open"></i>
<h3>مدیریت دوره‌ها</h3>
<p>ایجاد و مدیریت کلاس‌ها و واحدهای درسی.</p>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="footer mt-auto py-3 bg-light">
<div class="container">
<span class="text-muted">© 2025 سیستم مدیریت مدرسه</span>
</div>
</footer>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- Custom JS -->
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
<script>
feather.replace()
</script>
</body>
</html>

126
login.php Normal file
View File

@ -0,0 +1,126 @@
<?php
session_start();
require_once 'db/config.php';
$db = db();
// Redirect if already logged in
if (isset($_SESSION['user_id'])) {
header("Location: index.php");
exit();
}
$error_message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($username) || empty($password)) {
$error_message = 'Please enter both username and password.';
} else {
$stmt = $db->prepare("SELECT id, password, role_id FROM users WHERE username = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $username;
$_SESSION['role_id'] = $user['role_id'];
// Fetch role name
$role_stmt = $db->prepare("SELECT name FROM roles WHERE id = :role_id");
$role_stmt->bindParam(':role_id', $user['role_id']);
$role_stmt->execute();
$role = $role_stmt->fetch(PDO::FETCH_ASSOC);
$role_name = $role ? $role['name'] : null;
$_SESSION['role_name'] = $role_name;
// Log attendance
$login_time = date('Y-m-d H:i:s');
$ip_address = $_SERVER['REMOTE_ADDR'];
$attendance_stmt = $db->prepare("INSERT INTO attendance (user_id, login_time, ip_address) VALUES (:user_id, :login_time, :ip_address)");
$attendance_stmt->bindParam(':user_id', $user['id']);
$attendance_stmt->bindParam(':login_time', $login_time);
$attendance_stmt->bindParam(':ip_address', $ip_address);
$attendance_stmt->execute();
$_SESSION['attendance_id'] = $db->lastInsertId();
switch ($role_name) {
case 'admin':
header("Location: admin_dashboard.php");
break;
case 'parent':
header("Location: parent_dashboard.php");
break;
case 'student':
header("Location: student_dashboard.php");
break;
case 'teacher':
header("Location: teacher_dashboard.php");
break;
default:
header("Location: index.php");
break;
}
exit();
} else {
$error_message = 'Invalid username or password.';
}
}
}
// Fetch header content
ob_start();
include 'index.php';
$page_content = ob_get_clean();
// Extract only the <head> and <header>
$head_and_header = '';
if (preg_match('/<head>.*?<\/head>/s', $page_content, $head_match)) {
$head_and_header .= $head_match[0];
}
if (preg_match('/<header>.*?<\/header>/s', $page_content, $header_match)) {
$head_and_header .= $header_match[0];
}
// Replace active nav link
$head_and_header = str_replace('<a class="nav-link" href="index.php">Home</a>', '<a class="nav-link" href="index.php">Home</a>', $head_and_header);
$head_and_header = preg_replace('/<a class="nav-link active" (.*?)>/', '<a class="nav-link" $1>', $head_and_header);
echo str_replace('</head>', '<style>.login-container { max-width: 400px; margin: 5rem auto; }</style></head>', $head_and_header);
?>
<main class="container mt-5">
<div class="login-container card">
<div class="card-body">
<h1 class="card-title text-center mb-4">Login</h1>
<?php if ($error_message): ?>
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php endif; ?>
<form action="login.php" method="post">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
</div>
</div>
</main>
<?php
// Extract footer
if (preg_match('/<footer.*?>.*?<\/footer>/s', $page_content, $footer_match)) {
echo $footer_match[0];
}
?>

18
logout.php Normal file
View File

@ -0,0 +1,18 @@
<?php
session_start();
require_once 'db/config.php';
if (isset($_SESSION['attendance_id'])) {
$db = db();
$logout_time = date('Y-m-d H:i:s');
$attendance_stmt = $db->prepare("UPDATE attendance SET logout_time = :logout_time WHERE id = :id");
$attendance_stmt->bindParam(':logout_time', $logout_time);
$attendance_stmt->bindParam(':id', $_SESSION['attendance_id']);
$attendance_stmt->execute();
}
session_unset();
session_destroy();
header("Location: login.php");
exit();

43
parent_dashboard.php Normal file
View File

@ -0,0 +1,43 @@
<?php
session_start();
// Authentication check
if (!isset($_SESSION['user_id']) || empty($_SESSION['role_name']) || $_SESSION['role_name'] !== 'parent') {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Parent Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">School Management</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="parent_dashboard.php" class="nav-link px-2 link-secondary">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-dark">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
</ul>
<div class="text-end">
<a href="logout.php" class="btn btn-outline-primary">Logout</a>
</div>
</div>
</div>
</header>
<main class="container py-5">
<h1>Welcome, Parent!</h1>
<p>This is your dashboard.</p>
</main>
</body>
</html>

183
roles.php Normal file
View File

@ -0,0 +1,183 @@
<?php
session_start();
// Authentication check
if (!isset($_SESSION['user_id']) || $_SESSION['role_name'] !== 'admin') {
//header('Location: login.php');
//exit();
}
require_once 'db/config.php';
try {
$pdo = db();
// Create roles table if it doesn't exist
$pdo->exec("CREATE TABLE IF NOT EXISTS roles (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(255) NOT NULL UNIQUE
)");
// Function to log activity
function log_activity($user_id, $action) {
global $pdo;
$stmt = $pdo->prepare("INSERT INTO activities (user_id, action) VALUES (:user_id, :action)");
$stmt->execute(['user_id' => $user_id, 'action' => $action]);
}
// Handle Create and Update
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_role'])) {
$name = trim($_POST['role_name']);
if (!empty($name)) {
$stmt = $pdo->prepare("INSERT INTO roles (role_name) VALUES (:role_name)");
$stmt->execute(['role_name' => $name]);
$new_role_id = $pdo->lastInsertId();
log_activity($_SESSION['user_id'], "Created role {$name} (ID: {$new_role_id})");
}
} elseif (isset($_POST['update_role'])) {
$id = $_POST['role_id'];
$name = trim($_POST['role_name']);
if (!empty($name) && !empty($id)) {
$stmt = $pdo->prepare("UPDATE roles SET role_name = :role_name WHERE id = :id");
$stmt->execute(['role_name' => $name, 'id' => $id]);
log_activity($_SESSION['user_id'], "Updated role {$name} (ID: {$id})");
}
}
header("Location: roles.php");
exit;
}
// Handle Delete
if (isset($_GET['delete_id'])) {
$id = $_GET['delete_id'];
// Get role name for logging
$stmt = $pdo->prepare("SELECT role_name FROM roles WHERE id = :id");
$stmt->execute(['id' => $id]);
$deleted_role = $stmt->fetch();
$stmt = $pdo->prepare("DELETE FROM roles WHERE id = :id");
$stmt->execute(['id' => $id]);
if ($deleted_role) {
log_activity($_SESSION['user_id'], "Deleted role {$deleted_role['role_name']} (ID: {$id})");
}
header("Location: roles.php");
exit;
}
// Fetch all roles
$roles = $pdo->query("SELECT * FROM roles ORDER BY id DESC")->fetchAll();
// Fetch role for editing
$editing_role = null;
if (isset($_GET['edit_id'])) {
$id = $_GET['edit_id'];
$stmt = $pdo->prepare("SELECT * FROM roles WHERE id = :id");
$stmt->execute(['id' => $id]);
$editing_role = $stmt->fetch();
}
} catch (PDOException $e) {
die("Database error: " . $e->getMessage());
}
?>
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>مدیریت نقش‌ها</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.rtl.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<script src="https://unpkg.com/feather-icons"></script>
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">مدیریت مدرسه</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="index.php" class="nav-link px-2 link-dark">خانه</a></li>
<li><a href="roles.php" class="nav-link px-2 link-secondary">مدیریت نقش‌ها</a></li>
<li><a href="users.php" class="nav-link px-2 link-dark">مدیریت کاربران</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-dark">Attendance</a></li>
</ul>
<div class="text-end">
<?php if (isset($_SESSION['user_id'])): ?>
<a href="logout.php" class="btn btn-outline-primary">خروج</a>
<?php else: ?>
<a href="login.php" class="btn btn-primary">ورود</a>
<?php endif; ?>
</div>
</div>
</div>
</header>
<main class="container py-5">
<div class="row">
<div class="col-md-8">
<h2>فهرست نقش‌ها</h2>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
<th>نام نقش</th>
<th>عملیات</th>
</tr>
</thead>
<tbody>
<?php foreach ($roles as $role): ?>
<tr>
<td><?php echo htmlspecialchars($role['id']); ?></td>
<td><?php echo htmlspecialchars($role['role_name']); ?></td>
<td>
<a href="roles.php?edit_id=<?php echo $role['id']; ?>" class="btn btn-sm btn-outline-primary">ویرایش</a>
<a href="roles.php?delete_id=<?php echo $role['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('آیا مطمئن هستید؟')">حذف</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<h2><?php echo $editing_role ? 'ویرایش نقش' : 'افزودن نقش جدید'; ?></h2>
<form method="POST" action="roles.php">
<?php if ($editing_role): ?>
<input type="hidden" name="role_id" value="<?php echo $editing_role['id']; ?>">
<?php endif; ?>
<div class="mb-3">
<label for="role_name" class="form-label">نام نقش</label>
<input type="text" class="form-control" id="role_name" name="role_name" value="<?php echo htmlspecialchars($editing_role['role_name'] ?? ''); ?>" required>
</div>
<?php if ($editing_role): ?>
<button type="submit" name="update_role" class="btn btn-primary w-100">به‌روزرسانی</button>
<a href="roles.php" class="btn btn-secondary w-100 mt-2">انصراف</a>
<?php else: ?>
<button type="submit" name="add_role" class="btn btn-success w-100">افزودن</button>
<?php endif; ?>
</form>
</div>
</div>
</main>
<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">© 2025 سیستم مدیریت مدرسه</span>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
feather.replace()
</script>
</body>
</html>

43
student_dashboard.php Normal file
View File

@ -0,0 +1,43 @@
<?php
session_start();
// Authentication check
if (!isset($_SESSION['user_id']) || empty($_SESSION['role_name']) || $_SESSION['role_name'] !== 'student') {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">School Management</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="student_dashboard.php" class="nav-link px-2 link-secondary">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-dark">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
</ul>
<div class="text-end">
<a href="logout.php" class="btn btn-outline-primary">Logout</a>
</div>
</div>
</div>
</header>
<main class="container py-5">
<h1>Welcome, Student!</h1>
<p>This is your dashboard.</p>
</main>
</body>
</html>

133
take_exam.php Normal file
View File

@ -0,0 +1,133 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'student') {
header('Location: login.php');
exit();
}
$user_id = $_SESSION['user_id'];
$pdo = db();
if (!isset($_GET['student_exam_id'])) {
header('Location: exams.php');
exit();
}
$student_exam_id = $_GET['student_exam_id'];
// Verify student is assigned to this exam
$stmt = $pdo->prepare('SELECT * FROM student_exams WHERE id = ? AND student_id = ?');
$stmt->execute([$student_exam_id, $user_id]);
$student_exam = $stmt->fetch();
if (!$student_exam) {
echo "You are not assigned to this exam.";
exit();
}
// Prevent re-taking a completed exam
if ($student_exam['status'] === 'completed') {
echo "You have already completed this exam.";
// Maybe redirect to a results page in the future
echo '<br><a href="exams.php">Back to Exams</a>';
exit();
}
// Fetch exam details
$stmt = $pdo->prepare('SELECT * FROM exams WHERE id = ?');
$stmt->execute([$student_exam['exam_id']]);
$exam = $stmt->fetch();
// Fetch exam questions
$stmt = $pdo->prepare('SELECT * FROM exam_questions WHERE exam_id = ? ORDER BY id ASC');
$stmt->execute([$exam['id']]);
$questions = $stmt->fetchAll();
// Handle exam submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['answers'])) {
$answers = $_POST['answers'];
$pdo->beginTransaction();
try {
foreach ($answers as $question_id => $answer_text) {
// Use INSERT ... ON DUPLICATE KEY UPDATE to prevent duplicate answer submissions
$sql = 'INSERT INTO student_answers (student_exam_id, question_id, answer_text) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE answer_text = VALUES(answer_text)';
$stmt = $pdo->prepare($sql);
$stmt->execute([$student_exam_id, $question_id, trim($answer_text)]);
}
// Mark exam as completed
$stmt = $pdo->prepare('UPDATE student_exams SET status = \'completed\' WHERE id = ?');
$stmt->execute([$student_exam_id]);
$pdo->commit();
header('Location: exams.php');
exit();
} catch (Exception $e) {
$pdo->rollBack();
// Log error properly in a real application
die("An error occurred while submitting your exam. Please try again. Error: " . $e->getMessage());
}
}
// If student is starting the exam, mark it as 'in-progress'
if ($student_exam['status'] === 'assigned') {
$stmt = $pdo->prepare('UPDATE student_exams SET status = \'in-progress\' WHERE id = ?');
$stmt->execute([$student_exam_id]);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Take Exam: <?php echo htmlspecialchars($exam['name']); ?></title>
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<header>
<h1><?php echo htmlspecialchars($exam['name']); ?></h1>
<nav>
<ul>
<li><a href="exams.php">Back to Exams</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</header>
<main>
<form action="take_exam.php?student_exam_id=<?php echo $student_exam_id; ?>" method="POST">
<?php foreach ($questions as $index => $q): ?>
<div class="question-block">
<p><strong>Question <?php echo $index + 1; ?>:</strong> <?php echo nl2br(htmlspecialchars($q['question_text'])); ?></p>
<?php if ($q['question_type'] === 'multiple_choice'): ?>
<?php $options = json_decode($q['options']); ?>
<?php if($options):
foreach ($options as $option):
?>
<div>
<input type="radio" id="q_<?php echo $q['id'] . '_' . htmlspecialchars($option); ?>" name="answers[<?php echo $q['id']; ?>]" value="<?php echo htmlspecialchars($option); ?>" required>
<label for="q_<?php echo $q['id'] . '_' . htmlspecialchars($option); ?>"><?php echo htmlspecialchars($option); ?></label>
</div>
<?php endforeach; ?>
<?php endif; ?>
<?php else: // free_text ?>
<textarea name="answers[<?php echo $q['id']; ?>]" rows="5" required></textarea>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php if (empty($questions)): ?>
<p>This exam has no questions.</p>
<?php else: ?>
<button type="submit" onclick="return confirm('Are you sure you want to submit your answers?');">Submit Exam</button>
<?php endif; ?>
</form>
</main>
</body>
</html>

43
teacher_dashboard.php Normal file
View File

@ -0,0 +1,43 @@
<?php
session_start();
// Authentication check
if (!isset($_SESSION['user_id']) || empty($_SESSION['role_name']) || $_SESSION['role_name'] !== 'teacher') {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Teacher Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">School Management</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="teacher_dashboard.php" class="nav-link px-2 link-secondary">Dashboard</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-dark">Attendance</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
</ul>
<div class="text-end">
<a href="logout.php" class="btn btn-outline-primary">Logout</a>
</div>
</div>
</div>
</header>
<main class="container py-5">
<h1>Welcome, Teacher!</h1>
<p>This is your dashboard.</p>
</main>
</body>
</html>

318
users.php Normal file
View File

@ -0,0 +1,318 @@
<?php
session_start();
// Authentication check
if (!isset($_SESSION['user_id']) || $_SESSION['role_name'] !== 'admin') {
//header('Location: login.php');
//exit();
}
require_once 'db/config.php';
try {
$pdo = db();
// Create users table if it doesn't exist
$pdo->exec("CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role_id INT,
first_name VARCHAR(255),
last_name VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE SET NULL
)");
// Fetch all roles for the dropdown
$roles = $pdo->query("SELECT * FROM roles ORDER BY role_name")->fetchAll();
// Function to log activity
function log_activity($user_id, $action) {
global $pdo;
$stmt = $pdo->prepare("INSERT INTO activities (user_id, action) VALUES (:user_id, :action)");
$stmt->execute(['user_id' => $user_id, 'action' => $action]);
}
// Handle Create and Update
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_user'])) {
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$role_id = $_POST['role_id'];
$first_name = trim($_POST['first_name']);
$last_name = trim($_POST['last_name']);
if (!empty($username) && !empty($email) && !empty($password) && !empty($role_id)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (username, email, password, role_id, first_name, last_name) VALUES (:username, :email, :password, :role_id, :first_name, :last_name)");
$stmt->execute([
'username' => $username,
'email' => $email,
'password' => $hashed_password,
'role_id' => $role_id,
'first_name' => $first_name,
'last_name' => $last_name
]);
$new_user_id = $pdo->lastInsertId();
log_activity($_SESSION['user_id'], "Created user {$username} (ID: {$new_user_id})");
}
} elseif (isset($_POST['update_user'])) {
$id = $_POST['user_id'];
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$role_id = $_POST['role_id'];
$first_name = trim($_POST['first_name']);
$last_name = trim($_POST['last_name']);
if (!empty($id) && !empty($username) && !empty($email) && !empty($role_id)) {
if (!empty($password)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET username = :username, email = :email, password = :password, role_id = :role_id, first_name = :first_name, last_name = :last_name WHERE id = :id");
$stmt->execute([
'username' => $username,
'email' => $email,
'password' => $hashed_password,
'role_id' => $role_id,
'first_name' => $first_name,
'last_name' => $last_name,
'id' => $id
]);
} else {
$stmt = $pdo->prepare("UPDATE users SET username = :username, email = :email, role_id = :role_id, first_name = :first_name, last_name = :last_name WHERE id = :id");
$stmt->execute([
'username' => $username,
'email' => $email,
'role_id' => $role_id,
'first_name' => $first_name,
'last_name' => $last_name,
'id' => $id
]);
}
log_activity($_SESSION['user_id'], "Updated user {$username} (ID: {$id})");
} elseif (isset($_POST['link_parent_child'])) {
$parent_id = $_POST['parent_id'];
$child_id = $_POST['child_id'];
if (!empty($parent_id) && !empty($child_id)) {
$stmt = $pdo->prepare("INSERT INTO parent_child (parent_id, child_id) VALUES (:parent_id, :child_id)");
$stmt->execute(['parent_id' => $parent_id, 'child_id' => $child_id]);
log_activity($_SESSION['user_id'], "Linked parent (ID: {$parent_id}) to child (ID: {$child_id})");
}
header("Location: users.php?link_success=1");
exit;
}
header("Location: users.php");
exit;
}
// Handle Delete
if (isset($_GET['delete_id'])) {
$id = $_GET['delete_id'];
// Get username for logging
$stmt = $pdo->prepare("SELECT username FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$deleted_user = $stmt->fetch();
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
if ($deleted_user) {
log_activity($_SESSION['user_id'], "Deleted user {$deleted_user['username']} (ID: {$id})");
}
header("Location: users.php");
exit;
}
// Fetch all users with their role names
$users = $pdo->query("
SELECT users.*, roles.role_name AS role_name
FROM users
LEFT JOIN roles ON users.role_id = roles.id
ORDER BY users.id DESC
")->fetchAll();
// Fetch all parents and students
$parents = $pdo->query("SELECT u.id, u.first_name, u.last_name FROM users u JOIN roles r ON u.role_id = r.id WHERE r.role_name = 'parent'")->fetchAll();
$students = $pdo->query("SELECT u.id, u.first_name, u.last_name FROM users u JOIN roles r ON u.role_id = r.id WHERE r.role_name = 'student'")->fetchAll();
// Fetch user for editing
$editing_user = null;
if (isset($_GET['edit_id'])) {
$id = $_GET['edit_id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$editing_user = $stmt->fetch();
}
} catch (PDOException $e) {
die("Database error: " . $e->getMessage());
}
?>
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>مدیریت کاربران</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.rtl.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<script src="https://unpkg.com/feather-icons"></script>
</head>
<body>
<header class="p-3 mb-3 border-bottom sticky-top bg-light">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-dark text-decoration-none">
<span class="fs-4">مدیریت مدرسه</span>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="index.php" class="nav-link px-2 link-dark">خانه</a></li>
<li><a href="roles.php" class="nav-link px-2 link-dark">مدیریت نقش‌ها</a></li>
<li><a href="users.php" class="nav-link px-2 link-secondary">مدیریت کاربران</a></li>
<li><a href="activities.php" class="nav-link px-2 link-dark">Activities</a></li>
<li><a href="exams.php" class="nav-link px-2 link-dark">Exams</a></li>
<li><a href="attendance.php" class="nav-link px-2 link-dark">Attendance</a></li>
</ul>
<div class="text-end">
<?php if (isset($_SESSION['user_id'])): ?>
<a href="logout.php" class="btn btn-outline-primary">خروج</a>
<?php else: ?>
<a href="login.php" class="btn btn-primary">ورود</a>
<?php endif; ?>
</div>
</div>
</div>
</header>
<main class="container py-5">
<div class="row">
<div class="col-md-8">
<h2>فهرست کاربران</h2>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
<th>نام کاربری</th>
<th>ایمیل</th>
<th>نقش</th>
<th>عملیات</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['id']); ?></td>
<td><?php echo htmlspecialchars($user['username']); ?></td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td><?php echo htmlspecialchars($user['role_name'] ?? 'بدون نقش'); ?></td>
<td>
<a href="users.php?edit_id=<?php echo $user['id']; ?>" class="btn btn-sm btn-outline-primary">ویرایش</a>
<a href="users.php?delete_id=<?php echo $user['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('آیا مطمئن هستید؟')">حذف</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<h2><?php echo $editing_user ? 'ویرایش کاربر' : 'افزودن کاربر جدید'; ?></h2>
<form method="POST" action="users.php">
<?php if ($editing_user): ?>
<input type="hidden" name="user_id" value="<?php echo $editing_user['id']; ?>">
<?php endif; ?>
<div class="mb-3">
<label for="username" class="form-label">نام کاربری</label>
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($editing_user['username'] ?? ''); ?>" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">ایمیل</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($editing_user['email'] ?? ''); ?>" required>
</div>
<div class="mb-3">
<label for="first_name" class="form-label">نام</label>
<input type="text" class="form-control" id="first_name" name="first_name" value="<?php echo htmlspecialchars($editing_user['first_name'] ?? ''); ?>">
</div>
<div class="mb-3">
<label for="last_name" class="form-label">نام خانوادگی</label>
<input type="text" class="form-control" id="last_name" name="last_name" value="<?php echo htmlspecialchars($editing_user['last_name'] ?? ''); ?>">
</div>
<div class="mb-3">
<label for="password" class="form-label">رمز عبور <?php echo $editing_user ? '(خالی بگذارید تا بدون تغییر بماند)' : ''; ?></label>
<input type="password" class="form-control" id="password" name="password" <?php echo !$editing_user ? 'required' : ''; ?>>
</div>
<div class="mb-3">
<label for="role_id" class="form-label">نقش</label>
<select class="form-select" id="role_id" name="role_id" required>
<option value="">یک نقش انتخاب کنید</option>
<?php foreach ($roles as $role): ?>
<option value="<?php echo $role['id']; ?>" <?php echo (isset($editing_user) && $editing_user['role_id'] == $role['id']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($role['role_name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php if ($editing_user): ?>
<button type="submit" name="update_user" class="btn btn-primary w-100">به‌روزرسانی</button>
<a href="users.php" class="btn btn-secondary w-100 mt-2">انصراف</a>
<?php else: ?>
<button type="submit" name="add_user" class="btn btn-success w-100">افزودن</button>
<?php endif; ?>
</form>
</div>
</div>
<div class="row mt-5">
<div class="col-md-12">
<h2>Link Parent to Child</h2>
<?php if (isset($_GET['link_success'])): ?>
<div class="alert alert-success">Parent and child linked successfully.</div>
<?php endif; ?>
<form method="POST" action="users.php">
<div class="row">
<div class="col-md-5">
<label for="parent_id" class="form-label">Parent</label>
<select class="form-select" id="parent_id" name="parent_id" required>
<option value="">Select a parent</option>
<?php foreach ($parents as $parent): ?>
<option value="<?php echo $parent['id']; ?>"><?php echo htmlspecialchars($parent['first_name'] . ' ' . $parent['last_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-5">
<label for="child_id" class="form-label">Child</label>
<select class="form-select" id="child_id" name="child_id" required>
<option value="">Select a child</option>
<?php foreach ($students as $student): ?>
<option value="<?php echo $student['id']; ?>"><?php echo htmlspecialchars($student['first_name'] . ' ' . $student['last_name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" name="link_parent_child" class="btn btn-primary w-100">Link</button>
</div>
</div>
</form>
</div>
</div>
</main>
<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">© 2025 سیستم مدیریت مدرسه</span>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
feather.replace()
</script>
</body>
</html>