0% found this document useful (0 votes)
27 views12 pages

ATS Resume Builder App Guide

Uploaded by

smileygen123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views12 pages

ATS Resume Builder App Guide

Uploaded by

smileygen123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

ATS-RESUME-BUILDER

BACKEND

backend\api.js
const express = require('express');
const router = express.Router();

router.post('/submit', (req, res) => {


const formData = req.body;
console.log('Received form data:', formData);
res.send({ message: 'Form data received successfully' });
});

module.exports = router;

backend\package.json
{
"name": "ats-resume-builder-backend",
"version": "1.0.0",
"description": "Backend for ATS Resume Builder",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"express": "^4.18.2"
}
}

backend\server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();


const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(bodyParser.json());

// Basic route for testing


app.get('/', (req, res) => {
res.send('Server is running');
});

// Import API routes


const apiRoutes = require('./api');
app.use('/api', apiRoutes);
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

backend\package-lock.json

FRONTEND

frontend\ats-resume-builder-frontend

frontend\ats-resume-builder-frontend\public

frontend\ats-resume-builder-frontend\public\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ATS Resume Builder</title>
<link rel="stylesheet" href="%PUBLIC_URL%/index.css">
</head>
<body>
<div id="loading-screen" class="loading-screen">
<img src="%PUBLIC_URL%/logo.png" alt="App Logo" class="logo" />
<h1 class="caption">ATS Resume Builder</h1>
</div>
<div id="root"></div>
</body>
</html>

frontend\ats-resume-builder-frontend\public\logo.png

frontend\ats-resume-builder-frontend\src

frontend\ats-resume-builder-frontend\src\components

frontend\ats-resume-builder-frontend\src\components\FormComponent.css
.experience-section {
margin-bottom: 20px;
}

button {
margin-top: 10px;
}

frontend\ats-resume-builder-frontend\src\components\FormComponent.js
import React, { useState, useEffect } from 'react';

