diff --git a/src/components/App/App.js b/src/components/App/App.js index 761ee40f..8815f7e6 100644 --- a/src/components/App/App.js +++ b/src/components/App/App.js @@ -10,6 +10,7 @@ import RightSidebar from '../RightSidebar/RightSidebar'; import templates from '../../templates'; import PageController from '../../shared/PageController'; +import PrintDialog from '../../shared/PrintDialog'; const App = () => { const pageRef = useRef(null); @@ -36,7 +37,7 @@ const App = () => {
-
+
{ style={{ outline: 'none' }} >
- {templates.find(x => theme.layout.toLowerCase() === x.key).component()} + {templates.find((x) => theme.layout.toLowerCase() === x.key).component()}
@@ -56,6 +57,8 @@ const App = () => {
+ +
); diff --git a/src/components/RightSidebar/tabs/Actions.js b/src/components/RightSidebar/tabs/Actions.js index 5fdb69ab..cddbf6b8 100644 --- a/src/components/RightSidebar/tabs/Actions.js +++ b/src/components/RightSidebar/tabs/Actions.js @@ -1,15 +1,16 @@ /* eslint-disable new-cap */ /* eslint-disable jsx-a11y/anchor-has-content */ /* eslint-disable jsx-a11y/anchor-is-valid */ + import React, { useRef, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import PageContext from '../../../context/PageContext'; -import { importJson, saveAsPdf } from '../../../utils'; +import { importJson } from '../../../utils'; const ActionsTab = ({ data, theme, dispatch }) => { const pageContext = useContext(PageContext); - const { pageRef, panZoomRef } = pageContext; + const { setPrintDialogOpen } = pageContext; const { t } = useTranslation('rightSidebar'); const fileInputRef = useRef(null); @@ -47,7 +48,7 @@ const ActionsTab = ({ data, theme, dispatch }) => { ref={fileInputRef} type="file" className="hidden" - onChange={e => importJson(e, dispatch)} + onChange={(e) => importJson(e, dispatch)} /> @@ -84,7 +85,7 @@ const ActionsTab = ({ data, theme, dispatch }) => { + + +
+ + + ); +}; + +export default PrintDialog; diff --git a/src/templates/castform/Castform.js b/src/templates/castform/Castform.js index 720cb095..157485d0 100644 --- a/src/templates/castform/Castform.js +++ b/src/templates/castform/Castform.js @@ -78,7 +78,7 @@ const Castform = () => { ); - const SkillItem = x => ( + const SkillItem = (x) => (
  • {x}
  • @@ -96,7 +96,7 @@ const Castform = () => { const Objective = () => data.objective && data.objective.enable &&

    {data.objective.body}

    ; - const WorkItem = x => ( + const WorkItem = (x) => (
    @@ -116,11 +116,11 @@ const Castform = () => { data.work.enable && (
    - {data.work.items.filter(x => x.enable).map(WorkItem)} + {data.work.items.filter((x) => x.enable).map(WorkItem)}
    ); - const ReferenceItem = x => ( + const ReferenceItem = (x) => (
    {x.name}
    {x.position} @@ -136,12 +136,12 @@ const Castform = () => {
    - {data.references.items.filter(x => x.enable).map(ReferenceItem)} + {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
    ); - const LanguageItem = x => ( + const LanguageItem = (x) => (
    {x.key}
    @@ -168,12 +168,12 @@ const Castform = () => {
    - {data.languages.items.filter(x => x.enable).map(LanguageItem)} + {data.languages.items.filter((x) => x.enable).map(LanguageItem)}
    ); - const EducationItem = x => ( + const EducationItem = (x) => (
    @@ -196,11 +196,11 @@ const Castform = () => { data.education.enable && (
    - {data.education.items.filter(x => x.enable).map(EducationItem)} + {data.education.items.filter((x) => x.enable).map(EducationItem)}
    ); - const AwardItem = x => ( + const AwardItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -213,11 +213,11 @@ const Castform = () => { data.awards.enable && (
    - {data.awards.items.filter(x => x.enable).map(AwardItem)} + {data.awards.items.filter((x) => x.enable).map(AwardItem)}
    ); - const CertificationItem = x => ( + const CertificationItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -230,11 +230,11 @@ const Castform = () => { data.certifications.enable && (
    - {data.certifications.items.filter(x => x.enable).map(CertificationItem)} + {data.certifications.items.filter((x) => x.enable).map(CertificationItem)}
    ); - const ExtraItem = x => ( + const ExtraItem = (x) => (
    {x.key}
    {x.value}
    @@ -246,7 +246,7 @@ const Castform = () => { data.extras.enable && (
    - {data.extras.items.filter(x => x.enable).map(ExtraItem)} + {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
    ); @@ -260,7 +260,7 @@ const Castform = () => { >
    {
    ); - const SkillItem = x => ( + const SkillItem = (x) => (
  • {x}
  • @@ -78,7 +78,7 @@ const Gengar = () => {
    ); - const EducationItem = x => ( + const EducationItem = (x) => (
    @@ -109,11 +109,11 @@ const Gengar = () => { data.education.enable && (
    - {data.education.items.filter(x => x.enable).map(EducationItem)} + {data.education.items.filter((x) => x.enable).map(EducationItem)}
    ); - const CertificationItem = x => ( + const CertificationItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -126,11 +126,11 @@ const Gengar = () => { data.certifications.enable && (
    - {data.certifications.items.filter(x => x.enable).map(CertificationItem)} + {data.certifications.items.filter((x) => x.enable).map(CertificationItem)}
    ); - const AwardItem = x => ( + const AwardItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -143,11 +143,11 @@ const Gengar = () => { data.awards.enable && (
    - {data.awards.items.filter(x => x.enable).map(AwardItem)} + {data.awards.items.filter((x) => x.enable).map(AwardItem)}
    ); - const ReferenceItem = x => ( + const ReferenceItem = (x) => (
    {x.name}
    {x.position} @@ -163,12 +163,12 @@ const Gengar = () => {
    - {data.references.items.filter(x => x.enable).map(ReferenceItem)} + {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
    ); - const WorkItem = x => ( + const WorkItem = (x) => (
    @@ -188,11 +188,11 @@ const Gengar = () => { data.work.enable && (
    - {data.work.items.filter(x => x.enable).map(WorkItem)} + {data.work.items.filter((x) => x.enable).map(WorkItem)}
    ); - const LanguageItem = x => ( + const LanguageItem = (x) => (
    {x.key}
    @@ -210,11 +210,11 @@ const Gengar = () => { data.languages.enable && (
    -
    {data.languages.items.filter(x => x.enable).map(LanguageItem)}
    +
    {data.languages.items.filter((x) => x.enable).map(LanguageItem)}
    ); - const ExtraItem = x => ( + const ExtraItem = (x) => (
    {x.key}
    {x.value}
    @@ -227,7 +227,7 @@ const Gengar = () => {
    - {data.extras.items.filter(x => x.enable).map(ExtraItem)} + {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
    ); diff --git a/src/templates/glalie/Glalie.js b/src/templates/glalie/Glalie.js index 98bda52c..07966428 100644 --- a/src/templates/glalie/Glalie.js +++ b/src/templates/glalie/Glalie.js @@ -95,7 +95,7 @@ const Glalie = () => {
    ); - const WorkItem = x => ( + const WorkItem = (x) => (
    @@ -114,11 +114,11 @@ const Glalie = () => { data.work.enable && (
    - {data.work.items.filter(x => x.enable).map(WorkItem)} + {data.work.items.filter((x) => x.enable).map(WorkItem)}
    ); - const EducationItem = x => ( + const EducationItem = (x) => (
    {x.name}
    @@ -137,12 +137,12 @@ const Glalie = () => {
    - {data.education.items.filter(x => x.enable).map(EducationItem)} + {data.education.items.filter((x) => x.enable).map(EducationItem)}
    ); - const AwardItem = x => ( + const AwardItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -155,11 +155,11 @@ const Glalie = () => { data.awards.enable && (
    - {data.awards.items.filter(x => x.enable).map(AwardItem)} + {data.awards.items.filter((x) => x.enable).map(AwardItem)}
    ); - const CertificationItem = x => ( + const CertificationItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -172,11 +172,11 @@ const Glalie = () => { data.certifications.enable && (
    - {data.certifications.items.filter(x => x.enable).map(CertificationItem)} + {data.certifications.items.filter((x) => x.enable).map(CertificationItem)}
    ); - const SkillItem = x => ( + const SkillItem = (x) => (
  • {x}
  • @@ -191,7 +191,7 @@ const Glalie = () => {
    ); - const LanguageItem = x => ( + const LanguageItem = (x) => (
    {x.key}
    @@ -209,11 +209,13 @@ const Glalie = () => { data.languages.enable && (
    -
    {data.languages.items.filter(x => x.enable).map(LanguageItem)}
    +
    + {data.languages.items.filter((x) => x.enable).map(LanguageItem)} +
    ); - const ReferenceItem = x => ( + const ReferenceItem = (x) => (
    {x.name}
    {x.position} @@ -229,12 +231,12 @@ const Glalie = () => {
    - {data.references.items.filter(x => x.enable).map(ReferenceItem)} + {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
    ); - const ExtraItem = x => ( + const ExtraItem = (x) => ( {x.key} {x.value} @@ -247,7 +249,7 @@ const Glalie = () => {
    - {data.extras.items.filter(x => x.enable).map(ExtraItem)} + {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
    ); diff --git a/src/templates/onyx/Onyx.js b/src/templates/onyx/Onyx.js index 8ee8a6f2..e8eeef7b 100644 --- a/src/templates/onyx/Onyx.js +++ b/src/templates/onyx/Onyx.js @@ -60,7 +60,7 @@ const Onyx = () => {
    ); - const WorkItem = x => ( + const WorkItem = (x) => (
    @@ -80,11 +80,11 @@ const Onyx = () => { data.work.enable && (
    - {data.work.items.filter(x => x.enable).map(WorkItem)} + {data.work.items.filter((x) => x.enable).map(WorkItem)}
    ); - const EducationItem = x => ( + const EducationItem = (x) => (
    @@ -107,11 +107,11 @@ const Onyx = () => { data.education.enable && (
    - {data.education.items.filter(x => x.enable).map(EducationItem)} + {data.education.items.filter((x) => x.enable).map(EducationItem)}
    ); - const AwardItem = x => ( + const AwardItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -124,11 +124,11 @@ const Onyx = () => { data.awards.enable && (
    - {data.awards.items.filter(x => x.enable).map(AwardItem)} + {data.awards.items.filter((x) => x.enable).map(AwardItem)}
    ); - const CertificationItem = x => ( + const CertificationItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -141,11 +141,11 @@ const Onyx = () => { data.certifications.enable && (
    - {data.certifications.items.filter(x => x.enable).map(CertificationItem)} + {data.certifications.items.filter((x) => x.enable).map(CertificationItem)}
    ); - const SkillItem = x => ( + const SkillItem = (x) => ( {
    ); - const LanguageItem = x => ( + const LanguageItem = (x) => (
    {x.key}
    @@ -185,11 +185,13 @@ const Onyx = () => { data.languages.enable && (
    -
    {data.languages.items.filter(x => x.enable).map(LanguageItem)}
    +
    + {data.languages.items.filter((x) => x.enable).map(LanguageItem)} +
    ); - const ReferenceItem = x => ( + const ReferenceItem = (x) => (
    {x.name}
    {x.position} @@ -205,12 +207,12 @@ const Onyx = () => {
    - {data.references.items.filter(x => x.enable).map(ReferenceItem)} + {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
    ); - const ExtraItem = x => ( + const ExtraItem = (x) => ( {x.key} {x.value} @@ -223,7 +225,7 @@ const Onyx = () => {
    - {data.extras.items.filter(x => x.enable).map(ExtraItem)} + {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
    ); diff --git a/src/templates/pikachu/Pikachu.js b/src/templates/pikachu/Pikachu.js index ea6ad9aa..40a8c741 100644 --- a/src/templates/pikachu/Pikachu.js +++ b/src/templates/pikachu/Pikachu.js @@ -58,7 +58,7 @@ const Pikachu = () => {
    ); - const SkillItem = x => ( + const SkillItem = (x) => ( {
    ); - const ReferenceItem = x => ( + const ReferenceItem = (x) => (
    {x.name}
    {x.position} @@ -92,12 +92,12 @@ const Pikachu = () => {
    - {data.references.items.filter(x => x.enable).map(ReferenceItem)} + {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
    ); - const LanguageItem = x => ( + const LanguageItem = (x) => (
    {x.key}
    @@ -115,11 +115,11 @@ const Pikachu = () => { data.languages.enable && (
    -
    {data.languages.items.filter(x => x.enable).map(LanguageItem)}
    +
    {data.languages.items.filter((x) => x.enable).map(LanguageItem)}
    ); - const ExtraItem = x => ( + const ExtraItem = (x) => (
    {x.key}
    {x.value}
    @@ -132,12 +132,12 @@ const Pikachu = () => {
    - {data.extras.items.filter(x => x.enable).map(ExtraItem)} + {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
    ); - const WorkItem = x => ( + const WorkItem = (x) => (
    @@ -158,12 +158,12 @@ const Pikachu = () => {
    - {data.work.items.filter(x => x.enable).map(WorkItem)} + {data.work.items.filter((x) => x.enable).map(WorkItem)}
    ); - const EducationItem = x => ( + const EducationItem = (x) => (
    @@ -189,12 +189,12 @@ const Pikachu = () => {
    - {data.education.items.filter(x => x.enable).map(EducationItem)} + {data.education.items.filter((x) => x.enable).map(EducationItem)}
    ); - const AwardItem = x => ( + const AwardItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -208,12 +208,12 @@ const Pikachu = () => {
    - {data.awards.items.filter(x => x.enable).map(AwardItem)} + {data.awards.items.filter((x) => x.enable).map(AwardItem)}
    ); - const CertificationItem = x => ( + const CertificationItem = (x) => (
    {x.title}

    {x.subtitle}

    @@ -227,7 +227,7 @@ const Pikachu = () => {
    - {data.certifications.items.filter(x => x.enable).map(CertificationItem)} + {data.certifications.items.filter((x) => x.enable).map(CertificationItem)}
    ); diff --git a/src/utils/index.js b/src/utils/index.js index 3dd17b6a..f9cf775a 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -10,7 +10,7 @@ const move = (array, element, delta) => { array.splice(indexes[0], 2, array[indexes[1]], array[indexes[0]]); }; -const hexToRgb = hex => { +const hexToRgb = (hex) => { const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b); const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); @@ -23,7 +23,7 @@ const hexToRgb = hex => { : null; }; -const copyToClipboard = text => { +const copyToClipboard = (text) => { const textArea = document.createElement('textarea'); textArea.style.position = 'fixed'; textArea.style.top = 0; @@ -44,7 +44,7 @@ const copyToClipboard = text => { return successful; }; -const saveData = dispatch => dispatch({ type: 'save_data' }); +const saveData = (dispatch) => dispatch({ type: 'save_data' }); const addItem = (dispatch, key, value) => { dispatch({ @@ -104,42 +104,88 @@ const importJson = (event, dispatch) => { fr.readAsText(event.target.files[0]); }; -const saveAsPdf = (pageRef, panZoomRef) => { - panZoomRef.current.autoCenter(1); - panZoomRef.current.reset(); +const saveAsPdf = (pageRef, panZoomRef, quality, type) => + new Promise((resolve) => { + panZoomRef.current.autoCenter(1); + panZoomRef.current.reset(); - setTimeout(() => { - html2canvas(pageRef.current, { - scale: 6, - useCORS: true, - allowTaint: true, - }).then(canvas => { - const image = canvas.toDataURL('image/jpeg', 1.0); - const doc = new jsPDF({ - orientation: 'portrait', - unit: 'px', - format: [canvas.width, canvas.height], + setTimeout(() => { + html2canvas(pageRef.current, { + scale: 5, + useCORS: true, + allowTaint: true, + }).then((canvas) => { + const image = canvas.toDataURL('image/jpeg', quality / 100); + const doc = new jsPDF({ + orientation: 'portrait', + unit: 'px', + format: type === 'unconstrained' ? [canvas.width, canvas.height] : 'a4', + }); + + const pageWidth = doc.internal.pageSize.getWidth(); + const pageHeight = doc.internal.pageSize.getHeight(); + + const widthRatio = pageWidth / canvas.width; + const heightRatio = pageHeight / canvas.height; + const ratio = widthRatio > heightRatio ? heightRatio : widthRatio; + + const canvasWidth = canvas.width * ratio; + const canvasHeight = canvas.height * ratio; + + let marginX = 0; + let marginY = 0; + + if (type !== 'unconstrained') { + marginX = (pageWidth - canvasWidth) / 2; + marginY = (pageHeight - canvasHeight) / 2; + } + + doc.addImage(image, 'JPEG', marginX, marginY, canvasWidth, canvasHeight, null, 'SLOW'); + doc.save(`RxResume_${Date.now()}.pdf`); + resolve(); }); + }, 250); + }); - const pageWidth = doc.internal.pageSize.getWidth(); - const pageHeight = doc.internal.pageSize.getHeight(); +const saveAsMultiPagePdf = (pageRef, panZoomRef, quality) => + new Promise((resolve) => { + panZoomRef.current.autoCenter(1); + panZoomRef.current.reset(); - const widthRatio = pageWidth / canvas.width; - const heightRatio = pageHeight / canvas.height; - const ratio = widthRatio > heightRatio ? heightRatio : widthRatio; + setTimeout(() => { + html2canvas(pageRef.current, { + scale: 5, + useCORS: true, + allowTaint: true, + }).then((canvas) => { + const image = canvas.toDataURL('image/jpeg', quality / 100); + const doc = new jsPDF({ + orientation: 'portrait', + unit: 'px', + format: 'a4', + }); - const canvasWidth = canvas.width * ratio; - const canvasHeight = canvas.height * ratio; - // const marginX = (pageWidth - canvasWidth) / 2; - // const marginY = (pageHeight - canvasHeight) / 2; + const pageHeight = doc.internal.pageSize.getHeight(); + const canvasWidth = doc.internal.pageSize.getWidth(); + const canvasHeight = (canvas.height * canvasWidth) / canvas.width; + let marginTop = 0; + let heightLeft = canvasHeight; - panZoomRef.current.autoCenter(0.7); + doc.addImage(image, 'JPEG', 0, marginTop, canvasWidth, canvasHeight); + heightLeft -= pageHeight; - doc.addImage(image, 'JPEG', 0, 0, canvasWidth, canvasHeight, null, 'SLOW'); - doc.save(`RxResume_${Date.now()}.pdf`); - }); - }, 200); -}; + while (heightLeft >= 0) { + marginTop = heightLeft - canvasHeight; + doc.addPage(); + doc.addImage(image, 'JPEG', 0, marginTop, canvasWidth, canvasHeight); + heightLeft -= pageHeight; + } + + doc.save(`RxResume_${Date.now()}.pdf`); + resolve(); + }); + }, 250); + }); export { move, @@ -152,4 +198,5 @@ export { moveItemDown, importJson, saveAsPdf, + saveAsMultiPagePdf, };