Tweaks
This commit is contained in:
parent
a197535bea
commit
149ce9e9b3
@ -61,16 +61,18 @@ const ResumeGenerator: React.FC<ResumeGeneratorProps> = (props: ResumeGeneratorP
|
|||||||
if (!job || !candidate || !skills || resume || generating) {
|
if (!job || !candidate || !skills || resume || generating) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateResume = async () => {
|
const generateResume = async () => {
|
||||||
setGenerating(true);
|
|
||||||
const request : any = await apiClient.generateResume(candidate.id || '', skills, generateResumeHandlers);
|
const request : any = await apiClient.generateResume(candidate.id || '', skills, generateResumeHandlers);
|
||||||
const result = await request.promise;
|
const result = await request.promise;
|
||||||
setSystemPrompt(result.systemPrompt)
|
setSystemPrompt(result.systemPrompt)
|
||||||
setPrompt(result.prompt)
|
setPrompt(result.prompt)
|
||||||
setResume(result.resume)
|
setResume(result.resume)
|
||||||
setGenerating(false);
|
|
||||||
};
|
};
|
||||||
generateResume()
|
setGenerating(true);
|
||||||
|
generateResume().then(() =>{
|
||||||
|
setGenerating(false);
|
||||||
|
});
|
||||||
}, [job, candidate, apiClient, resume, skills, generating]);
|
}, [job, candidate, apiClient, resume, skills, generating]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -82,9 +84,9 @@ const ResumeGenerator: React.FC<ResumeGeneratorProps> = (props: ResumeGeneratorP
|
|||||||
}}>
|
}}>
|
||||||
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}>
|
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}>
|
||||||
<Tabs value={tabValue} onChange={handleTabChange} centered>
|
<Tabs value={tabValue} onChange={handleTabChange} centered>
|
||||||
<Tab value="system" icon={<TuneIcon />} label="System" />
|
<Tab sx={{display: systemPrompt ? "flex" : "none"}} value="system" icon={<TuneIcon />} label="System" />
|
||||||
<Tab value="prompt" icon={<InputIcon />} label="Prompt" />
|
<Tab sx={{display: prompt ? "flex" : "none"}}value="prompt" icon={<InputIcon />} label="Prompt" />
|
||||||
<Tab value="resume" icon={<ArticleIcon />} label="Resume" />
|
<Tab sx={{display: resume ? "flex" : "none"}}value="resume" icon={<ArticleIcon />} label="Resume" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Box>
|
</Box>
|
||||||
{ statusMessage && <Message message={statusMessage} />}
|
{ statusMessage && <Message message={statusMessage} />}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { JSX } from 'react';
|
||||||
import { Box, Link, Typography, Avatar, Grid, SxProps, CardActions } from '@mui/material';
|
import { Box, Link, Typography, Avatar, Grid, SxProps, CardActions, Chip, Stack, CardHeader } from '@mui/material';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@ -14,6 +14,7 @@ import { rest } from 'lodash';
|
|||||||
import { AIBanner } from 'components/ui/AIBanner';
|
import { AIBanner } from 'components/ui/AIBanner';
|
||||||
import { useAuth } from 'hooks/AuthContext';
|
import { useAuth } from 'hooks/AuthContext';
|
||||||
import { DeleteConfirmation } from '../DeleteConfirmation';
|
import { DeleteConfirmation } from '../DeleteConfirmation';
|
||||||
|
import { Build, CheckCircle, Description, Psychology, Star, Work } from '@mui/icons-material';
|
||||||
|
|
||||||
interface JobInfoProps {
|
interface JobInfoProps {
|
||||||
job: JobFull;
|
job: JobFull;
|
||||||
@ -45,7 +46,97 @@ const JobInfo: React.FC<JobInfoProps> = (props: JobInfoProps) => {
|
|||||||
if (!job) {
|
if (!job) {
|
||||||
return <Box>No user loaded.</Box>;
|
return <Box>No user loaded.</Box>;
|
||||||
}
|
}
|
||||||
console.log(job);
|
|
||||||
|
const renderRequirementSection = (title: string, items: string[] | undefined, icon: JSX.Element, required = false) => {
|
||||||
|
if (!items || items.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ mb: 2 }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1.5 }}>
|
||||||
|
{icon}
|
||||||
|
<Typography variant="subtitle1" sx={{ ml: 1, fontWeight: 600, fontSize: '0.85rem !important'}}>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
{required && <Chip label="Required" size="small" color="error" sx={{ ml: 1, fontSize: '0.75rem !important' }} />}
|
||||||
|
</Box>
|
||||||
|
<Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<Chip
|
||||||
|
key={index}
|
||||||
|
label={item}
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
sx={{ mb: 1, fontSize: '0.75rem !important' }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderJobRequirements = () => {
|
||||||
|
if (!job.requirements) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card elevation={0} sx={{ m: 0, p: 0, mt: 2, }}>
|
||||||
|
<CardHeader
|
||||||
|
title="Job Requirements Analysis"
|
||||||
|
avatar={<CheckCircle color="success" />}
|
||||||
|
sx={{ p: 0, pb: 1 }}
|
||||||
|
/>
|
||||||
|
<CardContent sx={{ p: 0 }}>
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Technical Skills (Required)",
|
||||||
|
job.requirements.technicalSkills.required,
|
||||||
|
<Build color="primary" />,
|
||||||
|
true
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Technical Skills (Preferred)",
|
||||||
|
job.requirements.technicalSkills.preferred,
|
||||||
|
<Build color="action" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Experience Requirements (Required)",
|
||||||
|
job.requirements.experienceRequirements.required,
|
||||||
|
<Work color="primary" />,
|
||||||
|
true
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Experience Requirements (Preferred)",
|
||||||
|
job.requirements.experienceRequirements.preferred,
|
||||||
|
<Work color="action" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Soft Skills",
|
||||||
|
job.requirements.softSkills,
|
||||||
|
<Psychology color="secondary" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Experience",
|
||||||
|
job.requirements.experience,
|
||||||
|
<Star color="warning" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Education",
|
||||||
|
job.requirements.education,
|
||||||
|
<Description color="info" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Certifications",
|
||||||
|
job.requirements.certifications,
|
||||||
|
<CheckCircle color="success" />
|
||||||
|
)}
|
||||||
|
{renderRequirementSection(
|
||||||
|
"Preferred Attributes",
|
||||||
|
job.requirements.preferredAttributes,
|
||||||
|
<Star color="secondary" />
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
elevation={elevation}
|
elevation={elevation}
|
||||||
@ -90,6 +181,10 @@ const JobInfo: React.FC<JobInfoProps> = (props: JobInfoProps) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
</>}
|
</>}
|
||||||
|
|
||||||
|
<Divider/>
|
||||||
|
{renderJobRequirements()}
|
||||||
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
{isAdmin &&
|
{isAdmin &&
|
||||||
|
@ -136,13 +136,14 @@ Phone: {self.user.phone or 'N/A'}
|
|||||||
- Professional Summary (highlight strongest skills and experience level)
|
- Professional Summary (highlight strongest skills and experience level)
|
||||||
- Skills (organized by strength)
|
- Skills (organized by strength)
|
||||||
- Professional Experience (focus on achievements and evidence of the skill)
|
- Professional Experience (focus on achievements and evidence of the skill)
|
||||||
- If present in material, provide an Education section
|
4. Optional sections, to include only if evidence is present:
|
||||||
- If present in material, provide a Certifications section
|
- Education section
|
||||||
|
Certifications section
|
||||||
- Additional sections as appropriate
|
- Additional sections as appropriate
|
||||||
4. Use action verbs and quantifiable achievements where possible.
|
5. Use action verbs and quantifiable achievements where possible.
|
||||||
5. Maintain a professional tone throughout.
|
6. Maintain a professional tone throughout.
|
||||||
6. Be concise and impactful - the resume should be 1-2 pages MAXIMUM.
|
7. Be concise and impactful - the resume should be 1-2 pages MAXIMUM.
|
||||||
7. Ensure all information is accurate to the original resume - do not embellish or fabricate experiences.
|
8. Ensure all information is accurate to the original resume - do not embellish or fabricate experiences.
|
||||||
|
|
||||||
## OUTPUT FORMAT:
|
## OUTPUT FORMAT:
|
||||||
Provide the resume in clean markdown format, ready for the candidate to use.
|
Provide the resume in clean markdown format, ready for the candidate to use.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user