Research Critique Tool

Research Critique Tool

Systematically analyze and critique a research paper.

${tab.prompt}

`; if (tab.id === 'citation') { contentHtml += ``; } contentHtml += ``; contentHtml += `
`; tabContentContainer.innerHTML += `
${contentHtml}
`; }); updateNavButtons(); } window.showTab = (index) => { if (index >= tabsData.length) { showFinalReview(); return; } currentTab = index; pdfDownloadSection.classList.add('hidden'); document.querySelectorAll('[role="tab"]').forEach((button, i) => { button.className = button.className.replace('tab-active', 'tab-inactive'); button.setAttribute('aria-selected', 'false'); if (i === currentTab) { button.className = button.className.replace('tab-inactive', 'tab-active'); button.setAttribute('aria-selected', 'true'); } }); document.querySelectorAll('[role="tabpanel"]').forEach((panel, i) => { panel.classList.toggle('hidden', i !== currentTab); }); updateNavButtons(); }; function updateNavButtons() { if (!prevBtn || !nextBtn) return; prevBtn.disabled = currentTab === 0; nextBtn.textContent = currentTab === tabsData.length - 1 ? 'Finish & Review' : 'Next'; } function showFinalReview() { currentTab = tabsData.length; document.querySelectorAll('[role="tabpanel"]').forEach(p => p.classList.add('hidden')); prevBtn.disabled = false; nextBtn.classList.add('hidden'); let fullCritiqueHtml = `

Critique of: ${document.getElementById('input-citation')?.value || 'N/A'}

`; tabsData.forEach(tab => { const textarea = document.getElementById(`textarea-${tab.id}`); if (textarea && textarea.value.trim() !== '') { fullCritiqueHtml += `

${tab.title}

`; fullCritiqueHtml += `

${textarea.value.trim().replace(/\n/g, '
')}

`; } }); critiquePreviewForPdf.innerHTML = fullCritiqueHtml; pdfDownloadSection.classList.remove('hidden'); } function handleNavigation(direction) { const newTab = currentTab + direction; if (newTab >= 0 && newTab <= tabsData.length) { newTab === tabsData.length ? showFinalReview() : (nextBtn.classList.remove('hidden'), window.showTab(newTab)); } } window.handleAIAction = async (button, tabId) => { const textarea = document.getElementById(`textarea-${tabId}`); const aiOutputContainer = document.getElementById(`ai-output-${tabId}`); if (!textarea || !aiOutputContainer) return; const text = textarea.value.trim(); if (text.length < 25) { alert("Please write at least 25 characters for a meaningful analysis."); return; } const buttonText = button.querySelector('.button-text'); const spinner = button.querySelector('.spinner'); button.disabled = true; buttonText.textContent = 'Analyzing...'; spinner.classList.remove('hidden'); try { const systemPrompt = `You are a university professor teaching research methods. Review the following student's critique of a research paper section. Your task is to refine the critique to be more analytical, specific, and constructive. Improve the academic tone and suggest deeper questions the student could ask. Do not critique the original paper, only the student's analysis of it. Respond only with the refined critique.`; const refinedText = await callGeminiAPI(text, systemPrompt); aiOutputContainer.innerHTML = `

AI Suggestion:

${refinedText.replace(/\n/g, '
')}

`; setTimeout(() => aiOutputContainer.querySelector('.ai-suggestion-enter')?.classList.add('ai-suggestion-enter-active'), 10); } catch (error) { aiOutputContainer.innerHTML = `

Error: ${error.message}

`; } finally { button.disabled = false; buttonText.textContent = 'Critique for Clarity & Depth'; spinner.classList.add('hidden'); } }; async function callGeminiAPI(text, systemPrompt) { const apiKey = ""; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: text }] }], systemInstruction: { parts: [{ text: systemPrompt }] }, }; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) throw new Error((await response.json()).error?.message || `API Error`); const result = await response.json(); const candidate = result.candidates?.[0]; if (candidate?.content?.parts?.[0]?.text) return candidate.content.parts[0].text; throw new Error("Invalid response from AI model."); } window.downloadPDF = function() { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const citation = document.getElementById('input-citation')?.value.trim() || 'No Citation Provided'; const leftMargin = 20, topMargin = 25, contentWidth = doc.internal.pageSize.getWidth() - leftMargin * 2; const pageHeight = doc.internal.pageSize.getHeight(), bottomMargin = 20; const lineHeight = 6, font = 'Times'; let cursorY = 0; // --- Title Page --- doc.setFont(font, 'normal'); doc.setFontSize(16); doc.text('A Critical Appraisal of:', doc.internal.pageSize.getWidth() / 2, pageHeight / 3, { align: 'center' }); doc.setFont(font, 'bold'); doc.setFontSize(12); const citationLines = doc.splitTextToSize(citation, contentWidth - 10); doc.text(citationLines, doc.internal.pageSize.getWidth() / 2, pageHeight / 3 + 15, { align: 'center' }); const critiqueDate = `Critique Date: ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}`; doc.setFont(font, 'normal'); doc.setFontSize(12); doc.text(critiqueDate, doc.internal.pageSize.getWidth() / 2, pageHeight / 3 * 2, { align: 'center' }); doc.addPage(); cursorY = topMargin; // --- Main Content --- const headingColWidth = 50; const contentColWidth = contentWidth - headingColWidth - 5; const contentColX = leftMargin + headingColWidth + 5; const addFooter = (pageNum) => { doc.setFontSize(10); doc.setFont(font, 'normal'); doc.text(`Page ${pageNum}`, doc.internal.pageSize.getWidth() / 2, pageHeight - 10, { align: 'center' }); }; const checkPageBreak = (requiredHeight) => { if (cursorY + requiredHeight > pageHeight - bottomMargin) { addFooter(doc.internal.getNumberOfPages()); doc.addPage(); cursorY = topMargin; } }; tabsData.forEach(tab => { const textarea = document.getElementById(`textarea-${tab.id}`); if (!textarea || textarea.value.trim() === '') return; const contentText = textarea.value.trim(); const contentLines = doc.splitTextToSize(contentText, contentColWidth); const requiredHeight = contentLines.length * lineHeight + 5; checkPageBreak(requiredHeight); doc.setFont(font, 'bold'); doc.setFontSize(12); doc.text(tab.title, leftMargin, cursorY); doc.setFont(font, 'normal'); doc.setFontSize(11); doc.text(contentLines, contentColX, cursorY); cursorY += requiredHeight; doc.setLineDashPattern([1, 1], 0); doc.line(leftMargin, cursorY - (lineHeight / 2), leftMargin + contentWidth, cursorY - (lineHeight/2)); doc.setLineDashPattern([], 0); }); addFooter(doc.internal.getNumberOfPages()); const safeFilename = citation.substring(0, 30).replace(/[^a-z0-9]/gi, '_').toLowerCase(); doc.save(`critique_of_${safeFilename}.pdf`); } if (prevBtn && nextBtn && downloadPdfBtn) { prevBtn.addEventListener('click', () => handleNavigation(-1)); nextBtn.addEventListener('click', () => handleNavigation(1)); downloadPdfBtn.addEventListener('click', window.downloadPDF); } initializeUI(); });
Scroll to Top