Skip to content

Commit

Permalink
Merge pull request #237 from Lemoncode/epic/new-template-html
Browse files Browse the repository at this point in the history
merged Epic/new template html
  • Loading branch information
juanpms2 authored Nov 3, 2023
2 parents 4c63bc7 + 30e35fc commit c13a4a2
Show file tree
Hide file tree
Showing 114 changed files with 1,103 additions and 145 deletions.
2 changes: 1 addition & 1 deletion apps/react-app/src/common-app/components/modal/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './modal.component'
export * from './modal.component';
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ interface Props {
isOpen: boolean;
}

export const Modal: React.FC<Props> = (props) => {
export const Modal: React.FC<Props> = props => {
const { children, isOpen } = props;
return isOpen && <div className={classes.container}>{children}</div>

return isOpen && <div className={classes.container}>{children}</div>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import * as classes from './customSelect.styles';
interface Props {
listOptions: string[];
label: string;
onSelectedOption: (option: string) => void;
}
export const CustomSelect: React.FC<Props> = ({ listOptions, label }) => {
export const CustomSelect: React.FC<Props> = props => {
const { listOptions, label, onSelectedOption } = props;
const [isOpen, setIsOpen] = React.useState<boolean>(false);
const [selectedOption, setSelectedOption] = React.useState<string>(label);

Expand All @@ -14,6 +16,7 @@ export const CustomSelect: React.FC<Props> = ({ listOptions, label }) => {
};

const handleOptionSelect = (option: string) => {
onSelectedOption(option);
setSelectedOption(option);
setIsOpen(false);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './inputRadioButton.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { HexColor, ColorTheme } from '@lemoncode/manfred2html';
import * as classes from './inputRadioButton.styles';

interface Props {
value: ColorTheme;
hexColor: HexColor;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

export const InputRadioButton: React.FC<Props> = ({ value, hexColor, onChange }) => {
return (
<input
type="radio"
id={value}
name="color"
value={value}
className={classes.inputRadioButton(hexColor)}
onChange={onChange}
defaultChecked={value === 'default'}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { css } from '@emotion/css';
import { theme } from '@/core/theme';

export const inputRadioButton = (color: string) => css`
appearance: none;
width: 82px;
height: 82px;
box-shadow: 8px 8px 16px 0px rgba(0, 0, 0, 0.25);
border-radius: 50%;
background-color: ${color};
cursor: pointer;
outline: none;
border: 15px solid ${theme.palette.info[50]};
&[type='radio']:checked {
box-shadow: 0px 0px 0px 4px ${theme.palette.dark[200]};
}
`;
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { theme } from '@/core/theme';
import * as classes from './customSelectColor.styles';
import { cx } from '@emotion/css';
import { ColorTheme, HexColor } from '@lemoncode/manfred2html';
import { InputRadioButton } from './components';
import * as classes from './customSelectColor.styles';

interface Props {
label: string;
Expand Down Expand Up @@ -31,55 +32,14 @@ export const CustomSelectColor: React.FC<Props> = ({ label, onChange }) => {
/>
</div>
<fieldset className={classes.colorFieldset}>
<input
type="radio"
id={theme.palette.primary[600]}
name="color"
value={theme.palette.primary[600]}
className={classes.inputRadioButton(theme.palette.primary[600])}
onChange={onChange}
defaultChecked
/>
<input
type="radio"
id={theme.palette.secondary[600]}
name="color"
value={theme.palette.secondary[600]}
className={classes.inputRadioButton(theme.palette.secondary[600])}
onChange={onChange}
/>
<input
type="radio"
id={theme.palette.success[600]}
name="color"
value={theme.palette.success[600]}
className={classes.inputRadioButton(theme.palette.success[600])}
onChange={onChange}
/>
<input
type="radio"
id={theme.palette.warning[600]}
name="color"
value={theme.palette.warning[600]}
className={classes.inputRadioButton(theme.palette.warning[600])}
onChange={onChange}
/>
<input
type="radio"
id={theme.palette.error[600]}
name="color"
value={theme.palette.error[600]}
className={classes.inputRadioButton(theme.palette.error[600])}
onChange={onChange}
/>
<input
type="radio"
id={theme.palette.dark[600]}
name="color"
value={theme.palette.dark[600]}
className={classes.inputRadioButton(theme.palette.dark[600])}
onChange={onChange}
/>
{Object.keys(HexColor).map(colorKey => (
<InputRadioButton
key={colorKey}
value={colorKey as ColorTheme}
hexColor={HexColor[colorKey as keyof typeof HexColor]}
onChange={onChange}
/>
))}
</fieldset>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,6 @@ export const colorFieldset = css`
justify-content: center;
gap: ${theme.spacing(8)};
`;
export const inputRadioButton = (color: string) => css`
appearance: none;
width: 82px;
height: 82px;
box-shadow: 8px 8px 16px 0px rgba(0, 0, 0, 0.25);
border-radius: 50%;
background-color: ${color};
cursor: pointer;
outline: none;
border: 15px solid ${theme.palette.info[50]};
&[type='radio']:checked {
box-shadow: 0px 0px 0px 4px ${theme.palette.dark[200]};
}
`;

export const rotate = (customSelectState: boolean) => css`
rotate: ${customSelectState ? '180deg' : '0deg'};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React from 'react';
import { ExportHTMLSettings } from '@lemoncode/manfred2html';
import { theme } from '@/core/theme';
import {
TemplateCV,
ColorTheme,
Language,
ExportHTMLSettings,
createDefaultExportHTMLSettings,
} from '@lemoncode/manfred2html';
import { Button, CustomSelect } from '@/common-app/components';
import { useUserChoiceContext } from '@/core/user-choice';
import { CustomSelectColor } from '../customSelectColor/customSelectColor.component';
import * as classes from './export-config.styles';
interface Props {
Expand All @@ -13,24 +17,42 @@ interface Props {
}

const DOWNLOAD_MESSAGE_TIMEOUT = 2500;
const OPTIONSDESING = ['Item 1', 'Item 2', 'Item 3'];
const OPTIONSlANGUAGE = ['Item 1', 'Item 2', 'Item 3'];
const DESING_OPTIONS: TemplateCV[] = ['default', 'CV-1'];
const LANGUAGE_OPTIONS: Language[] = ['es', 'en'];

export const ExportConfig: React.FC<Props> = props => {
const { onExportToHTML, cancelExport, htmlTemplate, onHTMLSettingSelectionChanged } = props;
const { userChoice } = useUserChoiceContext();
const [exportHTMLSettings, setExportHTMLSettings] = React.useState<ExportHTMLSettings>({
primaryColor: theme.palette.primary[600],
});
const [exportHTMLSettings, setExportHTMLSettings] = React.useState<ExportHTMLSettings>(
createDefaultExportHTMLSettings()
);
const [isDownloadInProgress, setIsDownloadInProgress] = React.useState<boolean>(false);

const [htmlPreview, setHtmlPreview] = React.useState<string>(
onHTMLSettingSelectionChanged(htmlTemplate, exportHTMLSettings)
);

const handleColorChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setExportHTMLSettings({ primaryColor: event.target.value });
onHTMLSettingSelectionChanged(htmlTemplate, { primaryColor: event.target.value });
setExportHTMLSettings({ ...exportHTMLSettings, colorTheme: event.target.value as ColorTheme });
onHTMLSettingSelectionChanged(htmlTemplate, {
...exportHTMLSettings,
colorTheme: event.target.value as ColorTheme,
});
};

const handleTemplateChange = (templateCV: string) => {
setExportHTMLSettings({ ...exportHTMLSettings, template: templateCV as TemplateCV });
onHTMLSettingSelectionChanged(htmlTemplate, {
...exportHTMLSettings,
template: templateCV as TemplateCV,
});
};

const handleLanguageChange = (language: string) => {
setExportHTMLSettings({ ...exportHTMLSettings, language: language as Language });
onHTMLSettingSelectionChanged(htmlTemplate, {
...exportHTMLSettings,
language: language as Language,
});
};
const handleExportConfigSelection = () => {
setIsDownloadInProgress(true);
Expand All @@ -51,8 +73,12 @@ export const ExportConfig: React.FC<Props> = props => {
<div className={classes.optionsContainer}>
<div className={classes.optionsContent}>
<div className={classes.selectContainer}>
<CustomSelect listOptions={OPTIONSDESING} label={'Diseño'} />
<CustomSelect listOptions={OPTIONSlANGUAGE} label={'Idioma cabeceras'} />
<CustomSelect listOptions={DESING_OPTIONS} onSelectedOption={handleTemplateChange} label={'Diseño'} />
<CustomSelect
listOptions={LANGUAGE_OPTIONS}
onSelectedOption={handleLanguageChange}
label={'Idioma cabeceras'}
/>
</div>
<div className={classes.selectColorContainer}>
<CustomSelectColor label={'Colores'} onChange={handleColorChange} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { ExportHTMLSettings } from '@lemoncode/manfred2html';
import { useUserChoiceContext } from '@/core';
import { Button, Footer, Header, Modal, Navbar } from '@/common-app/components';
import * as classes from './template-export.styles';
import { ExportConfig } from './components/export-config';
import * as classes from './template-export.styles';

interface Props {
error: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { exportManfredJSonToWordAndDownload, parseStringToManfredJSon } from '@lemoncode/manfred2word';
import { exportManfredJSonToMarkdown } from '@lemoncode/manfred2md';
import { exportManfredJSonToHTML, ExportHTMLSettings } from '@lemoncode/manfred2html';
import { exportHTMLTemplate, ExportHTMLSettings } from '@lemoncode/manfred2html';
import { DEFAULT_EXPORT_FILENAME } from '@/core';
import { download } from '@/common';
import { TemplateExport } from './template-export.component';
Expand Down Expand Up @@ -38,7 +38,7 @@ export const TemplateExportContainer: React.FC = () => {
const onExportToHTML = async (text: string, exportHTMLSettings: ExportHTMLSettings) => {
try {
const manfredJsonContent = parseManfredJson(text);
const content = exportManfredJSonToHTML(manfredJsonContent, exportHTMLSettings);
const content = exportHTMLTemplate(manfredJsonContent, exportHTMLSettings);
const blob = new Blob([content], { type: 'text/html' });

await download(blob, 'manfred.html');
Expand All @@ -49,7 +49,7 @@ export const TemplateExportContainer: React.FC = () => {

const onHTMLSettingChanged = (text: string, exportHTMLSettings: ExportHTMLSettings): string => {
const manfredJsonContent = parseManfredJson(text);
const content = exportManfredJSonToHTML(manfredJsonContent, exportHTMLSettings);
const content = exportHTMLTemplate(manfredJsonContent, exportHTMLSettings);
return content;
};

Expand Down

This file was deleted.

63 changes: 13 additions & 50 deletions packages/manfred2html/src/engine/index.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,20 @@
import { ManfredAwesomicCV, ExportHTMLSettings } from '@/model';
import {
generateHtmlDocumentStart,
generateHtmlDocumentEnd,
generateHeaderElementStart,
generateHeaderElementEnd,
generateAboutMeSection,
generateAsideElementStart,
generateAsideElementEnd,
generateRelevantsLinksSection,
generateLanguageSection,
generateHardSkillsSection,
generateSoftSkillsSection,
generateMainElementStart,
generateMainElementEnd,
generateExperiencesSection,
generateStudiesSection,
} from './html-parts';
import { mapExportHTMLSettingsToSettings } from '@/mappers';
import { exportManfredJSonToHTMLTemplateA } from './template-a';
import { exportManfredJSonToHTMLTemplateB } from './template-b';

export const exportManfredJSonToHTML = (
export const exportHTMLTemplate = (
manfredJsonContent: ManfredAwesomicCV,
exportHTMLSettings: ExportHTMLSettings
): string => {
const htmlDocumentStart = generateHtmlDocumentStart(exportHTMLSettings.primaryColor);
const htmlDocumentEnd = generateHtmlDocumentEnd();
const headerElementStart = generateHeaderElementStart();
const headerElementEnd = generateHeaderElementEnd();
const aboutMeSection = generateAboutMeSection(manfredJsonContent);
const asideElementStart = generateAsideElementStart();
const asideElementEnd = generateAsideElementEnd();
const relevantsLinksSection = generateRelevantsLinksSection(manfredJsonContent);
const mainElementStart = generateMainElementStart();
const mainElementEnd = generateMainElementEnd();
const languageSection = generateLanguageSection(manfredJsonContent);
const hardSkillsSection = generateHardSkillsSection(manfredJsonContent);
const softSkillsSection = generateSoftSkillsSection(manfredJsonContent);
const experienceSection = generateExperiencesSection(manfredJsonContent);
const studiesSection = generateStudiesSection(manfredJsonContent);
const settings = mapExportHTMLSettingsToSettings(exportHTMLSettings);

return `
${htmlDocumentStart}
${headerElementStart}
${aboutMeSection}
${headerElementEnd}
${asideElementStart}
${relevantsLinksSection}
${languageSection}
${hardSkillsSection}
${softSkillsSection}
${asideElementEnd}
${mainElementStart}
${experienceSection}
${studiesSection}
${mainElementEnd}
${htmlDocumentEnd}
`;
switch (settings.template) {
case 'default':
return exportManfredJSonToHTMLTemplateA(manfredJsonContent, settings);
case 'CV-1':
return exportManfredJSonToHTMLTemplateB(manfredJsonContent, settings);
default:
throw new Error('Template not found');
}
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<html lang="en">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ejs from 'ejs';
import { HexColor } from '@/model';
import htmlDocumentStartTemplate from './html-document-start.ejs?raw';

export const generateHtmlDocumentStart = (color: HexColor): string => ejs.render(htmlDocumentStartTemplate, { color });
Loading

0 comments on commit c13a4a2

Please sign in to comment.