Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 3-Step Resume Builder Feature with PDF Download Capability #798

Merged
merged 1 commit into from
Oct 21, 2024

Conversation

Mohitranag18
Copy link
Contributor

@Mohitranag18 Mohitranag18 commented Oct 21, 2024

Issue Reference: #757 – Resume Builder Feature with 3-Step Process

Description:

This PR adds a Resume Builder feature, enabling users to create and download resumes using a simple three-step process. The feature is fully responsive and utilizes a dynamic transition-based UI, allowing for a streamlined user experience without reloading the page.

Feature Breakdown:

Step 1: User Information Input

  • A form collects user details, including name, email, education, skills, and experience.
  • Data is stored using JavaScript variables for use in subsequent steps.
  • A Next Step button transitions the user to the template selection stage.

Step 2: Template Selection

  • Multiple HTML/CSS-based resume templates are presented for users to choose from.
  • Once a template is selected, the choice is stored, and users can move to the final step.
  • Previous Step and Next Step buttons allow navigation between steps.

Step 3: Resume Preview and Download

  • The resume is dynamically generated based on user inputs and the selected template.
  • Users can preview their resume, edit any details, and download it as a PDF.
  • Utilizes the html2pdf library to convert the HTML preview into a PDF file.
  • An Edit button enables users to return to Step 1 to make modifications if needed.

Key Features:

Seamless transitions: Hides and shows different sections of the page as users move between steps.
Responsive design: Ensures optimal functionality across various devices and screen sizes.
PDF download styling matches the browser preview.

Screenshots:

Screenshot 2024-10-21 at 00-50-02 Resume Builder - Step 1

Screenshot 2024-10-21 at 00-50-55 Resume Builder - Step 1

Screenshot 2024-10-21 at 00-51-14 Resume Builder - Step 1

Screenshot (231)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a comprehensive resume builder with dynamic sections for Education, Job Experience, and Projects.
    • Added multiple resume templates (Basic, Classic, Modern) for user selection.
    • Implemented functionality to review and download resumes as PDFs.
  • Styling Enhancements

    • New CSS styles for improved layout and user experience across the application.
    • Responsive design considerations for better accessibility.
  • Documentation

    • Updated HTML structure for improved organization and usability.

Copy link

coderabbitai bot commented Oct 21, 2024

Walkthrough

The changes encapsulate the development of a resume builder application, including a complete overhaul of the HTML structure, the introduction of a CSS file for styling, and the addition of JavaScript functionality. The application now allows users to dynamically add sections for personal information, education, job experience, and projects. Users can select templates, preview their resumes, and download them as PDFs. The overall design is modernized with improved layout, accessibility, and user interaction features.

Changes

File Change Summary
Resume.css Added comprehensive styles for the resume application, including form elements, buttons, and layout sections.
Resume.js Introduced functions for dynamic section addition, template selection, data collection, and PDF generation.
resume.html Overhauled structure with a new header, organized form sections, and dynamic elements for user interaction.
templates/basic.html Added a new HTML template for resumes with structured sections and placeholders for user data.
templates/classic.html Added a new HTML template for resumes with a structured layout and placeholders for user data.
templates/modern.html Added a new HTML template for modern resumes with a structured layout and placeholders for user data.
templates/templates.css Introduced styles for resume templates, including layout, headings, and interactive elements.

Possibly related issues

Possibly related PRs

Suggested labels

hacktoberfest, level3, gssoc-ext, hacktoberfest-accepted

Suggested reviewers

  • GarimaSingh0109

Poem

🐰 In a world of resumes, neat and bright,
A builder's magic takes to flight.
With templates galore and styles so fine,
Craft your story, let your skills shine!
Click, create, and download with glee,
Your dream job awaits, just wait and see! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Outside diff range and nitpick comments (10)
Resume.css (5)

1-15: LGTM! Consider adding max-width for larger screens.

