diff --git a/certificate.php b/certificate.php new file mode 100644 index 0000000..904e07e --- /dev/null +++ b/certificate.php @@ -0,0 +1,125 @@ +prepare("SELECT name FROM users WHERE id = ?"); +$user_stmt->execute([$user_id]); +$user_name = $user_stmt->fetchColumn(); + +// Fetch skill title +$skill_stmt = $db->prepare("SELECT title FROM skills WHERE id = ?"); +$skill_stmt->execute([$skill_id]); +$skill_title = $skill_stmt->fetchColumn(); + +// Fetch latest quiz attempt with a score of 70% or higher +$attempt_stmt = $db->prepare("SELECT score, completed_at FROM quiz_attempts WHERE user_id = ? AND skill_id = ? AND score >= 70 ORDER BY completed_at DESC LIMIT 1"); +$attempt_stmt->execute([$user_id, $skill_id]); +$attempt = $attempt_stmt->fetch(PDO::FETCH_ASSOC); + +if (!$user_name || !$skill_title || !$attempt) { + // Redirect or show an error if the user is not eligible for a certificate + header('Location: dashboard.php?error=not_eligible'); + exit; +} + +$completion_date = date("F j, Y", strtotime($attempt['completed_at'])); + +?> + + + + + + Certificate of Completion + + + + + +
+
Certificate of Completion
+
This is to certify that
+
+
has successfully completed the skill
+
""
+
on
+
+ Back to Dashboard + +
+
+ + + \ No newline at end of file diff --git a/db/migrations/011_create_lesson_completion_table.sql b/db/migrations/011_create_lesson_completion_table.sql new file mode 100644 index 0000000..e6e4214 --- /dev/null +++ b/db/migrations/011_create_lesson_completion_table.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS lesson_completion ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT(11) UNSIGNED NOT NULL, + lesson_id INT(11) NOT NULL, + completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE, + UNIQUE KEY (user_id, lesson_id) +); \ No newline at end of file diff --git a/db/migrations/012_create_quizzes_table.sql b/db/migrations/012_create_quizzes_table.sql new file mode 100644 index 0000000..6cb75ea --- /dev/null +++ b/db/migrations/012_create_quizzes_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS quizzes ( + id INT AUTO_INCREMENT PRIMARY KEY, + skill_id INT NOT NULL, + question TEXT NOT NULL, + option_a VARCHAR(255) NOT NULL, + option_b VARCHAR(255) NOT NULL, + option_c VARCHAR(255) NOT NULL, + option_d VARCHAR(255) NOT NULL, + correct_option CHAR(1) NOT NULL, + FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE +); \ No newline at end of file diff --git a/db/migrations/013_create_quiz_attempts_table.sql b/db/migrations/013_create_quiz_attempts_table.sql new file mode 100644 index 0000000..d580c33 --- /dev/null +++ b/db/migrations/013_create_quiz_attempts_table.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS quiz_attempts ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT(11) UNSIGNED NOT NULL, + skill_id INT NOT NULL, + score INT NOT NULL, + completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE +); \ No newline at end of file diff --git a/db/migrations/014_insert_sample_quiz.sql b/db/migrations/014_insert_sample_quiz.sql new file mode 100644 index 0000000..913110c --- /dev/null +++ b/db/migrations/014_insert_sample_quiz.sql @@ -0,0 +1,6 @@ +INSERT INTO quizzes (skill_id, question, option_a, option_b, option_c, option_d, correct_option) VALUES +(1, 'What does HTML stand for?', 'Hyper Text Markup Language', 'High Tech Modern Language', 'Hyperlink and Text Markup Language', 'Home Tool Markup Language', 'a'), +(1, 'Who is making the Web standards?', 'Mozilla', 'The World Wide Web Consortium', 'Google', 'Microsoft', 'b'), +(1, 'Choose the correct HTML element for the largest heading:', '

', '', '
', '', 'a'), +(1, 'What is the correct HTML element for inserting a line break?', '', '
', '', '', 'b'), +(1, 'What is the correct HTML for creating a hyperlink?', 'Example', 'http://www.example.com', 'Example', 'http://www.example.com', 'a'); \ No newline at end of file diff --git a/db/show_schema.php b/db/show_schema.php index f9ca1d6..71b2ef2 100644 --- a/db/show_schema.php +++ b/db/show_schema.php @@ -9,12 +9,11 @@ try { echo "Users table definition:\n"; print_r($user_table_def); - $stmt = $pdo->query("SHOW CREATE TABLE skills"); - $skill_table_def = $stmt->fetch(PDO::FETCH_ASSOC); - echo "\nSkills table definition:\n"; - print_r($skill_table_def); + $stmt = $pdo->query("SHOW CREATE TABLE lessons"); + $lesson_table_def = $stmt->fetch(PDO::FETCH_ASSOC); + echo "\nLessons table definition:\n"; + print_r($lesson_table_def); } catch (PDOException $e) { die("Database query failed: " . $e->getMessage()); -} - +} \ No newline at end of file diff --git a/learn.php b/learn.php index 8e109e2..2467dbc 100644 --- a/learn.php +++ b/learn.php @@ -8,6 +8,41 @@ require_once 'db/config.php'; $db = db(); $skill_id = $_GET['skill_id'] ?? 0; +$user_id = $_SESSION['user_id']; + +// Handle marking a lesson as complete +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['complete_lesson'])) { + $lesson_id = $_POST['lesson_id']; + + // Check if already completed + $stmt = $db->prepare("SELECT id FROM lesson_completion WHERE user_id = ? AND lesson_id = ?"); + $stmt->execute([$user_id, $lesson_id]); + if ($stmt->fetch()) { + // Already completed, do nothing + } else { + // Insert into lesson_completion + $stmt = $db->prepare("INSERT INTO lesson_completion (user_id, lesson_id) VALUES (?, ?)"); + $stmt->execute([$user_id, $lesson_id]); + + // Recalculate progress + $total_lessons_stmt = $db->prepare("SELECT COUNT(*) FROM lessons l JOIN modules m ON l.module_id = m.id WHERE m.skill_id = ?"); + $total_lessons_stmt->execute([$skill_id]); + $total_lessons = $total_lessons_stmt->fetchColumn(); + + $completed_lessons_stmt = $db->prepare("SELECT COUNT(*) FROM lesson_completion lc JOIN lessons l ON lc.lesson_id = l.id JOIN modules m ON l.module_id = m.id WHERE lc.user_id = ? AND m.skill_id = ?"); + $completed_lessons_stmt->execute([$user_id, $skill_id]); + $completed_lessons = $completed_lessons_stmt->fetchColumn(); + + $progress = ($total_lessons > 0) ? round(($completed_lessons / $total_lessons) * 100) : 0; + + // Update enrollments table + $update_stmt = $db->prepare("UPDATE enrollments SET progress = ? WHERE user_id = ? AND skill_id = ?"); + $update_stmt->execute([$progress, $user_id, $skill_id]); + } + header("Location: learn.php?skill_id=$skill_id"); + exit; +} + // Fetch skill details $stmt = $db->prepare("SELECT * FROM skills WHERE id = ?"); @@ -18,6 +53,11 @@ if (!$skill) { die('Skill not found!'); } +// Fetch completed lesson IDs for the user +$completed_lessons_stmt = $db->prepare("SELECT lesson_id FROM lesson_completion WHERE user_id = ?"); +$completed_lessons_stmt->execute([$user_id]); +$completed_lesson_ids = $completed_lessons_stmt->fetchAll(PDO::FETCH_COLUMN); + // Fetch modules and lessons $modules_stmt = $db->prepare("SELECT * FROM modules WHERE skill_id = ? ORDER BY `order` ASC"); $modules_stmt->execute([$skill_id]); @@ -25,6 +65,13 @@ $modules = $modules_stmt->fetchAll(PDO::FETCH_ASSOC); $lessons_stmt = $db->prepare("SELECT * FROM lessons WHERE module_id = ? ORDER BY `order` ASC"); +// Calculate progress +$total_lessons_stmt = $db->prepare("SELECT COUNT(*) FROM lessons l JOIN modules m ON l.module_id = m.id WHERE m.skill_id = ?"); +$total_lessons_stmt->execute([$skill_id]); +$total_lessons = $total_lessons_stmt->fetchColumn(); +$completed_lessons = count($completed_lesson_ids); +$progress = ($total_lessons > 0) ? round(($completed_lessons / $total_lessons) * 100) : 0; + ?> @@ -33,6 +80,7 @@ $lessons_stmt = $db->prepare("SELECT * FROM lessons WHERE module_id = ? ORDER BY Learning: <?php echo htmlspecialchars($skill['title']); ?> + @@ -40,6 +88,12 @@ $lessons_stmt = $db->prepare("SELECT * FROM lessons WHERE module_id = ? ORDER BY Back to Dashboard

+ + +
+
% Complete
+
+

@@ -66,10 +120,25 @@ $lessons_stmt = $db->prepare("SELECT * FROM lessons WHERE module_id = ? ORDER BY

No lessons in this module yet.

    - -
  • -
    -

    + +
  • +
    +
    + + + + +
    +

    +
    + +
    + + +
    +
@@ -81,6 +150,39 @@ $lessons_stmt = $db->prepare("SELECT * FROM lessons WHERE module_id = ? ORDER BY + + prepare("SELECT * FROM quiz_attempts WHERE user_id = ? AND skill_id = ? ORDER BY completed_at DESC LIMIT 1"); + $quiz_attempt_stmt->execute([$user_id, $skill_id]); + $quiz_attempt = $quiz_attempt_stmt->fetch(PDO::FETCH_ASSOC); + ?> + + = 100): ?> +
+
+ +

Quiz Result

+

You scored % on your last attempt.

+ = 70): ?> + + View Certificate + + +

You need a score of 70% or higher to get a certificate.

+ + Retake Quiz + + + +

Ready to test your knowledge?

+

You have completed all the lessons. It's time to take the quiz!

+ Take Quiz + +
+
+ + diff --git a/quiz.php b/quiz.php new file mode 100644 index 0000000..92a9362 --- /dev/null +++ b/quiz.php @@ -0,0 +1,108 @@ +prepare("SELECT title FROM skills WHERE id = ?"); +$stmt->execute([$skill_id]); +$skill_title = $stmt->fetchColumn(); + +if (!$skill_title) { + die('Skill not found!'); +} + +// Fetch quiz questions +$questions_stmt = $db->prepare("SELECT * FROM quizzes WHERE skill_id = ?"); +$questions_stmt->execute([$skill_id]); +$questions = $questions_stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $score = 0; + $total_questions = count($questions); + + foreach ($questions as $question) { + $question_id = $question['id']; + $user_answer = $_POST['question_' . $question_id] ?? ''; + if ($user_answer === $question['correct_option']) { + $score++; + } + } + + $percentage_score = ($total_questions > 0) ? round(($score / $total_questions) * 100) : 0; + + // Save quiz attempt + $insert_stmt = $db->prepare("INSERT INTO quiz_attempts (user_id, skill_id, score) VALUES (?, ?, ?)"); + $insert_stmt->execute([$user_id, $skill_id, $percentage_score]); + + header("Location: learn.php?skill_id=$skill_id"); + exit; +} + +?> + + + + + + Quiz: <?php echo htmlspecialchars($skill_title); ?> + + + + +
+ Back to Learning +

Quiz:

+ + +
No quiz questions available for this skill yet.
+ +
+ $question): ?> +
+
+
Question
+
+
+

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+ +
+ + + \ No newline at end of file