Auto commit: 2025-11-18T10:40:14.646Z

This commit is contained in:
Flatlogic Bot 2025-11-18 10:40:14 +00:00
parent 046470377a
commit d8e46675be
12 changed files with 539 additions and 51 deletions

View File

@ -1,6 +1,9 @@
<?php
session_start();
require_once __DIR__ . '/../ai/LocalAIApi.php';
require_once __DIR__ . '/../db/config.php';
header('Content-Type: application/json');
$questions = [
@ -36,9 +39,72 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_SESSION['question_index'] < count($questions)) {
$response['question'] = $questions[$_SESSION['question_index']];
} else {
$response['message'] = 'Thank you for completing the survey! We will provide your results shortly.';
// Here you could add the logic to analyze the answers and provide recommendations
session_destroy();
// Survey is complete, analyze the answers
$formatted_answers = [];
foreach ($_SESSION['answers'] as $index => $answer) {
$formatted_answers[] = "Q: " . $questions[$index] . "\nA: " . $answer;
}
$prompt = "You are a burnout analysis expert. A user has completed a burnout survey. The user answered on a scale of 1-5 where 1 is 'Never' and 5 is 'Always'. Analyze the following survey answers and provide a detailed analysis. Return the response as a JSON object with the following structure:
{
\"scores\": {
\"Exhaustion\": <score_0_to_5>,
\"Cynicism\": <score_0_to_5>,
\"Inefficacy\": <score_0_to_5>
},
\"analysis\": {
\"overallSummary\": \"<A paragraph summarizing the user's burnout level and key areas of concern.>\",
\"exhaustionSummary\": \"<A sentence or two explaining the exhaustion score.>\",
\"cynicismSummary\": \"<A sentence or two explaining the cynicism score.>\",
\"inefficacySummary\": \"<A sentence or two explaining the inefficacy score.>\"
},
\"recommendations\": [
{
\"title\": \"<Short recommendation title>\",
\"description\": \"<Longer description of the recommendation, explaining why it's important and how to implement it.>\"
},
... (provide 3 to 5 detailed recommendations)
],
\"nextSteps\": [
\"<A suggestion for a next step, e.g., 'Consider talking to a mental health professional.'>\",
\"<Another suggestion, e.g., 'Explore mindfulness exercises.'>\"
]
}
Answers:
" . implode("\n\n", $formatted_answers);
$ai_response = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => 'You are a burnout analysis expert.'],
['role' => 'user', 'content' => $prompt],
],
]);
if (!empty($ai_response['success'])) {
$decoded_response = LocalAIApi::decodeJsonFromResponse($ai_response);
$_SESSION['results'] = $decoded_response;
if (isset($_SESSION['user_id'])) {
try {
$pdo = db();
$stmt = $pdo->prepare('INSERT INTO survey_results (user_id, results_json) VALUES (:user_id, :results_json)');
$stmt->execute([
':user_id' => $_SESSION['user_id'],
':results_json' => json_encode($decoded_response)
]);
} catch (PDOException $e) {
// Optionally handle or log the database error
}
}
} else {
// Handle AI API error, maybe provide default results
$_SESSION['results'] = [
'scores' => ['Exhaustion' => 0, 'Cynicism' => 0, 'Inefficacy' => 0],
'recommendations' => ['Could not analyze results at this time. Please try again later.']
];
}
$response['redirect'] = 'results.php';
}
echo json_encode($response);

View File

