import React, { useState, useEffect } from 'react'; import Header from './components/Header'; import Hero from './components/Hero'; import SearchInterface from './components/SearchInterface'; import ExploreSection from './components/ExploreSection'; import StudyPlansSection from './components/StudyPlansSection'; import AIStudyPlanGenerator from './components/AIStudyPlanGenerator'; import ContentTransformer from './components/ContentTransformer'; import MultilingualExplorer from './components/MultilingualExplorer'; import ArticleViewer from './components/ArticleViewer'; import { StudyPlan, StudyTopic, ProgressData } from './types'; import { WikimediaAPI } from './utils/wikimedia-api'; function App() { const [activeTab, setActiveTab] = useState('hero'); const [studyPlans, setStudyPlans] = useState([]); const [progressData, setProgressData] = useState({ studyStreak: 0, topicsCompleted: 0, totalStudyTime: 0, achievements: 0, weeklyGoal: { current: 0, target: 12 }, recentActivity: [], completedTopics: new Set() }); // Article viewer state const [viewingArticle, setViewingArticle] = useState<{ title: string; project: string; content: string; } | null>(null); // Load data from localStorage on component mount useEffect(() => { const storedPlans = WikimediaAPI.getStoredStudyPlans(); const storedProgress = WikimediaAPI.getStoredProgress(); setStudyPlans(storedPlans); setProgressData({ ...storedProgress, completedTopics: new Set(storedProgress.completedTopics || []) }); }, []); // Save data to localStorage whenever it changes useEffect(() => { WikimediaAPI.saveStudyPlans(studyPlans); }, [studyPlans]); useEffect(() => { WikimediaAPI.saveProgress({ ...progressData, completedTopics: Array.from(progressData.completedTopics) }); }, [progressData]); const handleGetStarted = () => { setActiveTab('search'); }; const handlePlanGenerated = (plan: StudyPlan) => { setStudyPlans(prev => [...prev, plan]); setActiveTab('study'); }; const handlePlanCreated = (plan: StudyPlan) => { setStudyPlans(prev => [...prev, plan]); }; const handleTopicComplete = (planId: string, topicId: string) => { // Update study plans setStudyPlans(prev => prev.map(plan => { if (plan.id === planId) { return { ...plan, topics: plan.topics.map(topic => { if (topic.id === topicId) { return { ...topic, completed: true }; } return topic; }) }; } return plan; })); // Update progress data setProgressData(prev => { const newCompletedTopics = new Set(prev.completedTopics); newCompletedTopics.add(topicId); const plan = studyPlans.find(p => p.id === planId); const topic = plan?.topics.find(t => t.id === topicId); const newActivity = { type: 'completed' as const, title: topic?.title || 'Unknown Topic', course: plan?.title || 'Unknown Plan', time: 'Just now', icon: 'CheckCircle' as const, color: 'text-success-600' }; // Calculate study streak const today = new Date().toDateString(); const lastStudyDate = prev.lastStudyDate; let newStreak = prev.studyStreak; if (!lastStudyDate || lastStudyDate !== today) { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); if (lastStudyDate === yesterday.toDateString()) { newStreak += 1; } else if (!lastStudyDate) { newStreak = 1; } else { newStreak = 1; // Reset streak if gap } } const newProgress = { ...prev, studyStreak: newStreak, topicsCompleted: prev.topicsCompleted + 1, totalStudyTime: prev.totalStudyTime + 2, weeklyGoal: { ...prev.weeklyGoal, current: Math.min(prev.weeklyGoal.current + 2, prev.weeklyGoal.target) }, completedTopics: newCompletedTopics, recentActivity: [newActivity, ...prev.recentActivity.slice(0, 9)], lastStudyDate: today }; // Check for new achievements const newAchievements = calculateAchievements(newProgress); newProgress.achievements = newAchievements; return newProgress; }); }; const handleTopicStart = (planId: string, topicId: string) => { const plan = studyPlans.find(p => p.id === planId); const topic = plan?.topics.find(t => t.id === topicId); const newActivity = { type: 'started' as const, title: topic?.title || 'Unknown Topic', course: plan?.title || 'Unknown Plan', time: 'Just now', icon: 'BookOpen' as const, color: 'text-primary-600' }; setProgressData(prev => ({ ...prev, recentActivity: [newActivity, ...prev.recentActivity.slice(0, 9)] })); }; const calculateAchievements = (progress: ProgressData): number => { let count = 0; if (progress.topicsCompleted >= 1) count++; if (progress.studyStreak >= 7) count++; if (progress.topicsCompleted >= 10) count++; if (progress.totalStudyTime >= 25) count++; if (progress.topicsCompleted >= 50) count++; if (progress.studyStreak >= 30) count++; return count; }; const handleViewArticle = (title: string, project: string, content: string) => { setViewingArticle({ title, project, content }); }; const handleBackFromArticle = () => { setViewingArticle(null); }; const handleTabChange = (tab: string) => { // If viewing an article, go back to the previous tab first if (viewingArticle) { setViewingArticle(null); } setActiveTab(tab); }; const renderContent = () => { // If viewing an article, show the article viewer if (viewingArticle) { return ( { setActiveTab('ai-generator'); setViewingArticle(null); }} onTransformContent={(title, content) => { setActiveTab('transformer'); setViewingArticle(null); }} /> ); } switch (activeTab) { case 'search': return ; case 'explore': return ; case 'study': return ( ); case 'ai-generator': return ; case 'transformer': return ; case 'multilingual': return ; default: return ; } }; return (
{renderContent()}
); } export default App;