Question Paper AI Assistant
Error!
Extracted Questions:
${extractedQuestions}
Please Fill Out the Form Below to Continue
The extracted questions are ready! To get your results, please complete the student information form provided on this page. After submitting the form, your results will appear here automatically.
${loading ? `
` : `
${solutions && actionType === 'solve' ? `
`;
if (!loading) {
document.getElementById('start-over-button').addEventListener('click', resetApplication);
}
}
}
// --- Event Handlers ---
function handleImageChange(event) {
const file = event.target.files?.[0];
if (file) {
selectedImage = file;
imagePreview = URL.createObjectURL(file);
// Reset all relevant states when a new image is selected
extractedQuestions = '';
solutions = '';
similarQuestions = '';
error = '';
actionType = null;
awaitingFormSubmission = false;
formSubmittedViaElementor = false;
studentInfo = null;
removeSessionData('ai_action_type');
removeSessionData('extracted_questions');
removeSessionData('student_info');
} else {
selectedImage = null;
imagePreview = null;
}
renderApp(); // Re-render UI
}
async function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result.split(',')[1]);
reader.onerror = (error) => reject(error);
});
}
async function handleExtractQuestions() {
if (!selectedImage) {
error = 'Please select an image first.';
renderApp();
return;
}
loading = true;
error = '';
extractedQuestions = '';
solutions = '';
similarQuestions = '';
actionType = null;
awaitingFormSubmission = false;
formSubmittedViaElementor = false;
studentInfo = null;
removeSessionData('ai_action_type');
removeSessionData('extracted_questions');
removeSessionData('student_info');
renderApp(); // Show loading state
try {
const base64ImageData = await getBase64(selectedImage);
const prompt = "Extract all questions from this image, numbering them clearly. If there are multiple parts to a question (e.g., a, b, c), list them under the main question number. Focus on mathematical problems if present.";
const payload = {
contents: [
{
role: "user",
parts: [
{ text: prompt },
{
inlineData: {
mimeType: selectedImage.type,
data: base64ImageData
}
}
]
}
]
};
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GOOGLE_GEMINI_API_KEY}`;
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const result = await response.json();
if (result.candidates && result.candidates.length > 0 &&
result.candidates?.[0]?.content?.parts?.[0]?.text) {
extractedQuestions = result.candidates?.[0]?.content?.parts?.[0]?.text;
} else {
error = 'Could not extract questions. Please try a clearer image or different prompt.';
console.error('API response structure unexpected:', result);
}
} catch (err) {
error = 'Failed to extract questions. Please check your network connection or try again.';
console.error('Error extracting questions:', err);
} finally {
loading = false;
renderApp(); // Update UI after extraction
}
}
function handleSelectAction(type) {
if (!extractedQuestions) {
error = 'Please extract questions first.';
renderApp();
return;
}
actionType = type;
awaitingFormSubmission = true; // Indicate that we are now waiting for the form
// Store data in session storage before redirecting/showing form instructions
setSessionData('ai_action_type', type);
setSessionData('extracted_questions', extractedQuestions);
solutions = ''; // Clear previous results
similarQuestions = ''; // Clear previous results
error = '';
renderApp(); // Update UI to show form instructions
}
async function fetchResultsFromAI() {
if (!extractedQuestions || !actionType || !studentInfo) {
error = 'Missing data to fetch results. Please start over.';
renderApp();
return;
}
loading = true;
error = '';
solutions = '';
similarQuestions = '';
renderApp(); // Show loading state
try {
let prompt = '';
if (actionType === 'solve') {
prompt = `Provide detailed, step-by-step solutions for the following mathematical questions. Show all calculations and reasoning clearly. If a question is not mathematical, provide a concise answer.\n\nQuestions:\n${extractedQuestions}`;
} else if (actionType === 'practice') {
prompt = `Generate 3-5 alternative and similar practice questions for each of the following questions. Vary the numbers, context, or slight variations in the problem statement to make them distinct but related. Ensure the difficulty level is comparable to the original questions. If a question is not mathematical, provide similar conceptual questions.\n\nOriginal Questions:\n${extractedQuestions}`;
}
const payload = { contents: [{ role: "user", parts: [{ text: prompt }] }] };
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GOOGLE_GEMINI_API_KEY}`;
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const result = await response.json();
if (result.candidates && result.candidates.length > 0 &&
result.candidates?.[0]?.content?.parts?.[0]?.text) {
if (actionType === 'solve') {
solutions = result.candidates?.[0]?.content?.parts?.[0]?.text;
} else if (actionType === 'practice') {
similarQuestions = result.candidates?.[0]?.content?.parts?.[0]?.text;
}
} else {
error = `Could not generate ${actionType === 'solve' ? 'solutions' : 'similar questions'}. Please try again.`;
console.error('API response structure unexpected:', result);
}
} catch (err) {
error = `Failed to get ${actionType === 'solve' ? 'solutions' : 'similar questions'}. Please check your network connection or try again.`;
console.error('Error getting results:', err);
} finally {
loading = false;
renderApp(); // Update UI with results or error
}
}
function resetApplication() {
selectedImage = null;
imagePreview = null;
extractedQuestions = '';
solutions = '';
similarQuestions = '';
loading = false;
error = '';
actionType = null;
awaitingFormSubmission = false;
formSubmittedViaElementor = false;
studentInfo = null;
removeSessionData('ai_action_type');
removeSessionData('extracted_questions');
removeSessionData('student_info');
renderApp(); // Reset UI to initial state
}
// --- Initial Load Logic ---
document.addEventListener('DOMContentLoaded', () => {
// Check if we're returning from an Elementor form submission
const storedActionType = getSessionData('ai_action_type');
const storedExtractedQuestions = getSessionData('extracted_questions');
const storedStudentInfo = getSessionData('student_info');
if (storedActionType && storedExtractedQuestions && storedStudentInfo) {
// We have data from a previous Elementor form submission, trigger AI call
actionType = storedActionType;
extractedQuestions = storedExtractedQuestions;
studentInfo = storedStudentInfo;
formSubmittedViaElementor = true;
awaitingFormSubmission = false; // No longer awaiting
// Clear session storage *after* retrieving data to prevent re-triggering on subsequent loads
// and to ensure a clean slate for the next interaction.
removeSessionData('ai_action_type');
removeSessionData('extracted_questions');
removeSessionData('student_info');
fetchResultsFromAI(); // Immediately fetch results
} else {
// If no form data from Elementor, render the initial upload section
renderApp();
}
});
${actionType === 'solve' ? 'Generating Solutions...' : 'Generating Similar Questions...'}
Solutions:
${solutions}
` : ''}
${similarQuestions && actionType === 'practice' ? `
Similar Questions for Practice:
${similarQuestions}
` : ''}
`}