const FormComponent = ({ onDataChange }) => {


const [formData, setFormData] = useState({
name: '',
objective: '',
email: '',
phone: '',
website: '',
location: '',
workExperience: [],
education: [],
projects: [],
skills: [],
});

useEffect(() => {
onDataChange(formData);
}, [formData, onDataChange]);

const handleChange = (e) => {


setFormData({ ...formData, [e.target.name]: e.target.value });
};

const handleAddItem = (section) => {


const newItem = section === 'skills' ? { name: '', proficiency: '' } : { name: '', date: '', description: '' };
if (section === 'education') {
newItem.degree = '';
newItem.major = '';
newItem.gpa = '';
}
setFormData({
...formData,
[section]: [...formData[section], newItem],
});
};

const handleItemChange = (section, index, field, value) => {


const newItems = formData[section].map((item, itemIndex) => {
if (index === itemIndex) {
return { ...item, [field]: value };
}
return item;
});
setFormData({ ...formData, [section]: newItems });
};

const handleDeleteItem = (section, index) => {


const newItems = formData[section].filter((_, itemIndex) => index !== itemIndex);
setFormData({ ...formData, [section]: newItems });
};

return (
<form>
<input type="text" name="name" placeholder="Name" onChange={handleChange}
value={formData.name} />
<input type="text" name="objective" placeholder="Objective" onChange={handleChange}
value={formData.objective} />
<input type="email" name="email" placeholder="Email" onChange={handleChange}
value={formData.email} />
<input type="text" name="phone" placeholder="Phone" onChange={handleChange}
value={formData.phone} />
<input type="url" name="website" placeholder="Website" onChange={handleChange}
value={formData.website} />
<input type="text" name="location" placeholder="Location" onChange={handleChange}
value={formData.location} />

<h3>Work Experience</h3>
{formData.workExperience.map((exp, index) => (
<div key={index}>
<input
type="text"
placeholder="Company"
value={exp.company}
onChange={(e) => handleItemChange('workExperience', index, 'company', e.target.value)}
/>
<input
type="text"
placeholder="Job Title"
value={exp.title}
onChange={(e) => handleItemChange('workExperience', index, 'title', e.target.value)}
/>
<input
type="date"
placeholder="Start Date"
value={exp.startDate}
onChange={(e) => handleItemChange('workExperience', index, 'startDate', e.target.value)}
/>
<input
type="date"
placeholder="End Date"
value={exp.endDate}
onChange={(e) => handleItemChange('workExperience', index, 'endDate', e.target.value)}
/>
<textarea
placeholder="Description"
value={exp.description}
onChange={(e) => handleItemChange('workExperience', index, 'description', e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
handleItemChange('workExperience', index, 'description', exp.description + '\n• ');
}
}}
/>
<button type="button" onClick={() => handleDeleteItem('workExperience', index)}>Delete</button>
</div>
))}
<button type="button" onClick={() => handleAddItem('workExperience')}>Add Work
Experience</button>

<h3>Education</h3>
{formData.education.map((edu, index) => (
<div key={index}>
<input
type="text"
placeholder="School"
value={edu.name}
onChange={(e) => handleItemChange('education', index, 'name', e.target.value)}
/>
<input
type="text"
placeholder="Date"
value={edu.date}
onChange={(e) => handleItemChange('education', index, 'date', e.target.value)}
/>
<input
type="text"
placeholder="Degree"
value={edu.degree}
onChange={(e) => handleItemChange('education', index, 'degree', e.target.value)}
/>
<input
type="text"
placeholder="Major"
value={edu.major}
onChange={(e) => handleItemChange('education', index, 'major', e.target.value)}
/>
<input
type="text"
placeholder="GPA"
value={edu.gpa}
onChange={(e) => handleItemChange('education', index, 'gpa', e.target.value)}
/>
<textarea
placeholder="Description (optional)"
value={edu.description}
onChange={(e) => handleItemChange('education', index, 'description', e.target.value)}
/>
<button type="button" onClick={() => handleDeleteItem('education', index)}>Delete</button>
</div>
))}
<button type="button" onClick={() => handleAddItem('education')}>Add Education</button>

<h3>Projects</h3>
{formData.projects.map((proj, index) => (
<div key={index}>
<input
type="text"
placeholder="Name"
value={proj.name}
onChange={(e) => handleItemChange('projects', index, 'name', e.target.value)}
/>
<input
type="text"
placeholder="Date"
value={proj.date}
onChange={(e) => handleItemChange('projects', index, 'date', e.target.value)}
/>
<textarea
placeholder="Description"
value={proj.description}
onChange={(e) => handleItemChange('projects', index, 'description', e.target.value)}
/>
<button type="button" onClick={() => handleDeleteItem('projects', index)}>Delete</button>
</div>
))}
<button type="button" onClick={() => handleAddItem('projects')}>Add Project</button>

<h3>Skills</h3>
{formData.skills.map((skill, index) => (
<div key={index}>
<input
type="text"
placeholder="Skill"
value={skill.name}
onChange={(e) => handleItemChange('skills', index, 'name', e.target.value)}
/>
<input
type="text"
placeholder="Proficiency"
value={skill.proficiency}
onChange={(e) => handleItemChange('skills', index, 'proficiency', e.target.value)}
/>
<button type="button" onClick={() => handleDeleteItem('skills', index)}>Delete</button>
</div>
))}
<button type="button" onClick={() => handleAddItem('skills')}>Add Skill</button>
</form>
);
};

export default FormComponent;

frontend\ats-resume-builder-frontend\src\components\Logo.css
.logo-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}

.logo {
font-size: 3rem;
font-weight: bold;
}

frontend\ats-resume-builder-frontend\src\components\Logo.js
import React from 'react';
import './logo.css';

const Logo = () => (


<div className="logo-container">
<h1 className="logo">ATS Resume Builder</h1>
</div>
);

export default Logo;

frontend\ats-resume-builder-frontend\src\components\PreviewComponent.css
.preview-container {
padding: 20px;
}

.experience {
margin-bottom: 20px;
}

frontend\ats-resume-builder-frontend\src\components\PreviewComponent.js
import React from 'react';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
import { saveAs } from 'file-saver';
import htmlDocx from 'html-docx-js/dist/html-docx';

const PreviewComponent = ({ data }) => {


const generatePDF = () => {
const input = document.getElementById('resume');
html2canvas(input).then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
pdf.save('resume.pdf');
});
};

const generateDocx = () => {


const content = document.getElementById('resume').innerHTML;
const blob = htmlDocx.asBlob(content);
saveAs(blob, 'resume.docx');
};

