From c9d9ee75e6189b19ea7ee3da9773567a523be1b2 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 30 Nov 2025 05:59:02 +0000 Subject: [PATCH] JobHune 29112025 --- analyze.php | 71 ++++++++++++++++++++++++++++++++++ assets/js/main.js | 98 ++++++++++++++++++++++++++++++++++++++++++++--- index.php | 5 +-- 3 files changed, 165 insertions(+), 9 deletions(-) create mode 100644 analyze.php diff --git a/analyze.php b/analyze.php new file mode 100644 index 0000000..4b18fd2 --- /dev/null +++ b/analyze.php @@ -0,0 +1,71 @@ + false, 'message' => 'Failed to read resume file.']); + exit; + } + + // Define the AI prompt + $prompt = <<, + "status": "", + "strengths": [ + "", + "" + ], + "weaknesses": [ + "", + "" + ] +} + +Here is the resume content: +--- +{$resumeContent} +--- +PROMPT; + + // Call the AI + $response = LocalAIApi::createResponse([ + 'input' => [ + ['role' => 'system', 'content' => 'You are an expert ATS resume analyzer that only responds with JSON.'], + ['role' => 'user', 'content' => $prompt], + ], + ]); + + if (empty($response['success'])) { + error_log('AI API Error: ' . ($response['error'] ?? 'Unknown error')); + echo json_encode(['success' => false, 'message' => 'AI analysis failed. Please try again later.']); + exit; + } + + $analysisJson = LocalAIApi::decodeJsonFromResponse($response); + + if ($analysisJson === null) { + error_log('AI API JSON Decode Error: ' . LocalAIApi::extractText($response)); + echo json_encode(['success' => false, 'message' => 'Failed to parse AI response. The response may not be valid JSON.']); + exit; + } + + echo json_encode(['success' => true, 'data' => $analysisJson]); + +} else { + echo json_encode([ + 'success' => false, + 'message' => 'File upload failed or no file was uploaded.' + ]); +} +?> \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index 295d7de..acf1958 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,15 +1,101 @@ document.addEventListener('DOMContentLoaded', function() { + const uploadForm = document.getElementById('upload-form'); const analyzeBtn = document.getElementById('analyze-btn'); const uploadSection = document.getElementById('upload-section'); const analysisSection = document.getElementById('analysis-section'); + const resumeFileInput = document.getElementById('resume-file'); - if (analyzeBtn) { - analyzeBtn.addEventListener('click', function(event) { + if (uploadForm) { + uploadForm.addEventListener('submit', function(event) { event.preventDefault(); - - // Hide upload section and show analysis section - uploadSection.style.display = 'none'; - analysisSection.style.display = 'block'; + + if (!resumeFileInput.files || resumeFileInput.files.length === 0) { + alert('Please select a resume file to analyze.'); + return; + } + + const formData = new FormData(); + formData.append('resume', resumeFileInput.files[0]); + + // Show loading state + analyzeBtn.disabled = true; + analyzeBtn.innerHTML = ' Analyzing...'; + + fetch('analyze.php', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + // Hide loading state + analyzeBtn.disabled = false; + analyzeBtn.innerHTML = 'Analyze My Resume'; + + if (data.success && data.data) { + const analysis = data.data; + + // Update Score and Status + document.getElementById('ats-score').textContent = analysis.score; + const scoreCircle = document.querySelector('.score-circle'); + const statusElement = scoreCircle.parentElement.parentElement.querySelector('.fw-semibold'); + statusElement.textContent = analysis.status; + + if (analysis.score >= 80) { + statusElement.className = 'fw-semibold text-success'; + } else if (analysis.score >= 60) { + statusElement.className = 'fw-semibold text-warning'; + } else { + statusElement.className = 'fw-semibold text-danger'; + } + + // Update Strengths + const strengthsList = document.querySelector('#analysis-section .bg-success').parentElement.querySelector('.list-group'); + strengthsList.innerHTML = ''; // Clear existing items + if (analysis.strengths && analysis.strengths.length > 0) { + analysis.strengths.forEach(item => { + const li = document.createElement('li'); + li.className = 'list-group-item'; + li.textContent = item; + strengthsList.appendChild(li); + }); + } else { + const li = document.createElement('li'); + li.className = 'list-group-item'; + li.textContent = 'No specific strengths identified.'; + strengthsList.appendChild(li); + } + + // Update Weaknesses + const weaknessesList = document.querySelector('#analysis-section .bg-warning').parentElement.querySelector('.list-group'); + weaknessesList.innerHTML = ''; // Clear existing items + if (analysis.weaknesses && analysis.weaknesses.length > 0) { + analysis.weaknesses.forEach(item => { + const li = document.createElement('li'); + li.className = 'list-group-item'; + li.textContent = item; + weaknessesList.appendChild(li); + }); + } else { + const li = document.createElement('li'); + li.className = 'list-group-item'; + li.textContent = 'No specific areas for improvement identified.'; + weaknessesList.appendChild(li); + } + + // Show the analysis + uploadSection.style.display = 'none'; + analysisSection.style.display = 'block'; + } else { + alert('Error: ' + data.message); + } + }) + .catch(error => { + // Hide loading state + analyzeBtn.disabled = false; + analyzeBtn.innerHTML = 'Analyze My Resume'; + alert('An unexpected error occurred. Please try again.'); + console.error('Error:', error); + }); }); } }); diff --git a/index.php b/index.php index ca61358..187c7d6 100644 --- a/index.php +++ b/index.php @@ -29,10 +29,10 @@

Get Your Resume ATS-Ready

Upload your resume to see your ATS compatibility score and get actionable insights in seconds.

-
+
- +
-

For demo purposes, just click "Analyze" to see a sample report.