diff --git a/frontend/src/components/JobManagement.tsx b/frontend/src/components/JobManagement.tsx
index 41f5055..87a7ad5 100644
--- a/frontend/src/components/JobManagement.tsx
+++ b/frontend/src/components/JobManagement.tsx
@@ -354,13 +354,20 @@ const JobManagement = (props: BackstoryElementProps) => {
// This would call your API to extract requirements from the job description
};
- const renderJobCreation = () => {
- if (!user) {
- return You must be logged in;
- }
+ const loadJob = async () => {
+ const job = await apiClient.getJob("7594e989-a926-45a2-9b07-ae553d2e0d0d");
+ setSelectedJob(job);
+ }
+ const renderJobCreation = () => {
+ if (!user) {
+ return You must be logged in;
+ }
return (
-
+
+
{/* Upload Section */}
{
};
return (
-
{selectedJob === null && renderJobCreation()}
diff --git a/frontend/src/components/JobMatchAnalysis.tsx b/frontend/src/components/JobMatchAnalysis.tsx
index 110ea88..3a47a36 100644
--- a/frontend/src/components/JobMatchAnalysis.tsx
+++ b/frontend/src/components/JobMatchAnalysis.tsx
@@ -322,7 +322,7 @@ const JobMatchAnalysis: React.FC = (props: JobAnalysisProps) =
- Backstory Job Summary:
+ Backstory Generated Job Summary:
{job.summary || "N/A"}
@@ -333,7 +333,7 @@ const JobMatchAnalysis: React.FC = (props: JobAnalysisProps) =
- Job Description:
+ Original Job Description:
diff --git a/frontend/src/components/layout/BackstoryLayout.tsx b/frontend/src/components/layout/BackstoryLayout.tsx
index c3873f9..a00eb26 100644
--- a/frontend/src/components/layout/BackstoryLayout.tsx
+++ b/frontend/src/components/layout/BackstoryLayout.tsx
@@ -98,26 +98,34 @@ const BackstoryPageContainer = (props : BackstoryPageContainerProps) => {
className="BackstoryPageContainer"
sx={{
display: "flex",
+ flexDirection: "row", // Must be row; if column, the box will expand for all children
flexGrow: 1,
- p: { xs: 0, sm: 0.5 }, // Zero padding on mobile (xs), 0.5 on larger screens (sm and up)
+ p: "0 !important", // Let the first box use padding to offset main content
m: "0 auto !important",
maxWidth: '1024px', //{ xs: '100%', md: '700px', lg: '1024px' },
+ height: "100%", // Restrict to main-container's height
+ minHeight: 0,//"min-content", // Prevent flex overflow
...sx
+ }}>
+
{children}
+
);
}
diff --git a/frontend/src/pages/FindCandidatePage.tsx b/frontend/src/pages/FindCandidatePage.tsx
index d56b472..6971ac3 100644
--- a/frontend/src/pages/FindCandidatePage.tsx
+++ b/frontend/src/pages/FindCandidatePage.tsx
@@ -1,77 +1,10 @@
-import React, { useEffect, useState } from 'react';
-import { useNavigate } from "react-router-dom";
-import Button from '@mui/material/Button';
-import Box from '@mui/material/Box';
+import React, { } from 'react';
import { BackstoryPageProps } from '../components/BackstoryTab';
-import { CandidateInfo } from 'components/CandidateInfo';
-import { Candidate, CandidateAI } from "../types/types";
-import { useAuth } from 'hooks/AuthContext';
-import { useSelectedCandidate } from 'hooks/GlobalContext';
+import { CandidatePicker } from 'components/ui/CandidatePicker';
const CandidateListingPage = (props: BackstoryPageProps) => {
- const { apiClient, user } = useAuth();
- const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate();
- const navigate = useNavigate();
- const { setSnack } = props;
- const [candidates, setCandidates] = useState(null);
-
- useEffect(() => {
- if (candidates !== null) {
- 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;
- });
- setCandidates(candidates);
- } catch (err) {
- setSnack("" + err);
- }
- };
-
- getCandidates();
- }, [candidates, setSnack]);
-
- return (
-
- {user?.isAdmin &&
-
- Not seeing a candidate you like?
-
-
- }
-
- {candidates?.map((u, i) =>
- { setSelectedCandidate(u); navigate("/chat"); }}
- sx={{ cursor: "pointer" }}>
- {selectedCandidate?.id === u.id &&
-
- }
- {selectedCandidate?.id !== u.id &&
-
- }
-
- )}
-
-
- );
+ return ;
};
export {
diff --git a/frontend/src/pages/JobAnalysisPage.tsx b/frontend/src/pages/JobAnalysisPage.tsx
index b5705e8..dcfdfac 100644
--- a/frontend/src/pages/JobAnalysisPage.tsx
+++ b/frontend/src/pages/JobAnalysisPage.tsx
@@ -7,25 +7,14 @@ import {
Button,
Typography,
Paper,
- TextField,
- Grid,
- Card,
- CardContent,
- CardActionArea,
Avatar,
- Divider,
- CircularProgress,
- Container,
useTheme,
Snackbar,
Alert,
} 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';
@@ -37,6 +26,7 @@ import { ComingSoon } from 'components/ui/ComingSoon';
import { JobManagement } from 'components/JobManagement';
import { LoginRequired } from 'components/ui/LoginRequired';
import { Scrollable } from 'components/Scrollable';
+import { CandidatePicker } from 'components/ui/CandidatePicker';
// Main component
const JobAnalysisPage: React.FC = (props: BackstoryPageProps) => {
@@ -51,44 +41,6 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
const [activeStep, setActiveStep] = useState(0);
const [analysisStarted, setAnalysisStarted] = useState(false);
const [error, setError] = useState(null);
- 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;
- });
- setCandidates(candidates);
- } catch (err) {
- setSnack("" + err);
- }
- };
-
- getCandidates();
- }, [candidates, setSnack]);
-
- useEffect(() => {
- if (selectedCandidate && activeStep === 0) {
- setActiveStep(1);
- }
- }, [selectedCandidate, activeStep]);
useEffect(() => {
if (selectedJob && activeStep === 1) {
@@ -98,13 +50,11 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
// Steps in our process
const steps = [
+ { index: 0, label: 'Select Candidate', icon: },
{ index: 1, label: 'Job Selection', icon: },
- { index: 2, label: 'AI Analysis', icon: },
+ { index: 2, label: 'Job Analysis', icon: },
{ index: 3, label: 'Generated Resume', icon: }
];
- if (!selectedCandidate) {
- steps.unshift({ index: 0, label: 'Select Candidate', icon: })
- }
// Navigation handlers
const handleNext = () => {
@@ -126,18 +76,38 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
};
const handleBack = () => {
+ console.log(activeStep);
+ if (activeStep === 1) {
+ setSelectedCandidate(null);
+ }
+ if (activeStep === 2) {
+ setSelectedJob(null);
+ }
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
- const handleReset = () => {
- // setActiveStep(0);
+ const moveToStep = (step: number) => {
+ switch (step) {
+ case 0: /* Select candidate */
+ setSelectedCandidate(null);
+ setSelectedJob(null);
+ break;
+ case 1: /* Select Job */
+ setSelectedCandidate(null);
+ setSelectedJob(null);
+ break;
+ case 2: /* Job Analysis */
+ break;
+ case 3: /* Generate Resume */
+ break;
+ }
+ setActiveStep(step);
+ }
+
+ const onCandidateSelect = (candidate: Candidate) => {
+ setSelectedCandidate(candidate);
setActiveStep(1);
- // setSelectedCandidate(null);
- setSelectedJob(null);
- // setJobTitle('');
- // setJobLocation('');
- setAnalysisStarted(false);
- };
+ }
// Render function for the candidate selection step
const renderCandidateSelection = () => (
@@ -146,77 +116,7 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
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}
- }
-
-
-
-
- ))}
-
+
);
@@ -258,30 +158,49 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
}
return (
-
+ *:not(.Scrollable)": {
+ flexShrink: 0, /* Prevent shrinking */
+ },
+ position: "relative",
+ }}>
{selectedCandidate && }
-
+
-
- Match candidates to job requirements with AI-powered analysis
-
+
+ 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}
-
- )
- }}
+ {steps.map((step, index) => (
+
+ { moveToStep(index); }}
+ slots={{
+ stepIcon: () => (
+ = step.index ? theme.palette.primary.main : theme.palette.grey[300],
+ color: 'white'
+ }}
+ >
+ {step.icon}
+
+ )
+ }}
>
{step.label}
@@ -294,6 +213,7 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps
{activeStep === 1 && renderJobDescription()}
{activeStep === 2 && renderAnalysis()}
{activeStep === 3 && renderResume()}
+
+
);
};