import React, { useState, useEffect } from 'react';
const LockIcon = () => (
);
const CheckIcon = () => (
);
const BackIcon = () => (
);
const SmartOwl = ({ isHappy, message, size = "w-32 h-32" }) => (
);
const CONTENT = {
logic: {
title: "Логика Перельмана",
color: "indigo",
levels: [
{
id: "logic_1", name: "Первые шаги",
questions: [
{ id: "l1_q1", question: "У мамы 5 дочерей. У каждой есть брат. Сколько детей в семье?", options: ["6", "10", "5"], answer: "6", explanation: "Брат один — общий для всех сестер. 5 сестер + 1 брат = 6 детей!" },
{ id: "l1_q2", question: "На столе лежало 3 спички. Как сделать из них цифру 4?", options: ["Сложить римскую IV", "Сломать одну", "Положить треугольником"], answer: "Сложить римскую IV", explanation: "Из трех целых палочек легко выложить римскую цифру IV!" },
{ id: "l1_q3", question: "Что тяжелее: 1кг пуха или 1кг камней?", options: ["Камни", "Пух", "Одинаково"], answer: "Одинаково", explanation: "Килограмм — это мера веса. И то, и другое весит ровно 1 килограмм." },
{ id: "l1_q4", question: "Два отца и два сына съели 3 апельсина. Каждому досталось по целому. Как так?", options: ["Это дед, отец и сын", "Кто-то не ел", "Апельсинов было 4"], answer: "Это дед, отец и сын", explanation: "Всего три человека: дедушка, папа и внук." },
{ id: "l1_q5", question: "Кирпич весит 1 кг и еще полкирпича. Сколько весит весь кирпич?", options: ["1.5 кг", "2 кг", "1 кг"], answer: "2 кг", explanation: "Если кирпич состоит из 1кг и своей половины, значит эта половина и весит 1кг. 1 + 1 = 2кг!" },
{ id: "l1_q6", question: "Сколько концов у трех палок?", options: ["3", "6", "9"], answer: "6", explanation: "У каждой палки по 2 конца. 3 * 2 = 6." },
{ id: "l1_q7", question: "На березе росло 10 яблок. 3 упало. Сколько осталось?", options: ["7", "0", "10"], answer: "0", explanation: "На березах яблоки не растут!" },
{ id: "l1_q8", question: "В комнате 4 угла. В каждом углу сидит кошка. Сколько всего кошек?", options: ["4", "8", "16"], answer: "4", explanation: "Всего 4 угла — в каждом по одной кошке, итого 4." },
{ id: "l1_q9", question: "У квадрата 4 угла. Если один угол отрезать, сколько останется?", options: ["3", "4", "5"], answer: "5", explanation: "На месте одного отрезанного угла появятся два новых." },
{ id: "l1_q10", question: "Летели три утки: одна впереди и две позади. Сколько уток?", options: ["3", "5", "6"], answer: "3", explanation: "Они летят друг за другом цепочкой." }
]
}
]
},
olympiad: {
title: "Олимпиады",
color: "orange",
levels: [
{
id: "olympiad_1", name: "Вступление",
questions: [
{ id: "o1_q1", question: "Сумма двух чисел равна 7, а разность 1. Что это за числа?", options: ["4 и 3", "5 и 2", "6 и 1"], answer: "4 и 3", explanation: "4+3=7, 4-3=1. Всё верно!" },
{ id: "o1_q2", question: "В коробке 4 синих и 3 красных шара. Сколько надо вынуть не глядя, чтобы точно был один красный?", options: ["5", "4", "3"], answer: "5", explanation: "Если не везет, сначала вынешь все 4 синих, и тогда 5-й точно будет красным." },
{ id: "o1_q3", question: "Улитка ползет на столб 10м. Днем вверх на 3м, ночью вниз на 2м. На какой день доползет?", options: ["8", "10", "7"], answer: "8", explanation: "На 8-й день она будет на 7м, проползет 3м и окажется наверху!" },
{ id: "o1_q4", question: "Тройка лошадей пробежала 15 км. Сколько пробежала каждая лошадь?", options: ["5 км", "15 км", "45 км"], answer: "15 км", explanation: "Они же бежали все вместе!" },
{ id: "o1_q5", question: "В семье 7 сыновей, у каждого есть сестра. Сколько детей?", options: ["8", "14", "7"], answer: "8", explanation: "Сестра одна для всех братьев." },
{ id: "o1_q6", question: "Что можно видеть с закрытыми глазами?", options: ["Сны", "Темноту", "Ничего"], answer: "Сны", explanation: "Даже с закрытыми глазами мы видим картинки во сне!" },
{ id: "o1_q7", question: "Как написать число 100 пятью единицами?", options: ["111-11", "11+11+1", "1*1*1*1*1"], answer: "111-11", explanation: "111 минус 11 равно ровно 100." },
{ id: "o1_q8", question: "В 12 часов дня идет дождь. Может ли через 72 часа быть солнечная погода?", options: ["Да", "Нет", "Только если лето"], answer: "Нет", explanation: "Через 72 часа (ровно 3 суток) снова будет 12 часов НОЧИ. Солнца не будет." },
{ id: "o1_q9", question: "Сколько граней у неточеного карандаша с 6 углами?", options: ["6", "8", "7"], answer: "8", explanation: "6 боковых граней + 2 торца (верх и низ) = 8." },
{ id: "o1_q10", question: "Летело 5 ворон, одну подстрелили. Сколько осталось?", options: ["4", "1", "0"], answer: "0", explanation: "Остальные просто улетели от испуга." }
]
}
]
},
math: {
title: "Математика",
color: "green",
levels: [
{
id: "math_1", name: "Разминка",
questions: Array.from({length: 10}, (_, i) => ({
id: `m1_q${i}`, question: `Сколько будет ${i+1} + ${i+2}?`, options: [`${2*i+3}`, `${2*i+4}`, `${2*i+2}`], answer: `${2*i+3}`, explanation: "Простая арифметика!"
}))
}
]
}
};
export default function TutorApp() {
const [userData, setUserData] = useState({
name: '', grade: 1, score: 0,
completedLevels: [], answered: []
});
const [currentView, setCurrentView] = useState('setup'); // setup, home, map, game, results, chat
const [activeCategory, setActiveCategory] = useState('logic');
const [activeLevel, setActiveLevel] = useState(null);
const [currentIndex, setCurrentIndex] = useState(0);
const [feedback, setFeedback] = useState(null);
const [correctInLevel, setCorrectInLevel] = useState(0);
const startLevel = (catKey, level) => {
if (!level || !level.questions || level.questions.length === 0) {
// Если вопросов нет, генерируем их на лету (заглушка для 100 уровней)
const generatedLevel = {
...level,
questions: Array.from({length: 10}, (_, i) => ({
id: `${level.id}_q${i}`,
question: `Вопрос №${i+1} для уровня ${level.name}. Сколько будет 2+2?`,
options: ["4", "5", "3"],
answer: "4",
explanation: "Это проверочный вопрос для новых уровней!"
}))
};
setActiveLevel(generatedLevel);
} else {
setActiveLevel(level);
}
setActiveCategory(catKey);
setCurrentIndex(0);
setCorrectInLevel(0);
setFeedback(null);
setCurrentView('game');
};
const handleAnswer = (selected) => {
if (feedback) return;
const q = activeLevel.questions[currentIndex];
const isCorrect = selected === q.answer;
if (isCorrect) {
setCorrectInLevel(prev => prev + 1);
setUserData(prev => ({...prev, score: prev.score + 10}));
}
setFeedback({ isCorrect, explanation: q.explanation, selected });
};
const nextQuestion = () => {
if (currentIndex < activeLevel.questions.length - 1) {
setFeedback(null);
setCurrentIndex(prev => prev + 1);
} else {
const newCompleted = [...new Set([...userData.completedLevels, activeLevel.id])];
setUserData(prev => ({...prev, completedLevels: newCompleted}));
setCurrentView('results');
}
};
if (currentView === 'setup') return (
);
const renderHome = () => (
{userData.name || 'Ученик'}
Класс {userData.grade}
Звёзды
{userData.score} ⭐
{Object.entries(CONTENT).map(([key, cat]) => (
))}
);
const renderMap = () => {
const cat = CONTENT[activeCategory];
const levelItems = Array.from({length: 100}, (_, i) => {
const real = cat.levels[i];
return {
id: real ? real.id : `${activeCategory}_${i+1}`,
name: real ? real.name : `Уровень ${i+1}`,
questions: real ? real.questions : []
};
});
return (
{cat.title}
{levelItems.map((level, idx) => {
const isCompleted = userData.completedLevels.includes(level.id);
const isUnlocked = idx === 0 || userData.completedLevels.includes(levelItems[idx-1].id);
return (
);
})}
);
};
const renderGame = () => {
if (!activeLevel) return null;
const q = activeLevel.questions[currentIndex];
return (
{activeLevel.questions.map((_, i) => (
))}
{currentIndex + 1} / 10
{q.question}
{q.options.map(opt => (
))}
{feedback && (
Мудрость Совы:
{feedback.explanation}
)}
);
};
const renderResults = () => (
ПОБЕДА!
Твой результат: {correctInLevel} из 10
);
return (
{currentView === 'home' && renderHome()}
{currentView === 'map' && renderMap()}
{currentView === 'game' && renderGame()}
{currentView === 'results' && renderResults()}
{currentView === 'chat' && (
)}
);
}