- Project Description
- User Personas
- User Stories
- System Architecture
- Database Design
- Design Mockups
- React Components
- API Endpoints
- Implementation Timeline
- Technical Requirements
The Metacognition Learning Engine is a web application that helps students learn more effectively by teaching them to think about their own thinking. Unlike traditional study apps that focus only on content memorization, our app guides users through a structured reflection process called the Plan-Monitor-Evaluate loop.
Students often:
- Read or review material without truly understanding it
- Overestimate how well they've learned something (illusion of knowing)
- Don't know which study strategies work best for them
- Lack awareness of their own learning patterns
We transform user-uploaded study material into short, guided learning loops (90 seconds each) where students:
- PLAN - Set a learning goal and choose a strategy
- MONITOR - Test their understanding and rate their confidence
- EVALUATE - Get feedback and reflect on what worked
Over time, students build metacognitive awareness - they learn not just the content, but also how they learn best.
- Text Upload - Students paste their notes, textbook sections, or study materials
- Chunk Generation - AI breaks content into bite-sized learning chunks
- Guided Learning Loop - Plan β Monitor β Evaluate cycle for each chunk
- Performance Tracking - Confidence vs accuracy calibration
- Session Insights - Summary showing which strategies worked best
Frontend:
- React 18 with Hooks
- CSS Modules (component-based styling)
- No prohibited libraries (no axios, mongoose, CORS)
Backend:
- Node.js + Express
- MongoDB with native driver (no Mongoose)
- RESTful API
Deployment:
- Frontend: Netlify or Vercel
- Backend: Render.com or Railway
- Database: MongoDB Atlas (free tier)
Demographics:
- Age: 20
- Major: Biology (Pre-Med track)
- Year: Sophomore
- Tech savviness: Medium
Background: Alex is juggling organic chemistry, cell biology, and physics. They spend hours re-reading lecture notes but still struggle on exams. They highlight everything but don't actually process the information.
Goals:
- Actually understand concepts, not just memorize them
- Study more efficiently (less time, better results)
- Know when they really "get it" vs when they're fooling themselves
Pain Points:
- Feels like they study a lot but scores don't reflect effort
- Doesn't know which study methods work best
- Often surprised by what they don't know on exam day
How Our App Helps:
- Breaks dense textbook sections into manageable chunks
- Forces active recall and self-explanation
- Shows calibration scores (confidence vs actual understanding)
- Reveals which strategies (diagrams, examples, self-explain) work best for different topics
Typical Session: Alex pastes a section about cellular respiration (500 words). The app generates 4 chunks. For each chunk, Alex:
- Picks a goal ("explain it to someone")
- Chooses a strategy ("draw a diagram mentally")
- Reads the mini-teach
- Answers a question
- Rates confidence (maybe 70%)
- Gets feedback showing actual accuracy (60% - slight overconfidence)
- Reflects on whether the strategy helped
After 4 chunks (~6 minutes), Alex sees that "self-explain" gave better accuracy than "visualize" for this topic.
Demographics:
- Age: 22
- Major: Computer Science
- Year: Junior
- Tech savviness: High
Background: Jordan learns best through hands-on practice but struggles with theoretical concepts (algorithms, complexity). They often skip the reading and jump straight to coding, leading to gaps in understanding.
Goals:
- Build stronger theoretical foundation
- Balance hands-on practice with conceptual understanding
- Track which study approaches work for abstract vs practical topics
Pain Points:
- Gets impatient with long reading assignments
- Performs well on coding projects but struggles on written exams
- Doesn't know how to study for theory-heavy courses
How Our App Helps:
- Short 90-second loops match Jordan's attention span
- "Work an example" strategy lets them apply concepts immediately
- Tracks performance by strategy and topic type
- Shows Jordan that they need different approaches for algorithms vs implementation
Typical Session: Jordan pastes notes about Dijkstra's algorithm. The app creates 5 chunks. Jordan tries different strategies:
- Chunk 1: "Work an example" (85% accuracy - works well!)
- Chunk 2: "Self-explain" (70% accuracy - harder for Jordan)
- Chunk 3: "Visualize the graph" (80% accuracy - also good)
Session summary shows Jordan learns algorithms best by working examples and visualizing, not reading passively.
Demographics:
- Age: 35
- Major: Business Administration (evening program)
- Year: Junior
- Tech savviness: Medium-Low
Background: Maria returned to college after 10 years. She's balancing classes, a full-time job, and two kids. Study time is precious - she needs to make every minute count. She feels rusty on studying and test-taking.
Goals:
- Use limited study time efficiently
- Rebuild confidence in her learning abilities
- Develop effective study habits
Pain Points:
- Only has 15-30 minute pockets of time to study
- Second-guesses herself on exams
- Doesn't remember how to study effectively
- Feels less confident than traditional students
How Our App Helps:
- Short sessions (5-10 chunks = ~12 minutes) fit her schedule
- Builds confidence through calibration feedback
- Shows concrete evidence of learning progress
- Simple, clear interface (not overwhelming)
Typical Session: Maria has 15 minutes before picking up kids. She pastes a section from her marketing textbook about consumer behavior. App generates 6 chunks. Maria completes 5 of them:
- Starts uncertain (40% confidence) but actually scores 55% (improving!)
- By chunk 5, confidence is 65% and accuracy is 70% (well-calibrated)
- Session summary shows "You're better than you think! Your calibration improved."
This builds Maria's confidence and shows her that she can learn effectively.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FRONTEND (React) β
β ββββββββββββββββ ββββββββββββββββ β
β β Upload β β Learning β β
β β Component β β Loop β β
β β β β Component β β
β ββββββββββββββββ ββββββββββββββββ β
β ββββββββββββββββ ββββββββββββββββ β
β β Session β β History β β
β β Summary β β Component β β
β ββββββββββββββββ ββββββββββββββββ β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β REST API
β (fetch)
ββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β BACKEND (Node + Express) β
β ββββββββββββββββ ββββββββββββββββ β
β β Routes β β Services β β
β β /chunks β β - LLM β β
β β /responses β β - Evaluate β β
β β /sessions β β β β
β ββββββββββββββββ ββββββββββββββββ β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β MongoDB Driver
β (native, no Mongoose)
ββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β DATABASE (MongoDB) β
β ββββββββββββββββ ββββββββββββββββ β
β β sessions β β responses β β
β β collection β β collection β β
β β (200 docs) β β (1200+ docs)β β
β ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User Action: Upload Text
β
UploadComponent.jsx
β POST /api/chunks/generate
Backend: chunksRoute.js
β
LLM Service (Gemini API)
β
Returns: Array of chunks
β
Store in sessions collection
β
Frontend: Navigate to LearningLoop
β
LearningLoopComponent.jsx
β For each chunk:
Plan β Monitor β Evaluate
β POST /api/responses
Backend: responsesRoute.js
β
Evaluate Service (LLM)
β
Store in responses collection
β
Frontend: Show feedback
β
Repeat until all chunks done
β
SessionSummaryComponent.jsx
β GET /api/sessions/:id/summary
Backend: Calculate stats
β
Display insights
Purpose: Store each learning session and its generated chunks
Fields:
{
_id: ObjectId,
userId: String, // "anonymous" for MVP (future: real user IDs)
rawContent: String, // Original pasted text
contentPreview: String, // First 100 chars (for list display)
createdAt: Date,
completedAt: Date, // null until session finished
status: String, // "in_progress", "completed"
chunks: [ // Array of generated chunks
{
chunkId: String, // "chunk_0", "chunk_1", etc.
topic: String,
miniTeach: String,
question: String,
expectedPoints: [String],
completed: Boolean
}
],
sessionStats: { // Calculated after session
totalChunks: Number,
chunksCompleted: Number,
averageAccuracy: Number,
averageConfidence: Number,
calibrationError: Number, // avgConfidence - avgAccuracy
totalTimeSeconds: Number
}
}CRUD Operations:
- CREATE: POST
/api/sessions(when user uploads content) - READ: GET
/api/sessions(list all sessions) - READ: GET
/api/sessions/:id(get specific session) - UPDATE: PATCH
/api/sessions/:id(mark chunk complete, update stats) - DELETE: DELETE
/api/sessions/:id(remove session)
Indexes:
_id(default)userId(for filtering user's sessions)createdAt(for sorting by date)
Synthetic Data: Generate 200 sample sessions with realistic text content (each session has 5-8 chunks)
Purpose: Store each individual chunk response (Plan-Monitor-Evaluate data)
Fields:
{
_id: ObjectId,
sessionId: ObjectId, // Reference to sessions collection
userId: String, // Same as session.userId
chunkId: String, // "chunk_0", "chunk_1", etc.
chunkTopic: String, // Denormalized for easy querying
// PLAN phase
goal: String, // "gist", "explain", "apply"
strategy: String, // "self-explain", "visualize", "example"
planTimestamp: Date,
// MONITOR phase
question: String, // The question asked
userAnswer: String, // User's explanation
confidence: Number, // 0-100
monitorTimestamp: Date,
// EVALUATE phase
expectedPoints: [String], // What should be in answer
correctPoints: [String], // What they got right
missingPoints: [String], // What they missed
accuracy: Number, // 0-100
calibrationError: Number, // confidence - accuracy
calibrationDirection: String, // "overconfident", "underconfident", "accurate"
feedback: String, // AI-generated feedback
strategyHelpful: Boolean, // Did strategy help? (yes/no)
evaluateTimestamp: Date,
createdAt: Date,
timeSpentSeconds: Number // Total time on this chunk
}CRUD Operations:
- CREATE: POST
/api/responses(when user submits chunk answer) - READ: GET
/api/responses(all responses) - READ: GET
/api/responses/session/:sessionId(responses for a session) - READ: GET
/api/responses/strategy/:strategy(filter by strategy) - UPDATE: PATCH
/api/responses/:id(edit response - rare) - DELETE: DELETE
/api/responses/:id(remove response)
Indexes:
_id(default)sessionId(for filtering by session)userId(for filtering user's responses)strategy(for aggregating by strategy)createdAt(for time-based queries)
Synthetic Data: Generate 1200 sample responses (6 responses per session on average: 200 sessions Γ 6 = 1200 docs)
This meets the requirement of at least 1000 documents in one collection.
sessions (1) ββββββ (many) responses
β
ββ sessionId referenced in responses.sessionId
Note: Using denormalization (storing chunkTopic in responses) for performance. This is acceptable for MVP scale.
sessionscollection: 200 documentsresponsescollection: 1200 documents- Total: 1400 documents β (exceeds 1000 minimum)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [Sign In] β
β β
β π§ Metacognition Learning Engine β
β β
β Learn by Reflecting, Not Just Reading β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Transform your notes into active learning β β
β β loops that teach you the content AND β β
β β how you learn best. β β
β β β β
β β Each loop takes ~90 seconds: β β
β β 1. Plan your approach β β
β β 2. Test your understanding β β
β β 3. Reflect and improve β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββ β
β β Try Demo Content β β
β ββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββ β
β β Upload Your Own Text β β
β ββββββββββββββββββββββββββββββ β
β β
β βββββββββββ βββββββββββ βββββββββββ β
β β π€ β β π§ β β π β β
β β Upload β β Reflect β β Discoverβ β
β β Notes β β Deeply β β Patternsβ β
β βββββββββββ βββββββββββ βββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Clear value proposition
- Call to action buttons
- Visual hierarchy
- Feature highlights
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Back to Home β
β β
β π Upload Your Study Material β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Paste your lecture notes, textbook β β
β β sections, or study materials here... β β
β β β β
β β Example: β β
β β "Photosynthesis is the process by which β β
β β plants convert light energy into chemical β β
β β energy. It occurs in chloroplasts..." β β
β β β β
β β β β
β β [Large textarea - 8 rows] β β
β β β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Characters: 1,245 / 500 minimum β β
β Estimated chunks: 5-7 β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Optional: Give this content a title β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β e.g., "Biology Lecture 3 - Photosynthesis" β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββ β
β β Generate Learning Chunks β β
β ββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Large text area for easy pasting
- Character counter with validation
- Estimated chunk count
- Optional title field
- Clear CTA button
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Chunk 1/5 [Pause] β
β β
β π PLAN: Set Your Approach β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Mini-Teach: Photosynthesis β β
β β β β
β β Photosynthesis converts light energy into β β
β β chemical energy (glucose). It has two stages:β β
β β light-dependent reactions (in thylakoids) β β
β β and light-independent reactions (in stroma). β β
β β The overall equation: 6COβ + 6HβO β CβHββOβ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π― What's your learning goal? β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β
β β π Get the β β π‘ Explain β β π οΈ Apply β β
β β gist β β it β β it β β
β β β β β β β β
β β Understand β β Teach to β β Use in β β
β β main idea β β someone else β β problem β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β
β [SELECTED - HIGHLIGHTED] β
β β
β π§ Which strategy will you use? β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β
β β π¬ Self- β β βοΈ Visualize β β π Work β β
β β Explain β β it β β Exampleβ β
β β β β β β β β
β β Describe in β β Create mentalβ β Apply to β β
β β own words β β picture β β a case β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββ β
β β Start Learning β β β
β ββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Chunk progress indicator
- Self-contained mini-teach
- Goal selection cards (large, clear)
- Strategy selection cards
- Visual feedback for selected items
- Single action button
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Chunk 1/5 [Pause] β
β β
β π MONITOR: Test Your Understanding β
β β
β Goal: Explain it β’ Strategy: Self-explain β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Question: β β
β β β β
β β Explain the difference between light- β β
β β dependent and light-independent reactions β β
β β in photosynthesis. β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βοΈ Your explanation: β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Light-dependent reactions need sunlight β β
β β and happen in the thylakoids, while light- β β
β β independent reactions (Calvin cycle) happen β β
β β in the stroma and don't need light directly.β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β 125 characters (aim for 100+) β
β β
β πͺ How confident are you? β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Not sure ββββββββββββββββββββ Very sure β β
β β 0 25 50 ^75 100 β β
β β 75% β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββ β
β β Check My Answer β β β
β ββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Shows selected goal and strategy
- Clear question
- Expandable text area
- Character counter
- Confidence slider with visual gradient
- Disabled button until answer provided
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Chunk 1/5 [Pause] β
β β
β β
EVALUATE: How Did You Do? β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β What you got right: β β
β β β’ Light-dependent reactions need sunlight β β
β β β’ They occur in thylakoids β β
β β β’ Light-independent reactions (Calvin β β
β β cycle) occur in stroma β β
β β β β
β β π‘ What to add to your understanding: β β
β β β’ Light-dependent reactions produce ATP β β
β β and NADPH, which power the Calvin cycle β β
β β β’ Light-independent reactions use COβ to β β
β β build glucose β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π Your Performance: β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Accuracy: 75% ββββββββββ β β
β β Confidence: 75% ββββββββββ β β
β β Calibration: Well-calibrated! β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π§ Did your strategy help? β
β β
β ββββββββββββββββ ββββββββββββββββ β
β β π Yes, it β β π Not reallyβ β
β β helped β β β β
β ββββββββββββββββ ββββββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββ β
β β Next Chunk β β β
β ββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Positive feedback first
- Constructive additions
- Performance visualization
- Calibration interpretation
- Strategy reflection question
- Clear path to continue
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β π Session Complete! β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Photosynthesis Study Session β β
β β 5 chunks completed in 8 minutes β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π Your Performance: β
β β
β βββββββββββββββββ βββββββββββββββββ βββββββββββββ
β β Overall β β Avg β β Calibrat-ββ
β β Accuracy β β Confidence β β ion ββ
β β β β β β ββ
β β 78% β β 73% β β -5% ββ
β β β β β β Slight ββ
β β β β β β under ββ
β βββββββββββββββββ βββββββββββββββββ βββββββββββββ
β β
β π― Strategy Performance: β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Self-explain ββββββββββ 85% (3 uses) β β
β β Visualize ββββββββββ 65% (1 use) β β
β β Work example ββββββββββ 75% (1 use) β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β π‘ Key Insight: β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Your "self-explain" strategy worked best! β β
β β When you described concepts in your own β β
β β words, you scored 10% higher. Try using it β β
β β more often! β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β View All Sessionsβ β Upload New Contentβ β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- Celebration message
- Session metadata
- Performance metrics (cards)
- Strategy comparison (visual bars)
- Personalized insight
- Clear next actions
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β π My Learning Sessions β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β Photosynthesis Study Session β β
β β Nov 5, 2025 β’ 5 chunks β’ 8 min β β
β β Accuracy: 78% β’ Confidence: 73% β β
β β β β
β β Best strategy: Self-explain (85%) β β
β β [View Details] β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β Cellular Respiration Notes β β
β β Nov 4, 2025 β’ 7 chunks β’ 12 min β β
β β Accuracy: 82% β’ Confidence: 80% β β
β β β β
β β Best strategy: Visualize (88%) β β
β β [View Details] β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β JavaScript Closures β β
β β Nov 3, 2025 β’ 4 chunks β’ 6 min β β
β β Accuracy: 70% β’ Confidence: 75% β β
β β β β
β β Best strategy: Work example (75%) β β
β β [View Details] β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β
β ββββββββββββββββββββββββββββββ β
β β Start New Session β β
β ββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Elements:
- List of all sessions
- Session cards with metadata
- Performance summaries
- Best strategy highlighted
- View details link
- New session CTA
App.jsx
βββ Header.jsx
βββ Router
β βββ LandingPage.jsx
β βββ UploadPage.jsx
β βββ ProcessingPage.jsx
β βββ LearningSession.jsx
β β βββ PlanPhase.jsx
β β β βββ GoalSelector.jsx
β β β βββ StrategySelector.jsx
β β βββ MonitorPhase.jsx
β β β βββ QuestionDisplay.jsx
β β β βββ AnswerInput.jsx
β β β βββ ConfidenceSlider.jsx
β β βββ EvaluatePhase.jsx
β β βββ FeedbackDisplay.jsx
β β βββ PerformanceMetrics.jsx
β β βββ StrategyReflection.jsx
β βββ SessionSummary.jsx
β β βββ PerformanceCards.jsx
β β βββ StrategyComparison.jsx
β β βββ InsightCard.jsx
β βββ HistoryPage.jsx
β βββ SessionCard.jsx
βββ Footer.jsx
- App.jsx - Main app container with routing
- Header.jsx - Navigation header
- Footer.jsx - Footer with credits
- LandingPage.jsx - Welcome screen
- UploadPage.jsx - Text paste interface
- ProcessingPage.jsx - Loading screen
- LearningSession.jsx - Main learning loop container
- PlanPhase.jsx - Goal + strategy selection
- GoalSelector.jsx - Goal cards
- StrategySelector.jsx - Strategy cards
- MonitorPhase.jsx - Question + answer interface
- ConfidenceSlider.jsx - Confidence rating component
- EvaluatePhase.jsx - Feedback display
- SessionSummary.jsx - Session complete screen
- HistoryPage.jsx - List of past sessions
- SessionCard.jsx - Individual session display card
- PerformanceCards.jsx - Summary metrics cards
import { useState } from "react";
import PropTypes from "prop-types";
import "./UploadPage.css";
function UploadPage({ onNavigate, setSessionData }) {
const [content, setContent] = useState("");
const [title, setTitle] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const handleSubmit = async () => {
if (content.length < 500) {
setError("Please enter at least 500 characters");
return;
}
setLoading(true);
setError("");
try {
const response = await fetch("/api/chunks/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content, title }),
});
if (!response.ok) {
throw new Error("Failed to generate chunks");
}
const data = await response.json();
setSessionData(data);
onNavigate("learning");
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
return (
<div className="upload-page">
<h2>π Upload Your Study Material</h2>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="Paste your lecture notes, textbook sections, or study materials here..."
rows={10}
disabled={loading}
/>
<p className="character-count">
Characters: {content.length} / 500 minimum
{content.length >= 500 && " β"}
</p>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Optional: Give this content a title"
disabled={loading}
/>
{error && <p className="error">{error}</p>}
<button onClick={handleSubmit} disabled={content.length < 500 || loading}>
{loading ? "Processing..." : "Generate Learning Chunks"}
</button>
</div>
);
}
UploadPage.propTypes = {
onNavigate: PropTypes.func.isRequired,
setSessionData: PropTypes.func.isRequired,
};
export default UploadPage;import PropTypes from "prop-types";
import "./GoalSelector.css";
function GoalSelector({ selectedGoal, onSelectGoal }) {
const goals = [
{
id: "gist",
icon: "π",
title: "Get the gist",
description: "Understand main idea",
},
{
id: "explain",
icon: "π‘",
title: "Explain it",
description: "Teach to someone else",
},
{
id: "apply",
icon: "π οΈ",
title: "Apply it",
description: "Use in problem",
},
];
return (
<div className="goal-selector">
<h3>π― What's your learning goal?</h3>
<div className="goal-cards">
{goals.map((goal) => (
<button
key={goal.id}
className={`goal-card ${selectedGoal === goal.id ? "selected" : ""}`}
onClick={() => onSelectGoal(goal.id)}
aria-pressed={selectedGoal === goal.id}
>
<span className="icon" aria-hidden="true">
{goal.icon}
</span>
<h4>{goal.title}</h4>
<p>{goal.description}</p>
</button>
))}
</div>
</div>
);
}
GoalSelector.propTypes = {
selectedGoal: PropTypes.string,
onSelectGoal: PropTypes.func.isRequired,
};
export default GoalSelector;import PropTypes from "prop-types";
import "./ConfidenceSlider.css";
function ConfidenceSlider({ value, onChange }) {
const getZoneColor = (val) => {
if (val < 34) return "red";
if (val < 67) return "yellow";
return "green";
};
const getZoneLabel = (val) => {
if (val < 34) return "Unsure";
if (val < 67) return "Somewhat confident";
return "Very confident";
};
return (
<div className="confidence-slider">
<h3>πͺ How confident are you?</h3>
<div className="slider-container">
<input
type="range"
min="0"
max="100"
step="5"
value={value}
onChange={(e) => onChange(Number(e.target.value))}
className={`slider ${getZoneColor(value)}`}
aria-label="Confidence level"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow={value}
aria-valuetext={`${value}% - ${getZoneLabel(value)}`}
/>
<div className="slider-labels">
<span>Not sure</span>
<span className="current-value">{value}%</span>
<span>Very sure</span>
</div>
<p className="zone-label">{getZoneLabel(value)}</p>
</div>
</div>
);
}
ConfidenceSlider.propTypes = {
value: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
};
export default ConfidenceSlider;Development: http://localhost:3000/api
Production: https://your-app.onrender.com/api
| Method | Endpoint | Purpose | Auth |
|---|---|---|---|
| POST | /chunks/generate |
Generate chunks from text | No |
| POST | /sessions |
Create new session | No |
| GET | /sessions |
List all sessions | No |
| GET | /sessions/:id |
Get specific session | No |
| PATCH | /sessions/:id/complete-chunk |
Mark chunk as done | No |
| DELETE | /sessions/:id |
Delete session | No |
| POST | /responses |
Submit chunk response | No |
| GET | /responses/session/:sessionId |
Get session responses | No |
| GET | /sessions/:id/summary |
Get session summary | No |
Request:
{
"content": "Long text content here (min 500 chars)...",
"title": "Optional title"
}Response (200 OK):
{
"sessionId": "673abc123def456...",
"chunks": [
{
"chunkId": "chunk_0",
"topic": "Photosynthesis Overview",
"miniTeach": "Photosynthesis converts light...",
"question": "Why do plants need light...",
"expectedPoints": ["Light energy", "Glucose production", "Oxygen release"]
}
],
"totalChunks": 5
}Error (400 Bad Request):
{
"error": "Content must be at least 500 characters"
}Request:
{
"sessionId": "673abc123def456...",
"chunkId": "chunk_0",
"goal": "explain",
"strategy": "self-explain",
"userAnswer": "Plants use light to make glucose...",
"confidence": 75
}Response (200 OK):
{
"responseId": "673xyz789abc...",
"accuracy": 70,
"calibrationError": 5,
"calibrationDirection": "overconfident",
"correctPoints": ["Light energy", "Glucose production"],
"missingPoints": ["Oxygen release", "Chlorophyll role"],
"feedback": "Great start! You correctly identified... To improve, also mention..."
}Response (200 OK):
{
"sessionId": "673abc123def456...",
"title": "Photosynthesis Study",
"completedAt": "2025-11-05T14:30:00Z",
"stats": {
"totalChunks": 5,
"averageAccuracy": 78,
"averageConfidence": 73,
"calibrationError": -5,
"totalTimeSeconds": 480
},
"strategyPerformance": [
{ "strategy": "self-explain", "accuracy": 85, "uses": 3 },
{ "strategy": "visualize", "accuracy": 65, "uses": 1 },
{ "strategy": "example", "accuracy": 75, "uses": 1 }
],
"insight": "Your 'self-explain' strategy worked best! You scored 10% higher when..."
}