Auto commit: 2025-09-17T14:30:44.243Z

This commit is contained in:
Flatlogic Bot 2025-09-17 14:30:44 +00:00
parent 9522bc839d
commit 09c227b106
3 changed files with 319 additions and 29 deletions

View File

@ -1,6 +1,130 @@
// MagiCV Custom Scripts // MagiCV Custom Scripts
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
// Future interactivity can be added here.
console.log("MagiCV loaded!"); 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}
<button type="button" class="btn-close btn-close-white ms-2" aria-label="Remove skill"></button>
`;
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();
}); });

View File

@ -58,41 +58,179 @@
<div class="row"> <div class="row">
<!-- Form Section --> <!-- Form Section -->
<div class="col-lg-7"> <div class="col-lg-7">
<form id="cv-form" action="preview.php" method="POST">
<div id="section-personal-details">
<div class="bg-white p-4 p-md-5 rounded-3 shadow-sm"> <div class="bg-white p-4 p-md-5 rounded-3 shadow-sm">
<h1 class="h3 fw-bold mb-4">1. Personal Details</h1> <h1 class="h3 fw-bold mb-4">1. Personal Details</h1>
<p class="text-muted mb-4">Let's start with the basics. This information will appear at the top of your CV.</p> <p class="text-muted mb-4">Let's start with the basics. This information will appear at the top of your CV.</p>
<form>
<div class="mb-3"> <div class="mb-3">
<label for="fullName" class="form-label">Full Name</label> <label for="fullName" class="form-label">Full Name</label>
<input type="text" class="form-control form-control-lg" id="fullName" placeholder="e.g., Jane Doe"> <input type="text" class="form-control form-control-lg" id="fullName" name="fullName" placeholder="e.g., Jane Doe">
</div> </div>
<div class="row g-3 mb-3"> <div class="row g-3 mb-3">
<div class="col-md-6"> <div class="col-md-6">
<label for="email" class="form-label">Email Address</label> <label for="email" class="form-label">Email Address</label>
<input type="email" class="form-control form-control-lg" id="email" placeholder="e.g., jane.doe@email.com"> <input type="email" class="form-control form-control-lg" id="email" name="email" placeholder="e.g., jane.doe@email.com">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label for="phone" class="form-label">Phone Number</label> <label for="phone" class="form-label">Phone Number</label>
<input type="tel" class="form-control form-control-lg" id="phone" placeholder="e.g., (123) 456-7890"> <input type="tel" class="form-control form-control-lg" id="phone" name="phone" placeholder="e.g., (123) 456-7890">
</div> </div>
</div> </div>
<div class="row g-3 mb-4"> <div class="row g-3 mb-4">
<div class="col-md-6"> <div class="col-md-6">
<label for="linkedin" class="form-label">LinkedIn Profile</label> <label for="linkedin" class="form-label">LinkedIn Profile</label>
<input type="url" class="form-control form-control-lg" id="linkedin" placeholder="linkedin.com/in/yourprofile"> <input type="url" class="form-control form-control-lg" id="linkedin" name="linkedin" placeholder="linkedin.com/in/yourprofile">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label for="website" class="form-label">Personal Website <span class="text-muted">(Optional)</span></label> <label for="website" class="form-label">Personal Website <span class="text-muted">(Optional)</span></label>
<input type="url" class="form-control form-control-lg" id="website" placeholder="yourportfolio.com"> <input type="url" class="form-control form-control-lg" id="website" name="website" placeholder="yourportfolio.com">
</div> </div>
</div> </div>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary btn-lg">Next: Experience &rarr;</button> <button type="button" class="btn btn-primary btn-lg" data-next="section-experience">Next: Experience &rarr;</button>
</div>
</div>
</div>
<div id="section-experience" class="d-none">
<!-- Spacer -->
<div class="my-4"></div>
<!-- Experience Section -->
<div class="bg-white p-4 p-md-5 rounded-3 shadow-sm">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="h3 fw-bold mb-0">2. Work Experience</h2>
<button type="button" id="add-experience-btn" class="btn btn-sm btn-outline-primary d-flex align-items-center">
<i data-feather="plus" class="me-1" style="width: 16px; height: 16px;"></i>
Add Experience
</button>
</div>
<p class="text-muted mb-4">Detail your professional history. Start with your most recent job.</p>
<div id="experience-entries">
<!-- Dynamic entries will be inserted here -->
</div>
</div>
<!-- Experience Template -->
<template id="experience-template">
<div class="experience-entry border rounded-3 p-3 mb-3">
<div class="d-flex justify-content-end">
<button type="button" class="btn-close remove-experience-btn" aria-label="Remove"></button>
</div>
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Job Title</label>
<input type="text" name="job_title[]" class="form-control" placeholder="e.g., Senior Product Manager">
</div>
<div class="col-md-6">
<label class="form-label">Company</label>
<input type="text" name="company[]" class="form-control" placeholder="e.g., Google">
</div>
<div class="col-md-6">
<label class="form-label">Start Date</label>
<input type="month" name="job_start_date[]" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">End Date</label>
<input type="month" name="job_end_date[]" class="form-control">
</div>
<div class="col-12">
<label class="form-label">Description</label>
<textarea name="job_description[]" class="form-control" rows="3" placeholder="Describe your responsibilities and achievements."></textarea>
</div>
</div>
</div>
</template>
<!-- Form-wide Actions -->
<div class="d-flex justify-content-between mt-4">
<button type="button" class="btn btn-secondary btn-lg" data-prev="section-personal-details">&larr; Back to Personal Details</button>
<button type="button" class="btn btn-primary btn-lg" data-next="section-education">Next: Education &rarr;</button>
</div>
</div>
<div id="section-education" class="d-none">
<!-- Spacer -->
<div class="my-4"></div>
<!-- Education Section -->
<div class="bg-white p-4 p-md-5 rounded-3 shadow-sm">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="h3 fw-bold mb-0">3. Education</h2>
<button type="button" id="add-education-btn" class="btn btn-sm btn-outline-primary d-flex align-items-center">
<i data-feather="plus" class="me-1" style="width: 16px; height: 16px;"></i>
Add Education
</button>
</div>
<p class="text-muted mb-4">List your academic background.</p>
<div id="education-entries">
<!-- Dynamic entries will be inserted here -->
</div>
</div>
<!-- Education Template -->
<template id="education-template">
<div class="education-entry border rounded-3 p-3 mb-3">
<div class="d-flex justify-content-end">
<button type="button" class="btn-close remove-education-btn" aria-label="Remove"></button>
</div>
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">School / University</label>
<input type="text" name="school[]" class="form-control" placeholder="e.g., Harvard University">
</div>
<div class="col-md-6">
<label class="form-label">Degree & Field of Study</label>
<input type="text" name="degree[]" class="form-control" placeholder="e.g., B.S. in Computer Science">
</div>
<div class="col-md-6">
<label class="form-label">Start Date</label>
<input type="month" name="edu_start_date[]" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">End Date</label>
<input type="month" name="edu_end_date[]" class="form-control">
</div>
</div>
</div>
</template>
<!-- Form-wide Actions -->
<div class="d-flex justify-content-between mt-4">
<button type="button" class="btn btn-secondary btn-lg" data-prev="section-experience">&larr; Back to Experience</button>
<button type="button" class="btn btn-primary btn-lg" data-next="section-skills">Next: Skills &rarr;</button>
</div>
</div>
<div id="section-skills" class="d-none">
<!-- Spacer -->
<div class="my-4"></div>
<!-- Skills Section -->
<div class="bg-white p-4 p-md-5 rounded-3 shadow-sm">
<h2 class="h3 fw-bold mb-4">4. Skills</h2>
<p class="text-muted mb-4">Highlight your key skills. Add them one by one.</p>
<div class="input-group mb-3">
<input type="text" id="skill-input" class="form-control form-control-lg" placeholder="e.g., JavaScript">
<button class="btn btn-outline-primary" type="button" id="add-skill-btn">Add Skill</button>
</div>
<div id="skills-list" class="d-flex flex-wrap gap-2">
<!-- Skills will be added here as badges -->
</div>
<input type="hidden" name="skills" id="skills-hidden-input">
</div>
<!-- Form-wide Actions -->
<div class="d-flex justify-content-between mt-4">
<button type="button" class="btn btn-secondary btn-lg" data-prev="section-education">&larr; Back to Education</button>
<button type="submit" class="btn btn-success btn-lg">Finish & Preview &rarr;</button>
</div>
</div> </div>
</form> </form>
</div>
</div>
<!-- Preview Section (Placeholder) --> <!-- Preview Section (Placeholder) -->
<div class="col-lg-5 d-none d-lg-block"> <div class="col-lg-5 d-none d-lg-block">

28
preview.php Normal file
View File

@ -0,0 +1,28 @@
<?php
// preview.php
// This is a placeholder for the CV preview.
// In a real application, you would use this data to populate a template.
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CV Preview - MagiCV</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body class="bg-light-gray">
<div class="container mt-5">
<div class="bg-white p-4 p-md-5 rounded-3 shadow-sm">
<h1 class="h3 fw-bold mb-4">CV Preview</h1>
<p class="text-muted mb-4">This is a preview of the data you entered. The final CV will be styled based on the template you choose.</p>
<h2 class="h4 fw-bold mt-5">Personal Details</h2>
<pre><?php print_r($_POST); ?></pre>
</div>
</div>
</body>
</html>