From 09c227b106cd6e87bfcad79f544d363e7390e65d Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 17 Sep 2025 14:30:44 +0000 Subject: [PATCH] Auto commit: 2025-09-17T14:30:44.243Z --- assets/js/main.js | 126 +++++++++++++++++++++++++++++- create.php | 194 +++++++++++++++++++++++++++++++++++++++------- preview.php | 28 +++++++ 3 files changed, 319 insertions(+), 29 deletions(-) create mode 100644 preview.php diff --git a/assets/js/main.js b/assets/js/main.js index ed873ab..1c5ada1 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,6 +1,130 @@ // MagiCV Custom Scripts document.addEventListener('DOMContentLoaded', function () { - // Future interactivity can be added here. console.log("MagiCV loaded!"); + + const experienceContainer = document.getElementById('experience-entries'); + const addExperienceBtn = document.getElementById('add-experience-btn'); + const experienceTemplate = document.getElementById('experience-template'); + + if (addExperienceBtn && experienceContainer && experienceTemplate) { + addExperienceBtn.addEventListener('click', () => { + const clone = experienceTemplate.content.cloneNode(true); + experienceContainer.appendChild(clone); + updateRemoveButtons(); + }); + } + + function updateRemoveButtons() { + const removeButtons = experienceContainer.querySelectorAll('.remove-experience-btn'); + removeButtons.forEach(button => { + button.removeEventListener('click', handleRemoveClick); // Avoid double-binding + button.addEventListener('click', handleRemoveClick); + }); + } + + function handleRemoveClick(event) { + const entry = event.target.closest('.experience-entry'); + if (entry) { + entry.remove(); + } + } + + // Initial call to bind to any existing entries + updateRemoveButtons(); + + const educationContainer = document.getElementById('education-entries'); + const addEducationBtn = document.getElementById('add-education-btn'); + const educationTemplate = document.getElementById('education-template'); + + if (addEducationBtn && educationContainer && educationTemplate) { + addEducationBtn.addEventListener('click', () => { + const clone = educationTemplate.content.cloneNode(true); + educationContainer.appendChild(clone); + updateRemoveEducationButtons(); + }); + } + + function updateRemoveEducationButtons() { + const removeButtons = educationContainer.querySelectorAll('.remove-education-btn'); + removeButtons.forEach(button => { + button.removeEventListener('click', handleRemoveEducationClick); // Avoid double-binding + button.addEventListener('click', handleRemoveEducationClick); + }); + } + + function handleRemoveEducationClick(event) { + const entry = event.target.closest('.education-entry'); + if (entry) { + entry.remove(); + } + } + + // Initial call to bind to any existing entries + updateRemoveEducationButtons(); + + const skillInput = document.getElementById('skill-input'); + const addSkillBtn = document.getElementById('add-skill-btn'); + const skillsList = document.getElementById('skills-list'); + const skillsHiddenInput = document.getElementById('skills-hidden-input'); + + if (addSkillBtn && skillInput && skillsList) { + addSkillBtn.addEventListener('click', addSkill); + skillInput.addEventListener('keypress', function (e) { + if (e.key === 'Enter') { + e.preventDefault(); // prevent form submission + addSkill(); + } + }); + } + + function addSkill() { + const skillText = skillInput.value.trim(); + if (skillText !== "") { + const skillBadge = document.createElement('span'); + skillBadge.className = 'badge bg-primary d-flex align-items-center fs-6'; + skillBadge.innerHTML = ` + ${skillText} + + `; + + skillBadge.querySelector('button').addEventListener('click', function() { + skillBadge.remove(); + updateSkillsInput(); + }); + + skillsList.appendChild(skillBadge); + updateSkillsInput(); + skillInput.value = ""; + skillInput.focus(); + } + } + + function updateSkillsInput() { + const skills = Array.from(skillsList.querySelectorAll('.badge')).map(badge => badge.innerText.trim()); + skillsHiddenInput.value = skills.join(','); + } + + // Section navigation + const form = document.getElementById('cv-form'); + const sections = form.querySelectorAll('[id^="section-"]'); + const navButtons = form.querySelectorAll('[data-next], [data-prev]'); + + navButtons.forEach(button => { + button.addEventListener('click', () => { + const currentSection = button.closest('[id^="section-"]'); + const targetSectionId = button.dataset.next || button.dataset.prev; + const targetSection = document.getElementById(targetSectionId); + + if (currentSection && targetSection) { + currentSection.classList.add('d-none'); + targetSection.classList.remove('d-none'); + window.scrollTo(0, 0); + } + }); + }); + + // Add a default experience and education entry on page load + addExperienceBtn.click(); + addEducationBtn.click(); }); diff --git a/create.php b/create.php index a99d011..2a00669 100644 --- a/create.php +++ b/create.php @@ -58,41 +58,179 @@
-
-

1. Personal Details

-

Let's start with the basics. This information will appear at the top of your CV.

- -
-
- - -
-
-
- - + +
+
+

1. Personal Details

+

Let's start with the basics. This information will appear at the top of your CV.

+ +
+ +
-
- - +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
-
-
- - +
+ +
+ +
+ + +
+
+

2. Work Experience

+
-
- - +

Detail your professional history. Start with your most recent job.

+ +
+
-
- + + + + + +
+ +
- -
-
+
+ +
+ +
+ + +
+
+

3. Education

+ +
+

List your academic background.

+ +
+ +
+
+ + + + + +
+ + +
+
+ +
+ +
+ + +
+

4. Skills

+

Highlight your key skills. Add them one by one.

+
+ + +
+
+ +
+ +
+ + +
+ + +
+
+
diff --git a/preview.php b/preview.php new file mode 100644 index 0000000..4ef3f33 --- /dev/null +++ b/preview.php @@ -0,0 +1,28 @@ + + + + + + CV Preview - MagiCV + + + + +
+
+

CV Preview

+

This is a preview of the data you entered. The final CV will be styled based on the template you choose.

+ +

Personal Details

+
+ +
+
+ +