Spaces:
Runtime error
Runtime error
| <html> | |
| <head> | |
| <title>{{ title if logged_in else 'Spiritual Path Finder - Login' }}</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; | |
| background: #F5F5F5; | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 20px; | |
| } | |
| .container { | |
| background: white; | |
| border-radius: 16px; | |
| padding: 40px; | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); | |
| max-width: 700px; | |
| width: 100%; | |
| animation: slideIn 0.4s ease; | |
| max-height: 90vh; | |
| overflow-y: auto; | |
| } | |
| @keyframes slideIn { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| h1 { | |
| color: #3D3D3D; | |
| font-size: 32px; | |
| margin-bottom: 8px; | |
| text-align: center; | |
| font-weight: 800; | |
| } | |
| p { | |
| color: #6B7280; | |
| text-align: center; | |
| margin-bottom: 30px; | |
| font-size: 15px; | |
| } | |
| .subtitle { | |
| color: #9CA3AF; | |
| font-size: 14px; | |
| text-align: center; | |
| margin-bottom: 25px; | |
| line-height: 1.6; | |
| } | |
| input[type="text"], input[type="password"] { | |
| width: 100%; | |
| padding: 12px 16px; | |
| font-size: 15px; | |
| border: none; | |
| background: #F5F5F5; | |
| border-radius: 10px; | |
| transition: all 0.2s; | |
| outline: none; | |
| } | |
| input:focus { | |
| background: #EBEBEB; | |
| box-shadow: 0 0 0 2px #E5E5E5; | |
| } | |
| button, .btn { | |
| padding: 12px 24px; | |
| font-size: 15px; | |
| background: #3D3D3D; | |
| color: white; | |
| border: none; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-weight: 600; | |
| text-decoration: none; | |
| display: inline-block; | |
| } | |
| button:hover, .btn:hover { | |
| background: #1A1A1A; | |
| transform: translateY(-1px); | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); | |
| } | |
| button:active, .btn:active { transform: translateY(0); } | |
| button:disabled { background: #E5E5E5; color: #999; cursor: not-allowed; transform: none; } | |
| .logout-btn, .reset-btn { | |
| background: #6B7280; | |
| padding: 8px 16px; | |
| font-size: 13px; | |
| margin-top: 15px; | |
| } | |
| .logout-btn:hover, .reset-btn:hover { | |
| background: #4B5563; | |
| box-shadow: 0 4px 12px rgba(107, 114, 128, 0.3); | |
| } | |
| .auth-form input { | |
| width: 100%; | |
| margin-bottom: 15px; | |
| } | |
| .auth-form button { | |
| width: 100%; | |
| } | |
| .switch-link { | |
| color: #3D3D3D; | |
| text-decoration: none; | |
| cursor: pointer; | |
| font-weight: 600; | |
| margin-top: 15px; | |
| display: inline-block; | |
| transition: color 0.2s; | |
| } | |
| .switch-link:hover { | |
| color: #1A1A1A; | |
| text-decoration: underline; | |
| } | |
| .question-block { | |
| background: #FAFAFA; | |
| padding: 30px; | |
| border-radius: 12px; | |
| margin-bottom: 20px; | |
| border: none; | |
| display: none; | |
| min-height: 400px; | |
| } | |
| .question-block.active { | |
| display: block; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateX(20px); } | |
| to { opacity: 1; transform: translateX(0); } | |
| } | |
| .question-block h4 { | |
| color: #3D3D3D; | |
| margin-bottom: 25px; | |
| font-weight: 700; | |
| font-size: 18px; | |
| line-height: 1.6; | |
| } | |
| .question-number { | |
| display: inline-block; | |
| background: #3D3D3D; | |
| color: #fff; | |
| width: 32px; | |
| height: 32px; | |
| border-radius: 50%; | |
| text-align: center; | |
| line-height: 32px; | |
| margin-right: 12px; | |
| font-size: 16px; | |
| } | |
| .option { | |
| display: block; | |
| padding: 16px 20px; | |
| margin-bottom: 12px; | |
| background: white; | |
| border: none; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-size: 15px; | |
| color: #3D3D3D; | |
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); | |
| } | |
| .option:hover { | |
| background: #F5F5F5; | |
| transform: translateX(5px); | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); | |
| } | |
| .option input[type="radio"] { | |
| margin-right: 12px; | |
| cursor: pointer; | |
| width: 18px; | |
| height: 18px; | |
| } | |
| .option input[type="radio"]:disabled { | |
| cursor: not-allowed; | |
| opacity: 0.5; | |
| } | |
| .option:has(input[type="radio"]:disabled) { | |
| opacity: 0.4; | |
| cursor: not-allowed; | |
| } | |
| .option:has(input[type="radio"]:disabled):hover { | |
| background: white; | |
| transform: none; | |
| } | |
| .question-counter { | |
| text-align: center; | |
| color: #999; | |
| font-size: 14px; | |
| margin-bottom: 15px; | |
| font-weight: 600; | |
| } | |
| .submit-btn { | |
| width: 100%; | |
| padding: 16px; | |
| font-size: 16px; | |
| margin-top: 10px; | |
| background: #3D3D3D; | |
| color: #fff; | |
| border: none; | |
| border-radius: 10px; | |
| font-weight: 600; | |
| transition: background 0.2s; | |
| } | |
| .submit-btn:hover { | |
| background: #1A1A1A; | |
| color: #fff; | |
| } | |
| .result-card { | |
| padding: 25px; | |
| border-radius: 12px; | |
| margin-bottom: 20px; | |
| border: none; | |
| box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); | |
| } | |
| .result-card.rank-1 { | |
| background: #FFFACD; | |
| } | |
| .result-card.rank-2 { | |
| background: #B4C7E7; | |
| } | |
| .result-card.rank-3 { | |
| background: #90EE90; | |
| } | |
| .result-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| margin-bottom: 15px; | |
| } | |
| .result-rank { | |
| color: #fff; | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 20px; | |
| font-weight: 800; | |
| background: #3D3D3D; | |
| } | |
| .result-title { flex: 1; margin-left: 15px; } | |
| .result-title h3 { | |
| font-size: 22px; margin-bottom: 5px; color: #3D3D3D; | |
| } | |
| .result-percentage { | |
| font-size: 24px; font-weight: 800; color: #3D3D3D; | |
| } | |
| .result-description { color: #666; line-height: 1.6; margin-bottom: 12px; font-size: 14px; } | |
| .result-details { background: rgba(255, 255, 255, 0.6); border: none; padding: 15px; border-radius: 8px; margin-top: 15px; } | |
| .result-details h5 { color: #3D3D3D; font-size: 13px; margin-bottom: 8px; font-weight: 700; } | |
| .result-details p { color: #666; font-size: 13px; margin-bottom: 10px; text-align: left; } | |
| .icon { font-size: 24px; margin-right: 8px; } | |
| .success-msg { color: #3D3D3D; font-weight: 600; } | |
| .error-msg { color: #666; font-weight: 600; text-align: center; padding: 10px; } | |
| .progress-bar { background: #F5F5F5; height: 8px; border-radius: 4px; overflow: hidden; margin-bottom: 20px; } | |
| .progress-fill { background: #3D3D3D; height: 100%; transition: width 0.3s; } | |
| .buttons-row { display: flex; gap: 10px; justify-content: center; margin-top: 20px; } | |
| .nav-buttons { display: flex; gap: 12px; justify-content: space-between; margin-top: 20px; } | |
| .nav-btn, .nav-btn.next { | |
| padding: 12px 24px; | |
| font-size: 15px; | |
| background: #3D3D3D; | |
| color: #fff; | |
| border: none; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| transition: background 0.2s; | |
| font-weight: 600; | |
| } | |
| .nav-btn:hover, .nav-btn.next:hover { background: #1A1A1A; color: #fff; transform: translateY(-1px); } | |
| .nav-btn:disabled { opacity: 0.3; cursor: not-allowed; transform: none; } | |
| h3 { text-align: center; color: #3D3D3D; } | |
| .chat-toggle-btn { | |
| background: rgba(255, 255, 255, 0.8); | |
| color: #3D3D3D; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-size: 14px; | |
| font-weight: 600; | |
| margin-top: 15px; | |
| width: 100%; | |
| transition: background 0.2s, color 0.2s; | |
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); | |
| } | |
| .chat-toggle-btn:hover { background: #3D3D3D; color: #fff; } | |
| .chat-window { | |
| display: none; | |
| background: rgba(255, 255, 255, 0.9); | |
| border: none; | |
| border-radius: 10px; | |
| margin-top: 15px; | |
| overflow: hidden; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); | |
| } | |
| .chat-window.open { display: block; animation: slideDown 0.3s ease; } | |
| @keyframes slideDown { from { opacity: 0; max-height: 0; } to { opacity: 1; max-height: 500px; } } | |
| .chat-messages { height: 250px; overflow-y: auto; padding: 15px; background: transparent; } | |
| .chat-message { margin-bottom: 12px; padding: 10px 14px; border-radius: 8px; max-width: 85%; line-height: 1.5; font-size: 14px; } | |
| .chat-message.user { | |
| background: #3D3D3D; | |
| color: #fff; | |
| margin-left: auto; | |
| text-align: right; | |
| } | |
| .chat-message.bot { | |
| background: white; | |
| color: #3D3D3D; | |
| border: none; | |
| text-align: left; | |
| box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); | |
| } | |
| .chat-message.bot ul { margin: 8px 0 0 0; padding-left: 20px; } | |
| .chat-message.bot li { margin-bottom: 6px; line-height: 1.6; } | |
| .chat-input-area { display: flex; gap: 8px; padding: 12px; background: transparent; border-top: none; } | |
| .chat-input { | |
| flex: 1; | |
| padding: 10px 14px; | |
| border: none; | |
| background: white; | |
| border-radius: 8px; | |
| font-size: 14px; | |
| outline: none; | |
| color: #3D3D3D; | |
| box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); | |
| } | |
| .chat-input:focus { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } | |
| .chat-send-btn { | |
| padding: 10px 20px; | |
| background: #3D3D3D; | |
| color: #fff; | |
| border: none; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-weight: 600; | |
| font-size: 14px; | |
| transition: background 0.2s; | |
| } | |
| .chat-send-btn:hover { background: #1A1A1A; color: #fff; } | |
| .chat-send-btn:disabled { background: #F5F5F5; color: #999; cursor: not-allowed; } | |
| .chat-typing { color: #999; font-style: italic; font-size: 13px; padding: 10px 14px; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| {% if not logged_in %} | |
| <!-- Login/Signup Form --> | |
| <h1><span class="icon">π</span>Spiritual Path Finder</h1> | |
| <p>{{ 'Begin your journey of self-discovery' if is_signup else 'Welcome back, seeker!' }}</p> | |
| <div class="auth-form"> | |
| <input type="text" id="authUsername" placeholder="Username"> | |
| <input type="password" id="authPassword" placeholder="Password"> | |
| <button onclick="authenticate()">{{ 'Sign Up' if is_signup else 'Sign In' }}</button> | |
| <div id="result"></div> | |
| <p class="switch-link" onclick="switchAuth()"> | |
| {{ 'Already have an account? Sign In' if is_signup else 'New here? Sign Up' }} | |
| </p> | |
| </div> | |
| <script> | |
| function authenticate() { | |
| const username = document.getElementById('authUsername').value.trim(); | |
| const password = document.getElementById('authPassword').value; | |
| if (!username || !password) { | |
| document.getElementById('result').innerHTML = | |
| '<p class="error-msg">β οΈ Please fill in all fields</p>'; | |
| return; | |
| } | |
| const endpoint = window.location.pathname === '/signup' ? '/signup' : '/login'; | |
| fetch(endpoint, { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'}, | |
| body: JSON.stringify({username, password}) | |
| }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| if (data.success) { | |
| window.location.href = '/'; | |
| } else { | |
| document.getElementById('result').innerHTML = | |
| `<p class="error-msg">${data.message}</p>`; | |
| } | |
| }); | |
| } | |
| function switchAuth() { | |
| const newPath = window.location.pathname === '/signup' ? '/login' : '/signup'; | |
| window.location.href = newPath; | |
| } | |
| document.getElementById('authPassword').addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') authenticate(); | |
| }); | |
| </script> | |
| {% else %} | |
| <!-- Assessment Interface --> | |
| <h1>{{ title }}</h1> | |
| <p>{{ message }}</p> | |
| {% if not has_results %} | |
| <p class="subtitle"> | |
| Discover which spiritual or religious path aligns with your beliefs, values, and lifestyle. | |
| Answer 8 thoughtful questions about your worldview. | |
| </p> | |
| <div class="question-counter" id="questionCounter">Question 1 of {{ questions|length }}</div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" id="progressBar" style="width: 0%"></div> | |
| </div> | |
| <div style="display:none;" id="assessmentData" | |
| data-total="{{ questions|length }}" | |
| data-ids="{{ questions|map(attribute='id')|list|tojson|safe }}"> | |
| </div> | |
| <form id="assessmentForm"> | |
| {% for question in questions %} | |
| {% set q_index = loop.index %} | |
| <div class="question-block" data-question-index="{{ q_index }}" {% if loop.first %}data-active="true"{% endif %}> | |
| <h4> | |
| <span class="question-number">{{ q_index }}</span> | |
| {{ question.question }} | |
| </h4> | |
| {% for option in question.options.keys() %} | |
| <label class="option"> | |
| <input type="radio" | |
| name="q{{ question.id }}" | |
| value="{{ option }}" | |
| data-question-index="{{ q_index }}" | |
| onchange="handleAnswer(this)"> | |
| {{ option }} | |
| </label> | |
| {% endfor %} | |
| <div class="nav-buttons" style="justify-content: flex-end;"> | |
| <button type="button" class="nav-btn next" id="nextBtn{{ q_index }}" onclick="goToNext()" disabled> | |
| Next β | |
| </button> | |
| </div> | |
| </div> | |
| {% endfor %} | |
| <button type="button" class="submit-btn" onclick="submitAssessment()" id="submitBtn" style="display: none;"> | |
| β¨ Discover Your Path | |
| </button> | |
| </form> | |
| <div id="errorMsg"></div> | |
| {% else %} | |
| <!-- Results Display --> | |
| <p class="subtitle"> | |
| Based on your responses, here are the spiritual paths that align most closely with your values and beliefs: | |
| </p> | |
| <div id="resultsContainer"> | |
| {% for result in results %} | |
| <div class="result-card rank-{{ loop.index }}"> | |
| <div class="result-header"> | |
| <div class="result-rank">{{ loop.index }}</div> | |
| <div class="result-title"> | |
| <h3>{{ result.name }}</h3> | |
| </div> | |
| <div class="result-percentage">{{ result.percentage }}%</div> | |
| </div> | |
| <p class="result-description">{{ result.description }}</p> | |
| <div class="result-details"> | |
| <h5>πΏ Common Practices:</h5> | |
| <p>{{ result.practices }}</p> | |
| <h5>π Core Beliefs:</h5> | |
| <p>{{ result.core_beliefs }}</p> | |
| </div> | |
| <button class="chat-toggle-btn" onclick="toggleChat('{{ result.name }}')"> | |
| π¬ Ask Questions About {{ result.name }} | |
| </button> | |
| <div class="chat-window" id="chat-{{ result.name|replace(' ', '-') }}"> | |
| <div class="chat-messages" id="messages-{{ result.name|replace(' ', '-') }}"> | |
| <div class="chat-message bot"> | |
| Hi! Ask me anything about {{ result.name }}.<br> | |
| <span style="color:#7C3AED; font-size:13px;"> | |
| Example: "What are the daily practices?"<br> | |
| Example: "How do I get started with this path?" | |
| </span> | |
| </div> | |
| </div> | |
| <div class="chat-input-area"> | |
| <input type="text" | |
| class="chat-input" | |
| id="input-{{ result.name|replace(' ', '-') }}" | |
| placeholder="Ask about {{ result.name }}..." | |
| onkeypress="if(event.key==='Enter') sendMessage('{{ result.name }}')"> | |
| <button class="chat-send-btn" | |
| id="send-{{ result.name|replace(' ', '-') }}" | |
| onclick="sendMessage('{{ result.name }}')"> | |
| Send | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| {% endfor %} | |
| </div> | |
| <div class="buttons-row"> | |
| <button class="btn reset-btn" onclick="resetAssessment()">π Retake Assessment</button> | |
| </div> | |
| {% endif %} | |
| <div style="text-align: center;"> | |
| <a href="/logout" class="btn logout-btn">Logout</a> | |
| </div> | |
| <script> | |
| var currentQuestion = 1; | |
| var maxQuestionReached = 1; // Track the furthest question reached | |
| var assessmentDataEl = document.getElementById('assessmentData'); | |
| var totalQuestions = assessmentDataEl ? parseInt(assessmentDataEl.getAttribute('data-total')) : 0; | |
| var questionIds = assessmentDataEl ? JSON.parse(assessmentDataEl.getAttribute('data-ids')) : []; | |
| // Show first question on load | |
| window.addEventListener('DOMContentLoaded', function() { | |
| showQuestion(1); | |
| }); | |
| function showQuestion(questionIndex) { | |
| if (questionIndex > maxQuestionReached + 1) return; | |
| if (questionIndex > maxQuestionReached) maxQuestionReached = questionIndex; | |
| document.querySelectorAll('.question-block').forEach(function(block) { | |
| block.classList.remove('active'); | |
| var blockIndex = parseInt(block.getAttribute('data-question-index')); | |
| if (blockIndex === questionIndex) block.classList.add('active'); | |
| if (blockIndex < questionIndex) { | |
| block.querySelectorAll('input[type="radio"]').forEach(function(radio) { radio.disabled = true; }); | |
| } | |
| }); | |
| currentQuestion = questionIndex; | |
| document.getElementById('questionCounter').textContent = 'Question ' + questionIndex + ' of ' + totalQuestions; | |
| document.getElementById('progressBar').style.width = ((questionIndex - 1) / totalQuestions) * 100 + '%'; | |
| updateNavigationButtons(); | |
| } | |
| function updateNavigationButtons() { | |
| var nextBtn = document.getElementById('nextBtn' + currentQuestion); | |
| if (nextBtn) { | |
| var currentQuestionId = questionIds[currentQuestion - 1]; | |
| var radioName = 'q' + currentQuestionId; | |
| var isAnswered = document.querySelector('input[name="' + radioName + '"]:checked') !== null; | |
| if (currentQuestion === totalQuestions && isAnswered) { | |
| nextBtn.style.display = 'none'; | |
| document.getElementById('submitBtn').style.display = 'block'; | |
| } else { | |
| nextBtn.disabled = !isAnswered; | |
| nextBtn.style.display = 'inline-block'; | |
| } | |
| } | |
| } | |
| function handleAnswer(radioElement) { | |
| var questionIndex = parseInt(radioElement.getAttribute('data-question-index')); | |
| // Only process if this is the current question | |
| if (questionIndex !== currentQuestion) { | |
| return; | |
| } | |
| updateNavigationButtons(); | |
| // Auto-advance to next question after selection | |
| setTimeout(function() { | |
| if (questionIndex < totalQuestions) { | |
| showQuestion(questionIndex + 1); | |
| } else { | |
| // Last question - show submit button | |
| var nextBtn = document.getElementById('nextBtn' + questionIndex); | |
| if (nextBtn) { | |
| nextBtn.style.display = 'none'; | |
| } | |
| document.getElementById('submitBtn').style.display = 'block'; | |
| } | |
| }, 400); | |
| } | |
| function goToNext() { | |
| if (currentQuestion < totalQuestions) { | |
| showQuestion(currentQuestion + 1); | |
| } | |
| } | |
| function submitAssessment() { | |
| var form = document.getElementById('assessmentForm'); | |
| var answers = []; | |
| questionIds.forEach(function(qId) { | |
| var radioName = 'q' + qId; | |
| var selectedRadio = form.querySelector('input[name="' + radioName + '"]:checked'); | |
| if (selectedRadio) { | |
| answers.push({ | |
| question_id: qId, | |
| answer: selectedRadio.value | |
| }); | |
| } | |
| }); | |
| if (answers.length !== totalQuestions) { | |
| document.getElementById('errorMsg').innerHTML = | |
| '<p class="error-msg">β οΈ Please answer all questions</p>'; | |
| return; | |
| } | |
| document.getElementById('submitBtn').disabled = true; | |
| document.getElementById('submitBtn').textContent = 'β¨ Calculating...'; | |
| fetch('/submit_assessment', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'}, | |
| body: JSON.stringify({answers: answers}) | |
| }) | |
| .then(function(response) { return response.json(); }) | |
| .then(function(data) { | |
| if (data.success) { | |
| window.location.reload(); | |
| } else { | |
| document.getElementById('errorMsg').innerHTML = | |
| '<p class="error-msg">' + data.message + '</p>'; | |
| document.getElementById('submitBtn').disabled = false; | |
| document.getElementById('submitBtn').textContent = 'β¨ Discover Your Path'; | |
| } | |
| }); | |
| } | |
| function resetAssessment() { | |
| if (!confirm('Are you sure you want to retake the assessment? Your current results will be cleared.')) { | |
| return; | |
| } | |
| fetch('/reset_assessment', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'} | |
| }) | |
| .then(function(response) { return response.json(); }) | |
| .then(function(data) { | |
| if (data.success) { | |
| window.location.reload(); | |
| } | |
| }); | |
| } | |
| // Chat functionality | |
| var chatHistories = {}; | |
| function formatBotResponse(text) { | |
| var div = document.createElement('div'); | |
| div.textContent = text; | |
| var escaped = div.innerHTML; | |
| if (escaped.match(/\*\s+/g) || escaped.match(/β’\s+/g) || escaped.match(/^\s*-\s+/gm)) { | |
| var lines = escaped.split(/(?:\*|β’|\n-)\s+/); | |
| if (lines.length > 1) { | |
| var formatted = lines[0].trim() ? lines[0].trim() + '<br><br>' : ''; | |
| formatted += '<ul style="margin: 0; padding-left: 20px; line-height: 1.8;">'; | |
| for (var i = 1; i < lines.length; i++) { | |
| if (lines[i].trim()) formatted += '<li style="margin-bottom: 6px;">' + lines[i].trim() + '</li>'; | |
| } | |
| return formatted + '</ul>'; | |
| } | |
| } | |
| return escaped.replace(/\n/g, '<br>'); | |
| } | |
| function toggleChat(religionName) { | |
| var chatId = 'chat-' + religionName.replace(/\s+/g, '-'); | |
| var chatWindow = document.getElementById(chatId); | |
| if (chatWindow.classList.contains('open')) { | |
| chatWindow.classList.remove('open'); | |
| } else { | |
| chatWindow.classList.add('open'); | |
| var inputId = 'input-' + religionName.replace(/\s+/g, '-'); | |
| setTimeout(function() { | |
| document.getElementById(inputId).focus(); | |
| }, 300); | |
| } | |
| } | |
| function sendMessage(religionName) { | |
| var inputId = 'input-' + religionName.replace(/\s+/g, '-'); | |
| var messagesId = 'messages-' + religionName.replace(/\s+/g, '-'); | |
| var sendBtnId = 'send-' + religionName.replace(/\s+/g, '-'); | |
| var inputEl = document.getElementById(inputId); | |
| var messagesEl = document.getElementById(messagesId); | |
| var sendBtn = document.getElementById(sendBtnId); | |
| var message = inputEl.value.trim(); | |
| if (!message) return; | |
| // Initialize chat history if not exists | |
| if (!chatHistories[religionName]) { | |
| chatHistories[religionName] = []; | |
| } | |
| // Add user message to UI | |
| var userMsgDiv = document.createElement('div'); | |
| userMsgDiv.className = 'chat-message user'; | |
| userMsgDiv.textContent = message; | |
| messagesEl.appendChild(userMsgDiv); | |
| // Clear input and disable send button | |
| inputEl.value = ''; | |
| sendBtn.disabled = true; | |
| // Show typing indicator | |
| var typingDiv = document.createElement('div'); | |
| typingDiv.className = 'chat-typing'; | |
| typingDiv.textContent = 'π Thinking...'; | |
| messagesEl.appendChild(typingDiv); | |
| // Scroll to bottom | |
| messagesEl.scrollTop = messagesEl.scrollHeight; | |
| // Add to chat history | |
| chatHistories[religionName].push({ | |
| role: 'user', | |
| content: message | |
| }); | |
| // Send to backend | |
| fetch('/chat', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'}, | |
| body: JSON.stringify({ | |
| message: message, | |
| religion: religionName, | |
| history: chatHistories[religionName] | |
| }) | |
| }) | |
| .then(function(response) { return response.json(); }) | |
| .then(function(data) { | |
| messagesEl.removeChild(typingDiv); | |
| if (data.success) { | |
| var botMsgDiv = document.createElement('div'); | |
| botMsgDiv.className = 'chat-message bot'; | |
| // Format the response with proper bullet points | |
| var formattedResponse = formatBotResponse(data.response); | |
| botMsgDiv.innerHTML = formattedResponse; | |
| messagesEl.appendChild(botMsgDiv); | |
| chatHistories[religionName].push({ | |
| role: 'assistant', | |
| content: data.response | |
| }); | |
| } else { | |
| var errorMsgDiv = document.createElement('div'); | |
| errorMsgDiv.className = 'chat-message bot'; | |
| errorMsgDiv.style.color = '#EF4444'; | |
| errorMsgDiv.textContent = 'β ' + data.message; | |
| messagesEl.appendChild(errorMsgDiv); | |
| } | |
| sendBtn.disabled = false; | |
| messagesEl.scrollTop = messagesEl.scrollHeight; | |
| }) | |
| .catch(function(error) { | |
| messagesEl.removeChild(typingDiv); | |
| var errorMsgDiv = document.createElement('div'); | |
| errorMsgDiv.className = 'chat-message bot'; | |
| errorMsgDiv.style.color = '#EF4444'; | |
| errorMsgDiv.textContent = 'β Connection error'; | |
| messagesEl.appendChild(errorMsgDiv); | |
| sendBtn.disabled = false; | |
| messagesEl.scrollTop = messagesEl.scrollHeight; | |
| }); | |
| } | |
| </script> | |
| {% endif %} | |
| </div> | |
| </body> | |
| </html> | |