import { useState } from 'react'; import { motion } from 'framer-motion'; import { Upload, FileText, Users, Sliders, Eye, Settings, Zap, Target, Download, BrainCircuit } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Slider } from '@/components/ui/slider'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Switch } from '@/components/ui/switch'; import { Label } from '@/components/ui/label'; const ResumeMatchingDashboard = ({ setError }) => { const [topN, setTopN] = useState("5"); const [customTopN, setCustomTopN] = useState(""); const handleChat = async (resumeId: string) => { console.log(`Chat button clicked for resume ID: ${resumeId}`); try { // 1. Retrieve the full resume text embeddings from the API const response = await fetch(`http://localhost:8000/api/resume-embedding/${resumeId}`); if (!response.ok) { throw new Error(`Failed to retrieve resume embedding: ${response.status}`); } const data = await response.json(); const resumeEmbedding = data.embedding; // 2. Send the embeddings to SLM_manager/augemented_generation.py as a JSON file // TODO: Implement the logic to send the embeddings to SLM_manager/augemented_generation.py // This might involve creating a new API endpoint or using an existing one // 3. Display the summarized information in the AI chatbot section // TODO: Implement the logic to display the summarized information in the AI chatbot section console.log("Resume embedding:", resumeEmbedding); } catch (error: any) { console.error("Error handling chat:", error); setError(error.message || "An unknown error occurred while handling chat."); } }; const [threshold, setThreshold] = useState([75]); const [previewMode, setPreviewMode] = useState(true); const [jobDescription, setJobDescription] = useState(null); const [resumes, setResumes] = useState([]); const [isAnalyzing, setIsAnalyzing] = useState(false); const [analysisComplete, setAnalysisComplete] = useState(false); const [analysisResults, setAnalysisResults] = useState([]); const [aiSummary, setAiSummary] = useState(null); const [jobText, setJobText] = useState(""); const handleJobDescriptionUpload = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { setJobDescription(file); setAnalysisComplete(false); setAnalysisResults([]); setAiSummary(null); setJobText(""); setError(null); } }; const handleResumeUpload = (event: React.ChangeEvent) => { const files = Array.from(event.target.files || []); setResumes(files); setAnalysisComplete(false); setAnalysisResults([]); setAiSummary(null); setError(null); }; const handleAnalysis = async () => { if (!jobDescription || resumes.length === 0) return; setIsAnalyzing(true); setAnalysisComplete(false); setError(null); setAiSummary(null); const formData = new FormData(); formData.append('job_description', jobDescription); resumes.forEach(resume => { formData.append('resumes', resume); }); try { const response = await fetch('http://localhost:8000/api/match-resumes', { method: 'POST', body: formData, }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.detail || `HTTP error! status: ${response.status}`); } const data = await response.json(); // Format the API response data const formattedResults = data.matches.map((match: any) => ({ id: match.filename, name: match.name || match.filename.split('/').pop()?.replace(/\.[^/.]+$/, "") || "Unknown", score: Math.round(match.relevance), experience: match.experience, highlight: match.section_text, skills: match.skills || [], bestSection: match.best_section, })); setAnalysisResults(formattedResults); setAiSummary(data.summary); // Store the job description text from the response setJobText(data.job_text || data.job_description || ""); setAnalysisComplete(true); } catch (e: any) { console.error("Analysis failed:", e); setError(e.message || "An unknown error occurred during analysis."); } finally { setIsAnalyzing(false); } }; const actualTopN = topN === "custom" ? parseInt(customTopN) || 5 : parseInt(topN); const filteredResults = analysisResults .filter(result => result.score >= threshold[0]) .slice(0, actualTopN); const handleExportResults = () => { const dataStr = JSON.stringify({ matches: analysisResults, summary: aiSummary }, null, 2); const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr); const exportFileDefaultName = `resume_matches_${new Date().toISOString().split('T')[0]}.json`; const linkElement = document.createElement('a'); linkElement.setAttribute('href', dataUri); linkElement.setAttribute('download', exportFileDefaultName); linkElement.click(); }; const controlSections = [ { title: "Job Description", icon: FileText, content: (
) }, { title: "Resume Upload", icon: Users, content: (
) }, { title: "Top N Matches", icon: Target, content: (
{topN === "custom" && (
setCustomTopN(e.target.value)} placeholder="Enter custom number" min="1" max="100" className="w-full px-3 py-2 rounded-lg glass-card border border-accent/30 focus:border-accent/50 outline-none text-sm" />
)}

Showing top {actualTopN} candidates

) }, { title: "Similarity Threshold", icon: Sliders, content: (
Minimum Match Score {threshold[0]}%
) }, ]; return (

Resume Matching
Dashboard

Upload a job description and resumes to find the perfect matches using our advanced RAG architecture.

{controlSections.map((section, index) => { const IconComponent = section.icon; return (

{section.title}

{section.content}
); })}
{analysisComplete && ( {jobText && (

Job Description

{jobText}

)} {/* AI Summary section temporarily disabled */} {filteredResults.length > 0 ? (

Top Matches (Showing {filteredResults.length} of {analysisResults.length} total matches)

{filteredResults.map((candidate, index) => (
#{index + 1}

{candidate.name !== "Unknown Candidate" ? candidate.name : candidate.id.split('/').pop()?.replace('.pdf', '').split('_').join(' ')}

{candidate.experience}

{candidate.highlight}

{candidate.skills.map((skill: string, skillIndex: number) => ( {skill} ))}
{candidate.score}%
Match Score
))}
) : (

No matching resumes found for the given criteria. Try adjusting the similarity threshold.

)} )}
); }; export default ResumeMatchingDashboard;