Skip to content

Commit 98fa39c

Browse files
committed
2 parents b817be6 + 8a96923 commit 98fa39c

File tree

4 files changed

+554
-440
lines changed

4 files changed

+554
-440
lines changed

frontend/src/components/Dashboard.tsx

Lines changed: 19 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@ import { useAuth } from '../contexts/AuthContext';
33
import { useNavigate } from 'react-router-dom';
44
import DocumentManager from './DocumentManager';
55
import PredictionPanel from './PredictionPanel';
6-
import SimplifiedUploader from './SimplifiedUploader';
7-
86
const Dashboard: React.FC = () => {
97
const { currentUser, logout } = useAuth();
108
const navigate = useNavigate();
119
const [activeTab, setActiveTab] = useState<string>('documents');
12-
const [useNewComponents, setUseNewComponents] = useState<boolean>(true);
1310

1411
const handleLogout = async () => {
1512
try {
@@ -32,51 +29,25 @@ const Dashboard: React.FC = () => {
3229
</div>
3330
</div>
3431

35-
{useNewComponents ? (
36-
<>
37-
<div style={styles.tabs}>
38-
<button
39-
style={activeTab === 'documents' ? styles.activeTab : styles.tab}
40-
onClick={() => setActiveTab('documents')}
41-
>
42-
Document Manager
43-
</button>
44-
<button
45-
style={activeTab === 'prediction' ? styles.activeTab : styles.tab}
46-
onClick={() => setActiveTab('prediction')}
47-
>
48-
Grade Prediction
49-
</button>
50-
</div>
51-
52-
<div style={styles.content}>
53-
{activeTab === 'documents' && <DocumentManager />}
54-
{activeTab === 'prediction' && <PredictionPanel />}
55-
</div>
56-
57-
{/* Fallback toggle for testing - remove in production */}
58-
<div style={styles.fallbackToggle}>
59-
<button
60-
onClick={() => setUseNewComponents(false)}
61-
style={styles.fallbackButton}
62-
>
63-
Switch to Legacy Mode
64-
</button>
65-
</div>
66-
</>
67-
) : (
68-
<>
69-
<SimplifiedUploader />
70-
<div style={styles.fallbackToggle}>
71-
<button
72-
onClick={() => setUseNewComponents(true)}
73-
style={styles.fallbackButton}
74-
>
75-
Switch to New Interface
76-
</button>
77-
</div>
78-
</>
79-
)}
32+
<div style={styles.tabs}>
33+
<button
34+
style={activeTab === 'documents' ? styles.activeTab : styles.tab}
35+
onClick={() => setActiveTab('documents')}
36+
>
37+
Document Manager
38+
</button>
39+
<button
40+
style={activeTab === 'prediction' ? styles.activeTab : styles.tab}
41+
onClick={() => setActiveTab('prediction')}
42+
>
43+
Grade Prediction
44+
</button>
45+
</div>
46+
47+
<div style={styles.content}>
48+
{activeTab === 'documents' && <DocumentManager />}
49+
{activeTab === 'prediction' && <PredictionPanel />}
50+
</div>
8051

8152
<div style={styles.footer}>
8253
<p>Upload your academic documents and get a prediction of your final grade.</p>
@@ -161,19 +132,6 @@ const styles = {
161132
textAlign: 'center' as const,
162133
color: '#666',
163134
},
164-
fallbackToggle: {
165-
marginTop: '20px',
166-
textAlign: 'center' as const,
167-
},
168-
fallbackButton: {
169-
padding: '8px 16px',
170-
backgroundColor: '#2196F3',
171-
color: 'white',
172-
border: 'none',
173-
borderRadius: '4px',
174-
cursor: 'pointer',
175-
fontSize: '14px',
176-
},
177135
};
178136

179137
export default Dashboard;

frontend/src/components/PredictionPanel.tsx

Lines changed: 127 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,22 @@ interface Document {
1111

1212
interface Prediction {
1313
grade: number | string;
14+
current_percentage: number;
15+
letter_grade: string;
16+
max_possible_grade: number;
17+
min_possible_grade: number;
1418
reasoning: string;
15-
confidence?: number;
19+
ai_prediction?: {
20+
grade: number | string;
21+
reasoning: string;
22+
};
23+
categorized_grades: {
24+
[category: string]: {
25+
completed: Array<{ name: string; grade: number }>;
26+
remaining: string[];
27+
average: number | null;
28+
};
29+
};
1630
}
1731

1832
const PredictionPanel: React.FC = () => {
@@ -162,40 +176,66 @@ const PredictionPanel: React.FC = () => {
162176
<h3>Prediction Result</h3>
163177
<div style={styles.gradeDisplay}>
164178
<div style={styles.gradeCircle}>
165-
{typeof predictionResult.grade === 'number'
166-
? predictionResult.grade.toFixed(1)
167-
: predictionResult.grade}
179+
{predictionResult.letter_grade}
180+
</div>
181+
<div style={styles.gradePercentage}>
182+
{typeof predictionResult.current_percentage === 'number'
183+
? `${predictionResult.current_percentage.toFixed(1)}%`
184+
: predictionResult.current_percentage}
185+
</div>
186+
<div style={styles.gradeLabel}>Current Grade</div>
187+
</div>
188+
189+
<div style={styles.gradeRangeSection}>
190+
<h4>Grade Range</h4>
191+
<div style={styles.gradeRange}>
192+
<div style={styles.rangeItem}>
193+
<span style={styles.rangeLabel}>Minimum:</span>
194+
<span style={styles.rangeValue}>{predictionResult.min_possible_grade.toFixed(1)}%</span>
195+
</div>
196+
<div style={styles.rangeItem}>
197+
<span style={styles.rangeLabel}>Maximum:</span>
198+
<span style={styles.rangeValue}>{predictionResult.max_possible_grade.toFixed(1)}%</span>
199+
</div>
168200
</div>
169-
<div style={styles.gradeLabel}>Predicted Grade</div>
170201
</div>
171202

172203
<div style={styles.reasoningSection}>
173204
<h4>Analysis</h4>
174205
<p style={styles.reasoning}>{predictionResult.reasoning}</p>
206+
{predictionResult.ai_prediction && (
207+
<div style={styles.aiPrediction}>
208+
<h4>AI Prediction</h4>
209+
<p>{predictionResult.ai_prediction.reasoning}</p>
210+
</div>
211+
)}
175212
</div>
176213

177-
{predictionResult.confidence && (
178-
<div style={styles.confidenceBar}>
179-
<div style={styles.confidenceLabel}>
180-
Confidence: {(predictionResult.confidence * 100).toFixed(1)}%
214+
<div style={styles.categoriesSection}>
215+
<h4>Grade Breakdown by Category</h4>
216+
{Object.entries(predictionResult.categorized_grades).map(([category, data]) => (
217+
<div key={category} style={styles.categoryItem}>
218+
<h5 style={styles.categoryTitle}>{category}</h5>
219+
{data.average !== null && (
220+
<div style={styles.categoryStats}>
221+
<span style={styles.categoryAverage}>
222+
Average: {data.average.toFixed(1)}%
223+
</span>
224+
<span style={styles.categoryProgress}>
225+
Progress: {data.completed.length} completed, {data.remaining.length} remaining
226+
</span>
227+
</div>
228+
)}
181229
</div>
182-
<div style={styles.confidenceBarOuter}>
183-
<div
184-
style={{
185-
...styles.confidenceBarInner,
186-
width: `${predictionResult.confidence * 100}%`
187-
}}
188-
/>
189-
</div>
190-
</div>
191-
)}
230+
))}
231+
</div>
192232
</div>
193233
)}
194234
</div>
195235
);
196236
};
197237

198-
const styles = {
238+
const baseStyles = {
199239
container: {
200240
padding: '20px',
201241
backgroundColor: 'white',
@@ -309,25 +349,6 @@ const styles = {
309349
lineHeight: '1.6',
310350
color: '#333',
311351
},
312-
confidenceBar: {
313-
marginTop: '15px',
314-
},
315-
confidenceLabel: {
316-
marginBottom: '5px',
317-
color: '#555',
318-
},
319-
confidenceBarOuter: {
320-
width: '100%',
321-
height: '10px',
322-
backgroundColor: '#e0e0e0',
323-
borderRadius: '5px',
324-
overflow: 'hidden',
325-
},
326-
confidenceBarInner: {
327-
height: '100%',
328-
backgroundColor: '#4CAF50',
329-
borderRadius: '5px',
330-
},
331352
error: {
332353
color: '#f44336',
333354
backgroundColor: '#ffebee',
@@ -344,4 +365,71 @@ const styles = {
344365
},
345366
};
346367

368+
const styles = {
369+
...baseStyles,
370+
gradePercentage: {
371+
fontSize: '24px',
372+
color: '#666',
373+
marginTop: '5px',
374+
},
375+
gradeRangeSection: {
376+
marginTop: '20px',
377+
padding: '15px',
378+
backgroundColor: '#fff',
379+
borderRadius: '8px',
380+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
381+
},
382+
gradeRange: {
383+
display: 'flex',
384+
justifyContent: 'space-around',
385+
marginTop: '10px',
386+
},
387+
rangeItem: {
388+
textAlign: 'center' as const,
389+
},
390+
rangeLabel: {
391+
display: 'block',
392+
color: '#666',
393+
fontSize: '14px',
394+
marginBottom: '5px',
395+
},
396+
rangeValue: {
397+
display: 'block',
398+
color: '#333',
399+
fontSize: '20px',
400+
fontWeight: 'bold',
401+
},
402+
aiPrediction: {
403+
marginTop: '15px',
404+
padding: '15px',
405+
backgroundColor: '#f5f5f5',
406+
borderRadius: '4px',
407+
},
408+
categoriesSection: {
409+
marginTop: '20px',
410+
},
411+
categoryItem: {
412+
padding: '15px',
413+
backgroundColor: '#fff',
414+
borderRadius: '8px',
415+
marginBottom: '10px',
416+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
417+
},
418+
categoryTitle: {
419+
margin: '0 0 10px 0',
420+
color: '#333',
421+
},
422+
categoryStats: {
423+
display: 'flex',
424+
justifyContent: 'space-between',
425+
color: '#666',
426+
},
427+
categoryAverage: {
428+
fontWeight: 'bold',
429+
},
430+
categoryProgress: {
431+
fontSize: '14px',
432+
}
433+
};
434+
347435
export default PredictionPanel;

0 commit comments

Comments
 (0)