From fc6fc579227ea4f37fdca7feb8b6e864ca14f18a Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sat, 7 Jun 2025 09:38:53 -0700 Subject: [PATCH] Scrolling in sub pages is working correctly --- frontend/src/components/JobManagement.tsx | 25 +- frontend/src/components/JobMatchAnalysis.tsx | 4 +- .../src/components/layout/BackstoryLayout.tsx | 12 +- frontend/src/pages/FindCandidatePage.tsx | 73 +----- frontend/src/pages/JobAnalysisPage.tsx | 227 ++++++------------ 5 files changed, 104 insertions(+), 237 deletions(-) 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()} + ) : ( @@ -327,8 +247,7 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps setError(null)} severity="error" sx={{ width: '100%' }}> {error} - - + ); };