chore: synchronize project dependencies and update vendor directory files
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const leftSection = document.querySelector('.left-section');
|
||||
const rightSection = document.querySelector('.right-section');
|
||||
|
||||
Sortable.create(leftSection, {
|
||||
group: 'sections',
|
||||
draggable: '.draggable-section',
|
||||
handle: 'h2',
|
||||
animation: 150
|
||||
});
|
||||
|
||||
Sortable.create(rightSection, {
|
||||
group: 'sections',
|
||||
draggable: '.draggable-section',
|
||||
handle: 'h2',
|
||||
animation: 150
|
||||
});
|
||||
|
||||
const addButtons = document.querySelectorAll('.add-item');
|
||||
addButtons.forEach(button => {
|
||||
button.addEventListener('click', function () {
|
||||
const listId = this.dataset.list;
|
||||
const listElement = document.querySelector(`.editable-list[data-field="${listId}"]`);
|
||||
if (listElement) {
|
||||
const newItem = document.createElement('li');
|
||||
newItem.classList.add('editable-item');
|
||||
let innerHTML = '';
|
||||
if (listId === 'skills') {
|
||||
innerHTML = `<label>
|
||||
<i class="fas fa-check"></i>
|
||||
</label>
|
||||
<input type="text" class="editable" placeholder="Kỹ năng mới"><button class="remove-item">×<span class="sr-only">Xóa</span></button>`;
|
||||
} else if (listId === 'experiences') {
|
||||
innerHTML = `
|
||||
<div>
|
||||
<input type="text" class="editable" data-field="job_title" placeholder="Vị trí">
|
||||
<input type="text" class="editable" data-field="company" placeholder="Công ty">
|
||||
<div class="date-range">
|
||||
<input type="text" class="editable" data-field="start_date"
|
||||
placeholder="Từ ngày">
|
||||
<input type="text" class="editable" data-field="end_date"
|
||||
placeholder="Đến ngày">
|
||||
</div>
|
||||
<textarea class="editable" data-field="description" placeholder="Mô tả công việc"></textarea>
|
||||
</div>
|
||||
<button class="remove-item">×<span class="sr-only">Xóa</span></button>
|
||||
`;
|
||||
} else if (listId === 'educations') {
|
||||
innerHTML = `
|
||||
<div>
|
||||
<input type="text" class="editable" data-field="degree" placeholder="Bằng cấp">
|
||||
<input type="text" class="editable" data-field="institution" placeholder="Trường/Trung tâm">
|
||||
<input type="text" class="editable" data-field="duration" placeholder="Thời gian">
|
||||
<textarea class="editable" data-field="description" placeholder="Mô tả"></textarea>
|
||||
</div>
|
||||
<button class="remove-item">×<span class="sr-only">Xóa</span></button>
|
||||
`;
|
||||
} else if (listId == 'awards') {
|
||||
innerHTML = `
|
||||
<input type="text" class="editable" value="Giải thưởng mới">
|
||||
<button class="remove-item">×<span class="sr-only">Xóa</span></button>
|
||||
`;
|
||||
} else if (listId == 'certifications') {
|
||||
innerHTML = `
|
||||
<input type="text" class="editable" value="Chứng chỉ mới">
|
||||
<button class="remove-item">×<span class="sr-only">Xóa</span></button>
|
||||
`;
|
||||
} else if (listId == 'activities') {
|
||||
innerHTML = `
|
||||
<input type="text" class="editable" value="Hoạt động mới">
|
||||
<button class="remove-item">×<span class="sr-only">Xóa</span></button>
|
||||
`;
|
||||
}
|
||||
newItem.innerHTML = innerHTML;
|
||||
listElement.appendChild(newItem);
|
||||
addRemoveButtonListener(newItem.querySelector('.remove-item'));
|
||||
|
||||
// Khởi tạo lại Sortable cho danh sách đã cập nhật
|
||||
Sortable.create(listElement, {
|
||||
group: listElement.dataset.field,
|
||||
draggable: '.editable-item',
|
||||
animation: 150
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function addRemoveButtonListener(button) {
|
||||
button.addEventListener('click', function () {
|
||||
this.parentNode.remove();
|
||||
});
|
||||
}
|
||||
|
||||
const editableLists = document.querySelectorAll('.editable-list');
|
||||
editableLists.forEach(list => {
|
||||
Sortable.create(list, {
|
||||
group: list.dataset.field,
|
||||
draggable: '.editable-item',
|
||||
animation: 150
|
||||
});
|
||||
|
||||
const items = list.querySelectorAll('.editable-item');
|
||||
items.forEach(item => {
|
||||
const removeButton = item.querySelector('.remove-item');
|
||||
if (removeButton) {
|
||||
addRemoveButtonListener(removeButton);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const saveCvButton = document.getElementById('save-cv');
|
||||
saveCvButton.addEventListener('click', () => {
|
||||
const formData = new FormData();
|
||||
|
||||
// Thu thập dữ liệu văn bản
|
||||
const personalInfoElements = document.querySelectorAll('#personal-info .editable');
|
||||
personalInfoElements.forEach(item => {
|
||||
formData.append(`personalInfo[${item.dataset.field}]`, item.value);
|
||||
});
|
||||
|
||||
const skillElements = document.querySelectorAll('#skills .editable-item > input.editable');
|
||||
skillElements.forEach(item => {
|
||||
formData.append('skills[]', item.value);
|
||||
});
|
||||
|
||||
const experienceElements = document.querySelectorAll('#experience .editable-item');
|
||||
experienceElements.forEach((item, index) => {
|
||||
item.querySelectorAll('.editable').forEach(editable => {
|
||||
formData.append(`experiences[${index}][${editable.dataset.field}]`, editable.value || editable.textContent);
|
||||
});
|
||||
});
|
||||
|
||||
const educationElements = document.querySelectorAll('#education .editable-item');
|
||||
educationElements.forEach((item, index) => {
|
||||
item.querySelectorAll('.editable').forEach(editable => {
|
||||
formData.append(`educations[${index}][${editable.dataset.field}]`, editable.value || editable.textContent);
|
||||
});
|
||||
});
|
||||
|
||||
const awardsElements = document.querySelectorAll('#awards .editable-item > input.editable');
|
||||
awardsElements.forEach(item => {
|
||||
formData.append('awards[]', item.value);
|
||||
});
|
||||
|
||||
const certificationsElements = document.querySelectorAll('#certifications .editable-item > input.editable');
|
||||
certificationsElements.forEach(item => {
|
||||
formData.append('certifications[]', item.value);
|
||||
});
|
||||
|
||||
const activitiesElements = document.querySelectorAll('#activities .editable-item > input.editable');
|
||||
activitiesElements.forEach(item => {
|
||||
formData.append('activities[]', item.value);
|
||||
});
|
||||
|
||||
|
||||
// Thu thập file avatar
|
||||
var fileInput = $('#avatar-upload')[0];
|
||||
var file = fileInput.files[0];
|
||||
if (file) {
|
||||
formData.append('avatar', file, file.name); // 'avatar' là tên input file ở server
|
||||
}
|
||||
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||||
let update_cv_route = $('#update_cv_route').val();
|
||||
fetch(update_cv_route, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
},
|
||||
body: formData, // Gửi FormData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
alert(data.error);
|
||||
} else {
|
||||
alert("Cập nhật CV thành công");
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
alert(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// ... (phần code JavaScript hiện tại của bạn) ...
|
||||
|
||||
const avatarUpload = document.getElementById('avatar-upload');
|
||||
const avatarPreview = document.getElementById('avatar-preview');
|
||||
|
||||
avatarUpload.addEventListener('change', function () {
|
||||
const file = this.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
avatarPreview.src = e.target.result;
|
||||
avatarPreview.style.display = 'block'; // Hiển thị ảnh sau khi tải
|
||||
}
|
||||
reader.readAsDataURL(file); // Đọc dữ liệu ảnh dưới dạng base64
|
||||
} else {
|
||||
avatarPreview.src = '#';
|
||||
avatarPreview.style.display = 'none'; // Ẩn ảnh nếu không có file nào được chọn
|
||||
}
|
||||
});
|
||||
|
||||
const exportPdfButton = document.getElementById('export-pdf');
|
||||
const cvContainer = document.querySelector('.cv-container');
|
||||
|
||||
exportPdfButton.addEventListener('click', () => {
|
||||
const { jsPDF } = window.jspdf;
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
const element = document.querySelector('.cv-container');
|
||||
|
||||
html2canvas(element).then(canvas => {
|
||||
const imgData = canvas.toDataURL('image/png');
|
||||
const pageWidth = pdf.internal.pageSize.getWidth();
|
||||
const pageHeight = pdf.internal.pageSize.getHeight();
|
||||
|
||||
const imgWidth = pageWidth;
|
||||
const imgHeight = canvas.height * imgWidth / canvas.width;
|
||||
|
||||
pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
|
||||
pdf.save('cv.pdf');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user