return (
<div>
<div id="resume">
<h1>{data.name}</h1>
<p>{data.objective}</p>
<p>{data.email} | {data.phone} | {data.website} | {data.location}</p>

<h2>Work Experience</h2>
{data.workExperience.map((exp, index) => (
<div key={index}>
<h3>{exp.company}</h3>
<p>{exp.title} ({exp.startDate} - {exp.endDate})</p>
<p>{exp.description.split('\n').map((line, i) => <span key={i}>{line}<br/></span>)}</p>
</div>
))}

<h2>Education</h2>
{data.education.map((edu, index) => (
<div key={index}>
<h3>{edu.name}</h3>
<p>{edu.degree} in {edu.major} ({edu.date})</p>
<p>GPA: {edu.gpa}</p>
<p>{edu.description.split('\n').map((line, i) => <span key={i}>{line}<br/></span>)}</p>
</div>
))}

<h2>Projects</h2>
{data.projects.map((proj, index) => (
<div key={index}>
<h3>{proj.name}</h3>
<p>{proj.date}</p>
<p>{proj.description.split('\n').map((line, i) => <span key={i}>{line}<br/></span>)}</p>
</div>
))}

<h2>Skills</h2>
<ul>
{data.skills.map((skill, index) => (
<li key={index}>{skill.name} - {skill.proficiency}</li>
))}
</ul>
</div>
<button onClick={generatePDF}>Download as PDF</button>
<button onClick={generateDocx}>Download as Word</button>
</div>
);
};

export default PreviewComponent;

frontend\ats-resume-builder-frontend\src\App.css
.main-container {
display: flex;
height: 80vh; /* Adjust based on your layout preference */
}

.form-container, .preview-container {
flex: 1;
overflow-y: auto;
padding: 20px;
border: 1px solid #ccc; /* Optional: add borders to visually distinguish sections */
margin: 10px;
}

.logo-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

frontend\ats-resume-builder-frontend\src\App.js
import React, { useState, useEffect } from 'react';
import './App.css';
import FormComponent from './components/FormComponent';
import PreviewComponent from './components/PreviewComponent';

const App = () => {


const [formData, setFormData] = useState({
name: '',
objective: '',
email: '',
phone: '',
website: '',
location: '',
workExperience: [],
education: [],
projects: [],
skills: [],
});

const [loading, setLoading] = useState(true);

useEffect(() => {
setTimeout(() => {
setLoading(false);
const loadingScreen = document.getElementById('loading-screen');
if (loadingScreen) {
loadingScreen.classList.add('hidden');
}
}, 2000);
}, []);

const handleDataChange = (data) => {


setFormData(data);
};

return (
<div className="App">
<div className="form-section">
<FormComponent onDataChange={handleDataChange} />
</div>
<div className="preview-section">
<PreviewComponent data={formData} />
</div>
</div>
);
};

export default App;


frontend\ats-resume-builder-frontend\src\index.css
body {
font-family: 'Roboto', sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
}

.loading-screen {
position: fixed;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
z-index: 9999;
}

.loading-screen.hidden {
display: none;
}

.logo {
width: 100px;
height: 100px;
}

.caption {
font-size: 24px;
margin-top: 20px;
}

.App {
display: flex;
justify-content: space-around;
padding: 20px;
}

.form-section {
width: 45%;
}

.preview-section {
width: 45%;
border: 1px solid #ccc;
padding: 20px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

input, button {
padding: 10px;
margin: 5px 0;
width: 100%;
border: 1px solid #ddd;
border-radius: 5px;
}

button {
background-color: #007bff;
color: #fff;
cursor: pointer;
}

button:hover {
background-color: #0056b3;
}

frontend\ats-resume-builder-frontend\src\index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

frontend\ats-resume-builder-frontend\package.json
{
"name": "ats-resume-builder-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.16.4",
"@mui/material": "^5.16.4",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.2",
"file-saver": "^2.0.5",
"html-docx-js": "^0.1.0",
"html2canvas": "^1.4.1",
"jspdf": "^2.5.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "^3.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

frontend\ats-resume-builder-frontend\package-lock.json

ats-resume-builder\frontend\-p

ats-resume-builder\package-lock.json

You might also like