🔧 Translation Improvements: - Enhanced getTranslation() with better error checking - Added t() method as safe alternative for template strings - Added extra validation for translation key existence - Better error logging for debugging translation issues ✅ Result: More robust translation system that handles edge cases
766 lines
29 KiB
JavaScript
766 lines
29 KiB
JavaScript
// KidsAI Explorer - Interactive Learning Assistant
|
|
console.log('🚀 KidsAI script-new.js is loading...');
|
|
|
|
// Test that AIResponses is available
|
|
console.log('🔍 Testing AIResponses availability:', typeof AIResponses);
|
|
if (typeof AIResponses !== 'undefined') {
|
|
console.log('✅ AIResponses loaded successfully:', Object.keys(AIResponses));
|
|
} else {
|
|
console.error('❌ AIResponses not loaded! Check ai-responses.js');
|
|
}
|
|
|
|
class KidsAIExplorer {
|
|
constructor() {
|
|
console.log('🏗️ KidsAI constructor started');
|
|
|
|
this.currentLanguage = localStorage.getItem('kidsai-language') || 'en';
|
|
|
|
// Get DOM elements
|
|
this.questionInput = document.getElementById('question-input');
|
|
this.askButton = document.getElementById('ask-button');
|
|
this.thinkingSection = document.getElementById('thinking-section');
|
|
this.thinkingSteps = document.getElementById('thinking-steps');
|
|
this.loadingOverlay = document.getElementById('loading');
|
|
this.suggestionCards = document.querySelectorAll('.suggestion-card');
|
|
this.langButtons = document.querySelectorAll('.lang-btn');
|
|
|
|
console.log('🔍 Elements found:', {
|
|
questionInput: !!this.questionInput,
|
|
askButton: !!this.askButton,
|
|
suggestionCards: this.suggestionCards.length,
|
|
langButtons: this.langButtons.length
|
|
});
|
|
|
|
// Hide loading overlay
|
|
if (this.loadingOverlay) {
|
|
this.loadingOverlay.classList.add('hidden');
|
|
}
|
|
|
|
// Initialize
|
|
this.initializeEventListeners();
|
|
this.initializeLanguage();
|
|
|
|
console.log('✅ KidsAI constructor completed');
|
|
}
|
|
|
|
// Detect mobile device
|
|
isMobileDevice() {
|
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
|
|| window.innerWidth <= 768;
|
|
}
|
|
|
|
initializeEventListeners() {
|
|
console.log('🔗 Setting up event listeners');
|
|
|
|
// Main question submission
|
|
if (this.askButton) {
|
|
console.log('📝 Adding click listener to ask button');
|
|
this.askButton.addEventListener('click', () => {
|
|
console.log('🖱️ Ask button clicked!');
|
|
this.handleQuestion();
|
|
});
|
|
}
|
|
|
|
if (this.questionInput) {
|
|
console.log('⌨️ Adding keypress listener to input');
|
|
this.questionInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
console.log('⏎ Enter key pressed!');
|
|
e.preventDefault();
|
|
this.handleQuestion();
|
|
}
|
|
});
|
|
|
|
// Add mobile-friendly input event for better responsiveness
|
|
if (this.isMobileDevice()) {
|
|
this.questionInput.addEventListener('input', () => {
|
|
// Auto-resize textarea on mobile for better UX
|
|
this.questionInput.style.height = 'auto';
|
|
this.questionInput.style.height = Math.min(this.questionInput.scrollHeight, 120) + 'px';
|
|
});
|
|
}
|
|
}
|
|
|
|
// Suggestion cards
|
|
console.log('🎯 Adding listeners to', this.suggestionCards.length, 'suggestion cards');
|
|
this.suggestionCards.forEach((card, index) => {
|
|
card.addEventListener('click', () => {
|
|
console.log('🎴 Suggestion card', index, 'clicked!');
|
|
const questionKey = `data-question-${this.currentLanguage}`;
|
|
const question = card.getAttribute(questionKey);
|
|
console.log('📝 Setting question:', question);
|
|
if (this.questionInput) {
|
|
this.questionInput.value = question;
|
|
}
|
|
this.handleQuestion();
|
|
});
|
|
});
|
|
|
|
// Language switching
|
|
this.langButtons.forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
console.log('🌐 Language button clicked:', btn.dataset.lang);
|
|
this.switchLanguage(btn.dataset.lang);
|
|
});
|
|
});
|
|
|
|
console.log('✅ Event listeners setup complete');
|
|
}
|
|
|
|
initializeLanguage() {
|
|
console.log('🌐 Initializing language:', this.currentLanguage);
|
|
|
|
// Set active language button
|
|
this.langButtons.forEach(btn => {
|
|
btn.classList.toggle('active', btn.dataset.lang === this.currentLanguage);
|
|
});
|
|
|
|
// Apply translations if available
|
|
if (typeof translations !== 'undefined') {
|
|
this.applyTranslations();
|
|
} else {
|
|
console.warn('⚠️ Translations not loaded');
|
|
}
|
|
}
|
|
|
|
applyTranslations() {
|
|
try {
|
|
const t = translations[this.currentLanguage];
|
|
if (!t) {
|
|
console.warn('⚠️ Translations not available for language:', this.currentLanguage);
|
|
return;
|
|
}
|
|
|
|
// Update all elements with data-translate attribute
|
|
document.querySelectorAll('[data-translate]').forEach(element => {
|
|
const key = element.getAttribute('data-translate');
|
|
if (t[key]) {
|
|
element.textContent = t[key];
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('❌ Error applying translations:', error);
|
|
}
|
|
}
|
|
|
|
// Helper method to get translation for a key
|
|
getTranslation(key) {
|
|
try {
|
|
if (typeof translations !== 'undefined' && translations[this.currentLanguage] && translations[this.currentLanguage][key]) {
|
|
return translations[this.currentLanguage][key];
|
|
}
|
|
} catch (error) {
|
|
console.warn('⚠️ Could not get translation for key:', key, error);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Safe translation method for use in template strings
|
|
t(key, fallback = '') {
|
|
try {
|
|
const translation = this.getTranslation(key);
|
|
return translation || fallback;
|
|
} catch (error) {
|
|
console.warn('⚠️ Translation error for key:', key, error);
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
switchLanguage(lang) {
|
|
console.log('🔄 Switching language to:', lang);
|
|
this.currentLanguage = lang;
|
|
localStorage.setItem('kidsai-language', lang);
|
|
this.initializeLanguage();
|
|
}
|
|
|
|
async handleQuestion() {
|
|
console.log('🤔 handleQuestion called');
|
|
|
|
const question = this.questionInput ? this.questionInput.value.trim() : '';
|
|
console.log('❓ Question:', question);
|
|
|
|
if (!question) {
|
|
console.log('⚠️ No question provided');
|
|
const message = this.getTranslation('ask-something-first') || 'Please ask me something first! 🤔';
|
|
this.showMessage(message, 'warning');
|
|
return;
|
|
}
|
|
|
|
this.showLoading();
|
|
console.log('🔄 Sending question to API...');
|
|
|
|
try {
|
|
const response = await fetch('/api/ask', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
question: question,
|
|
language: this.currentLanguage
|
|
})
|
|
});
|
|
|
|
console.log('📡 API response status:', response.status);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('📦 API response data:', data);
|
|
|
|
if (data.success) {
|
|
this.displayGuidance(data.guidance);
|
|
} else {
|
|
throw new Error(data.error || 'Unknown error');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error getting AI guidance:', error);
|
|
const message = this.getTranslation('processing-trouble') || 'Sorry, I had trouble processing your question. Let me give you some thinking guidance instead!';
|
|
this.showMessage(message, 'info');
|
|
this.displayLocalGuidance(question);
|
|
} finally {
|
|
this.hideLoading();
|
|
}
|
|
}
|
|
|
|
displayGuidance(guidance) {
|
|
console.log('💭 Displaying AI guidance');
|
|
|
|
if (!this.thinkingSection || !this.thinkingSteps) {
|
|
console.error('❌ Thinking section elements not found');
|
|
return;
|
|
}
|
|
|
|
// Show thinking section
|
|
this.thinkingSection.classList.remove('hidden');
|
|
|
|
// Clear previous content
|
|
this.thinkingSteps.innerHTML = '';
|
|
|
|
// Initialize conversation state
|
|
this.currentStep = 0;
|
|
this.userAnswers = [];
|
|
|
|
// Create conversation container
|
|
const conversationContainer = document.createElement('div');
|
|
conversationContainer.className = 'conversation-container';
|
|
this.thinkingSteps.appendChild(conversationContainer);
|
|
|
|
// Show initial encouragement
|
|
const welcomeStep = document.createElement('div');
|
|
welcomeStep.className = 'conversation-step visible';
|
|
|
|
// Get translations before creating HTML to avoid context issues
|
|
const encouragementText = guidance.encouragement || this.getTranslation('default-encouragement') || "Great question! Let's explore this together step by step! 🚀";
|
|
const detectiveHelpText = this.getTranslation('detective-help') || "Instead of giving you the answer right away, I'll help you think through this like a detective! 🕵️";
|
|
const aiTeacherText = this.getTranslation('ai-teacher') || "AI Teacher";
|
|
|
|
welcomeStep.innerHTML = `
|
|
<div class="ai-message">
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${aiTeacherText}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${encouragementText}</p>
|
|
<p>${detectiveHelpText}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
conversationContainer.appendChild(welcomeStep);
|
|
|
|
// Add thinking questions as interactive steps
|
|
const questions = guidance.steps ? guidance.steps.map(step => step.text) : guidance.questions || [
|
|
"What do you already know about this topic?",
|
|
"What do you think might be the reason for this?",
|
|
"Can you think of any examples or similar situations?"
|
|
];
|
|
|
|
// Create chat interface
|
|
this.conversationContainer = conversationContainer;
|
|
this.questions = questions;
|
|
this.currentQuestionIndex = 0;
|
|
|
|
// Start the conversation with the first question
|
|
this.askNextQuestion();
|
|
|
|
// Scroll to thinking section
|
|
this.thinkingSection.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
displayLocalGuidance(question) {
|
|
console.log('📚 Displaying local guidance for:', question);
|
|
|
|
// Get translated encouragements or use fallback
|
|
const encouragements = this.getTranslation('encouragements') || [
|
|
"Great question! You're thinking like a real scientist! 🔬",
|
|
"Wow, that's a fantastic thing to wonder about! 🌟",
|
|
"I love how curious you are! That's how great discoveries happen! 🚀"
|
|
];
|
|
|
|
const randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)];
|
|
|
|
// Get translated fallback questions
|
|
const fallbackQuestions = [
|
|
this.getTranslation('fallback-question-1') || "What do you already know about this topic?",
|
|
this.getTranslation('fallback-question-2') || "What do you think might be the reason for this?",
|
|
this.getTranslation('fallback-question-3') || "Where could you look to find more information?",
|
|
this.getTranslation('fallback-question-4') || "Can you think of any examples or similar situations?"
|
|
];
|
|
|
|
this.displayGuidance({
|
|
questions: fallbackQuestions,
|
|
encouragement: randomEncouragement
|
|
});
|
|
}
|
|
|
|
showLoading() {
|
|
console.log('⏳ Showing loading...');
|
|
if (this.loadingOverlay) {
|
|
this.loadingOverlay.classList.remove('hidden');
|
|
}
|
|
}
|
|
|
|
hideLoading() {
|
|
console.log('✅ Hiding loading...');
|
|
if (this.loadingOverlay) {
|
|
this.loadingOverlay.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
showMessage(message, type = 'info') {
|
|
console.log('💬 Showing message:', message, type);
|
|
|
|
// Create message popup
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.className = `message-popup ${type}`;
|
|
messageDiv.textContent = message;
|
|
messageDiv.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: ${type === 'error' ? '#fed7d7' : type === 'warning' ? '#fef5e7' : '#e6fffa'};
|
|
color: ${type === 'error' ? '#c53030' : type === 'warning' ? '#d69e2e' : '#00695c'};
|
|
padding: 15px 20px;
|
|
border-radius: 10px;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
|
|
z-index: 1001;
|
|
max-width: 300px;
|
|
font-size: 14px;
|
|
`;
|
|
|
|
document.body.appendChild(messageDiv);
|
|
|
|
// Remove after 3 seconds
|
|
setTimeout(() => {
|
|
messageDiv.remove();
|
|
}, 3000);
|
|
}
|
|
|
|
submitAnswer(stepIndex) {
|
|
console.log('📝 Submit answer for step:', stepIndex);
|
|
|
|
const textarea = document.getElementById(`user-input-${stepIndex}`);
|
|
const inputArea = document.getElementById(`input-area-${stepIndex}`);
|
|
const responseDiv = document.getElementById(`response-${stepIndex}`);
|
|
|
|
if (!textarea || !inputArea || !responseDiv) {
|
|
console.error('❌ Could not find elements for step:', stepIndex);
|
|
return;
|
|
}
|
|
|
|
const answer = textarea.value.trim();
|
|
|
|
if (!answer) {
|
|
const message = this.getTranslation('write-thoughts') || 'Please write down your thoughts! 🤔';
|
|
this.showMessage(message, 'warning');
|
|
return;
|
|
}
|
|
|
|
// Store the answer
|
|
this.userAnswers[stepIndex] = answer;
|
|
|
|
// Mark as answered
|
|
inputArea.classList.add('answered');
|
|
textarea.disabled = true;
|
|
|
|
// Show AI response using server-side AI
|
|
this.generateAIResponseToAnswer(answer, stepIndex, responseDiv);
|
|
}
|
|
|
|
// Generate AI response to user answer using server-side AI
|
|
async generateAIResponseToAnswer(answer, stepIndex, responseDiv) {
|
|
console.log('🚀 generateAIResponseToAnswer called with:', { answer, stepIndex });
|
|
|
|
try {
|
|
// Show loading state
|
|
responseDiv.innerHTML = `
|
|
<div class="ai-response-content">
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${this.getTranslation('thinking-about-answer')}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
responseDiv.style.display = 'block';
|
|
|
|
// Get current question context
|
|
const currentQuestion = this.currentSteps && this.currentSteps[stepIndex]
|
|
? this.currentSteps[stepIndex].text
|
|
: 'the current question';
|
|
|
|
console.log('📤 Sending request to /api/respond-to-answer:', { answer, currentQuestion });
|
|
|
|
// Call server API for contextual response
|
|
const response = await fetch('/api/respond-to-answer', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
answer: answer,
|
|
question: currentQuestion,
|
|
language: this.currentLanguage,
|
|
stepIndex: stepIndex
|
|
})
|
|
});
|
|
|
|
console.log('📥 Server response status:', response.status);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('✅ Server response data:', data);
|
|
|
|
if (data.success && data.response) {
|
|
responseDiv.innerHTML = `
|
|
<div class="ai-response-content">
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${data.response}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
} else {
|
|
throw new Error(data.error || 'Failed to generate response');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error generating AI response:', error);
|
|
// Fallback response
|
|
responseDiv.innerHTML = `
|
|
<div class="ai-response-content">
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${this.getTranslation('great-thinking-fallback')}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Show next question or reveal option after response
|
|
setTimeout(() => {
|
|
const nextStepIndex = stepIndex + 1;
|
|
const nextStep = document.querySelector(`.step-${nextStepIndex}`);
|
|
|
|
if (nextStep) {
|
|
// Show next question after a delay
|
|
setTimeout(() => {
|
|
nextStep.classList.add('visible');
|
|
nextStep.scrollIntoView({ behavior: 'smooth' });
|
|
}, 1500);
|
|
} else {
|
|
// All questions answered, show reveal option
|
|
setTimeout(() => {
|
|
const revealSection = document.querySelector('.reveal-section');
|
|
if (revealSection) {
|
|
revealSection.style.display = 'block';
|
|
revealSection.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
}, 2000);
|
|
}
|
|
}, 500);
|
|
}
|
|
|
|
// Generate AI response for chat system
|
|
async generateChatAIResponse(answer, questionIndex) {
|
|
console.log('🚀 generateChatAIResponse called with:', { answer, questionIndex });
|
|
|
|
try {
|
|
// Get current question context
|
|
const currentQuestion = this.questions && this.questions[questionIndex]
|
|
? this.questions[questionIndex]
|
|
: 'the current question';
|
|
|
|
console.log('📤 Sending chat request to /api/respond-to-answer:', { answer, currentQuestion });
|
|
|
|
// Call server API for contextual response
|
|
const response = await fetch('/api/respond-to-answer', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
answer: answer,
|
|
question: currentQuestion,
|
|
language: this.currentLanguage,
|
|
stepIndex: questionIndex
|
|
})
|
|
});
|
|
|
|
console.log('📥 Chat server response status:', response.status);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('✅ Chat server response data:', data);
|
|
|
|
if (data.success && data.response) {
|
|
// Add AI response bubble
|
|
const responseBubble = document.createElement('div');
|
|
responseBubble.className = 'chat-message ai-message';
|
|
responseBubble.innerHTML = `
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${data.response}</p>
|
|
</div>
|
|
`;
|
|
|
|
this.conversationContainer.appendChild(responseBubble);
|
|
|
|
// Show AI response with animation
|
|
setTimeout(() => {
|
|
responseBubble.classList.add('visible');
|
|
this.scrollToBottomSmoothly();
|
|
}, 100);
|
|
|
|
// Add choice buttons after AI response
|
|
setTimeout(() => {
|
|
this.addContinueChoiceButtons();
|
|
}, 1500);
|
|
} else {
|
|
throw new Error(data.error || 'Failed to generate response');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error generating chat AI response:', error);
|
|
|
|
// Fallback response
|
|
const responseBubble = document.createElement('div');
|
|
responseBubble.className = 'chat-message ai-message';
|
|
responseBubble.innerHTML = `
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${this.getTranslation('great-thinking-fallback')}</p>
|
|
</div>
|
|
`;
|
|
|
|
this.conversationContainer.appendChild(responseBubble);
|
|
|
|
setTimeout(() => {
|
|
responseBubble.classList.add('visible');
|
|
this.scrollToBottomSmoothly();
|
|
}, 100);
|
|
|
|
setTimeout(() => {
|
|
this.addContinueChoiceButtons();
|
|
}, 1500);
|
|
}
|
|
}
|
|
|
|
addContinueChoiceButtons() {
|
|
// Get translations before creating HTML to avoid context issues
|
|
const exploreDeeperText = this.getTranslation('explore-deeper') || "I want to explore this deeper";
|
|
const continueLearningText = this.getTranslation('continue-learning') || "Continue with next topic";
|
|
const tellMeMoreText = this.getTranslation('tell-me-more') || "Tell me more! 🤔";
|
|
const nextQuestionText = this.getTranslation('next-question') || "Next question! ➡️";
|
|
|
|
const choiceContainer = document.createElement('div');
|
|
choiceContainer.className = 'choice-container';
|
|
choiceContainer.innerHTML = `
|
|
<div class="choice-prompt">
|
|
<p>💭 ${exploreDeeperText} oder ${continueLearningText}?</p>
|
|
</div>
|
|
<div class="choice-buttons">
|
|
<button class="choice-btn explore-btn" onclick="kidsAI.exploreCurrentTopicDeeper()">
|
|
<span class="btn-icon">🔍</span> ${tellMeMoreText}
|
|
</button>
|
|
<button class="choice-btn next-btn" onclick="kidsAI.continueToNextQuestion()">
|
|
<span class="btn-icon">➡️</span> ${nextQuestionText}
|
|
</button>
|
|
</div>
|
|
`;
|
|
|
|
this.conversationContainer.appendChild(choiceContainer);
|
|
|
|
// Animate in the choices
|
|
setTimeout(() => {
|
|
choiceContainer.classList.add('visible');
|
|
this.scrollToBottomSmoothly();
|
|
}, 200);
|
|
}
|
|
|
|
// Handle choice to explore current topic deeper
|
|
async exploreCurrentTopicDeeper() {
|
|
// Remove choice buttons
|
|
const choiceContainer = document.querySelector('.choice-container');
|
|
if (choiceContainer) {
|
|
choiceContainer.remove();
|
|
}
|
|
|
|
// Get the current question and user's last answer for context
|
|
const currentQuestion = this.questions[this.currentQuestionIndex];
|
|
const lastUserMessage = Array.from(this.conversationContainer.querySelectorAll('.user-message'))
|
|
.pop()?.querySelector('.message-content p')?.textContent || '';
|
|
|
|
try {
|
|
// Request deeper exploration from the server
|
|
const response = await fetch('/api/explore-deeper', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
question: currentQuestion,
|
|
userAnswer: lastUserMessage,
|
|
language: this.currentLanguage,
|
|
context: 'deeper_exploration'
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success && data.response) {
|
|
// Add deeper exploration response
|
|
const explorationBubble = document.createElement('div');
|
|
explorationBubble.className = 'chat-message ai-message exploration';
|
|
explorationBubble.innerHTML = `
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>${data.response}</p>
|
|
</div>
|
|
`;
|
|
|
|
this.conversationContainer.appendChild(explorationBubble);
|
|
|
|
setTimeout(() => {
|
|
explorationBubble.classList.add('visible');
|
|
this.scrollToBottomSmoothly();
|
|
}, 100);
|
|
|
|
// Add choice buttons again for further exploration
|
|
setTimeout(() => {
|
|
this.addContinueChoiceButtons();
|
|
}, 2000);
|
|
} else {
|
|
throw new Error(data.error || 'Failed to get deeper exploration');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error exploring deeper:', error);
|
|
|
|
// Fallback deeper exploration
|
|
const explorationBubble = document.createElement('div');
|
|
explorationBubble.className = 'chat-message ai-message exploration';
|
|
explorationBubble.innerHTML = `
|
|
<div class="message-header">
|
|
<span class="ai-avatar">🤖</span>
|
|
<span class="ai-label">${this.getTranslation('ai-teacher')}</span>
|
|
</div>
|
|
<div class="message-content">
|
|
<p>🔍 Das ist ein wirklich interessantes Thema! Hast du schon mal daran gedacht, wie komplex die Wissenschaft dahinter ist? Möchtest du noch mehr darüber erfahren?</p>
|
|
</div>
|
|
`;
|
|
|
|
this.conversationContainer.appendChild(explorationBubble);
|
|
|
|
setTimeout(() => {
|
|
explorationBubble.classList.add('visible');
|
|
this.scrollToBottomSmoothly();
|
|
}, 100);
|
|
|
|
setTimeout(() => {
|
|
this.addContinueChoiceButtons();
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
// Handle choice to continue to next question
|
|
continueToNextQuestion() {
|
|
// Remove choice buttons
|
|
const choiceContainer = document.querySelector('.choice-container');
|
|
if (choiceContainer) {
|
|
choiceContainer.remove();
|
|
}
|
|
|
|
// Move to next question
|
|
this.currentQuestionIndex++;
|
|
this.askNextQuestion();
|
|
}
|
|
|
|
// ...existing code...
|
|
}
|
|
|
|
// Global variable for external access
|
|
let kidsAI;
|
|
|
|
// Initialize when DOM is ready
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
console.log('🚀 DOM loaded, initializing KidsAI Explorer...');
|
|
|
|
try {
|
|
kidsAI = new KidsAIExplorer();
|
|
window.kidsAI = kidsAI; // Make globally accessible
|
|
console.log('✅ KidsAI Explorer initialized successfully');
|
|
|
|
// Add visual indicator
|
|
const indicator = document.createElement('div');
|
|
indicator.innerHTML = '✅ KidsAI Ready!';
|
|
indicator.style.cssText = 'position:fixed;top:10px;left:10px;background:green;color:white;padding:5px;z-index:9999;border-radius:5px;font-size:12px;';
|
|
document.body.appendChild(indicator);
|
|
|
|
// Remove indicator after 3 seconds
|
|
setTimeout(() => indicator.remove(), 3000);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error initializing KidsAIExplorer:', error);
|
|
|
|
// Show error indicator
|
|
const indicator = document.createElement('div');
|
|
indicator.innerHTML = '❌ KidsAI Error: ' + error.message;
|
|
indicator.style.cssText = 'position:fixed;top:10px;left:10px;background:red;color:white;padding:5px;z-index:9999;border-radius:5px;font-size:12px;';
|
|
document.body.appendChild(indicator);
|
|
}
|
|
});
|
|
|
|
console.log('📜 KidsAI script-new.js loaded');
|