chore: synchronize project dependencies and update vendor directory files

This commit is contained in:
2026-07-15 13:15:05 +07:00
parent 2ab9f65c99
commit 3203c6e129
10000 changed files with 1501312 additions and 0 deletions
+227
View File
@@ -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');
});
});
});