Simple Question Paper AI Assistant

Question Paper AI Assistant

`; document.getElementById('image-upload').addEventListener('change', handleImageChange); document.getElementById('extract-button').addEventListener('click', handleExtractQuestions); } else if (showActionSelection) { appContainer.innerHTML = `

Extracted Questions:

                            ${extractedQuestions}
                        
`; document.getElementById('get-solutions-button').addEventListener('click', () => handleSelectAction('solve')); document.getElementById('generate-similar-button').addEventListener('click', () => handleSelectAction('practice')); } else if (showFormInstructions) { appContainer.innerHTML = `

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.

`; document.getElementById('start-over-button').addEventListener('click', resetApplication); } else if (showResults) { appContainer.innerHTML = `
${loading ? `

${actionType === 'solve' ? 'Generating Solutions...' : 'Generating Similar Questions...'}

` : ` ${solutions && actionType === 'solve' ? `

Solutions:

                                    ${solutions}
                                
` : ''} ${similarQuestions && actionType === 'practice' ? `

Similar Questions for Practice:

                                    ${similarQuestions}
                                
` : ''} `}
`; 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(); } });
Scroll to Top