document.addEventListener('DOMContentLoaded', () => { const studentSelector = document.getElementById('student-selector'); const generateReportBtn = document.getElementById('generate-report-btn'); const jobApplicationInput = document.getElementById('job-application-input'); const analyzeJobBtn = document.getElementById('analyze-job-btn'); const loadingSpinner = document.getElementById('loading-spinner'); const reportContainer = document.getElementById('report-container'); const jobAnalysisContainer = document.getElementById('job-analysis-container'); const chatbotContainer = document.getElementById('chatbot-container'); const chatForm = document.getElementById('chat-form'); const chatInput = document.getElementById('chat-input'); const chatHistory = document.getElementById('chat-history'); // 1. Populate student dropdown on page load fetch('/api/students') .then(response => response.json()) .then(students => { students.forEach(student => { const option = document.createElement('option'); option.value = student.enrollment_no; option.textContent = `${student.name} (${student.enrollment_no})`; studentSelector.appendChild(option); }); }) .catch(error => console.error('Error fetching students:', error)); // 2. Enable buttons when inputs are filled studentSelector.addEventListener('change', () => { const hasSelection = !!studentSelector.value; generateReportBtn.disabled = !hasSelection; chatbotContainer.classList.toggle('hidden', !hasSelection); reportContainer.classList.add('hidden'); // Hide old report on new selection chatHistory.innerHTML = ''; // Clear chat history }); jobApplicationInput.addEventListener('input', () => { analyzeJobBtn.disabled = !jobApplicationInput.value.trim(); }); // 3. Handle "Generate Report" button click generateReportBtn.addEventListener('click', () => { const enrollmentNo = studentSelector.value; if (!enrollmentNo) return; loadingSpinner.classList.remove('hidden'); reportContainer.classList.add('hidden'); jobAnalysisContainer.classList.add('hidden'); chatbotContainer.classList.add('hidden'); fetch(`/api/report/${enrollmentNo}`) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(report => { loadingSpinner.classList.add('hidden'); if (report.error) { alert(`Error generating report: ${report.error}`); } else { displayReport(report); reportContainer.classList.remove('hidden'); chatbotContainer.classList.remove('hidden'); } }) .catch(error => { loadingSpinner.classList.add('hidden'); console.error('Report generation error:', error); alert(`An unexpected error occurred: ${error.message}`); }); }); // 4. Handle "Analyze Job Application" button click analyzeJobBtn.addEventListener('click', () => { const jobApplicationLink = jobApplicationInput.value.trim(); if (!jobApplicationLink) return; loadingSpinner.classList.remove('hidden'); reportContainer.classList.add('hidden'); jobAnalysisContainer.classList.add('hidden'); chatbotContainer.classList.add('hidden'); fetch('/api/job-analysis', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ job_application_link: jobApplicationLink }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { loadingSpinner.classList.add('hidden'); if (data.error) { alert(`Error analyzing job application: ${data.error}`); } else { displayJobAnalysis(data.data); // Access data.data as per API response structure jobAnalysisContainer.classList.remove('hidden'); } }) .catch(error => { loadingSpinner.classList.add('hidden'); console.error('Job analysis error:', error); alert(`An unexpected error occurred: ${error.message}`); }); }); // 5. Handle chat form submission chatForm.addEventListener('submit', (e) => { e.preventDefault(); const enrollmentNo = studentSelector.value; const question = chatInput.value.trim(); if (!question || !enrollmentNo) return; appendMessage(question, 'user'); chatInput.value = ''; appendMessage('Thinking...', 'ai', true); // Show loading indicator fetch('/api/ask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enrollment_no: enrollmentNo, question: question }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { const loadingElement = chatHistory.querySelector('.loading'); if (loadingElement) { loadingElement.parentElement.remove(); } appendMessage(data.answer, 'ai'); }) .catch(error => { console.error('Chat error:', error); const loadingElement = chatHistory.querySelector('.loading'); if (loadingElement) { loadingElement.parentElement.remove(); } appendMessage('Sorry, an error occurred while fetching the answer.', 'ai'); }); }); // --- Helper Functions --- function displayReport(report) { document.getElementById('report-title').textContent = `Performance Report for ${studentSelector.options[studentSelector.selectedIndex].text}`; document.getElementById('summary-text').textContent = report.overall_summary; // Display resume analysis displayResumeAnalysis(report.resume_analysis); const scoresGrid = document.getElementById('scores-grid'); scoresGrid.innerHTML = ''; report.detailed_scores.forEach(item => { scoresGrid.innerHTML += `
No YouTube recommendations available for this student.
'; return; } recommendations.forEach(topic => { // Check if this is a topic with videos or a single video if (topic.videos && Array.isArray(topic.videos)) { // This is a topic with multiple videos const topicSection = document.createElement('div'); topicSection.className = 'topic-section'; const topicHeader = document.createElement('h3'); topicHeader.textContent = topic.topic; topicSection.appendChild(topicHeader); const topicReason = document.createElement('p'); topicReason.className = 'topic-reason'; topicReason.textContent = topic.reason; topicSection.appendChild(topicReason); const videosContainer = document.createElement('div'); videosContainer.className = 'videos-container'; topic.videos.forEach(video => { const card = document.createElement('div'); card.className = 'youtube-card'; // Fix URL formatting - remove extra spaces const embedUrl = (video.embed_url || video.url).replace(/\s+/g, ''); card.innerHTML = `${video.reason || video.description}
${topic.reason || topic.description}
No strengths data available.
'; } // Display weaknesses const weaknessesContainer = document.getElementById('job-weaknesses-list'); weaknessesContainer.innerHTML = ''; // Check if weaknesses exist and is an array if (data.weaknesses && Array.isArray(data.weaknesses)) { data.weaknesses.forEach(weakness => { const item = document.createElement('div'); item.className = 'job-weakness-item'; item.innerHTML = `No weaknesses data available.
'; } // Display enhancement recommendations const enhancementsContainer = document.getElementById('job-enhancements-list'); enhancementsContainer.innerHTML = ''; // Check if enhancement_recommendations exist and is an array if (data.enhancement_recommendations && Array.isArray(data.enhancement_recommendations)) { data.enhancement_recommendations.forEach(rec => { const item = document.createElement('div'); item.className = 'job-enhancement-item'; item.innerHTML = `No enhancement recommendations available.
'; } // Display YouTube recommendations displayJobYouTubeRecommendations(data.video_recommendations); } function displayJobYouTubeRecommendations(recommendations) { const container = document.getElementById('job-youtube-recommendations'); container.innerHTML = ''; if (!recommendations || !Array.isArray(recommendations) || recommendations.length === 0) { container.innerHTML = 'No YouTube recommendations available for this job application.
'; return; } recommendations.forEach(topic => { // Check if this is a topic with videos or a single video if (topic.videos && Array.isArray(topic.videos)) { // This is a topic with multiple videos const topicSection = document.createElement('div'); topicSection.className = 'topic-section'; const topicHeader = document.createElement('h3'); topicHeader.textContent = topic.topic || 'Recommended Topic'; topicSection.appendChild(topicHeader); const topicReason = document.createElement('p'); topicReason.className = 'topic-reason'; topicReason.textContent = topic.reason || 'Recommended to improve your skills'; topicSection.appendChild(topicReason); const videosContainer = document.createElement('div'); videosContainer.className = 'videos-container'; topic.videos.forEach(video => { const card = document.createElement('div'); card.className = 'youtube-card'; // Fix URL formatting - remove extra spaces const embedUrl = (video.embed_url || video.url).replace(/\s+/g, ''); card.innerHTML = `${video.reason || video.description || 'Recommended for skill development'}
${topic.reason || topic.description || 'Recommended for skill development'}