diff --git a/backend/public/assets/javascripts/main.js b/backend/public/assets/javascripts/main.js index c85afe1..7df769c 100644 --- a/backend/public/assets/javascripts/main.js +++ b/backend/public/assets/javascripts/main.js @@ -149,35 +149,33 @@ let resumeButton = document.getElementById("resume-button"); // Generate PDF with html2pdf.js function generateResume() { // PDF filename change depending of the light/dark mode - if (document.body.classList.contains(darkTheme)) { - // html2pdf.js options - let opt = { - margin: 0, - filename: 'myResumeCV-dark.pdf', - image: { type: 'jpeg', quality: 0.98 }, - html2canvas: { scale: 4, useCORS: true }, - jsPDF: { format: 'a4', orientation: 'portrait' } - }; - html2pdf(areaCV, opt); - } else { - // html2pdf.js options - let opt = { - margin: 0, - filename: 'myResumeCV-light.pdf', - image: { type: 'jpeg', quality: 0.98 }, - html2canvas: { scale: 4, useCORS: true }, - jsPDF: { format: 'a4', orientation: 'portrait' } - }; - html2pdf(areaCV, opt); - } + let theme = document.body.classList.contains(darkTheme) ? 'dark' : 'light'; + + // html2pdf.js options + let opt = { + margin: 0, + filename: 'myResumeCV-' + theme + '.pdf', + image: { type: 'jpeg', quality: 0.98 }, + html2canvas: { scale: 4, useCORS: true }, + jsPDF: { format: 'a4', orientation: 'portrait' }, + pagebreak: { mode: 'css', avoid: ['.experience_content', '.education_content', '.section-title'] } + }; + + return html2pdf().set(opt).from(areaCV).toContainer().then(function () { + // Stretch the copy being rendered to a whole number of pages, so the + // left column background reaches the bottom of the last page. + // 1px less avoids a blank extra page from rounding. + let pageHeight = this.prop.pageSize.inner.px.height; + let resume = this.prop.container.firstElementChild; + let pages = Math.ceil(resume.offsetHeight / pageHeight); + resume.style.minHeight = (Math.floor(pages * pageHeight) - 1) + 'px'; + }).save(); } // Action executed by clicking on the button => generation of the final PDF CV CV resumeButton.addEventListener("click", () => { // Adapt the area of the PDF addScaleCV(); - // Generate the PDF - generateResume(); - // Remove adaptation after 1 second (you can choose to set more than 1 second if your PDF download time is long) - setTimeout(removeScaleCV, 1000); + // Generate the PDF, then remove the adaptation once it is saved + generateResume().finally(removeScaleCV); }); \ No newline at end of file diff --git a/backend/public/assets/stylesheets/style.css b/backend/public/assets/stylesheets/style.css index 6783cfd..3becfd8 100644 --- a/backend/public/assets/stylesheets/style.css +++ b/backend/public/assets/stylesheets/style.css @@ -123,7 +123,20 @@ body.scale-cv { } .scale-cv .resume { - height: 1122px; + /* At least one A4 page; grows so html2pdf can split it onto more pages */ + min-height: 1122px; +} + +/* Keep entries and section titles together when breaking to a new page */ +.scale-cv .experience_content, +.scale-cv .education_content, +.scale-cv .section-title { + break-inside: avoid; +} + +/* Put
in the template to start a new PDF page there */ +.page-break { + break-before: page; } .scale-cv .resume_left { diff --git a/backend/userKnowledge.json b/backend/userKnowledge.json index 8123cba..3f66792 100644 --- a/backend/userKnowledge.json +++ b/backend/userKnowledge.json @@ -6,7 +6,7 @@ "birth": "14, November, 2000", "living_location": "Ljubljana, Slovenia", "web_link": "https://petrovv.com", - "git_link": "https://git.petrovv.com/explore", + "git_link": "https://git.petrovv.com", "email": "nikola@petrovv.com", "instagram_handle": "@nikolainsta7", "instagram_link": "https://www.instagram.com/nikolainsta7", diff --git a/backend/views/cv2.hbs b/backend/views/cv2.hbs index e3a984b..0d57853 100644 --- a/backend/views/cv2.hbs +++ b/backend/views/cv2.hbs @@ -215,7 +215,9 @@ - + + +