@ -49,7 +49,9 @@ document.addEventListener('DOMContentLoaded', function () {
const data = await getNextQuestion(rating);
if (data.question) {
if (data.redirect) {
window.location.href = data.redirect;
} else if (data.question) {
addMessage(data.question, 'bot');
} else if (data.message) {
addMessage(data.message, 'bot');
@ -71,10 +73,10 @@ document.addEventListener('DOMContentLoaded', function () {
async function startConversation() {
const data = await getNextQuestion();
if (data.question) {
addMessage("Welcome to the Burnout Survey. I'll ask you a series of questions. Please rate each one on a scale of 1 (Strongly Disagree) to 5 (Strongly Agree).", 'bot');
addMessage("Welcome to the Burnout Survey. I'll ask you a series of questions. Please rate each one on a scale of 1 (Never) to 5 (Always).", 'bot');
addMessage(data.question, 'bot');
}
}
startConversation();
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -0,0 +1,15 @@
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,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS survey_results (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
results_json TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

View File

@ -1,51 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Burnout Adviser</title>
<meta name="description" content="Built with Flatlogic Generator">
<meta name="keywords" content="burnout, survey, mental health, wellness, stress, analysis, recommendations, self-assessment, psychology, Flatlogic">
<meta property="og:title" content="Burnout Adviser">
<meta property="og:description" content="Built with Flatlogic Generator">
<meta property="og:image" content="">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="#">Burnout Adviser</a>
</div>
</nav>
<?php require_once 'partials/header.php'; ?>
<main class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">AI Assistant</h4>
</div>
<div class="card-body" id="chat-window" style="height: 400px; overflow-y: auto;">
<!-- Chat messages will be appended here -->
</div>
<div class="card-footer">
<div class="input-group">
<input type="text" id="chat-input" class="form-control" placeholder="Rate from 1 (Strongly Disagree) to 5 (Strongly Agree)">
<button id="send-btn" class="btn btn-primary">
<i class="bi bi-send"></i>
</button>
</div>
<main class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">AI Assistant</h4>
</div>
<div class="card-body" id="chat-window" style="height: 400px; overflow-y: auto;">
<!-- Chat messages will be appended here -->
</div>
<div class="card-footer">
<div class="input-group">
<input type="text" id="chat-input" class="form-control" placeholder="Rate from 1 (Strongly Disagree) to 5 (Strongly Agree)">
<button id="send-btn" class="btn btn-primary">
<i class="bi bi-send"></i>
</button>
</div>
</div>
</div>
</div>
</main>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>
<?php require_once 'partials/footer.php'; ?>

66
login.php Normal file
View File

@ -0,0 +1,66 @@
<?php
require_once 'partials/header.php';
require_once 'db/config.php';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($email)) {
$errors[] = 'Email is required';
}
if (empty($password)) {
$errors[] = 'Password is required';
}
if (empty($errors)) {
try {
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
header('Location: index.php');
exit;
} else {
$errors[] = 'Invalid email or password';
}
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">Login</div>
<div class="card-body">
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form method="POST">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</div>
</div>
</div>
<?php require_once 'partials/footer.php'; ?>

6
logout.php Normal file
View File

@ -0,0 +1,6 @@
<?php
session_start();
session_unset();
session_destroy();
header('Location: login.php');
exit;

5
partials/footer.php Normal file
View File

@ -0,0 +1,5 @@
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>

41
partials/header.php Normal file
View File

@ -0,0 +1,41 @@
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Burnout Survey</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Burnout Survey</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">
<a class="nav-link" href="profile.php">Profile</a>
</li>
<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" href="register.php">Register</a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<div class="container mt-4">

110
profile.php Normal file
View File

@ -0,0 +1,110 @@
<?php
require_once 'partials/header.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$results = [];
try {
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM survey_results WHERE user_id = :user_id ORDER BY created_at DESC');
$stmt->execute([':user_id' => $user_id]);
$results = $stmt->fetchAll();
} catch (PDOException $e) {
// handle error
}
?>
<h2>Your Past Results</h2>
<?php if (empty($results)): ?>
<p>You have no past survey results.</p>
<?php else: ?>
<div class="accordion" id="resultsAccordion">
<?php foreach ($results as $index => $result): ?>
<?php $data = json_decode($result['results_json'], true); ?>
<div class="accordion-item">
<h2 class="accordion-header" id="heading<?php echo $index; ?>">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse<?php echo $index; ?>" aria-expanded="false" aria-controls="collapse<?php echo $index; ?>">
Survey from <?php echo date('F j, Y, g:i a', strtotime($result['created_at'])); ?>
</button>
</h2>
<div id="collapse<?php echo $index; ?>" class="accordion-collapse collapse" aria-labelledby="heading<?php echo $index; ?>" data-bs-parent="#resultsAccordion">
<div class="accordion-body">
<h5>Overall Summary</h5>
<p><?php echo htmlspecialchars($data['summary'] ?? ''); ?></p>
<h5>Score Breakdown</h5>
<canvas id="chart-<?php echo $index; ?>" width="400" height="400"></canvas>
<h5>Recommendations</h5>
<div class="accordion" id="recommendationsAccordion-<?php echo $index; ?>">
<?php foreach ($data['recommendations'] as $rec_index => $rec): ?>
<div class="accordion-item">
<h2 class="accordion-header" id="rec-heading-<?php echo $index; ?>-<?php echo $rec_index; ?>">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#rec-collapse-<?php echo $index; ?>-<?php echo $rec_index; ?>" aria-expanded="false" aria-controls="rec-collapse-<?php echo $index; ?>-<?php echo $rec_index; ?>">
<?php echo htmlspecialchars($rec['title']); ?>
</button>
</h2>
<div id="rec-collapse-<?php echo $index; ?>-<?php echo $rec_index; ?>" class="accordion-collapse collapse" aria-labelledby="rec-heading-<?php echo $index; ?>-<?php echo $rec_index; ?>" data-bs-parent="#recommendationsAccordion-<?php echo $index; ?>">
<div class="accordion-body">
<?php echo htmlspecialchars($rec['description']); ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<h5>Next Steps</h5>
<ul>
<?php foreach ($data['next_steps'] as $step): ?>
<li><?php echo htmlspecialchars($step); ?></li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
new Chart(document.getElementById('chart-<?php echo $index; ?>'), {
type: 'radar',
data: {
labels: ['Exhaustion', 'Cynicism', 'Inefficacy'],
datasets: [{
label: 'Burnout Score',
data: [
<?php echo $data['scores']['Exhaustion'] ?? 0; ?>,
<?php echo $data['scores']['Cynicism'] ?? 0; ?>,
<?php echo $data['scores']['Inefficacy'] ?? 0; ?>
],
fill: true,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgb(255, 99, 132)',
pointBackgroundColor: 'rgb(255, 99, 132)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgb(255, 99, 132)'
}]
},
options: {
elements: {
line: {
borderWidth: 3
}
}
}
});
});
</script>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php require_once 'partials/footer.php'; ?>

75
register.php Normal file
View File

@ -0,0 +1,75 @@
<?php
require_once 'partials/header.php';
require_once 'db/config.php';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($username)) {
$errors[] = 'Username is required';
}
if (empty($email)) {
$errors[] = 'Email is required';
}
if (empty($password)) {
$errors[] = 'Password is required';
}
if (empty($errors)) {
try {
$pdo = db();
$stmt = $pdo->prepare('SELECT id FROM users WHERE username = :username OR email = :email');
$stmt->execute([':username' => $username, ':email' => $email]);
if ($stmt->fetch()) {
$errors[] = 'Username or email already exists';
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (:username, :email, :password)');
$stmt->execute([':username' => $username, ':email' => $email, ':password' => $hashed_password]);
$_SESSION['user_id'] = $pdo->lastInsertId();
header('Location: index.php');
exit;
}
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">Register</div>
<div class="card-body">
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form 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="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
</div>
</div>
</div>
</div>
<?php require_once 'partials/footer.php'; ?>

127
results.php Normal file
View File

@ -0,0 +1,127 @@
<?php
require_once 'partials/header.php';
if (!isset($_SESSION['results'])) {
// Redirect to the main page if no results are available
header('Location: index.php');
exit;
}
$results = $_SESSION['results'];
$scores = $results['scores'] ?? [];
$analysis = $results['analysis'] ?? [];
$recommendations = $results['recommendations'] ?? [];
$nextSteps = $results['nextSteps'] ?? [];
// Clear the session data after displaying the results
unset($_SESSION['answers']);
unset($_SESSION['question_index']);
unset($_SESSION['results']);
?>
<div class="card">
<div class="card-header text-center">
<h1>Your Burnout Analysis</h1>
</div>
<div class="card-body">
<?php if (!empty($analysis['overallSummary'])): ?>
<div class="alert alert-light" role="alert">
<h4 class="alert-heading">Overall Summary</h4>
<p><?php echo htmlspecialchars($analysis['overallSummary']); ?></p>
</div>
<?php endif; ?>
<div class="row">
<div class="col-md-6">
<h2>Your Scores</h2>
<canvas id="burnoutChart"></canvas>
</div>
<div class="col-md-6">
<h2>Analysis</h2>
<?php if (!empty($analysis['exhaustionSummary'])): ?>
<h5>Exhaustion</h5>
<p><?php echo htmlspecialchars($analysis['exhaustionSummary']); ?></p>
<?php endif; ?>
<?php if (!empty($analysis['cynicismSummary'])): ?>
<h5>Cynicism</h5>
<p><?php echo htmlspecialchars($analysis['cynicismSummary']); ?></p>
<?php endif; ?>
<?php if (!empty($analysis['inefficacySummary'])): ?>
<h5>Inefficacy</h5>
<p><?php echo htmlspecialchars($analysis['inefficacySummary']); ?></p>
<?php endif; ?>
</div>
</div>
<hr class="my-4">
<h2>Recommendations</h2>
<?php if (!empty($recommendations)): ?>
<div class="accordion" id="recommendationsAccordion">
<?php foreach ($recommendations as $index => $rec): ?>
<div class="accordion-item">
<h2 class="accordion-header" id="heading<?php echo $index; ?>">
<button class="accordion-button <?php echo $index > 0 ? 'collapsed' : ''; ?>" type="button" data-bs-toggle="collapse" data-bs-target="#collapse<?php echo $index; ?>" aria-expanded="<?php echo $index === 0 ? 'true' : 'false'; ?>" aria-controls="collapse<?php echo $index; ?>">
<?php echo htmlspecialchars($rec['title']); ?>
</button>
</h2>
<div id="collapse<?php echo $index; ?>" class="accordion-collapse collapse <?php echo $index === 0 ? 'show' : ''; ?>" aria-labelledby="heading<?php echo $index; ?>" data-bs-parent="#recommendationsAccordion">
<div class="accordion-body">
<?php echo htmlspecialchars($rec['description']); ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<p>No specific recommendations available at this time.</p>
<?php endif; ?>
<hr class="my-4">
<h2>Next Steps</h2>
<?php if (!empty($nextSteps)): ?>
<ul>
<?php foreach ($nextSteps as $step): ?>
<li><?php echo htmlspecialchars($step); ?></li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>No specific next steps available at this time.</p>
<?php endif; ?>
</div>
<div class="card-footer text-center">
<a href="index.php" class="btn btn-primary">Take the Survey Again</a>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const scores = <?php echo json_encode($scores); ?>;
const ctx = document.getElementById('burnoutChart').getContext('2d');
const burnoutChart = new Chart(ctx, {
type: 'radar',
data: {
labels: Object.keys(scores),
datasets: [{
label: 'Burnout Dimensions',
data: Object.values(scores),
backgroundColor: 'rgba(0, 123, 255, 0.2)',
borderColor: 'rgba(0, 123, 255, 1)',
borderWidth: 1
}]
},
options: {
scales: {
r: {
angleLines: {
display: false
},
suggestedMin: 0,
suggestedMax: 5
}
}
}
});
</script>
<?php require_once 'partials/footer.php'; ?>