The body and form container styles create a clean, modern look that aligns well with the PR objectives. The use of box-shadow adds depth, and the 90% width allows for responsiveness.

Consider adding a max-width to .form-container for better readability on larger screens:

.form-container {
    max-width: 1200px; /* or any suitable value */
    /* existing styles... */
}

29-53: LGTM! Consider adding focus styles for improved accessibility.

The form element styles create a consistent and responsive look. The vertical resize for textareas is a good UX decision.

For improved accessibility, consider adding focus styles to input and textarea elements:

input[type="text"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
textarea:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.5);
}

76-130: LGTM! Consider adding keyboard focus styles for template cards.

The template selection styles align well with the PR objectives and create an interactive, responsive layout using flexbox. The hover effects on template cards enhance the user experience.

For improved accessibility, consider adding keyboard focus styles to the template cards:

.template-card:focus-within {
    outline: 2px solid #007bff;
    outline-offset: 2px;
}

132-174: LGTM! Consider using consistent units for font sizes.

The resume preview styles create a clear structure and visual hierarchy, aligning well with the PR objectives. The specific styles for headings and paragraphs enhance readability.

For consistency, consider using rem units for all font sizes in the resume preview:

#resume-display h1 { font-size: 2rem; }
#resume-display h2 { font-size: 1.5rem; }
#resume-display h3 { font-size: 1.2rem; }

176-194: LGTM! Consider using variables for consistent colors.

The final button styles create visually distinct buttons for different actions, aligning well with the PR objectives. The use of Bootstrap-like colors helps with user recognition of button purposes.

For better maintainability and consistency, consider using CSS variables for colors:

:root {
    --warning-color: #f0ad4e;
    --success-color: #5cb85c;
}

#prev-step-3 { background-color: var(--warning-color); }
#download-resume { background-color: var(--success-color); }
resume.html (2)

13-13: Typo in Logo Text: "Resum Resume"

The logo text currently reads "Resum Resume". If this is unintentional, consider correcting it to "Resume Resume" or your intended branding.


245-246: Consider Using a Local Copy of External Libraries

Including html2pdf.js via a CDN is acceptable, but relying on external resources can lead to issues if the CDN is unavailable. Consider hosting a local copy of the library to ensure consistent availability.

Alternatively, ensure proper fallback mechanisms are in place if the CDN cannot be reached.

Resume.js (3)

98-109: Improper Handling of Validation Feedback

Currently, if validation fails, an alert is shown. This interrupts the user experience and may not be user-friendly.

Consider displaying validation messages inline next to the relevant fields to provide better feedback.


123-126: Duplicate Validation of Template Selection

The check for !selectedTemplate before proceeding is redundant since the "Next" button is disabled until a template is selected.

You can remove this validation to streamline the code.


251-255: PDF Generation Margin Units Inconsistency

In the PDF options, the margin is specified as 0.5, but the unit is not explicitly set, which may cause inconsistencies in the generated PDF.

Specify the unit for the margin to ensure consistent formatting.

