import React, { useState, useEffect } from 'react'; import { Box, Stepper, Step, StepLabel, Button, Typography, Paper, TextField, Grid, Card, CardContent, CardActionArea, Avatar, Divider, CircularProgress, Container, useTheme, Snackbar, Alert, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, InputAdornment, IconButton } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import PersonIcon from '@mui/icons-material/Person'; import WorkIcon from '@mui/icons-material/Work'; import AssessmentIcon from '@mui/icons-material/Assessment'; import DescriptionIcon from '@mui/icons-material/Description'; import FileUploadIcon from '@mui/icons-material/FileUpload'; import { JobMatchAnalysis } from 'components/JobMatchAnalysis'; import { Candidate } from "types/types"; import { useNavigate } from 'react-router-dom'; import { BackstoryPageProps } from 'components/BackstoryTab'; import { useAuth } from 'hooks/AuthContext'; import { useSelectedCandidate } from 'hooks/GlobalContext'; import { CandidateInfo } from 'components/CandidateInfo'; import { ComingSoon } from 'components/ui/ComingSoon'; // Main component const JobAnalysisPage: React.FC = (props: BackstoryPageProps) => { const theme = useTheme(); const { user } = useAuth(); const navigate = useNavigate(); const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate() const { setSnack, submitQuery } = props; const backstoryProps = { setSnack, submitQuery }; // State management const [activeStep, setActiveStep] = useState(0); const [jobDescription, setJobDescription] = useState(''); const [jobTitle, setJobTitle] = useState(''); const [company, setCompany] = useState(''); const [jobLocation, setJobLocation] = useState(''); const [analysisStarted, setAnalysisStarted] = useState(false); const [error, setError] = useState(null); const [openUploadDialog, setOpenUploadDialog] = useState(false); const { apiClient } = useAuth(); const [candidates, setCandidates] = useState(null); const user_type = user?.userType || 'guest'; const user_id = user?.id || ''; useEffect(() => { if (candidates !== null || selectedCandidate) { return; } const getCandidates = async () => { try { const results = await apiClient.getCandidates(); const candidates: Candidate[] = results.data; candidates.sort((a, b) => { let result = a.lastName.localeCompare(b.lastName); if (result === 0) { result = a.firstName.localeCompare(b.firstName); } if (result === 0) { result = a.username.localeCompare(b.username); } return result; }); console.log(candidates); setCandidates(candidates); } catch (err) { setSnack("" + err); } }; getCandidates(); }, [candidates, setSnack]); useEffect(() => { if (selectedCandidate && activeStep === 0) { setActiveStep(1); } }, [selectedCandidate, activeStep]); // Steps in our process const steps = [ { index: 1, label: 'Job Selection', icon: }, { index: 2, label: 'AI Analysis', icon: }, { index: 3, label: 'Generated Resume', icon: } ]; if (!selectedCandidate) { steps.unshift({ index: 0, label: 'Select Candidate', icon: }) } // Navigation handlers const handleNext = () => { if (activeStep === 0 && !selectedCandidate) { setError('Please select a candidate before continuing.'); return; } if (activeStep === 1) { if (!jobDescription) { setError('Please provide job description before continuing.'); return; } } if (activeStep === 2) { setAnalysisStarted(true); } setActiveStep((prevActiveStep) => prevActiveStep + 1); }; const handleBack = () => { setActiveStep((prevActiveStep) => prevActiveStep - 1); }; const handleReset = () => { // setActiveStep(0); setActiveStep(1); // setSelectedCandidate(null); setJobDescription(''); // setJobTitle(''); // setJobLocation(''); setAnalysisStarted(false); }; // Render function for the candidate selection step const renderCandidateSelection = () => ( Select a Candidate {/* setSearchQuery(e.target.value)} InputProps={{ endAdornment: ( ), }} sx={{ mr: 2 }} /> */} {candidates?.map((candidate) => ( setSelectedCandidate(candidate)} sx={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'stretch' }} > {candidate.fullName} {candidate.description} {candidate.location && Location: {candidate.location.country} } Email: {candidate.email} {candidate.phone && Phone: {candidate.phone} } ))} ); // Render function for the job description step const renderJobDescription = () => ( Enter Job Details setJobTitle(e.target.value)} required margin="normal" /> setCompany(e.target.value)} required margin="normal" /> setJobLocation(e.target.value)} margin="normal" /> Job Selection setJobDescription(e.target.value)} required InputProps={{ startAdornment: ( ), }} /> The job description will be used to extract requirements for candidate matching. ); // Render function for the analysis step const renderAnalysis = () => ( {selectedCandidate && ( )} ); const renderResume = () => ( {selectedCandidate && Resume Builder} ); // If no user is logged in, show message if (!user?.id) { return ( Please log in to access candidate analysis ); } return ( Candidate Analysis {selectedCandidate && } Match candidates to job requirements with AI-powered analysis {steps.map(step => ( ( = step.index ? theme.palette.primary.main : theme.palette.grey[300], color: 'white' }} > {step.icon} ) }} > {step.label} ))} {activeStep === 0 && renderCandidateSelection()} {activeStep === 1 && renderJobDescription()} {activeStep === 2 && renderAnalysis()} {activeStep === 3 && renderResume()} {activeStep === steps[steps.length - 1].index ? ( ) : ( )} {/* Error Snackbar */} setError(null)} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} > setError(null)} severity="error" sx={{ width: '100%' }}> {error} {/* Upload Dialog */} setOpenUploadDialog(false)}> Upload Job Description Upload a job description document (.pdf, .docx, .txt, or .md) ); }; export { JobAnalysisPage };