import React, { useState, useEffect } from 'react';
import {
Box,
Stepper,
Step,
StepLabel,
Button,
Typography,
Paper,
useTheme,
Snackbar,
Alert,
Tabs,
Tab,
Avatar,
} from '@mui/material';
import {
Add,
WorkOutline,
} from '@mui/icons-material';
import PersonIcon from '@mui/icons-material/Person';
import WorkIcon from '@mui/icons-material/Work';
import AssessmentIcon from '@mui/icons-material/Assessment';
import { JobMatchAnalysis } from 'components/JobMatchAnalysis';
import { Candidate, Job, SkillAssessment } from "types/types";
import { useNavigate } from 'react-router-dom';
import { BackstoryPageProps } from 'components/BackstoryTab';
import { useAuth } from 'hooks/AuthContext';
import { useAppState, useSelectedCandidate, useSelectedJob } from 'hooks/GlobalContext';
import { CandidateInfo } from 'components/ui/CandidateInfo';
import { ComingSoon } from 'components/ui/ComingSoon';
import { LoginRequired } from 'components/ui/LoginRequired';
import { Scrollable } from 'components/Scrollable';
import { CandidatePicker } from 'components/ui/CandidatePicker';
import { JobPicker } from 'components/ui/JobPicker';
import { JobCreator } from 'components/JobCreator';
import { LoginRestricted } from 'components/ui/LoginRestricted';
import JsonView from '@uiw/react-json-view';
import { ResumeGenerator } from 'components/ResumeGenerator';
function WorkAddIcon() {
return (
);
}
// Main component
const JobAnalysisPage: React.FC = (props: BackstoryPageProps) => {
const theme = useTheme();
const { user, guest } = useAuth();
const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate()
const { selectedJob, setSelectedJob } = useSelectedJob();
// State management
const [activeStep, setActiveStep] = useState(0);
const [error, setError] = useState(null);
const [jobTab, setJobTab] = useState('load');
const [skills, setSkills] = useState(null)
useEffect(() => {
if (!selectedCandidate) {
if (activeStep !== 0) {
setActiveStep(0);
}
} else if (!selectedJob) {
if (activeStep !== 1) {
setActiveStep(1);
}
}
}, [selectedCandidate, selectedJob, activeStep])
// Steps in our process
const steps = [
{ index: 0, label: 'Select Candidate', icon: },
{ index: 1, label: 'Job Selection', icon: },
{ index: 2, label: 'Job Analysis', icon: },
{ index: 3, label: 'Generated Resume', icon: }
];
// Navigation handlers
const handleNext = () => {
if (activeStep === 0 && !selectedCandidate) {
setError('Please select a candidate before continuing.');
return;
}
if (activeStep === 1 && !selectedJob) {
setError('Please select a job before continuing.');
return;
}
if (activeStep === 2 && !skills) {
setError('Skill assessment must be complete before continuing.');
return;
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
console.log(activeStep);
if (activeStep === 1) {
setSelectedCandidate(null);
}
if (activeStep === 2) {
setSelectedJob(null);
}
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const moveToStep = (step: number) => {
console.log(`Move to ${step}`)
switch (step) {
case 0: /* Select candidate */
setSelectedCandidate(null);
setSelectedJob(null);
setSkills(null);
break;
case 1: /* Select Job */
setSelectedJob(null);
setSkills(null);
break;
case 2: /* Job Analysis */
setSkills(null);
break;
case 3: /* Generate Resume */
break;
}
setActiveStep(step);
}
const onCandidateSelect = (candidate: Candidate) => {
setSelectedCandidate(candidate);
setActiveStep(1);
}
const onJobSelect = (job: Job) => {
setSelectedJob(job)
setActiveStep(2);
}
// Render function for the candidate selection step
const renderCandidateSelection = () => (
Select a Candidate
);
const handleTabChange = (event: React.SyntheticEvent, value: string) => {
setJobTab(value);
};
// Render function for the job description step
const renderJobDescription = () => {
if (!selectedCandidate) {
return;
}
return (
} label="Load" />
} label="Create" />
{jobTab === 'load' &&
}
{jobTab === 'create' && user &&
}
{jobTab === 'create' && guest &&
}
);
}
const onAnalysisComplete = (skills: SkillAssessment[]) => {
setSkills(skills);
};
// Render function for the analysis step
const renderAnalysis = () => (
{selectedCandidate && selectedJob && (
)}
);
const renderResume = () => (
{skills && selectedCandidate && selectedJob &&
}
);
return (
*:not(.Scrollable)": {
flexShrink: 0, /* Prevent shrinking */
},
position: "relative",
}}>
{selectedCandidate && }
Match candidates to job requirements with AI-powered analysis
{steps.map((step, index) => (
{ moveToStep(index); }}
slots={{
stepIcon: () => (
= 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}
);
};
export { JobAnalysisPage };