Skip to content

Commit 7aa3125

Browse files
committed
2 parents a9229ea + 7929f6a commit 7aa3125

File tree

4 files changed

+242
-68
lines changed

4 files changed

+242
-68
lines changed

client/src/App.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Uploadpyq from "./components/Uploadpyq";
1616
import Anythingmore from "./components/Anythingmore";
1717
import Uploadn from "./components/Uploadn";
1818
import Aibot from "./components/Aibot";
19+
import Uploadp from "./components/Uploadp";
1920

2021
function App() {
2122
return (
@@ -41,6 +42,7 @@ function App() {
4142
<Route path="/uploadpyq" element={<Uploadpyq/>} />
4243
<Route path="/anythingmore" element={<Anythingmore/>} />
4344
<Route path="/uploadn" element={<Uploadn/>} />
45+
<Route path="/uploadp" element={<Uploadp/>} />
4446

4547
<Route path="/aibot" element={<Aibot/>} />
4648

client/src/components/Anythingmore.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
33

44
function Anythingmore() {
55
const [details, setDetails] = useState('');
6+
const [apiError, setApiError] = useState(false);
67

78
const handleInputChange = (event) => {
89
setDetails(event.target.value);
@@ -35,9 +36,17 @@ function Anythingmore() {
3536
callAPI(textFile)
3637
.then(() => {
3738
console.log('API call successful');
39+
// Reset the API error state
40+
setApiError(false);
3841
})
3942
.catch((error) => {
4043
console.error('Error calling API:', error);
44+
// Set the API error state to true
45+
setApiError(true);
46+
// Retry the API call after a delay
47+
setTimeout(() => {
48+
retryAPI(textFile);
49+
}, 3000); // Retry after 3 seconds (adjust as needed)
4150
});
4251

4352
// Clear the input field after submission
@@ -57,6 +66,18 @@ function Anythingmore() {
5766
);
5867
};
5968

69+
const retryAPI = (file) => {
70+
callAPI(file)
71+
.then(() => {
72+
console.log('API call retried successfully');
73+
setApiError(false);
74+
})
75+
.catch((error) => {
76+
console.error('Error retrying API:', error);
77+
setApiError(true);
78+
});
79+
};
80+
6081
return (
6182
<div className="flex flex-col items-center justify-center h-screen text-center w-screen bg-gradient-to-tr from-violet-700 via-green-600 to-green-400">
6283
<h1 className="text-3xl font-bold mb-4 text-white">Anything more to add!</h1>
@@ -69,6 +90,7 @@ function Anythingmore() {
6990
<button className="bg-violet-900 text-white py-2 px-6 rounded-lg mb-4" onClick={handleSubmit}>
7091
Submit
7192
</button>
93+
{apiError && <p className="text-red-500">Error calling API. Retrying...</p>}
7294
<Link to="/dashboard">
7395
<button className="bg-violet-900 text-white py-2 px-6 rounded-lg">Finish</button>
7496
</Link>

client/src/components/Uploadp.jsx

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import React, { useState } from 'react';
2+
import { motion } from 'framer-motion';
3+
import Lottie from 'lottie-react';
4+
import animationData from '../assets/101391-online-test.json';
5+
import { Link } from 'react-router-dom';
6+
7+
function Uploadp({ moduleNumber }) {
8+
const [numNotes, setNumNotes] = useState(0);
9+
const [selectedFiles, setSelectedFiles] = useState([]);
10+
const [uploading, setUploading] = useState(false);
11+
const [uploadSuccess, setUploadSuccess] = useState(false);
12+
const [showSuccessMessage, setShowSuccessMessage] = useState(false);
13+
const [fadeOut, setFadeOut] = useState(false); // New state to control fading out
14+
15+
const handleNumNotesChange = (event) => {
16+
const count = parseInt(event.target.value, 10);
17+
setNumNotes(count);
18+
setSelectedFiles(new Array(count).fill(null));
19+
setUploadSuccess(false);
20+
};
21+
22+
const handleFileChange = async (index, event) => {
23+
const file = event.target.files[0];
24+
const updatedFiles = [...selectedFiles];
25+
updatedFiles[index] = file;
26+
setSelectedFiles(updatedFiles);
27+
setUploadSuccess(false);
28+
29+
try {
30+
const formData = new FormData();
31+
formData.append('files', file);
32+
33+
const response = await fetch('https://3f2ssd7loqowjtj7hnzhni7trq0blutk.lambda-url.us-east-1.on.aws/notestotext_pyqs', {
34+
method: 'POST',
35+
body: formData,
36+
});
37+
38+
if (response.ok) {
39+
setUploadSuccess(true);
40+
setShowSuccessMessage(true);
41+
setTimeout(() => {
42+
setShowSuccessMessage(false);
43+
setFadeOut(true);
44+
}, 10000);
45+
} else {
46+
throw new Error('Error uploading file');
47+
}
48+
} catch (error) {
49+
console.error('Error uploading file:', error);
50+
}
51+
};
52+
53+
const handleUpload = () => {
54+
if (selectedFiles.some((file) => file === null)) {
55+
return;
56+
}
57+
58+
setUploading(true);
59+
60+
const formData = new FormData();
61+
selectedFiles.forEach((file) => {
62+
formData.append('files', file);
63+
});
64+
65+
fetch('http://192.168.137.193:8000/notestotext_modwise', {
66+
method: 'POST',
67+
body: formData,
68+
})
69+
.then((response) => {
70+
if (response.ok) {
71+
setUploadSuccess(true);
72+
setShowSuccessMessage(true);
73+
setTimeout(() => {
74+
setShowSuccessMessage(false);
75+
setFadeOut(true);
76+
}, 10000);
77+
} else {
78+
throw new Error('Error uploading files');
79+
}
80+
})
81+
.catch((error) => {
82+
console.error('Error uploading files:', error);
83+
})
84+
.finally(() => {
85+
setUploading(false);
86+
});
87+
};
88+
89+
const saveFileLocally = (filePath, file) => {
90+
return new Promise((resolve, reject) => {
91+
const virtualLink = document.createElement('a');
92+
virtualLink.href = URL.createObjectURL(file);
93+
virtualLink.download = filePath;
94+
virtualLink.addEventListener('load', () => {
95+
URL.revokeObjectURL(virtualLink.href);
96+
resolve();
97+
});
98+
virtualLink.addEventListener('error', (error) => {
99+
reject(error);
100+
});
101+
document.body.appendChild(virtualLink);
102+
virtualLink.click();
103+
document.body.removeChild(virtualLink);
104+
});
105+
};
106+
107+
const handleUploadAnother = () => {
108+
setSelectedFiles(new Array(numNotes).fill(null));
109+
setUploadSuccess(false);
110+
setShowSuccessMessage(false);
111+
setFadeOut(false);
112+
};
113+
114+
const renderUploadInputs = () => {
115+
const inputs = [];
116+
117+
for (let i = 0; i < numNotes; i++) {
118+
inputs.push(
119+
<div key={`upload-input-${i}`}>
120+
<label>PYQ {i + 1} PDF:</label>
121+
<input
122+
type="file"
123+
accept="application/pdf"
124+
className="mb-4 rounded-md px-3"
125+
onChange={(event) => handleFileChange(i, event)}
126+
/>
127+
</div>
128+
);
129+
}
130+
131+
return inputs;
132+
};
133+
134+
return (
135+
<div className="flex flex-col items-center justify-center w-screen text-center h-screen bg-gradient-to-tr from-violet-700 via-green-600 to-green-400">
136+
{!fadeOut && (
137+
<motion.div
138+
className="bg-violet-900 text-white py-6 px-6 rounded-lg shadow-lg text-center justify-center items-center flex flex-col"
139+
initial={{ scale: 0 }}
140+
animate={{ scale: 1 }}
141+
transition={{ duration: 0.5 }}
142+
>
143+
<Lottie animationData={animationData} style={{ width: 400, height: 300 }} />
144+
<h1 className="text-3xl font-bold mb-4">Upload PYQ</h1>
145+
{!uploadSuccess ? (
146+
<>
147+
<label htmlFor="num-notes" className="block font-medium mb-2">
148+
Number of PYQ:
149+
</label>
150+
<input
151+
type="number"
152+
id="num-notes"
153+
min={0}
154+
value={numNotes}
155+
onChange={handleNumNotesChange}
156+
className="border border-gray-300 rounded-md px-3 py-2 mb-4"
157+
/>
158+
{renderUploadInputs()}
159+
<motion.button
160+
className={`bg-green-500 text-white py-2 px-6 rounded-lg ml-4 ${
161+
uploading ? 'opacity-50 cursor-not-allowed' : ''
162+
}`}
163+
disabled={uploading || selectedFiles.some((file) => file === null)}
164+
onClick={handleUpload}
165+
whileHover={!uploading ? { scale: 1.05 } : {}}
166+
whileTap={!uploading ? { scale: 0.95 } : {}}
167+
>
168+
{uploading ? 'Uploaded' : 'Upload'}
169+
</motion.button>
170+
<Link to="/uploadsyllabus" className="bg-green-500 text-white py-2 ml-4 px-6 mt-4 rounded-lg">
171+
Next
172+
</Link>
173+
</>
174+
) : (
175+
<>
176+
{showSuccessMessage && (
177+
<motion.div className="text-xl" initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
178+
Successfully Uploaded!
179+
</motion.div>
180+
)}
181+
<motion.button
182+
className="bg-green-500 text-white py-2 px-6 rounded-lg mt-4"
183+
onClick={handleUploadAnother}
184+
>
185+
Upload Another
186+
</motion.button>
187+
<Link to="/uploadsyllabus" className="text-blue-500 mt-8">
188+
Next
189+
</Link>
190+
</>
191+
)}
192+
</motion.div>
193+
)}
194+
</div>
195+
);
196+
}
197+
198+
export default Uploadp;

client/src/components/Uploadpyq.jsx

Lines changed: 20 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,36 @@ function Uploadpyq({ moduleNumber }) {
1919
setUploadSuccess(false);
2020
};
2121

22-
const handleFileChange = async (index, event) => {
22+
const handleFileChange = (index, event) => {
2323
const file = event.target.files[0];
2424
const updatedFiles = [...selectedFiles];
2525
updatedFiles[index] = file;
2626
setSelectedFiles(updatedFiles);
2727
setUploadSuccess(false);
28+
};
29+
30+
const handleUpload = async () => {
31+
if (selectedFiles.some((file) => file === null)) {
32+
return;
33+
}
34+
35+
setUploading(true);
2836

2937
try {
3038
const formData = new FormData();
31-
formData.append('files', file);
3239

33-
const response = await fetch('https://3f2ssd7loqowjtj7hnzhni7trq0blutk.lambda-url.us-east-1.on.aws/notestotext_syllabus', {
34-
method: 'POST',
35-
body: formData,
40+
selectedFiles.forEach((file, index) => {
41+
formData.append(`file${index + 1}`, file);
3642
});
3743

44+
const response = await fetch(
45+
'https://3f2ssd7loqowjtj7hnzhni7trq0blutk.lambda-url.us-east-1.on.aws/notestotext_pyqs',
46+
{
47+
method: 'POST',
48+
body: formData,
49+
}
50+
);
51+
3852
if (response.ok) {
3953
setUploadSuccess(true);
4054
setShowSuccessMessage(true);
@@ -48,70 +62,8 @@ function Uploadpyq({ moduleNumber }) {
4862
} catch (error) {
4963
console.error('Error uploading file:', error);
5064
}
51-
};
5265

53-
const handleUpload = () => {
54-
if (selectedFiles.some((file) => file === null)) {
55-
return;
56-
}
57-
58-
setUploading(true);
59-
60-
const promises = selectedFiles.map((file) => {
61-
return new Promise((resolve, reject) => {
62-
const reader = new FileReader();
63-
64-
reader.onload = () => {
65-
const fileContents = reader.result;
66-
const blob = new Blob([fileContents], { type: file.type });
67-
const filePath = `Local_Storage/pyq_pdf/module_${moduleNumber}/${file.name}`;
68-
69-
saveFileLocally(filePath, blob)
70-
.then(() => {
71-
resolve();
72-
})
73-
.catch((error) => {
74-
console.error('Error saving file:', error);
75-
reject(error);
76-
});
77-
};
78-
79-
reader.readAsArrayBuffer(file);
80-
});
81-
});
82-
83-
Promise.all(promises)
84-
.then(() => {
85-
setUploadSuccess(true);
86-
setUploading(false);
87-
setShowSuccessMessage(true);
88-
setTimeout(() => {
89-
setShowSuccessMessage(false);
90-
setFadeOut(true);
91-
}, 10000);
92-
})
93-
.catch((error) => {
94-
console.error('Error uploading files:', error);
95-
setUploading(false);
96-
});
97-
};
98-
99-
const saveFileLocally = (filePath, file) => {
100-
return new Promise((resolve, reject) => {
101-
const virtualLink = document.createElement('a');
102-
virtualLink.href = URL.createObjectURL(file);
103-
virtualLink.download = filePath;
104-
virtualLink.addEventListener('load', () => {
105-
URL.revokeObjectURL(virtualLink.href);
106-
resolve();
107-
});
108-
virtualLink.addEventListener('error', (error) => {
109-
reject(error);
110-
});
111-
document.body.appendChild(virtualLink);
112-
virtualLink.click();
113-
document.body.removeChild(virtualLink);
114-
});
66+
setUploading(false);
11567
};
11668

11769
const handleUploadAnother = () => {

0 commit comments

Comments
 (0)