diff --git a/client/src/components/CodeEditor.css b/summership-26-prs/Ishi Jain/client/src/components/CodeEditor.css similarity index 100% rename from client/src/components/CodeEditor.css rename to summership-26-prs/Ishi Jain/client/src/components/CodeEditor.css diff --git a/client/src/components/CodeEditor.jsx b/summership-26-prs/Ishi Jain/client/src/components/CodeEditor.jsx similarity index 100% rename from client/src/components/CodeEditor.jsx rename to summership-26-prs/Ishi Jain/client/src/components/CodeEditor.jsx diff --git a/client/src/components/Dashboard.css b/summership-26-prs/Ishi Jain/client/src/components/Dashboard.css similarity index 100% rename from client/src/components/Dashboard.css rename to summership-26-prs/Ishi Jain/client/src/components/Dashboard.css diff --git a/client/src/components/Dashboard.jsx b/summership-26-prs/Ishi Jain/client/src/components/Dashboard.jsx similarity index 100% rename from client/src/components/Dashboard.jsx rename to summership-26-prs/Ishi Jain/client/src/components/Dashboard.jsx diff --git a/client/src/components/LearningPath.css b/summership-26-prs/Ishi Jain/client/src/components/LearningPath.css similarity index 100% rename from client/src/components/LearningPath.css rename to summership-26-prs/Ishi Jain/client/src/components/LearningPath.css diff --git a/client/src/components/LearningPath.jsx b/summership-26-prs/Ishi Jain/client/src/components/LearningPath.jsx similarity index 100% rename from client/src/components/LearningPath.jsx rename to summership-26-prs/Ishi Jain/client/src/components/LearningPath.jsx diff --git a/summership-26-prs/Ishi Jain/server/.gitignore b/summership-26-prs/Ishi Jain/server/.gitignore new file mode 100644 index 00000000..4c49bd78 --- /dev/null +++ b/summership-26-prs/Ishi Jain/server/.gitignore @@ -0,0 +1 @@ +.env diff --git a/test.json b/summership-26-prs/Ishi Jain/test.json similarity index 100% rename from test.json rename to summership-26-prs/Ishi Jain/test.json diff --git a/summership-26-prs/Vanisha Tiwari/client/src/main.jsx b/summership-26-prs/Vanisha Tiwari/client/src/main.jsx index 26b36271..8e8cf92a 100644 --- a/summership-26-prs/Vanisha Tiwari/client/src/main.jsx +++ b/summership-26-prs/Vanisha Tiwari/client/src/main.jsx @@ -1,5 +1,13 @@ -import React, { useEffect, useMemo, useState } from 'react'; -import { createRoot } from 'react-dom/client'; +import React, { + useEffect, + useMemo, + useState +} from 'react'; + +import { + createRoot +} from 'react-dom/client'; + import { Brain, ChartNoAxesCombined, @@ -11,568 +19,548 @@ import { Route, Search, Send, - Sparkles, -<<<<<<< HEAD:summership-26-prs/Vanisha Tiwari/client/src/main.jsx - Gamepad2, - ArrowLeft, - ShieldCheck + Sparkles } from 'lucide-react'; -import OopStoryApp from './oop-story/OopStoryApp'; -======= - Rocket, - Target, - BookOpen, - Zap -} from 'lucide-react'; -import CodeEditor from './components/CodeEditor'; -import LearningPath from './components/LearningPath'; ->>>>>>> upstream/main:client/src/main.jsx + import './styles.css'; -const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000/api'; +const API_URL = + import.meta.env.VITE_API_URL || + 'http://localhost:5000/api'; async function api(path, options) { - const response = await fetch(`${API_URL}${path}`, { - headers: { 'Content-Type': 'application/json' }, - ...options - }); - if (!response.ok) throw new Error(await response.text()); + const response = await fetch( + `${API_URL}${path}`, + { + headers: { + 'Content-Type': 'application/json' + }, + ...options + } + ); + + if (!response.ok) { + throw new Error( + await response.text() + ); + } + return response.json(); } function App() { - const [activeTab, setActiveTab] = useState('scenarios'); // 'scenarios' | 'story-lab' - const [scenarios, setScenarios] = useState([]); - const [selected, setSelected] = useState(null); - const [sessions, setSessions] = useState([]); - const [analytics, setAnalytics] = useState(null); - const [roadmap, setRoadmap] = useState([]); - const [learningPath, setLearningPath] = useState(null); - const [filters, setFilters] = useState({ q: '', difficulty: '', concept: '' }); - const [form, setForm] = useState({ learnerName: 'Guest learner', reasoning: '', promptText: '', reflection: '' }); - const [activeResult, setActiveResult] = useState(null); - const [loading, setLoading] = useState(true); - const [submitting, setSubmitting] = useState(false); - const [showCodeEditor, setShowCodeEditor] = useState(false); - const [currentCode, setCurrentCode] = useState(''); - const [activeTab, setActiveTab] = useState('learn'); - const [nlpResult, setNlpResult] = useState(null); - - const concepts = useMemo(() => [...new Set(scenarios.flatMap((scenario) => scenario.concepts || []))].sort(), [scenarios]); + const [scenarios, setScenarios] = + useState([]); + + const [selected, setSelected] = + useState(null); + + const [sessions, setSessions] = + useState([]); + + const [analytics, setAnalytics] = + useState(null); + + const [roadmap, setRoadmap] = + useState([]); + + const [filters, setFilters] = + useState({ + q: '', + difficulty: '', + concept: '' + }); + + const [form, setForm] = + useState({ + learnerName: 'Guest learner', + reasoning: '', + promptText: '', + reflection: '' + }); + + const [activeResult, setActiveResult] = + useState(null); + + const [loading, setLoading] = + useState(true); + + const [loadError, setLoadError] = + useState(null); + + const [submitting, setSubmitting] = + useState(false); + + const concepts = useMemo( + () => + [ + ...new Set( + scenarios.flatMap( + (scenario) => + scenario.concepts || [] + ) + ) + ].sort(), + [scenarios] + ); async function refresh() { - const params = new URLSearchParams(Object.entries(filters).filter(([, value]) => value)); + const params = + new URLSearchParams( + Object.entries(filters).filter( + ([, value]) => value + ) + ); + try { - const [scenarioData, sessionData, analyticsData, roadmapData, pathData] = await Promise.all([ + const [ + scenarioData, + sessionData, + analyticsData, + roadmapData + ] = await Promise.all([ api(`/scenarios?${params}`), api('/sessions'), api('/analytics'), - api('/roadmap'), - api('/learning-path').catch(() => null) // Changed from /analytics/learning-path + api('/roadmap') ]); + setScenarios(scenarioData); setSessions(sessionData); setAnalytics(analyticsData); setRoadmap(roadmapData); - setLearningPath(pathData); - setSelected((current) => current || scenarioData[0] || null); + + setSelected( + (current) => + current || + scenarioData[0] || + null + ); + + setLoadError(null); } catch (error) { - console.error('Refresh error:', error); + console.error( + 'PyBe API loading failed:', + error + ); + + setLoadError( + error.message || + 'Unable to connect to PyBe API' + ); } finally { setLoading(false); } } useEffect(() => { - refresh().catch(console.error); - }, [filters.q, filters.difficulty, filters.concept]); + setLoading(true); + refresh(); + }, [ + filters.q, + filters.difficulty, + filters.concept + ]); - // EXISTING: Submit learning session (uses /sessions) async function submitSession(event) { event.preventDefault(); - if (!selected || !form.reasoning.trim()) return; - setSubmitting(true); - try { - const result = await api('/sessions', { - method: 'POST', - body: JSON.stringify({ ...form, scenarioId: selected._id }) - }); - setActiveResult(result); - setForm({ ...form, reasoning: '', promptText: '', reflection: '' }); - await refresh(); - } finally { - setSubmitting(false); - } - } - - const handleScenarioSelect = (scenario) => { - setSelected(scenario); - setActiveResult(null); - setNlpResult(null); - // Generate initial code - const initialCode = `# Scenario: ${scenario.title}\n# Difficulty: ${scenario.difficulty}\n# Concepts: ${scenario.concepts?.join(', ') || 'N/A'}\n\ndef solve():\n # TODO: Implement your solution here\n pass\n\n# Call your function\nsolver = solve()`; - setCurrentCode(initialCode); - }; - - const handleCodeSave = async (code) => { - try { - const response = await api('/sessions/save-code', { - method: 'POST', - body: JSON.stringify({ code, scenarioId: selected?._id }) - }); - alert('βœ… Code saved successfully!'); - } catch (error) { - console.error('Save error:', error); - alert('❌ Failed to save code'); - } - }; - // NEW: NLP - Convert reasoning to Python code (uses /nlp) - const handleConvertReasoning = async () => { - if (!form.reasoning.trim()) { - alert('Please enter your reasoning first'); + if ( + !selected || + !form.reasoning.trim() + ) { return; } - - try { - const result = await api('/nlp/convert-reasoning', { - method: 'POST', - body: JSON.stringify({ - reasoning: form.reasoning, - scenarioId: selected?._id - }) - }); - - if (result.success) { - setNlpResult(result); - setCurrentCode(result.pythonCode); - setShowCodeEditor(true); - setActiveTab('code'); - - if (activeResult) { - setActiveResult({ - ...activeResult, - generatedCode: result.pythonCode, - codeExplanation: result.explanation - }); - } - } - } catch (error) { - console.error('Conversion error:', error); - alert('Failed to convert reasoning to code'); - } - }; - // NEW: NLP - Extract concepts from reasoning - const handleExtractConcepts = async () => { - if (!form.reasoning.trim()) { - alert('Please enter your reasoning first'); - return; - } - - try { - const result = await api('/nlp/extract-concepts', { - method: 'POST', - body: JSON.stringify({ - reasoning: form.reasoning - }) - }); - - if (result.success) { - alert(`πŸ“š Detected Concepts:\n${result.concepts.join('\n')}`); - } - } catch (error) { - console.error('Extract concepts error:', error); - alert('Failed to extract concepts'); - } - }; + setSubmitting(true); + setLoadError(null); - // NEW: NLP - Validate code - const handleValidateCode = async (code) => { try { - const result = await api('/nlp/validate-code', { - method: 'POST', - body: JSON.stringify({ code }) - }); - - if (result.success) { - alert('βœ… Code is valid!'); - } else { - alert(`❌ Validation errors:\n${result.errors.join('\n')}`); - } - return result; - } catch (error) { - console.error('Validation error:', error); - return { success: false, errors: ['Validation failed'] }; - } - }; + const result = + await api('/sessions', { + method: 'POST', + body: JSON.stringify({ + ...form, + scenarioId: + selected._id + }) + }); - // NEW: NLP - Generate code with context - const handleGenerateCodeWithContext = async () => { - if (!form.reasoning.trim()) { - alert('Please enter your reasoning first'); - return; - } - - try { - const context = selected?.context || ''; - const result = await api('/nlp/generate-code', { - method: 'POST', - body: JSON.stringify({ - reasoning: form.reasoning, - scenarioId: selected?._id, - context: context - }) + setActiveResult(result); + + setForm({ + ...form, + reasoning: '', + promptText: '', + reflection: '' }); - - if (result.success) { - setNlpResult(result); - setCurrentCode(result.pythonCode); - setShowCodeEditor(true); - setActiveTab('code'); - } + + await refresh(); } catch (error) { - console.error('Generate code error:', error); - alert('Failed to generate code with context'); + console.error( + 'Session submission failed:', + error + ); + + setLoadError( + error.message || + 'Unable to submit session' + ); + } finally { + setSubmitting(false); } - }; - - if (loading) return
Loading PyBe...
; + } - if (activeTab === 'story-lab') { + if (loading) { return ( -
-
- -
- - PyBe Interactive OOP Story Lab - Encapsulation -
-
- - Python WebAssembly Engine Active -
-
-
- -
-
+
+ Loading PyBe... +
); } - const isOopScenario = selected?.concepts?.some((c) => ['oop', 'encapsulation', 'properties'].includes(c.toLowerCase())) || - selected?.title?.toLowerCase().includes('oop') || selected?.title?.toLowerCase().includes('pet shop'); + if (loadError) { + return ( +
+

+ Unable to load PyBe +

+ +

{loadError}

+ +

+ Make sure the backend is + running on port 5000. +

+ + +
+ ); + } return (
-

AI-native learning journey

-

Learn Python by reasoning through real situations first.

+

+ AI-native learning journey +

+ +

+ Learn Python by reasoning + through real situations first. +

+
- {analytics?.scenarioCount || 0}Scenarios - {analytics?.sessionCount || 0}Sessions - {analytics?.averagePromptScore || 0}Prompt score + + {analytics?.scenarioCount || 0} + + Scenarios + + + + + {analytics?.sessionCount || 0} + + Sessions + + + + + {analytics?.averagePromptScore || 0} + + Prompt score + +
-<<<<<<< HEAD:summership-26-prs/Vanisha Tiwari/client/src/main.jsx - {isOopScenario && ( -
-
-
✨ Interactive Adventure Available
-

Master Encapsulation with Buddy the Puppy!

-

Experience an animated 2D cartoon storyline with live Capsule shielding, tamper defense, and in-browser Python runtime.

-
- -
- )} -
-

{selected?.title}

+ +

+ {selected?.title} +

-

{selected?.context}

+ +

+ {selected?.context} +

+
- {selected?.objectives.map((item) => {item})} + {selected?.objectives.map( + (item) => ( + + {item} + + ) + )}
-
+ +