Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'psychologist') {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("
|
||||
SELECT u.username, t.title, ut.score, ut.completed_at
|
||||
FROM user_tests ut
|
||||
JOIN users u ON ut.user_id = u.id
|
||||
JOIN tests t ON ut.test_id = t.id
|
||||
ORDER BY ut.completed_at DESC
|
||||
");
|
||||
$results = $stmt->fetchAll();
|
||||
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<h1 class="mt-5">Панель психолога</h1>
|
||||
<p class="lead">Добро пожаловать, <?php echo htmlspecialchars($_SESSION['username']); ?>!</p>
|
||||
|
||||
<h2 class="mt-4">Результаты тестов</h2>
|
||||
|
||||
<?php if (empty($results)): ?>
|
||||
<div class="alert alert-info mt-3" role="alert">
|
||||
Пока нет ни одного пройденного теста.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive mt-3">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col">Пользователь</th>
|
||||
<th scope="col">Тест</th>
|
||||
<th scope="col">Баллы</th>
|
||||
<th scope="col">Дата</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($results as $result): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($result['username']); ?></td>
|
||||
<td><?php echo htmlspecialchars($result['title']); ?></td>
|
||||
<td><?php echo htmlspecialchars($result['score']); ?></td>
|
||||
<td><?php echo date('d.m.Y H:i', strtotime($result['completed_at'])); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
@ -1,43 +0,0 @@
|
||||
/* Psychological Testing System Custom Styles */
|
||||
:root {
|
||||
--primary: #3B82F6;
|
||||
--secondary: #10B981;
|
||||
--background: #F9FAFB;
|
||||
--surface: #FFFFFF;
|
||||
--text-primary: #1F2937;
|
||||
--text-secondary: #4B5563;
|
||||
--border: #E5E7EB;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.test-card {
|
||||
background-color: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.test-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
opacity: 0.9;
|
||||
background-color: var(--primary);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
163
create_test.php
163
create_test.php
@ -1,163 +0,0 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once 'db/config.php';
|
||||
require_once 'includes/header.php';
|
||||
|
||||
// Block access if not logged in or not a psychologist
|
||||
if (!isset($_SESSION["user_id"]) || !isset($_SESSION["role"]) || $_SESSION["role"] !== 'psychologist') {
|
||||
header("Location: login.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$description = trim($_POST['description'] ?? '');
|
||||
$is_public = isset($_POST['is_public']) ? 1 : 0;
|
||||
$questions = $_POST['questions'] ?? [];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
if (empty($title) || empty($description) || empty($questions)) {
|
||||
$error = "Please fill out the title, description, and add at least one question.";
|
||||
} else {
|
||||
$pdo = db();
|
||||
if ($pdo) {
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Insert test
|
||||
$stmt = $pdo->prepare("INSERT INTO tests (user_id, title, description, is_public) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$user_id, $title, $description, $is_public]);
|
||||
$test_id = $pdo->lastInsertId();
|
||||
|
||||
// Insert questions and options
|
||||
foreach ($questions as $q_data) {
|
||||
$question_text = trim($q_data['text'] ?? '');
|
||||
if (empty($question_text)) continue;
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO questions (test_id, question_text) VALUES (?, ?)");
|
||||
$stmt->execute([$test_id, $question_text]);
|
||||
$question_id = $pdo->lastInsertId();
|
||||
|
||||
$options = $q_data['options'] ?? [];
|
||||
$correct_option_index = isset($q_data['correct']) ? intval($q_data['correct']) : -1;
|
||||
|
||||
foreach ($options as $index => $option_text) {
|
||||
$option_text = trim($option_text);
|
||||
if(empty($option_text)) continue;
|
||||
|
||||
$is_correct = ($index === $correct_option_index);
|
||||
$stmt = $pdo->prepare("INSERT INTO options (question_id, option_text, is_correct) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$question_id, $option_text, $is_correct]);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
$message = "Test created successfully!";
|
||||
} catch (PDOException $e) {
|
||||
$pdo->rollBack();
|
||||
$error = "Database error: " . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$error = "Could not connect to the database.";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<main class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<h2 class="mb-4">Create a New Test</h2>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="alert alert-success"><?php echo $message; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="create_test.php" method="POST" id="create-test-form">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">Test Title</label>
|
||||
<input type="text" class="form-control" id="title" name="title" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3" required></textarea>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="is_public" name="is_public" value="1" checked>
|
||||
<label class="form-check-label" for="is_public">Make this test public</label>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<h4>Questions</h4>
|
||||
<div id="questions-container">
|
||||
<!-- Questions will be added here dynamically -->
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary mt-2" id="add-question">Add Question</button>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<button type="submit" class="btn btn-primary">Create Test</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const questionsContainer = document.getElementById('questions-container');
|
||||
const addQuestionBtn = document.getElementById('add-question');
|
||||
let questionCounter = 0;
|
||||
|
||||
addQuestionBtn.addEventListener('click', function () {
|
||||
questionCounter++;
|
||||
const questionId = `q_${questionCounter}`;
|
||||
|
||||
const questionBlock = document.createElement('div');
|
||||
questionBlock.className = 'question-block border p-3 mb-3';
|
||||
questionBlock.innerHTML = `
|
||||
<div class="mb-2">
|
||||
<label for="${questionId}_text" class="form-label fw-bold">Question ${questionCounter}</label>
|
||||
<input type="text" class="form-control" id="${questionId}_text" name="questions[${questionCounter}][text]" required>
|
||||
</div>
|
||||
<div class="options-container ms-3">
|
||||
<label class="form-label">Options</label>
|
||||
<!-- Options will be added here -->
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary ms-3 mt-2 add-option-btn">Add Option</button>
|
||||
`;
|
||||
questionsContainer.appendChild(questionBlock);
|
||||
});
|
||||
|
||||
questionsContainer.addEventListener('click', function(e) {
|
||||
if (e.target && e.target.classList.contains('add-option-btn')) {
|
||||
const questionBlock = e.target.closest('.question-block');
|
||||
const questionIndex = Array.from(questionsContainer.children).indexOf(questionBlock);
|
||||
const optionsContainer = questionBlock.querySelector('.options-container');
|
||||
const optionCounter = optionsContainer.querySelectorAll('.input-group').length;
|
||||
|
||||
const optionBlock = document.createElement('div');
|
||||
optionBlock.className = 'input-group input-group-sm mb-2';
|
||||
optionBlock.innerHTML = `
|
||||
<div class="input-group-text">
|
||||
<input class="form-check-input mt-0" type="radio" value="${optionCounter}" name="questions[${questionIndex + 1}][correct]" required>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="questions[${questionIndex + 1}][options][]" required>
|
||||
`;
|
||||
optionsContainer.appendChild(optionBlock);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'includes/footer.php'; // Assuming you might have a footer ?>
|
||||
</body>
|
||||
</html>
|
||||
@ -1 +0,0 @@
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
<?php
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Psychological Testing System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<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;500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light mb-5">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="index.php">Psychological Testing System</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<?php if (isset($_SESSION['user_id'])): ?>
|
||||
<li class="nav-item">
|
||||
<span class="nav-link">Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?>!</span>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">Tests</a>
|
||||
</li>
|
||||
<?php if ($_SESSION['role'] === 'psychologist'): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="admin_panel.php">Admin Panel</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="create_test.php">Create Test</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="logout.php">Logout</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="login.php">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link btn btn-primary text-white" href="register.php">Register</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
290
index.php
290
index.php
@ -1,156 +1,150 @@
|
||||
<?php
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(0);
|
||||
|
||||
require_once 'db/config.php';
|
||||
|
||||
function setupDatabase($pdo) {
|
||||
try {
|
||||
// Create users table
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role ENUM('user', 'psychologist') NOT NULL DEFAULT 'user',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);");
|
||||
|
||||
// Create tests table
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS tests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
is_public BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);");
|
||||
|
||||
// Add user_id column to tests table if it doesn't exist
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM tests LIKE 'user_id'");
|
||||
if ($stmt->rowCount() == 0) {
|
||||
$pdo->exec("ALTER TABLE tests ADD COLUMN user_id INT, ADD FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;");
|
||||
}
|
||||
|
||||
|
||||
// Create questions table
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS questions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
test_id INT NOT NULL,
|
||||
question_text TEXT NOT NULL,
|
||||
FOREIGN KEY (test_id) REFERENCES tests(id) ON DELETE CASCADE
|
||||
);");
|
||||
|
||||
// Create options table
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS options (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
question_id INT NOT NULL,
|
||||
option_text VARCHAR(255) NOT NULL,
|
||||
FOREIGN KEY (question_id) REFERENCES questions(id) ON DELETE CASCADE
|
||||
);");
|
||||
|
||||
// Add score column to options table if it doesn't exist
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM options LIKE 'score'");
|
||||
if ($stmt->rowCount() == 0) {
|
||||
$pdo->exec("ALTER TABLE options ADD COLUMN score INT NOT NULL DEFAULT 0;");
|
||||
}
|
||||
|
||||
|
||||
// Create user_tests table to track completed tests and scores
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS user_tests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
test_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 (test_id) REFERENCES tests(id) ON DELETE CASCADE,
|
||||
UNIQUE(user_id, test_id)
|
||||
);");
|
||||
|
||||
// Create test_results_interpretations table
|
||||
$pdo->exec("CREATE TABLE IF NOT EXISTS test_results_interpretations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
test_id INT NOT NULL,
|
||||
min_score INT NOT NULL,
|
||||
max_score INT NOT NULL,
|
||||
interpretation TEXT NOT NULL,
|
||||
FOREIGN KEY (test_id) REFERENCES tests(id) ON DELETE CASCADE
|
||||
);");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Check if there's any data
|
||||
$stmt = $pdo->query('SELECT COUNT(*) FROM tests');
|
||||
$count = $stmt->fetchColumn();
|
||||
|
||||
if ($count == 0) {
|
||||
// Insert dummy data
|
||||
$tests = [
|
||||
['title' => 'Big Five Personality Test', 'description' => 'A comprehensive test to understand your personality based on five major traits.'],
|
||||
['title' => 'IQ Test - Logic & Reasoning', 'description' => 'Assess your logical reasoning and problem-solving abilities.'],
|
||||
['title' => 'Myers-Briggs Type Indicator (MBTI)', 'description' => 'Discover your personality type and how you perceive the world.'],
|
||||
['title' => 'Emotional Intelligence (EQ) Test', 'description' => 'Evaluate your ability to perceive, control, and evaluate emotions.'],
|
||||
];
|
||||
$insertStmt = $pdo->prepare('INSERT INTO tests (title, description) VALUES (?, ?)');
|
||||
foreach ($tests as $test) {
|
||||
$insertStmt->execute([$test['title'], $test['description']]);
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
// Don't expose error details to the user
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
if ($pdo) {
|
||||
setupDatabase($pdo);
|
||||
try {
|
||||
$stmt = $pdo->query('SELECT id, title, description FROM tests WHERE is_public = TRUE ORDER BY created_at DESC');
|
||||
$tests = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
$tests = [];
|
||||
}
|
||||
} else {
|
||||
$tests = [];
|
||||
}
|
||||
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');
|
||||
?>
|
||||
<?php require_once 'includes/header.php'; ?>
|
||||
|
||||
<main class="container">
|
||||
<div class="text-center mb-5">
|
||||
<h1 class="fw-bold">Available Tests</h1>
|
||||
<p class="lead text-secondary">Choose a test to start your self-discovery journey.</p>
|
||||
</div>
|
||||
|
||||
<?php if (empty($tests)): ?>
|
||||
<div class="alert alert-warning text-center" role="alert">
|
||||
Could not connect to the database or no tests are available at the moment. Please try again later.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="row g-4">
|
||||
<?php foreach ($tests as $test): ?>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card h-100 test-card p-3">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h5 class="card-title fw-bold"><?php echo htmlspecialchars($test['title']); ?></h5>
|
||||
<p class="card-text text-secondary flex-grow-1"><?php echo htmlspecialchars($test['description']); ?></p>
|
||||
<a href="take_test.php?test_id=<?php echo $test['id']; ?>" class="btn btn-primary mt-3">Start Test</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<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>
|
||||
</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 class="py-5 mt-5 text-center text-secondary">
|
||||
<p>© <?php echo date('Y'); ?> Psychological Testing System. All rights reserved.</p>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
97
login.php
97
login.php
@ -1,97 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
// If already logged in, redirect to index
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
header("Location: index.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$username = trim($_POST['username']);
|
||||
$password = $_POST['password'];
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
$error = 'Please enter both username and password.';
|
||||
} else {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT id, username, password, role FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
// Password is correct, start a new session
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['role'] = $user['role'];
|
||||
|
||||
// Redirect to the main page
|
||||
header("Location: index.php");
|
||||
exit;
|
||||
} else {
|
||||
$error = 'Invalid username or password.';
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$error = 'Database error. Please try again later.';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login - Psychological Testing System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light mb-5">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="index.php">Psychological Testing System</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="text-center fw-bold mb-4">Login</h1>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></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-4">
|
||||
<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 class="text-center mt-4">
|
||||
<p>Don't have an account? <a href="register.php">Register here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="py-5 mt-5 text-center text-secondary">
|
||||
<p>© <?php echo date('Y'); ?> Psychological Testing System. All rights reserved.</p>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
20
logout.php
20
logout.php
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
// Unset all of the session variables
|
||||
$_SESSION = array();
|
||||
|
||||
// Destroy the session.
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
}
|
||||
|
||||
session_destroy();
|
||||
|
||||
// Redirect to login page
|
||||
header("Location: index.php");
|
||||
exit;
|
||||
110
register.php
110
register.php
@ -1,110 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
$error = '';
|
||||
$success = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$username = trim($_POST['username']);
|
||||
$password = $_POST['password'];
|
||||
$role = $_POST['role'] ?? 'user';
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
$error = 'Please fill in all fields.';
|
||||
} elseif (strlen($password) < 6) {
|
||||
$error = 'Password must be at least 6 characters long.';
|
||||
} elseif ($role !== 'user' && $role !== 'psychologist') {
|
||||
$error = 'Invalid role selected.';
|
||||
} else {
|
||||
try {
|
||||
$pdo = db();
|
||||
// Check if username already exists
|
||||
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
if ($stmt->fetch()) {
|
||||
$error = 'Username already taken.';
|
||||
} else {
|
||||
// Hash the password
|
||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||
|
||||
// Insert new user
|
||||
$insertStmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
|
||||
if ($insertStmt->execute([$username, $hashed_password, $role])) {
|
||||
$success = 'Registration successful! You can now <a href="login.php">login</a>.';
|
||||
} else {
|
||||
$error = 'Something went wrong. Please try again later.';
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$error = 'Database error. Please try again later.';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Register - Psychological Testing System</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light mb-5">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="index.php">Psychological Testing System</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="text-center fw-bold mb-4">Create an Account</h1>
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||
<?php else: ?>
|
||||
<form action="register.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="mb-3">
|
||||
<label for="role" class="form-label">Register as</label>
|
||||
<select class="form-select" id="role" name="role">
|
||||
<option value="user" selected>User</option>
|
||||
<option value="psychologist">Psychologist</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary">Register</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<div class="text-center mt-4">
|
||||
<p>Already have an account? <a href="login.php">Login here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="py-5 mt-5 text-center text-secondary">
|
||||
<p>© <?php echo date('Y'); ?> Psychological Testing System. All rights reserved.</p>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Redirect if not logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check for test ID
|
||||
if (!isset($_GET['test_id']) || !is_numeric($_GET['test_id'])) {
|
||||
// Redirect to home or show an error
|
||||
header('Location: index.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
$test_id = intval($_GET['test_id']);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Start a transaction
|
||||
$db->beginTransaction();
|
||||
|
||||
// Delete from user_answers
|
||||
$stmt_answers = $db->prepare("DELETE FROM user_answers WHERE user_id = :user_id AND question_id IN (SELECT id FROM questions WHERE test_id = :test_id)");
|
||||
$stmt_answers->execute(['user_id' => $user_id, 'test_id' => $test_id]);
|
||||
|
||||
// Delete from user_tests
|
||||
$stmt_tests = $db->prepare("DELETE FROM user_tests WHERE user_id = :user_id AND test_id = :test_id");
|
||||
$stmt_tests->execute(['user_id' => $user_id, 'test_id' => $test_id]);
|
||||
|
||||
// Commit the transaction
|
||||
$db->commit();
|
||||
|
||||
// Redirect to the test page
|
||||
header('Location: take_test.php?test_id=' . $test_id);
|
||||
exit();
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// Rollback the transaction if something failed
|
||||
if ($db->inTransaction()) {
|
||||
$db->rollBack();
|
||||
}
|
||||
// You might want to log this error instead of showing it to the user
|
||||
die("Database error while trying to reset the test. Please try again.");
|
||||
}
|
||||
|
||||
// No need for footer as we are redirecting
|
||||
?>
|
||||
@ -1,83 +0,0 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Redirect if not logged in or if it's not a POST request
|
||||
if (!isset($_SESSION['user_id']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// Basic validation
|
||||
if (!isset($_POST['test_id']) || !is_numeric($_POST['test_id']) || !isset($_POST['answers']) || !is_array($_POST['answers'])) {
|
||||
die("Invalid data submitted.");
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$test_id = intval($_POST['test_id']);
|
||||
$answers = $_POST['answers'];
|
||||
$total_score = 0;
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Get the scores for the selected options
|
||||
$option_ids = array_values($answers);
|
||||
$placeholders = implode(',', array_fill(0, count($option_ids), '?'));
|
||||
|
||||
$scoreStmt = $db->prepare("SELECT id, score FROM options WHERE id IN ($placeholders)");
|
||||
$scoreStmt->execute($option_ids);
|
||||
$scores = $scoreStmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
|
||||
// Begin transaction
|
||||
$db->beginTransaction();
|
||||
|
||||
// Prepare statement for inserting or updating user answers
|
||||
$answerStmt = $db->prepare(
|
||||
"INSERT INTO user_answers (user_id, question_id, option_id) VALUES (:user_id, :question_id, :option_id)
|
||||
ON DUPLICATE KEY UPDATE option_id = VALUES(option_id)"
|
||||
);
|
||||
|
||||
// Calculate total score and insert individual answers
|
||||
foreach ($answers as $question_id => $option_id) {
|
||||
if (isset($scores[$option_id])) {
|
||||
$total_score += $scores[$option_id];
|
||||
}
|
||||
|
||||
// Insert the answer
|
||||
$answerStmt->execute([
|
||||
'user_id' => $user_id,
|
||||
'question_id' => $question_id,
|
||||
'option_id' => $option_id
|
||||
]);
|
||||
}
|
||||
|
||||
// Save the final score in the user_tests table
|
||||
$userTestStmt = $db->prepare("
|
||||
INSERT INTO user_tests (user_id, test_id, score)
|
||||
VALUES (:user_id, :test_id, :score)
|
||||
ON DUPLICATE KEY UPDATE score = :score
|
||||
");
|
||||
$userTestStmt->execute([
|
||||
'user_id' => $user_id,
|
||||
'test_id' => $test_id,
|
||||
'score' => $total_score
|
||||
]);
|
||||
|
||||
// Commit transaction
|
||||
$db->commit();
|
||||
|
||||
// Redirect to results page
|
||||
header("Location: test_results.php?test_id=" . $test_id);
|
||||
exit();
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// Rollback on error
|
||||
if ($db->inTransaction()) {
|
||||
$db->rollBack();
|
||||
}
|
||||
// A generic error message is better for production
|
||||
die("An error occurred while submitting your test. Please try again later. Error: " . $e->getMessage());
|
||||
}
|
||||
|
||||
?>
|
||||
184
take_test.php
184
take_test.php
@ -1,184 +0,0 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Redirect if not logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check for test ID
|
||||
if (!isset($_GET['test_id']) || !is_numeric($_GET['test_id'])) {
|
||||
echo "<div class='container mt-5'><div class='alert alert-danger'>Invalid test ID.</div></div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
$test_id = intval($_GET['test_id']);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Check if user has already taken this test
|
||||
$checkStmt = $db->prepare("SELECT COUNT(*) FROM user_tests WHERE user_id = :user_id AND test_id = :test_id");
|
||||
$checkStmt->execute(['user_id' => $user_id, 'test_id' => $test_id]);
|
||||
if ($checkStmt->fetchColumn() > 0) {
|
||||
echo "<div class='container mt-5'><div class='alert alert-info'>You have already completed this test. <a href='test_results.php?test_id=$test_id'>View your results</a>.</div></div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch test details
|
||||
$stmt = $db->prepare("SELECT title, description FROM tests WHERE id = :id");
|
||||
$stmt->execute(['id' => $test_id]);
|
||||
$test = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$test) {
|
||||
echo "<div class='container mt-5'><div class='alert alert-danger'>Test not found.</div></div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch questions and options
|
||||
$questionsStmt = $db->prepare("
|
||||
SELECT q.id AS question_id, q.question_text, o.id AS option_id, o.option_text, o.score
|
||||
FROM questions q
|
||||
JOIN options o ON q.id = o.question_id
|
||||
WHERE q.test_id = :test_id
|
||||
ORDER BY q.id, o.id
|
||||
");
|
||||
$questionsStmt->execute(['test_id' => $test_id]);
|
||||
$questionsData = $questionsStmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
|
||||
$question_keys = array_keys($questionsData);
|
||||
} catch (PDOException $e) {
|
||||
die("Database error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
.question-container {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
.question-container.active {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
.progress-bar-container {
|
||||
width: 100%;
|
||||
background-color: #e9ecef;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
.progress-bar-fill {
|
||||
height: 10px;
|
||||
background-color: #28a745;
|
||||
border-radius: .25rem;
|
||||
transition: width 0.3s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2><?php echo htmlspecialchars($test['title']); ?></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead"><?php echo nl2br(htmlspecialchars($test['description'])); ?></p>
|
||||
<hr>
|
||||
|
||||
<?php if (empty($questionsData)): ?>
|
||||
<div class="alert alert-warning">This test has no questions yet.</div>
|
||||
<?php else: ?>
|
||||
<div class="progress-bar-container mb-4">
|
||||
<div class="progress-bar-fill" id="progress-bar"></div>
|
||||
</div>
|
||||
<p id="progress-text" class="text-center"></p>
|
||||
|
||||
<form id="test-form" action="submit_test.php" method="post">
|
||||
<input type="hidden" name="test_id" value="<?php echo $test_id; ?>">
|
||||
|
||||
<?php foreach ($question_keys as $index => $question_id):
|
||||
$options = $questionsData[$question_id];
|
||||
$is_first = ($index === 0);
|
||||
$is_last = ($index === count($question_keys) - 1);
|
||||
?>
|
||||
<div class="question-container <?php if ($is_first) echo 'active'; ?>" data-question-index="<?php echo $index; ?>">
|
||||
<div class="mb-4">
|
||||
<h5><?php echo htmlspecialchars($options[0]['question_text']); ?></h5>
|
||||
<?php foreach ($options as $option): ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="answers[<?php echo $question_id; ?>]" id="option_<?php echo $option['option_id']; ?>" value="<?php echo $option['option_id']; ?>" required>
|
||||
<label class="form-check-label" for="option_<?php echo $option['option_id']; ?>">
|
||||
<?php echo htmlspecialchars($option['option_text']); ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between">
|
||||
<?php if (!$is_first): ?>
|
||||
<button type="button" class="btn btn-secondary btn-prev">Previous</button>
|
||||
<?php endif; ?>
|
||||
<?php if (!$is_last): ?>
|
||||
<button type="button" class="btn btn-primary btn-next ml-auto">Next</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($is_last): ?>
|
||||
<button type="submit" class="btn btn-success ml-auto">Submit Answers</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const questions = document.querySelectorAll('.question-container');
|
||||
const progressBar = document.getElementById('progress-bar');
|
||||
const progressText = document.getElementById('progress-text');
|
||||
let currentQuestionIndex = 0;
|
||||
const totalQuestions = questions.length;
|
||||
|
||||
function updateProgress() {
|
||||
const progressPercentage = ((currentQuestionIndex + 1) / totalQuestions) * 100;
|
||||
progressBar.style.width = progressPercentage + '%';
|
||||
progressText.textContent = `Question ${currentQuestionIndex + 1} of ${totalQuestions}`;
|
||||
}
|
||||
|
||||
function showQuestion(index) {
|
||||
questions.forEach((question, i) => {
|
||||
if (i === index) {
|
||||
question.classList.add('active');
|
||||
} else {
|
||||
question.classList.remove('active');
|
||||
}
|
||||
});
|
||||
currentQuestionIndex = index;
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
document.getElementById('test-form').addEventListener('click', function(e) {
|
||||
if (e.target.classList.contains('btn-next')) {
|
||||
const currentQuestion = questions[currentQuestionIndex];
|
||||
const radio = currentQuestion.querySelector('input[type="radio"]:checked');
|
||||
if(radio){
|
||||
showQuestion(currentQuestionIndex + 1);
|
||||
} else {
|
||||
alert('Please select an answer.');
|
||||
}
|
||||
}
|
||||
if (e.target.classList.contains('btn-prev')) {
|
||||
showQuestion(currentQuestionIndex - 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Initial setup
|
||||
showQuestion(0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
// Redirect if not logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// Check for test ID
|
||||
if (!isset($_GET['test_id']) || !is_numeric($_GET['test_id'])) {
|
||||
echo "<div class='container mt-5'><div class='alert alert-danger'>Invalid test ID.</div></div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
$test_id = intval($_GET['test_id']);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Fetch test details
|
||||
$stmt = $db->prepare("SELECT title FROM tests WHERE id = :id");
|
||||
$stmt->execute(['id' => $test_id]);
|
||||
$test = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$test) {
|
||||
echo "<div class='container mt-5'><div class='alert alert-danger'>Test not found.</div></div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fetch user's score
|
||||
$scoreStmt = $db->prepare("SELECT score FROM user_tests WHERE user_id = :user_id AND test_id = :test_id");
|
||||
$scoreStmt->execute(['user_id' => $user_id, 'test_id' => $test_id]);
|
||||
$result = $scoreStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
die("Database error: " . $e->getMessage());
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="card text-center">
|
||||
<div class="card-header">
|
||||
<h2>Results for <?php echo htmlspecialchars($test['title']); ?></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($result): ?>
|
||||
<h3 class="card-title">Your Score:</h3>
|
||||
<p class="display-4 fw-bold"><?php echo htmlspecialchars($result['score']); ?></p>
|
||||
<p class="text-muted">This score reflects your responses to the test questions.</p>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">We couldn't find your results for this test. Please make sure you have completed it.</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-footer text-muted">
|
||||
<a href="index.php" class="btn btn-secondary">Back to Test List</a>
|
||||
<a href="retake_test.php?test_id=<?php echo $test_id; ?>" class="btn btn-primary">Retake Test</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user