From 89e735575c488248fefdcc72773ac2e8f0638404 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 19 Nov 2025 15:51:26 +0000 Subject: [PATCH] AI analysis v1 --- assets/css/custom.css | 207 ++++++++++++++++++++++++++++++++++ assets/js/main.js | 135 ++++++++++++++++++++++ followup.php | 40 +++++++ index.php | 178 ++++++----------------------- results.php | 254 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 671 insertions(+), 143 deletions(-) create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 followup.php create mode 100644 results.php diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..9e54e9a --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,207 @@ +/* General Body Styling */ +body { + background-color: #F3F4F6; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + color: #111827; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + margin: 0; +} + +/* Main Chat Container */ +.chat-container { + width: 100%; + max-width: 768px; + height: 90vh; + max-height: 800px; + background-color: #FFFFFF; + border-radius: 0.75rem; + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* Chat Header */ +.chat-header { + padding: 1rem 1.5rem; + background: linear-gradient(45deg, #4F46E5, #6366F1); + color: white; + border-bottom: 1px solid #E5E7EB; + text-align: center; + flex-shrink: 0; +} + +.chat-header h1 { + margin: 0; + font-size: 1.25rem; + font-weight: 600; +} + +/* Message List */ +.message-list { + flex-grow: 1; + padding: 1.5rem; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 1rem; +} + +/* Individual Message Styling */ +.message { + display: flex; + align-items: flex-end; + gap: 0.75rem; + max-width: 85%; + animation: fadeIn 0.3s ease-out; +} + +.message .avatar { + width: 40px; + height: 40px; + border-radius: 50%; + background-color: #E5E7EB; + display: flex; + justify-content: center; + align-items: center; + font-weight: 600; + flex-shrink: 0; +} + +.message .message-content { + padding: 0.75rem 1rem; + border-radius: 0.75rem; + line-height: 1.5; +} + +/* AI (Bot) Message */ +.message.bot { + align-self: flex-start; +} + +.message.bot .avatar { + background-color: #4F46E5; + color: white; +} + +.message.bot .message-content { + background-color: #EEF2FF; + color: #3730A3; + border-top-left-radius: 0; +} + +/* User Message */ +.message.user { + align-self: flex-end; +} + +.message.user .message-content { + background-color: #10B981; + color: white; + border-top-right-radius: 0; +} +.message.user .avatar { + display: none; /* Hide avatar for user messages for a cleaner look */ +} + + +/* Input Area */ +.input-area { + padding: 1rem 1.5rem; + border-top: 1px solid #E5E7EB; + background-color: #F9FAFB; + display: flex; + gap: 0.75rem; + flex-shrink: 0; +} + +.input-area input { + flex-grow: 1; + padding: 0.75rem 1rem; + border: 1px solid #D1D5DB; + border-radius: 0.375rem; + font-size: 1rem; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.input-area input:focus { + outline: none; + border-color: #4F46E5; + box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2); +} + +.input-area button { + padding: 0.75rem 1.5rem; + border: none; + background-color: #4F46E5; + color: white; + border-radius: 0.375rem; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s; +} + +.input-area button:hover { + background-color: #4338CA; +} + +.input-area button:disabled { + background-color: #A5B4FC; + cursor: not-allowed; +} + +#analyze-button { + width: 100%; + padding: 1rem; + border: none; + background-color: #10B981; /* Emerald Green */ + color: white; + border-radius: 0.375rem; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s; +} + +#analyze-button:hover { + background-color: #059669; +} + +/* Typing indicator */ +.typing-indicator { + display: flex; + align-items: center; + padding: 5px 0; +} +.typing-indicator span { + height: 8px; + width: 8px; + float: left; + margin: 0 2px; + background-color: #9E9E9E; + display: block; + border-radius: 50%; + opacity: 0.4; + animation: 1s blink infinite; +} +.typing-indicator span:nth-child(2) { animation-delay: .2s; } +.typing-indicator span:nth-child(3) { animation-delay: .4s; } + +@keyframes blink { + 50% { opacity: 1; } +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..63b44ef --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,135 @@ +document.addEventListener('DOMContentLoaded', () => { + const questions = [ + "I wake up feeling tired, even after a full night’s sleep.", + "By midday, I already feel mentally drained and out of energy.", + "I feel emotionally numb, detached, or “on autopilot” most of the time.", + "Things that used to excite me now feel pointless or like a chore.", + "I feel irritated or cynical about people I work or study with.", + "I struggle to focus and constantly procrastinate, even on important tasks.", + "I feel guilty for not doing “enough”, no matter how much I actually do.", + "I often think about quitting everything for a while or disappearing from social media and work.", + "I use caffeine, sugar, nicotine, alcohol, or scrolling to “numb out” instead of resting.", + "I feel like my life is just surviving, not really living." + ]; + + const messageList = document.getElementById('message-list'); + const inputArea = document.getElementById('input-area'); + const userInput = document.getElementById('user-input'); + const sendButton = document.getElementById('send-button'); + + let currentQuestionIndex = 0; + const userAnswers = []; + + function addMessage(text, sender) { + const messageElement = document.createElement('div'); + messageElement.classList.add('message', sender); + + const avatar = document.createElement('div'); + avatar.classList.add('avatar'); + avatar.textContent = sender === 'bot' ? 'AI' : 'You'; + + const messageContent = document.createElement('div'); + messageContent.classList.add('message-content'); + messageContent.textContent = text; + + if (sender === 'bot') { + messageElement.appendChild(avatar); + } + messageElement.appendChild(messageContent); + + messageList.appendChild(messageElement); + messageList.scrollTop = messageList.scrollHeight; + } + + function showTypingIndicator() { + const typingElement = document.createElement('div'); + typingElement.id = 'typing-indicator'; + typingElement.classList.add('message', 'bot'); + typingElement.innerHTML = ` +
AI
+
+
+ +
+
+ `; + messageList.appendChild(typingElement); + messageList.scrollTop = messageList.scrollHeight; + } + + function removeTypingIndicator() { + const typingElement = document.getElementById('typing-indicator'); + if (typingElement) { + typingElement.remove(); + } + } + + function askNextQuestion() { + if (currentQuestionIndex < questions.length) { + showTypingIndicator(); + setTimeout(() => { + removeTypingIndicator(); + addMessage(questions[currentQuestionIndex], 'bot'); + userInput.disabled = false; + sendButton.disabled = false; + userInput.focus(); + }, 1000); // Simulate AI "thinking" + } else { + showTypingIndicator(); + setTimeout(() => { + removeTypingIndicator(); + addMessage("Thank you for your responses. Click the button below to see your analysis.", 'bot'); + + // Create a form to submit the results + const form = document.createElement('form'); + form.method = 'POST'; + form.action = 'results.php'; + + const hiddenInput = document.createElement('input'); + hiddenInput.type = 'hidden'; + hiddenInput.name = 'conversation'; + hiddenInput.value = JSON.stringify(userAnswers); + form.appendChild(hiddenInput); + + const submitButton = document.createElement('button'); + submitButton.type = 'submit'; + submitButton.textContent = 'Analyze My Results'; + submitButton.id = 'analyze-button'; + form.appendChild(submitButton); + + inputArea.innerHTML = ''; // Clear the input field and send button + inputArea.appendChild(form); + inputArea.style.display = 'flex'; + + }, 1500); + } + } + + function handleUserInput() { + const text = userInput.value.trim(); + if (text === '') return; + + addMessage(text, 'user'); + userAnswers.push({ question: questions[currentQuestionIndex], answer: text }); + + userInput.value = ''; + userInput.disabled = true; + sendButton.disabled = true; + + currentQuestionIndex++; + askNextQuestion(); + } + + sendButton.addEventListener('click', handleUserInput); + userInput.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + handleUserInput(); + } + }); + + // Start the conversation + setTimeout(() => { + addMessage("Hello! I'm here to help you assess your level of burnout. I'll ask you 10 questions. Please answer them honestly.", 'bot'); + askNextQuestion(); + }, 500); +}); \ No newline at end of file diff --git a/followup.php b/followup.php new file mode 100644 index 0000000..11dd663 --- /dev/null +++ b/followup.php @@ -0,0 +1,40 @@ + [ + ['role' => 'system', 'content' => 'You are a helpful assistant specializing in mental health and burnout analysis.'], + ['role' => 'user', 'content' => $prompt], + ], + ] + ); + + if (!empty($resp['success'])) { + echo LocalAIApi::extractText($resp); + } else { + echo "Sorry, I couldn't process your request. Please try again later."; + } +} else { + http_response_code(400); + echo "Invalid request. Missing data."; +} + diff --git a/index.php b/index.php index 7205f3d..2d96d79 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,42 @@ - +?> - - - New Style - - - - - - - - - - - - - - - - - - - + + + + Burnout Survey & Analysis + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+

Burnout Assessment

+
+
+ +
+
+ + +
-
- + + + - + \ No newline at end of file diff --git a/results.php b/results.php new file mode 100644 index 0000000..e70fa4a --- /dev/null +++ b/results.php @@ -0,0 +1,254 @@ +` or `` tags.\n2. `chart_data`: A JSON object with two keys: `labels` (an array of strings for the chart categories, e.g., ['Exhaustion', 'Cynicism', 'Inefficacy']) and `scores` (an array of integers from 0 to 10 representing the user's score in each category).\n\nHere is the conversation: +"; + foreach ($conversation as $item) { + $prompt .= "Q: " . $item['question'] . "\nA: " . $item['answer'] . "\n\n"; + } + + $resp = LocalAIApi::createResponse( + [ + 'input' => [ + ['role' => 'system', 'content' => 'You are a helpful assistant specializing in mental health and burnout analysis. You always respond with a valid JSON object.'], + ['role' => 'user', 'content' => $prompt], + ], + ] + ); + + if (!empty($resp['success'])) { + $ai_response_raw = LocalAIApi::extractText($resp); + $ai_response_data = json_decode($ai_response_raw, true); + if ($ai_response_data && isset($ai_response_data['analysis_html']) && isset($ai_response_data['chart_data'])) { + $ai_response_text = $ai_response_data['analysis_html']; + $chart_data_json = json_encode($ai_response_data['chart_data']); + } else { + $error_message = 'AI response was not in the expected format. Please try again.'; + // For debugging: $error_message .= "
Raw response: " . htmlspecialchars($ai_response_raw); + } + } else { + $error_message = 'Failed to get response from AI. Error: ' . ($resp['error'] ?? 'Unknown error'); + } +} else { + $error_message = 'No conversation data received.'; +} + +?> + + + + + Your Burnout Analysis Results + + + + + + + + +
+
+

Your Burnout Analysis

+
+
+
+ +

+ + +
+ +
+ +

Analyzing your responses...

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