diff --git a/frontend/src/NewApp/Components/BackstoryLayout.tsx b/frontend/src/NewApp/Components/BackstoryLayout.tsx index a95b585..9d8fcfb 100644 --- a/frontend/src/NewApp/Components/BackstoryLayout.tsx +++ b/frontend/src/NewApp/Components/BackstoryLayout.tsx @@ -98,18 +98,23 @@ const BackstoryPageContainer = (props : BackstoryPageContainerProps) => { className="BackstoryPageContainer" maxWidth="xl" sx={{ + display: "flex", + flexGrow: 1, pt: 1, pb: 1, - flexGrow: 1, + width: "100%", ...sx }}> {children} @@ -161,13 +166,14 @@ const BackstoryLayout: React.FC<{ diff --git a/frontend/src/NewApp/Components/BackstoryRoutes.tsx b/frontend/src/NewApp/Components/BackstoryRoutes.tsx index a201978..3755820 100644 --- a/frontend/src/NewApp/Components/BackstoryRoutes.tsx +++ b/frontend/src/NewApp/Components/BackstoryRoutes.tsx @@ -17,7 +17,7 @@ import { BetaPage } from '../Pages/BetaPage'; import { CandidateListingPage } from '../Pages/CandidateListingPage'; import { JobAnalysisPage } from '../Pages/JobAnalysisPage'; import { DemoComponent } from "NewApp/Pages/DemoComponent"; -import { GenerateCandidate } from "NewApp/Pages/GenerateCandiate"; +import { GenerateCandidate } from "NewApp/Pages/GenerateCandidate"; const DashboardPage = () => (Dashboard); const ProfilePage = () => (Profile); diff --git a/frontend/src/NewApp/Components/CandidateInfo.tsx b/frontend/src/NewApp/Components/CandidateInfo.tsx index 6af478a..dbf46b0 100644 --- a/frontend/src/NewApp/Components/CandidateInfo.tsx +++ b/frontend/src/NewApp/Components/CandidateInfo.tsx @@ -7,6 +7,8 @@ import LinkIcon from '@mui/icons-material/Link'; import { CopyBubble } from "../../Components/CopyBubble"; // Styled components const StyledPaper = styled(Paper)(({ theme }) => ({ + display: "flex", + flexDirection: "column", padding: theme.spacing(2), marginBottom: theme.spacing(2), borderRadius: theme.shape.borderRadius, @@ -44,10 +46,10 @@ const CandidateInfo: React.FC = (props: CandidateInfoProps) return ( - + = (props: CandidateInfoProps) }} /> - + - - .MuiTypography-root": { m: 0 } }}> - {action !== '' && {action}} - - {view.full_name} - - - - /u/{view.username} - { event.stopPropagation() }} - tooltip="Copy link" content={`${window.location.origin}/u/{view.username}`} /> - - + + .MuiTypography-root": { m: 0 } }}> + {action !== '' && {action}} + + {view.full_name} + + + + /u/{view.username} + { event.stopPropagation() }} + tooltip="Copy link" content={`${window.location.origin}/u/{view.username}`} /> + + - {view.rag_content_size !== undefined && view.rag_content_size > 0 && ) => { navigate('/knowledge-explorer'); event.stopPropagation() }} - label={formatRagSize(view.rag_content_size)} + {view.rag_content_size !== undefined && view.rag_content_size > 0 && ) => { navigate('/knowledge-explorer'); event.stopPropagation() }} + label={formatRagSize(view.rag_content_size)} color="primary" size="small" sx={{ ml: 2 }} - />} + />} - + - {view.description} + {view.description} diff --git a/frontend/src/NewApp/Components/JobMatchAnalysis.tsx b/frontend/src/NewApp/Components/JobMatchAnalysis.tsx index 17b260e..6bcf9d4 100644 --- a/frontend/src/NewApp/Components/JobMatchAnalysis.tsx +++ b/frontend/src/NewApp/Components/JobMatchAnalysis.tsx @@ -153,7 +153,7 @@ const JobMatchAnalysis: React.FC = ({ }; return ( - + diff --git a/frontend/src/NewApp/Pages/GenerateCandiate.tsx b/frontend/src/NewApp/Pages/GenerateCandiate.tsx deleted file mode 100644 index 16c22cf..0000000 --- a/frontend/src/NewApp/Pages/GenerateCandiate.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; -import Box from '@mui/material/Box'; -import Tooltip from '@mui/material/Tooltip'; -import Button from '@mui/material/Button'; -import IconButton from '@mui/material/IconButton'; -import CancelIcon from '@mui/icons-material/Cancel'; -import SendIcon from '@mui/icons-material/Send'; -import PropagateLoader from 'react-spinners/PropagateLoader'; -import { CandidateInfo } from '../Components/CandidateInfo'; -import { Query } from '../../Components/ChatQuery' -import { streamQueryResponse, StreamQueryController } from '../Components/streamQueryResponse'; -import { connectionBase } from 'Global'; -import { UserInfo } from '../Components/UserContext'; -import { BackstoryElementProps } from 'Components/BackstoryTab'; -import { BackstoryTextField, BackstoryTextFieldRef } from 'Components/BackstoryTextField'; -import { jsonrepair } from 'jsonrepair'; -import { StyledMarkdown } from 'Components/StyledMarkdown'; -import { Scrollable } from 'Components/Scrollable'; -import { useForkRef } from '@mui/material'; - -const emptyUser : UserInfo = { - type: 'candidate', - description: "[blank]", - rag_content_size: 0, - username: "[blank]", - first_name: "[blank]", - last_name: "[blank]", - full_name: "[blank] [blank]", - contact_info: {}, - questions: [], - isAuthenticated: false, - has_profile: false -}; - -const GenerateCandidate = (props: BackstoryElementProps) => { - const {sessionId, setSnack, submitQuery} = props; - const [streaming, setStreaming] = useState(''); - const [processing, setProcessing] = useState(false); - const [user, setUser] = useState(emptyUser); - const controllerRef = useRef(null); - const backstoryTextRef = useRef(null); - const promptRef = useRef(null); - const stateRef = useRef(0); /* Generating persona */ - const userRef = useRef(user); - const [prompt, setPrompt] = useState(''); - const [resume, setResume] = useState(''); - - const processQuery = (query: Query) => { - if (controllerRef.current) { - return; - } - setPrompt(query.prompt); - promptRef.current = query.prompt; - stateRef.current = 0; - setUser(emptyUser); - setStreaming(''); - setResume(''); - setProcessing(true); - - controllerRef.current = streamQueryResponse({ - query, - type: "persona", - sessionId, - connectionBase, - onComplete: (msg) => { - console.log({ msg, state: stateRef.current, prompt: promptRef.current || '' }); - switch (msg.status) { - case "partial": - case "done": - switch (stateRef.current) { - case 0: /* Generating persona */ - let partialUser = JSON.parse(jsonrepair((msg.response || '').trim())); - if (!partialUser.full_name) { - partialUser.full_name = `${partialUser.first_name} ${partialUser.last_name}`; - } - console.log(partialUser); - setUser(partialUser); - stateRef.current = 1 /* Generating resume */ - break; - case 1: /* Generating resume */ - stateRef.current = 2 /* RAG generation */ - break; - case 2: /* RAG generation */ - stateRef.current = 2 /* Image generation */ - break; - case 3: /* Generating image */ - let imageGeneration = JSON.parse(jsonrepair((msg.response || '').trim())); - console.log(imageGeneration); - if (imageGeneration >= 100) { - setUser({...userRef.current}); - } else { - setPrompt(imageGeneration.status); - } - stateRef.current = 3 /* ... */ - } - if (msg.status === "done") { - setProcessing(false); - controllerRef.current = null; - stateRef.current = 0; - } - break; - case "thinking": - setPrompt(msg.response || ''); - break; - - case "error": - console.log(`Error generating persona: ${msg.response}`); - setSnack(msg.response || "", "error"); - setProcessing(false); - setUser({...userRef.current}); - controllerRef.current = null; - stateRef.current = 0; - break; - } - }, - onStreaming: (chunk) => { - setStreaming(chunk); - } - }); - }; - - const cancelQuery = () => { - if (controllerRef.current) { - controllerRef.current.abort(); - controllerRef.current = null; - stateRef.current = 0; - setProcessing(false); - } - } - - useEffect(() => { - promptRef.current = prompt; - }, [prompt]); - - useEffect(() => { - userRef.current = user; - }, [user]); - - useEffect(() => { - if (streaming.trim().length === 0) { - return; - } - - try { - switch (stateRef.current) { - case 0: /* Generating persona */ - const partialUser = {...emptyUser, ...JSON.parse(jsonrepair(`${streaming.trim()}...`))}; - if (!partialUser.full_name) { - partialUser.full_name = `${partialUser.first_name} ${partialUser.last_name}`; - } - setUser(partialUser); - break; - case 1: /* Generating resume */ - setResume(streaming); - break; - case 3: /* RAG streaming */ - break; - case 4: /* Image streaming */ - break; - } - } catch { - } - }, [streaming]); - - if (!sessionId) { - return <>; - } - - const onEnter = (value: string) => { - if (processing) { - return; - } - const query: Query = { - prompt: value - } - processQuery(query); - }; - - return (<> - { user && } - { resume !== '' && } - {processing && - Genearating - {stateRef.current === 0 && "persona"} - {stateRef.current === 1 && "resume"} - {stateRef.current === 2 && "RAG"} - {stateRef.current === 3 && "profile image"} - :{prompt} - - } - - - - - - - - - { /* This span is used to wrap the IconButton to ensure Tooltip works even when disabled */} - { cancelQuery(); }} - sx={{ display: "flex", margin: 'auto 0px' }} - size="large" - edge="start" - disabled={controllerRef.current === null || !sessionId || processing === false} - > - - - - - - ); -}; - -export { - GenerateCandidate -}; \ No newline at end of file