Updated FE to allow for user solutions
Browse files
frontend/src/App.tsx
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
-
import { Container, CssBaseline, ThemeProvider, createTheme } from '@mui/material';
|
2 |
import Header from './components/Header';
|
3 |
import DocumentInput from './components/DocumentInput';
|
4 |
import QuizGenerator from './components/QuizGenerator';
|
5 |
-
import
|
6 |
import { useState } from 'react';
|
|
|
7 |
|
8 |
const theme = createTheme({
|
9 |
palette: {
|
@@ -17,7 +18,29 @@ const theme = createTheme({
|
|
17 |
});
|
18 |
|
19 |
function App() {
|
20 |
-
const [problems, setProblems] = useState<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
return (
|
23 |
<ThemeProvider theme={theme}>
|
@@ -25,8 +48,27 @@ function App() {
|
|
25 |
<Container maxWidth="md" sx={{ py: 4 }}>
|
26 |
<Header />
|
27 |
<DocumentInput />
|
28 |
-
<QuizGenerator onProblemsGenerated={
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
</Container>
|
31 |
</ThemeProvider>
|
32 |
);
|
|
|
1 |
+
import { Container, CssBaseline, ThemeProvider, createTheme, Button, Box } from '@mui/material';
|
2 |
import Header from './components/Header';
|
3 |
import DocumentInput from './components/DocumentInput';
|
4 |
import QuizGenerator from './components/QuizGenerator';
|
5 |
+
import ProblemAnswer from './components/ProblemAnswer';
|
6 |
import { useState } from 'react';
|
7 |
+
import { Problem } from './types/Problem';
|
8 |
|
9 |
const theme = createTheme({
|
10 |
palette: {
|
|
|
18 |
});
|
19 |
|
20 |
function App() {
|
21 |
+
const [problems, setProblems] = useState<Problem[]>([]);
|
22 |
+
|
23 |
+
const handleProblemsGenerated = (newProblems: string[]) => {
|
24 |
+
const problemObjects = newProblems.map(question => ({ question }));
|
25 |
+
setProblems(problemObjects);
|
26 |
+
};
|
27 |
+
|
28 |
+
const handleAnswerChange = (index: number, answer: string) => {
|
29 |
+
setProblems(prevProblems => {
|
30 |
+
const newProblems = [...prevProblems];
|
31 |
+
newProblems[index] = { ...newProblems[index], userAnswer: answer };
|
32 |
+
return newProblems;
|
33 |
+
});
|
34 |
+
};
|
35 |
+
|
36 |
+
const handleSubmit = () => {
|
37 |
+
// Here you can add the logic to handle the submission
|
38 |
+
// For now, we'll just log the answers
|
39 |
+
console.log('Submitted answers:', problems.map(p => ({
|
40 |
+
question: p.question,
|
41 |
+
answer: p.userAnswer
|
42 |
+
})));
|
43 |
+
};
|
44 |
|
45 |
return (
|
46 |
<ThemeProvider theme={theme}>
|
|
|
48 |
<Container maxWidth="md" sx={{ py: 4 }}>
|
49 |
<Header />
|
50 |
<DocumentInput />
|
51 |
+
<QuizGenerator onProblemsGenerated={handleProblemsGenerated} />
|
52 |
+
{problems.map((problem, index) => (
|
53 |
+
<ProblemAnswer
|
54 |
+
key={index}
|
55 |
+
problem={problem}
|
56 |
+
index={index}
|
57 |
+
onAnswerChange={handleAnswerChange}
|
58 |
+
/>
|
59 |
+
))}
|
60 |
+
{problems.length > 0 && (
|
61 |
+
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'center' }}>
|
62 |
+
<Button
|
63 |
+
variant="contained"
|
64 |
+
color="primary"
|
65 |
+
size="large"
|
66 |
+
onClick={handleSubmit}
|
67 |
+
>
|
68 |
+
Submit for Feedback
|
69 |
+
</Button>
|
70 |
+
</Box>
|
71 |
+
)}
|
72 |
</Container>
|
73 |
</ThemeProvider>
|
74 |
);
|
frontend/src/components/ProblemAnswer.tsx
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { TextField, Box, Typography } from '@mui/material';
|
2 |
+
import { Problem } from '../types/Problem';
|
3 |
+
|
4 |
+
interface ProblemAnswerProps {
|
5 |
+
problem: Problem;
|
6 |
+
index: number;
|
7 |
+
onAnswerChange: (index: number, answer: string) => void;
|
8 |
+
}
|
9 |
+
|
10 |
+
function ProblemAnswer({ problem, index, onAnswerChange }: ProblemAnswerProps) {
|
11 |
+
return (
|
12 |
+
<Box sx={{ mb: 3 }}>
|
13 |
+
<Typography variant="h6" sx={{ mb: 1 }}>
|
14 |
+
Question {index + 1}:
|
15 |
+
</Typography>
|
16 |
+
<Typography sx={{ mb: 2 }}>{problem.question}</Typography>
|
17 |
+
<TextField
|
18 |
+
fullWidth
|
19 |
+
multiline
|
20 |
+
rows={3}
|
21 |
+
label="Your Answer"
|
22 |
+
value={problem.userAnswer || ''}
|
23 |
+
onChange={(e) => onAnswerChange(index, e.target.value)}
|
24 |
+
variant="outlined"
|
25 |
+
/>
|
26 |
+
</Box>
|
27 |
+
);
|
28 |
+
}
|
29 |
+
|
30 |
+
export default ProblemAnswer;
|
frontend/src/components/QuizGenerator.tsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
import { TextField, Button, Box } from '@mui/material';
|
2 |
import { useState } from 'react';
|
3 |
|
4 |
interface QuizGeneratorProps {
|
@@ -7,9 +7,11 @@ interface QuizGeneratorProps {
|
|
7 |
|
8 |
function QuizGenerator({ onProblemsGenerated }: QuizGeneratorProps) {
|
9 |
const [query, setQuery] = useState('');
|
|
|
10 |
|
11 |
const handleGenerate = async () => {
|
12 |
try {
|
|
|
13 |
const response = await fetch('/api/problems/', {
|
14 |
method: 'POST',
|
15 |
headers: {
|
@@ -23,6 +25,8 @@ function QuizGenerator({ onProblemsGenerated }: QuizGeneratorProps) {
|
|
23 |
setQuery('');
|
24 |
} catch (error) {
|
25 |
console.error('Error:', error);
|
|
|
|
|
26 |
}
|
27 |
};
|
28 |
|
@@ -33,9 +37,15 @@ function QuizGenerator({ onProblemsGenerated }: QuizGeneratorProps) {
|
|
33 |
label="Quiz topic?"
|
34 |
value={query}
|
35 |
onChange={(e) => setQuery(e.target.value)}
|
|
|
36 |
/>
|
37 |
-
<Button
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
39 |
</Button>
|
40 |
</Box>
|
41 |
);
|
|
|
1 |
+
import { TextField, Button, Box, CircularProgress } from '@mui/material';
|
2 |
import { useState } from 'react';
|
3 |
|
4 |
interface QuizGeneratorProps {
|
|
|
7 |
|
8 |
function QuizGenerator({ onProblemsGenerated }: QuizGeneratorProps) {
|
9 |
const [query, setQuery] = useState('');
|
10 |
+
const [isLoading, setIsLoading] = useState(false);
|
11 |
|
12 |
const handleGenerate = async () => {
|
13 |
try {
|
14 |
+
setIsLoading(true);
|
15 |
const response = await fetch('/api/problems/', {
|
16 |
method: 'POST',
|
17 |
headers: {
|
|
|
25 |
setQuery('');
|
26 |
} catch (error) {
|
27 |
console.error('Error:', error);
|
28 |
+
} finally {
|
29 |
+
setIsLoading(false);
|
30 |
}
|
31 |
};
|
32 |
|
|
|
37 |
label="Quiz topic?"
|
38 |
value={query}
|
39 |
onChange={(e) => setQuery(e.target.value)}
|
40 |
+
disabled={isLoading}
|
41 |
/>
|
42 |
+
<Button
|
43 |
+
variant="contained"
|
44 |
+
onClick={handleGenerate}
|
45 |
+
disabled={isLoading}
|
46 |
+
startIcon={isLoading ? <CircularProgress size={20} color="inherit" /> : null}
|
47 |
+
>
|
48 |
+
{isLoading ? 'Generating...' : 'Generate'}
|
49 |
</Button>
|
50 |
</Box>
|
51 |
);
|
frontend/src/types/Problem.ts
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface Problem {
|
2 |
+
question: string;
|
3 |
+
userAnswer?: string;
|
4 |
+
}
|