// 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');
}
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();
}
});
}
// 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;
}
console.log('π Applying translations for language:', this.currentLanguage);
// 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];
}
});
// Update all elements with data-translate-placeholder attribute
const placeholderElements = document.querySelectorAll('[data-translate-placeholder]');
console.log('π Found placeholder elements:', placeholderElements.length);
placeholderElements.forEach(element => {
const key = element.getAttribute('data-translate-placeholder');
console.log('π Translating placeholder key:', key, 'to:', t[key]);
if (t[key]) {
element.placeholder = t[key];
console.log('β
Updated placeholder for element:', element.tagName, 'to:', t[key]);
}
});
} catch (error) {
console.error('β Error applying translations:', error);
}
}
switchLanguage(lang) {
console.log('π Switching language to:', lang);
this.currentLanguage = lang;
localStorage.setItem('kidsai-language', lang);
// Force re-apply translations after language switch
setTimeout(() => {
this.initializeLanguage();
// Double-check placeholder specifically
if (this.questionInput && typeof translations !== 'undefined') {
const t = translations[this.currentLanguage];
if (t && t['question-placeholder']) {
this.questionInput.placeholder = t['question-placeholder'];
console.log('π Force-updated placeholder to:', t['question-placeholder']);
}
}
}, 50);
}
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');
this.showMessage('Please ask me something first! π€', '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);
this.showMessage('Sorry, I had trouble processing your question. Let me give you some thinking guidance instead!', '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);
// Get the original question for visual content
const currentQuestion = this.questionInput ? this.questionInput.value.trim() : '';
// Show initial encouragement
const welcomeStep = document.createElement('div');
welcomeStep.className = 'conversation-step visible';
// Get translations for current language
const t = (typeof translations !== 'undefined' && translations[this.currentLanguage])
? translations[this.currentLanguage]
: translations['en'];
const encouragementText = guidance.encouragement || t['default-encouragement'] || "Great question! Let's explore this together step by step! π";
const detectiveText = t['detective-help'] || "Instead of giving you the answer right away, I'll help you think through this like a detective! π΅οΈ";
const aiTeacherLabel = t['ai-teacher'] || "AI Teacher";
welcomeStep.innerHTML = `
${encouragementText}
${detectiveText}
`;
conversationContainer.appendChild(welcomeStep);
// Add visual content if available
if (typeof VisualContent !== 'undefined' && currentQuestion) {
const visualContent = VisualContent.getVisualForTopic(currentQuestion);
if (visualContent) {
const visualStep = document.createElement('div');
visualStep.className = 'conversation-step visual-step visible';
const visualDescription = visualContent.description[this.currentLanguage] || visualContent.description['en'];
visualStep.innerHTML = `
${visualDescription}
${visualContent.illustration}
`;
conversationContainer.appendChild(visualStep);
}
}
// Add thinking questions as interactive steps
const fallbackQuestions = [
t['fallback-question-1'] || "What do you already know about this topic?",
t['fallback-question-2'] || "What do you think might be the reason for this?",
t['fallback-question-3'] || "Where could you look to find more information?",
t['fallback-question-4'] || "Can you think of any examples or similar situations?"
];
const questions = guidance.steps ? guidance.steps.map(step => step.text) : guidance.questions || fallbackQuestions;
// 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 translations for current language
const t = (typeof translations !== 'undefined' && translations[this.currentLanguage])
? translations[this.currentLanguage]
: translations['en'];
const encouragements = t.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)];
this.displayGuidance({
questions: [
"What do you already know about this topic?",
"What do you think might be the reason for this?",
"Where could you look to find more information?",
"Can you think of any examples or similar situations?"
],
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) {
this.showMessage(
this.currentLanguage === 'de' ? 'Bitte schreibe deine Gedanken auf! π€' : 'Please write down your thoughts! π€',
'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 = `
π€ Thinking about your answer...
`;
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 = `
`;
} else {
throw new Error(data.error || 'Failed to generate response');
}
} catch (error) {
console.error('β Error generating AI response:', error);
// Fallback response
responseDiv.innerHTML = `
π Great thinking! Keep exploring - every thought helps us learn!
`;
}
// 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 = `
`;
this.conversationContainer.appendChild(responseBubble);
// Show AI response with animation
setTimeout(() => {
responseBubble.classList.add('visible');
this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight;
}, 100);
// Ask next question
setTimeout(() => {
this.currentQuestionIndex++; // Move to next question
this.askNextQuestion();
}, 2000);
} 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 = `
π Great thinking! Keep exploring - every thought helps us learn!
`;
this.conversationContainer.appendChild(responseBubble);
setTimeout(() => {
responseBubble.classList.add('visible');
this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight;
}, 100);
setTimeout(() => {
this.currentQuestionIndex++; // Move to next question
this.askNextQuestion();
}, 2000);
}
}
askNextQuestion() {
if (this.currentQuestionIndex >= this.questions.length) {
// All questions asked, add and show reveal section
const revealDiv = document.createElement('div');
revealDiv.className = 'reveal-section';
revealDiv.innerHTML = `
π Great thinking! You've explored this question step by step!
Would you like to see how close your thoughts were to the scientific explanation?
π― Reveal Answer!
`;
this.conversationContainer.appendChild(revealDiv);
setTimeout(() => {
revealDiv.classList.add('visible');
this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight;
}, 500);
return;
}
const question = this.questions[this.currentQuestionIndex];
// Add AI question bubble
const questionBubble = document.createElement('div');
questionBubble.className = 'chat-message ai-message';
questionBubble.innerHTML = `
${this.currentQuestionIndex + 1}) ${question}
`;
this.conversationContainer.appendChild(questionBubble);
// Add input area for user response
const inputContainer = document.createElement('div');
inputContainer.className = 'chat-input-container';
inputContainer.innerHTML = `
π¬ Send
`;
this.conversationContainer.appendChild(inputContainer);
// Animate in the question
setTimeout(() => {
questionBubble.classList.add('visible');
inputContainer.classList.add('visible');
// Smooth scroll to bottom of conversation instead of specific element
setTimeout(() => {
this.conversationContainer.scrollTop = this.conversationContainer.scrollHeight;
}, 100);
// Focus on the textarea
const textarea = document.getElementById(`user-input-${this.currentQuestionIndex}`);
if (textarea) {
textarea.focus();
}
}, 300);
}
submitChatAnswer(questionIndex) {
const textarea = document.getElementById(`user-input-${questionIndex}`);
const inputContainer = document.getElementById(`input-area-${questionIndex}`);
if (!textarea || !inputContainer) {
console.error('β Could not find elements for question:', questionIndex);
return;
}
const answer = textarea.value.trim();
if (!answer) {
this.showMessage(
this.currentLanguage === 'de' ? 'Bitte schreibe deine Gedanken auf! π€' : 'Please write down your thoughts! π€',
'warning'
);
return;
}
// Store the answer
this.userAnswers[questionIndex] = answer;
// Disable input
inputContainer.classList.add('answered');
textarea.disabled = true;
// Add user message bubble
const userBubble = document.createElement('div');
userBubble.className = 'chat-message user-message';
userBubble.innerHTML = `
`;
this.conversationContainer.appendChild(userBubble);
// Show user message and then AI response
setTimeout(() => {
userBubble.classList.add('visible');
// Generate AI response using server-side AI
this.generateChatAIResponse(answer, questionIndex);
}, 300);
}
generateContextualResponse(answer, questionIndex) {
const answerLower = answer.toLowerCase();
const currentQuestion = this.questions[questionIndex];
const questionLower = currentQuestion ? currentQuestion.toLowerCase() : '';
// Ensure AIResponses is available
if (typeof AIResponses === 'undefined') {
console.warn('β οΈ AIResponses not loaded, using fallback');
console.log('Available global objects:', Object.keys(window));
return "π Great thinking! Keep exploring - you're doing wonderfully!";
}
console.log('π Generating response for:', { answer: answerLower, question: questionLower });
// Handle "I don't know" or help-seeking responses
if (answerLower.includes('don\'t know') || answerLower.includes('no idea')) {
return AIResponses.helpSeeking.dontKnow;
}
if (answerLower.includes('what is it')) {
return AIResponses.helpSeeking.whatIsIt;
}
if (answerLower.includes('tell me')) {
return AIResponses.helpSeeking.tellMe;
}
// Handle very short positive answers like "yes"
if (answerLower === 'yes' || answerLower === 'yeah' || answerLower === 'yep') {
if (questionLower.includes('bicycle') || questionLower.includes('pedal')) {
return AIResponses.shortAnswers.yes.bicycle;
} else if (questionLower.includes('heard of') || questionLower.includes('know')) {
return AIResponses.shortAnswers.yes.knowledge;
} else {
return AIResponses.shortAnswers.yes.general;
}
}
// Handle "no" responses
if (answerLower === 'no' || answerLower === 'nope') {
return AIResponses.shortAnswers.no;
}
// Topic-specific contextual responses - BICYCLE
if (questionLower.includes('bicycle') || questionLower.includes('pedal') || questionLower.includes('chain')) {
if (answerLower.includes('brake') && (answerLower.includes('slow') || answerLower.includes('stop'))) {
return AIResponses.bicycle.brake.slowDown;
} else if (answerLower.includes('brake')) {
return AIResponses.bicycle.brake.technical;
} else if (answerLower.includes('pedal') || answerLower.includes('chain') || answerLower.includes('wheel')) {
return AIResponses.bicycle.mechanics.pedalChainWheel;
} else if (answerLower.includes('gear') || answerLower.includes('speed')) {
return AIResponses.bicycle.mechanics.gearSpeed;
} else if (answerLower.includes('slow') || answerLower.includes('stop')) {
return AIResponses.bicycle.mechanics.slowStop;
}
}
// CAR vs BICYCLE comparison
if (questionLower.includes('car') && questionLower.includes('bicycle')) {
if (answerLower.includes('engine')) {
return AIResponses.car.comparison.engine;
} else if (answerLower.includes('gear') || answerLower.includes('transmission')) {
return AIResponses.car.comparison.gearTransmission;
} else if (answerLower.includes('pedal') || answerLower.includes('brake')) {
return AIResponses.car.comparison.pedalBrake;
}
}
// CAR BRAKE responses
if (questionLower.includes('slow') || questionLower.includes('stop') || questionLower.includes('car')) {
if (answerLower.includes('brake') && (answerLower.includes('pedal') || answerLower.includes('system'))) {
return AIResponses.car.brake.perfectAnswer;
} else if (answerLower.includes('brake') && !answerLower.includes('clutch')) {
return AIResponses.car.brake.justBrake;
} else if (answerLower.includes('wheel') || answerLower.includes('tire')) {
return AIResponses.car.brake.wheelTire;
} else if (answerLower.includes('pedal') && !answerLower.includes('brake')) {
return AIResponses.car.brake.pedal;
}
}
// CLUTCH responses
if (questionLower.includes('clutch') || questionLower.includes('gears') || questionLower.includes('switch gears')) {
if (answerLower.includes('clutch')) {
return AIResponses.car.clutch.perfect;
} else if (answerLower.includes('transmission') || answerLower.includes('gearbox')) {
return AIResponses.car.clutch.transmission;
} else if (answerLower.includes('separate') || answerLower.includes('disconnect')) {
return AIResponses.car.clutch.separate;
} else if (answerLower.includes('different') && answerLower.includes('brake')) {
return AIResponses.car.clutch.different;
} else if (answerLower.includes('engine') && answerLower.includes('transmission')) {
return AIResponses.car.clutch.engineTransmission;
} else {
return AIResponses.car.clutch.general;
}
}
// TRAFFIC LIGHT / ENGINE RUNNING responses
if (questionLower.includes('traffic light') || questionLower.includes('stopped') || questionLower.includes('engine running')) {
if (answerLower.includes('clutch') || answerLower.includes('neutral')) {
return AIResponses.car.trafficLight.clutchNeutral;
} else if (answerLower.includes('disconnect') || answerLower.includes('separate')) {
return AIResponses.car.trafficLight.disconnect;
} else if (answerLower.includes('brake') || answerLower.includes('park')) {
return AIResponses.car.trafficLight.brakePark;
}
}
// BIRD FLIGHT responses
if (questionLower.includes('bird') || questionLower.includes('wing') || questionLower.includes('fly')) {
if (answerLower.includes('push') || answerLower.includes('air') || answerLower.includes('lift')) {
return AIResponses.birds.pushAirLift;
} else if (answerLower.includes('feather') || answerLower.includes('airflow')) {
return AIResponses.birds.featherAirflow;
} else if (answerLower.includes('flap') || answerLower.includes('move')) {
return AIResponses.birds.flapMove;
}
}
// MECHANICAL understanding responses
if (answerLower.includes('connect') || answerLower.includes('control')) {
return AIResponses.mechanical.connectControl;
}
// PNEUMATIC tools responses
if (questionLower.includes('pneumatic') || questionLower.includes('compressed air') || questionLower.includes('air hammer')) {
if (answerLower.includes('compress') && answerLower.includes('air')) {
return AIResponses.pneumatic.compressedAir;
} else if (answerLower.includes('air pressure') || answerLower.includes('pressure')) {
return AIResponses.pneumatic.airPressure;
} else if (answerLower.includes('direction') || answerLower.includes('releasing')) {
return AIResponses.pneumatic.direction;
} else if (answerLower.includes('balloon') || answerLower.includes('inflate')) {
return AIResponses.pneumatic.balloon;
} else if (answerLower.includes('release') || answerLower.includes('strikes')) {
return AIResponses.pneumatic.release;
} else {
return AIResponses.pneumatic.general;
}
}
// COMPUTER/CPU responses
if (questionLower.includes('cpu') || questionLower.includes('processor') || questionLower.includes('computer')) {
if (answerLower.includes('compute') || answerLower.includes('process')) {
return AIResponses.computer.cpu.computes;
} else if (answerLower.includes('don\'t know') || answerLower.includes('no idea')) {
return AIResponses.computer.cpu.dontKnow;
} else if (answerLower.includes('silicon')) {
return AIResponses.computer.cpu.silicon;
} else if (answerLower.includes('electric') || answerLower.includes('conduct')) {
return AIResponses.computer.cpu.electricity;
} else if (answerLower.includes('circuit')) {
return AIResponses.computer.cpu.circuits;
} else if (answerLower.includes('material')) {
return AIResponses.computer.cpu.materials;
} else {
return AIResponses.computer.general;
}
}
// Generic responses based on answer quality and engagement
if (answer.length > 25) {
return AIResponses.generic.veryDetailed;
} else if (answer.length > 15) {
return AIResponses.generic.detailed;
} else if (answer.length > 8) {
return AIResponses.generic.medium;
} else if (answer.length > 3) {
return AIResponses.generic.short;
} else {
return AIResponses.generic.veryShort;
}
}
async revealAnswer(question) {
console.log('π― Revealing answer for:', question);
const revealBtn = document.querySelector('.reveal-btn');
const answerContent = document.getElementById('answer-content');
if (!revealBtn || !answerContent) {
console.error('β Could not find reveal elements');
return;
}
// Show loading state
revealBtn.innerHTML = 'β³ Getting Answer...';
revealBtn.disabled = true;
try {
const response = await fetch('/api/reveal-answer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: question,
userAnswers: this.userAnswers,
language: this.currentLanguage
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.success && data.answer) {
// Display the answer
answerContent.innerHTML = `
`;
answerContent.style.display = 'block';
revealBtn.style.display = 'none';
// Animate answer in
answerContent.style.opacity = '0';
answerContent.style.transform = 'translateY(20px)';
setTimeout(() => {
answerContent.style.transition = 'all 0.6s ease-out';
answerContent.style.opacity = '1';
answerContent.style.transform = 'translateY(0)';
}, 100);
} else {
throw new Error(data.error || 'Failed to get answer');
}
} catch (error) {
console.error('β Error getting final answer:', error);
// Fallback answer display
revealBtn.innerHTML = `π― ${this.currentLanguage === 'de' ? 'Antwort zeigen!' : 'Reveal Answer!'}`;
revealBtn.disabled = false;
answerContent.innerHTML = `
${this.currentLanguage === 'de'
? 'Ich kann die Antwort gerade nicht abrufen. Das ist eine tolle Frage! Du hast schon toll nachgedacht. Frag gerne einen Erwachsenen oder schaue in einem Buch nach.'
: 'I can\'t fetch the answer right now. That\'s a great question! You\'ve done great thinking already. Feel free to ask an adult or look it up in a book.'}
`;
answerContent.style.display = 'block';
}
}
// Debug function to manually test placeholder translation
debugTranslatePlaceholder() {
console.log('π§ͺ DEBUG: Manually testing placeholder translation');
console.log('Current language:', this.currentLanguage);
console.log('Available translations:', typeof translations !== 'undefined' ? Object.keys(translations) : 'not loaded');
if (typeof translations !== 'undefined') {
const t = translations[this.currentLanguage];
if (t && t['question-placeholder']) {
console.log('German placeholder text:', t['question-placeholder']);
const input = document.getElementById('question-input');
if (input) {
input.placeholder = t['question-placeholder'];
console.log('β
Manually updated placeholder');
} else {
console.log('β Input element not found');
}
} else {
console.log('β Translation not found for question-placeholder');
}
}
}
}
// 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');
// Force placeholder translation after a short delay to ensure everything is loaded
setTimeout(() => {
console.log('π Force applying placeholder translation on load...');
if (kidsAI && typeof translations !== 'undefined') {
const currentLang = kidsAI.currentLanguage;
const input = document.getElementById('question-input');
if (input && translations[currentLang] && translations[currentLang]['question-placeholder']) {
input.placeholder = translations[currentLang]['question-placeholder'];
console.log('β
Force-set placeholder on load to:', translations[currentLang]['question-placeholder']);
}
}
}, 100);
// 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');