Fix missing askNextQuestion method in KidsAI Explorer
- Add askNextQuestion() method to handle conversation flow - Add addUserInputArea() for user input interface - Add submitChatAnswer() to handle user responses - Add showCompletionMessage() for conversation completion - Add scrollToBottomSmoothly() utility method - Resolves TypeError: this.askNextQuestion is not a function - Completes the interactive chat-based learning system
This commit is contained in:
@@ -727,6 +727,155 @@ class KidsAIExplorer {
|
||||
this.askNextQuestion();
|
||||
}
|
||||
|
||||
// Ask the next question in the conversation
|
||||
askNextQuestion() {
|
||||
console.log('❓ askNextQuestion called, currentQuestionIndex:', this.currentQuestionIndex);
|
||||
|
||||
if (!this.questions || this.currentQuestionIndex >= this.questions.length) {
|
||||
console.log('✅ All questions completed');
|
||||
this.showCompletionMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
const question = this.questions[this.currentQuestionIndex];
|
||||
|
||||
// Add AI question bubble
|
||||
const questionBubble = document.createElement('div');
|
||||
questionBubble.className = 'chat-message ai-message';
|
||||
questionBubble.innerHTML = `
|
||||
<div class="message-header">
|
||||
<span class="ai-avatar">🤖</span>
|
||||
<span class="ai-label">${this.getTranslation('ai-teacher') || 'AI Teacher'}</span>
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<p>${question}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.conversationContainer.appendChild(questionBubble);
|
||||
|
||||
// Show question with animation
|
||||
setTimeout(() => {
|
||||
questionBubble.classList.add('visible');
|
||||
this.scrollToBottomSmoothly();
|
||||
}, 100);
|
||||
|
||||
// Add input area for user response
|
||||
setTimeout(() => {
|
||||
this.addUserInputArea();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Add input area for user to respond
|
||||
addUserInputArea() {
|
||||
const inputContainer = document.createElement('div');
|
||||
inputContainer.className = 'user-input-container';
|
||||
inputContainer.innerHTML = `
|
||||
<div class="input-prompt">
|
||||
<p>💭 ${this.getTranslation('share-thoughts') || 'Share your thoughts:'}</p>
|
||||
</div>
|
||||
<div class="input-area">
|
||||
<textarea id="chat-input" placeholder="${this.getTranslation('type-thoughts') || 'Type your thoughts here...'}"
|
||||
rows="3" style="width: 100%; padding: 10px; border-radius: 8px; border: 2px solid #e2e8f0; font-size: 14px;"></textarea>
|
||||
<button onclick="kidsAI.submitChatAnswer()" class="submit-btn" style="margin-top: 10px; padding: 10px 20px; background: #4ade80; color: white; border: none; border-radius: 8px; cursor: pointer;">
|
||||
${this.getTranslation('submit') || 'Submit'} 🚀
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.conversationContainer.appendChild(inputContainer);
|
||||
|
||||
// Show input area with animation
|
||||
setTimeout(() => {
|
||||
inputContainer.classList.add('visible');
|
||||
this.scrollToBottomSmoothly();
|
||||
|
||||
// Focus on textarea
|
||||
const textarea = inputContainer.querySelector('#chat-input');
|
||||
if (textarea) {
|
||||
textarea.focus();
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
// Submit chat answer
|
||||
submitChatAnswer() {
|
||||
const textarea = document.getElementById('chat-input');
|
||||
if (!textarea) {
|
||||
console.error('❌ Chat input not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const answer = textarea.value.trim();
|
||||
if (!answer) {
|
||||
const message = this.getTranslation('write-thoughts') || 'Please write down your thoughts! 🤔';
|
||||
this.showMessage(message, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// Add user message bubble
|
||||
const userBubble = document.createElement('div');
|
||||
userBubble.className = 'chat-message user-message';
|
||||
userBubble.innerHTML = `
|
||||
<div class="message-header">
|
||||
<span class="user-avatar">👤</span>
|
||||
<span class="user-label">${this.getTranslation('you') || 'You'}</span>
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<p>${answer}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Remove input container and add user message
|
||||
const inputContainer = document.querySelector('.user-input-container');
|
||||
if (inputContainer) {
|
||||
inputContainer.remove();
|
||||
}
|
||||
|
||||
this.conversationContainer.appendChild(userBubble);
|
||||
|
||||
// Show user message with animation
|
||||
setTimeout(() => {
|
||||
userBubble.classList.add('visible');
|
||||
this.scrollToBottomSmoothly();
|
||||
}, 100);
|
||||
|
||||
// Generate AI response
|
||||
setTimeout(() => {
|
||||
this.generateChatAIResponse(answer, this.currentQuestionIndex);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Show completion message when all questions are done
|
||||
showCompletionMessage() {
|
||||
const completionBubble = document.createElement('div');
|
||||
completionBubble.className = 'chat-message ai-message completion';
|
||||
completionBubble.innerHTML = `
|
||||
<div class="message-header">
|
||||
<span class="ai-avatar">🤖</span>
|
||||
<span class="ai-label">${this.getTranslation('ai-teacher') || 'AI Teacher'}</span>
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<p>🎉 ${this.getTranslation('great-exploration') || 'Wow! You did a great job exploring this topic! You\'re thinking like a real scientist!'}</p>
|
||||
<p>💡 ${this.getTranslation('keep-wondering') || 'Keep wondering about the world around you - that\'s how we make amazing discoveries!'}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.conversationContainer.appendChild(completionBubble);
|
||||
|
||||
setTimeout(() => {
|
||||
completionBubble.classList.add('visible');
|
||||
this.scrollToBottomSmoothly();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Smooth scroll to bottom of conversation
|
||||
scrollToBottomSmoothly() {
|
||||
if (this.conversationContainer) {
|
||||
this.conversationContainer.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
||||
}
|
||||
}
|
||||
|
||||
// ...existing code...
|
||||
}
|
||||
|
||||
|
||||
44
html/kidsai/test-translations.js
Normal file
44
html/kidsai/test-translations.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// Quick test script to validate translations
|
||||
const fs = require('fs');
|
||||
|
||||
// Load and parse translations manually
|
||||
const translationsCode = fs.readFileSync('translations.js', 'utf8');
|
||||
|
||||
// Extract just the translations object
|
||||
const translationsMatch = translationsCode.match(/const translations = ({[\s\S]*?});/);
|
||||
if (!translationsMatch) {
|
||||
console.error('Could not parse translations');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const translations = eval(`(${translationsMatch[1]})`);
|
||||
|
||||
// Test key translations exist
|
||||
const testKeys = [
|
||||
'title', 'tagline', 'welcome-title', 'welcome-text',
|
||||
'ai-teacher', 'scientific-explanation', 'type-thoughts-placeholder',
|
||||
'send-button', 'the-answer', 'reveal-answer', 'getting-answer',
|
||||
'great-thinking-fallback', 'thinking-about-answer', 'hmm'
|
||||
];
|
||||
|
||||
console.log('🧪 Testing translation completeness...\n');
|
||||
|
||||
let allGood = true;
|
||||
|
||||
testKeys.forEach(key => {
|
||||
const enExists = translations.en[key] !== undefined;
|
||||
const deExists = translations.de[key] !== undefined;
|
||||
|
||||
if (!enExists || !deExists) {
|
||||
console.log(`❌ Missing translation for '${key}': EN=${enExists}, DE=${deExists}`);
|
||||
allGood = false;
|
||||
} else {
|
||||
console.log(`✅ '${key}': EN="${translations.en[key]}" | DE="${translations.de[key]}"`);
|
||||
}
|
||||
});
|
||||
|
||||
if (allGood) {
|
||||
console.log('\n🎉 All translations complete!');
|
||||
} else {
|
||||
console.log('\n⚠️ Some translations are missing');
|
||||
}
|
||||
Reference in New Issue
Block a user