const options = {
    margin: [0.5, 0.5, 0.5, 0.5], // Top, right, bottom, left margins in inches
    // other options
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ce18434 and c2d2dc3.

⛔ Files ignored due to path filters (3)
  • templates/basic.jpg is excluded by !**/*.jpg
  • templates/classic.jpg is excluded by !**/*.jpg
  • templates/modern.jpg is excluded by !**/*.jpg
📒 Files selected for processing (7)
  • Resume.css (1 hunks)
  • Resume.js (1 hunks)
  • resume.html (1 hunks)
  • templates/basic.html (1 hunks)
  • templates/classic.html (1 hunks)
  • templates/modern.html (1 hunks)
  • templates/templates.css (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • templates/basic.html
  • templates/classic.html
  • templates/modern.html
  • templates/templates.css
🧰 Additional context used
🔇 Additional comments (6)
Resume.css (3)

17-27: LGTM! Good use of rem units and visual hierarchy.

The heading styles create a clear visual hierarchy and use rem units, which is great for accessibility and responsiveness. The margin-bottom values help with proper spacing between elements.


55-74: LGTM! Excellent button styles with accessibility considerations.

The button styles create visually appealing and interactive elements. The use of transitions for hover and focus effects enhances the user experience. The focus styles improve accessibility by providing a clear visual indicator for keyboard navigation.


1-194: Overall, excellent CSS implementation for the resume builder.

The CSS file successfully implements styles that align with the PR objectives, creating a cohesive and responsive design for the 3-step resume builder. The use of modern CSS techniques like flexbox, transitions, and hover effects enhances the user experience. Minor suggestions were made throughout the review to further improve accessibility, consistency, and maintainability.

resume.html (2)

93-94: Sanitize and Parse Comma-Separated Inputs

The Skills and Languages fields accept comma-separated values. Ensure that the JavaScript code properly trims whitespace and handles potential input errors to prevent issues during resume generation.

Consider updating the parsing logic in Resume.js to handle extra spaces and missing commas gracefully.

Also applies to: 155-156


185-188: Ensure Navigation Buttons Function Correctly

Verify that the "Prev Step" and "Next Step" buttons have the correct onclick handlers and that the functions showStep(1) and proceedToNextStep(3) are properly defined in Resume.js.

Resume.js (1)

202-238: Potential XSS Vulnerability in Resume Generation

Data inserted into the resume HTML is taken directly from user input without sanitization, which could lead to Cross-Site Scripting (XSS) attacks.

[security]

Sanitize user input before including it in the HTML to prevent XSS vulnerabilities.

function sanitizeInput(input) {
    const div = document.createElement('div');
    div.textContent = input;
    return div.innerHTML;
}

// Use sanitizeInput on all user inputs
let educationHTML = educationEntries.map(edu => `
    <div>
        <strong>${sanitizeInput(edu.institute)}</strong> (${sanitizeInput(edu.startYear)} - ${sanitizeInput(edu.endYear)})<br>
        <em>${sanitizeInput(edu.course)}</em><br>
        <span>Score: ${sanitizeInput(edu.score)}</span>
    </div>
`).join('');
// Repeat for other sections

Comment on lines 29 to +40
<style>
@import url('https://fonts.googleapis.com/css2?family=Raleway&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Barlow:wght@500&display=swap');
body{
padding: 0;
}
header{
position: relative;
margin-bottom: 5rem;
}
footer{
margin-top: 5rem;
}
</style>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Move Inline Styles to External Stylesheet

Inline styles are included within the <body> element. It's best practice to place styles in external CSS files or within the <head> section to improve maintainability and performance.

Apply this diff to remove inline styles from the HTML file:

-    <style>
-        body{
-            padding: 0;
-        }
-        header{
-            position: relative;
-            margin-bottom: 5rem;
-        }
-        footer{
-            margin-top: 5rem;
-        }
-    </style>

Add these styles to Resume.css:

body {
    padding: 0;
}
header {
    position: relative;
    margin-bottom: 5rem;
}
footer {
    margin-top: 5rem;
}

Comment on lines +50 to +63
<label>Name:</label>
<input type="text" id="name" placeholder="Enter your name">

.none
{
display: none;
}
.resume
{
margin-top: 40px;
margin-bottom: 40px;
margin-left: 50px;
width: 800px;
box-shadow: rgba(17, 17, 26, 0.1) 0px 4px 16px, rgba(17, 17, 26, 0.1) 0px 8px 24px, rgba(17, 17, 26, 0.1) 0px 16px 56px;
}
#print
{
background-color: #fff;
padding: 30px 50px;
height: 1120px;
<label>Profile:</label>
<textarea id="profile" placeholder="Write about yourself"></textarea>

}
<label>Email:</label>
<input type="email" id="email" placeholder="Enter your email">

<label>Contact Number:</label>
<input type="tel" id="contact" placeholder="Enter your contact number">

<label>Location:</label>
<input type="text" id="location" placeholder="Enter your location">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Associate Labels with Inputs for Accessibility

The <label> elements are not associated with their corresponding form controls using the for attribute. This affects accessibility, especially for users relying on screen readers. Ensure each <label> has a for attribute matching the id of its associated input element.

Example fix:

-<label>Name:</label>
-<input type="text" id="name" placeholder="Enter your name">
+<label for="name">Name:</label>
+<input type="text" id="name" placeholder="Enter your name">

-<label>Profile:</label>
-<textarea id="profile" placeholder="Write about yourself"></textarea>
+<label for="profile">Profile:</label>
+<textarea id="profile" placeholder="Write about yourself"></textarea>

-<label>Email:</label>
-<input type="email" id="email" placeholder="Enter your email">
+<label for="email">Email:</label>
+<input type="email" id="email" placeholder="Enter your email">

-<label>Contact Number:</label>
-<input type="tel" id="contact" placeholder="Enter your contact number">
+<label for="contact">Contact Number:</label>
+<input type="tel" id="contact" placeholder="Enter your contact number">

-<label>Location:</label>
-<input type="text" id="location" placeholder="Enter your location">
+<label for="location">Location:</label>
+<input type="text" id="location" placeholder="Enter your location">

Apply similar changes to all other labels and inputs throughout the form.

Also applies to: 71-85, 102-116, 136-147, 155-156

Comment on lines +78 to +81
<input type="text" placeholder="Start Year">

<label>End Year:</label>
<input type="text" placeholder="End Year">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use Appropriate Input Types for Year Fields

The Start Year and End Year input fields are using type="text". Consider using type="number" or type="date" for better input validation and user experience.

Apply this diff:

-<input type="text" placeholder="Start Year">
+<input type="number" placeholder="Start Year">

-<input type="text" placeholder="End Year">
+<input type="number" placeholder="End Year">

Also applies to: 109-112

Comment on lines +173 to +199
return Array.from(document.querySelectorAll('.education-entry')).map(entry => ({
institute: entry.querySelector('input[placeholder="Enter institute name"]').value,
course: entry.querySelector('input[placeholder="Enter course name"]').value,
startYear: entry.querySelector('input[placeholder="Start Year"]').value,
endYear: entry.querySelector('input[placeholder="End Year"]').value,
score: entry.querySelector('input[placeholder="Score/Grade"]').value,
}));
}

function collectExperienceData() {
return Array.from(document.querySelectorAll('.experience-entry')).map(entry => ({
jobPosition: entry.querySelector('input[placeholder="Enter job position"]').value,
companyName: entry.querySelector('input[placeholder="Enter company name"]').value,
startYear: entry.querySelector('input[placeholder="Start Year"]').value,
endYear: entry.querySelector('input[placeholder="End Year"]').value,
description: entry.querySelector('textarea[placeholder="Describe your job experience"]').value,
}));
}

function collectProjectData() {
return Array.from(document.querySelectorAll('.project-entry')).map(entry => ({
title: entry.querySelector('input[placeholder="Enter project title"]').value,
description: entry.querySelector('textarea[placeholder="Describe the project"]').value,
responsibilities: entry.querySelector('textarea[placeholder="Describe your role"]').value,
link: entry.querySelector('input[placeholder="Enter project link"]').value,
}));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Lack of Validation for Dynamically Added Entries

The collected data from education, experience, and project entries does not undergo validation, which might result in incomplete or incorrect resume sections.

Implement validation for the dynamically added entries to ensure all necessary fields are filled.

};

// Generate and download the PDF
html2pdf().from(resumeElement).set(options).save();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Error Handling for PDF Generation

If an error occurs during PDF generation, the user is not notified, and the application may fail silently.

Implement error handling to catch and inform the user of any issues during PDF generation.

html2pdf().from(resumeElement).set(options).save()
+   .catch(function(error) {
+       alert('An error occurred while generating the PDF: ' + error.message);
+   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
html2pdf().from(resumeElement).set(options).save();
html2pdf().from(resumeElement).set(options).save()
.catch(function(error) {
alert('An error occurred while generating the PDF: ' + error.message);
});

Comment on lines +106 to +108
if (!name || !profile || !email || !contact || !location) {
alert('Please fill out all required fields in Step 1.');
return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Email and Contact Number Format Validation

The validation only checks if fields are filled but doesn't validate the format of the email and contact number, which could lead to incorrect data being submitted.

Enhance the validation to check for proper email and contact number formats using regular expressions.

+ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ const contactPattern = /^\d{10}$/;

if (!name || !profile || !email || !contact || !location) {
    alert('Please fill out all required fields in Step 1.');
    return;
+ } else if (!emailPattern.test(email)) {
+     alert('Please enter a valid email address.');
+     return;
+ } else if (!contactPattern.test(contact)) {
+     alert('Please enter a valid 10-digit contact number.');
+     return;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!name || !profile || !email || !contact || !location) {
alert('Please fill out all required fields in Step 1.');
return;
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const contactPattern = /^\d{10}$/;
if (!name || !profile || !email || !contact || !location) {
alert('Please fill out all required fields in Step 1.');
return;
} else if (!emailPattern.test(email)) {
alert('Please enter a valid email address.');
return;
} else if (!contactPattern.test(contact)) {
alert('Please enter a valid 10-digit contact number.');
return;
}

Comment on lines +74 to +82
function selectTemplate(templateName) {
selectedTemplate = templateName;
console.log("Selected Template: ", selectedTemplate);
document.querySelectorAll('.template-card').forEach(card => {
card.classList.remove('selected');
});
document.querySelector(`[onclick="selectTemplate('${templateName}')"]`).classList.add('selected');
document.getElementById('next-step-2').disabled = false;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Possible DOM Selection Issue in Template Selection

Using document.querySelector([onclick="selectTemplate('${templateName}')"]) assumes that the onclick attribute is used, which may not be reliable if event listeners are attached differently.

Consider adding a unique identifier or data attribute to template cards to select them more reliably.

// Add a data attribute to template cards in HTML:
// <div class="template-card" data-template-name="template1">...</div>

function selectTemplate(templateName) {
    selectedTemplate = templateName;
    console.log("Selected Template: ", selectedTemplate);
    document.querySelectorAll('.template-card').forEach(card => {
        card.classList.remove('selected');
+       if (card.dataset.templateName === templateName) {
+           card.classList.add('selected');
+       }
    });
    document.getElementById('next-step-2').disabled = false;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function selectTemplate(templateName) {
selectedTemplate = templateName;
console.log("Selected Template: ", selectedTemplate);
document.querySelectorAll('.template-card').forEach(card => {
card.classList.remove('selected');
});
document.querySelector(`[onclick="selectTemplate('${templateName}')"]`).classList.add('selected');
document.getElementById('next-step-2').disabled = false;
}
function selectTemplate(templateName) {
selectedTemplate = templateName;
console.log("Selected Template: ", selectedTemplate);
document.querySelectorAll('.template-card').forEach(card => {
card.classList.remove('selected');
if (card.dataset.templateName === templateName) {
card.classList.add('selected');
}
});
document.getElementById('next-step-2').disabled = false;
}

Comment on lines +264 to +266
document.getElementById('reset').addEventListener('click', function() {
location.reload();
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Inefficient Use of location.reload()

Using location.reload() resets the entire application state, which may not be necessary and can be jarring to the user.

Provide a function to reset only the necessary form fields and variables without reloading the page.

document.getElementById('reset').addEventListener('click', function() {
-   location.reload();
+   // Reset form fields
+   document.querySelector('form').reset();
+   // Clear dynamically added sections
+   document.getElementById('education-fields').innerHTML = '';
+   document.getElementById('experience-fields').innerHTML = '';
+   document.getElementById('project-fields').innerHTML = '';
+   // Reset variables
+   selectedTemplate = '';
+   showStep(1);
});

Committable suggestion was skipped due to low confidence.

Comment on lines +2 to +23
document.getElementById('add-education').addEventListener('click', function() {
const educationFields = document.getElementById('education-fields');
const newEducation = document.createElement('div');
newEducation.classList.add('education-entry');
newEducation.innerHTML = `
<label>Institute:</label>
<input type="text" placeholder="Enter institute name">

<label>Course:</label>
<input type="text" placeholder="Enter course name">

<label>Start Year:</label>
<input type="text" placeholder="Start Year">

<label>End Year:</label>
<input type="text" placeholder="End Year">

<label>Score/Grade:</label>
<input type="text" placeholder="Score/Grade">
`;
educationFields.appendChild(newEducation);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Memory Leak Risk in Dynamic Education Sections

The event listener for the 'add-education' button creates new DOM elements but does not provide a way to remove them. This could lead to a buildup of unused DOM nodes if the user adds and removes entries frequently.

Consider adding functionality to remove education entries if needed. Here's a possible enhancement:

+ // Adding a remove button to each education entry
newEducation.innerHTML = `
    <label>Institute:</label>
    <input type="text" placeholder="Enter institute name">
    <!-- other inputs -->
+   <button type="button" class="remove-education">Remove</button>
`;

// Append event listener to remove education entry
+ newEducation.querySelector('.remove-education').addEventListener('click', function() {
+     educationFields.removeChild(newEducation);
+ });

Committable suggestion was skipped due to low confidence.

Comment on lines +26 to +47
document.getElementById('add-experience').addEventListener('click', function() {
const experienceFields = document.getElementById('experience-fields');
const newExperience = document.createElement('div');
newExperience.classList.add('experience-entry');
newExperience.innerHTML = `
<label>Job Position:</label>
<input type="text" placeholder="Enter job position">

<label>Company Name:</label>
<input type="text" placeholder="Enter company name">

<label>Start Year:</label>
<input type="text" placeholder="Start Year">

<label>End Year:</label>
<input type="text" placeholder="End Year">

<label>Description:</label>
<textarea placeholder="Describe your job experience"></textarea>
`;
experienceFields.appendChild(newExperience);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Repeated Code in Dynamic Section Addition Functions

The code for dynamically adding education, experience, and project sections is very similar. This repetition violates the DRY (Don't Repeat Yourself) principle.

Refactor the code to create a generic function for adding new entries, reducing redundancy.

+ function addSection(entryType, fieldsContainerId, entryClass, entryHTML) {
+     const fieldsContainer = document.getElementById(fieldsContainerId);
+     const newEntry = document.createElement('div');
+     newEntry.classList.add(entryClass);
+     newEntry.innerHTML = entryHTML;
+     fieldsContainer.appendChild(newEntry);
+ }

document.getElementById('add-education').addEventListener('click', function() {
    const entryHTML = `
        <!-- Education entry HTML -->
    `;
+   addSection('education', 'education-fields', 'education-entry', entryHTML);
});

document.getElementById('add-experience').addEventListener('click', function() {
    const entryHTML = `
        <!-- Experience entry HTML -->
    `;
+   addSection('experience', 'experience-fields', 'experience-entry', entryHTML);
});

document.getElementById('add-project').addEventListener('click', function() {
    const entryHTML = `
        <!-- Project entry HTML -->
    `;
+   addSection('project', 'project-fields', 'project-entry', entryHTML);
});

Committable suggestion was skipped due to low confidence.

@GarimaSingh0109 GarimaSingh0109 merged commit 874ec9f into GarimaSingh0109:main Oct 21, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants