diff --git a/src/features/cv-preview/themes/ClassicTheme.tsx b/src/features/cv-preview/themes/ClassicTheme.tsx index 66e90d9..1b35d9c 100644 --- a/src/features/cv-preview/themes/ClassicTheme.tsx +++ b/src/features/cv-preview/themes/ClassicTheme.tsx @@ -2,170 +2,169 @@ import type { CVData } from "../../../core/domain/cv.types"; import { useTranslation } from "react-i18next"; export const ClassicTheme = ({ data }: { data: CVData }) => { - const { t } = useTranslation("theme", { - lng: data.metadata.language || "fr", - }); + const { t } = useTranslation("theme", { + lng: data.metadata.language || "fr", + }); - return ( -
-
-

- {data.personalInfo.fullName || t("defaultName")} -

-

- {data.personalInfo.title || t("defaultTitle")} -

+ return ( +
+
+

+ {data.personalInfo.fullName || t("defaultName")} +

+

+ {data.personalInfo.title || t("defaultTitle")} +

-
- {data.personalInfo.contacts.map((c, i) => ( - - {c.label}:  - {c.value} - {(i < data.personalInfo.contacts.length - 1 || - data.personalInfo.socials.length > 0) && ( - | - )} - - ))} - {data.personalInfo.socials.map((s, i) => ( - - {s.platform}:  - - {s.url.replace(/^https?:\/\//, "")} - - {i < data.personalInfo.socials.length - 1 && ( - | - )} - - ))} -
-
+
+ {data.personalInfo.contacts.map((c, i) => ( + + {c.label}:  + {c.value} + {(i < data.personalInfo.contacts.length - 1 || + data.personalInfo.socials.length > 0) && ( + | + )} + + ))} + {data.personalInfo.socials.map((s, i) => ( + + {s.platform}:  + + {s.url.replace(/^https?:\/\//, "")} + + {i < data.personalInfo.socials.length - 1 && ( + | + )} + + ))} +
+
-
- {data.personalInfo.summary && ( -
-

- {t("sections.summary")} -

-

- {data.personalInfo.summary} -

-
- )} +
+ {data.personalInfo.summary && ( +
+

+ {t("sections.summary")} +

+

+ {data.personalInfo.summary} +

+
+ )} -
-

- {t("sections.experience")} -

-
- {data.experiences.map((exp) => ( -
-
-

- {exp.company.toUpperCase()} —{" "} - {exp.role} -

- - {exp.startDate} — {exp.endDate} - -
- {exp.description && ( -

- {exp.description} -

- )} -
    - {exp.mission.map((m, idx) => ( -
  • - {m} -
  • - ))} -
-
- ))} -
-
+ {data.experiences.length > 0 && ( +
+

+ {t("sections.experience")} +

+
+ {data.experiences.map((exp) => ( +
+
+

+ {exp.company.toUpperCase()} —{" "} + {exp.role} +

+ + {exp.startDate} — {exp.endDate} + +
+ {exp.description && ( +

+ {exp.description} +

+ )} +
    + {exp.mission.map((m, idx) => ( +
  • + {m} +
  • + ))} +
+
+ ))} +
+
+ )} - {data.educations.length > 0 && ( -
-

- {t("sections.education")} -

-
- {data.educations.map((edu) => ( -
-
-

{edu.degree}

-

- {edu.school} -

-
- - {edu.year} - -
- ))} -
-
- )} + {data.educations.length > 0 && ( +
+

+ {t("sections.education")} +

+
+ {data.educations.map((edu) => ( +
+
+

{edu.degree}

+

+ {edu.school} +

+
+ + {edu.year} + +
+ ))} +
+
+ )} -
- {data.skills.length > 0 && ( -
-

- {t("sections.skills")} -

-

- {data.skills.join(" • ")} -

-
- )} +
+ {data.skills.length > 0 && ( +
+

+ {t("sections.skills")} +

+

+ {data.skills.join(" • ")} +

+
+ )} - {data.languages.length > 0 && ( -
-

- {t("sections.languages")} -

-
- {data.languages.map((lang) => ( -

- {lang.name} :{" "} - {lang.level} -

- ))} -
-
- )} -
+ {data.languages.length > 0 && ( +
+

+ {t("sections.languages")} +

+
+ {data.languages.map((lang) => ( +

+ {lang.name} :{" "} + {lang.level} +

+ ))} +
+
+ )} +
- {data.certifications.length > 0 && ( -
-

- {t("sections.certifications")} -

-
    - {data.certifications.map((cert) => ( -
  • - - {cert.name} - {cert.issuer && ` — ${cert.issuer}`} - - {cert.year} -
  • - ))} -
-
- )} -
-
- ); + {data.certifications.length > 0 && ( +
+

+ {t("sections.certifications")} +

+ +
+ )} +
+ + ); }; diff --git a/src/features/cv-preview/themes/ElegantTheme.tsx b/src/features/cv-preview/themes/ElegantTheme.tsx index 227b0b1..e90addd 100644 --- a/src/features/cv-preview/themes/ElegantTheme.tsx +++ b/src/features/cv-preview/themes/ElegantTheme.tsx @@ -1,193 +1,195 @@ import { Globe, ExternalLink } from "lucide-react"; import type { CVData } from "../../../core/domain/cv.types"; import { - CONTACT_ICONS, - SOCIAL_ICONS, - type ContactType, - type SocialType, + CONTACT_ICONS, + SOCIAL_ICONS, + type ContactType, + type SocialType, } from "../../shared/icon"; import { useTranslation } from "react-i18next"; export const ElegantTheme = ({ data }: { data: CVData }) => { - const { t } = useTranslation("theme", { - lng: data.metadata.language || "fr", - }); + const { t } = useTranslation("theme", { + lng: data.metadata.language || "fr", + }); - return ( -
-
-

- {data.personalInfo.fullName || t("defaultName")} -

+ return ( +
+
+

+ {data.personalInfo.fullName || t("defaultName")} +

-
- {data.personalInfo.contacts.map((c, i) => { - const Icon = - CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; - return ( -
- - {c.value} - {(i < data.personalInfo.contacts.length - 1 || - data.personalInfo.socials.length > 0) && ( - | - )} -
- ); - })} - {data.personalInfo.socials.map((s, i) => { - const Icon = - SOCIAL_ICONS[s.platform.toLowerCase() as SocialType] || - ExternalLink; - return ( -
- - - {s.url.replace(/^https?:\/\//, "")} - - {i < data.personalInfo.socials.length - 1 && ( - | - )} -
- ); - })} -
-
+
+ {data.personalInfo.contacts.map((c, i) => { + const Icon = + CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; + return ( +
+ + {c.value} + {(i < data.personalInfo.contacts.length - 1 || + data.personalInfo.socials.length > 0) && ( + | + )} +
+ ); + })} + {data.personalInfo.socials.map((s, i) => { + const Icon = + SOCIAL_ICONS[s.platform.toLowerCase() as SocialType] || + ExternalLink; + return ( +
+ + + {s.url.replace(/^https?:\/\//, "")} + + {i < data.personalInfo.socials.length - 1 && ( + | + )} +
+ ); + })} +
+
-
- {data.personalInfo.summary && ( -
-

- {t("sections.summary")} -

-

- {data.personalInfo.summary} -

-
- )} +
+ {data.personalInfo.summary && ( +
+

+ {t("sections.summary")} +

+

+ {data.personalInfo.summary} +

+
+ )} -
-

- {t("sections.experience")} -

-
- {data.experiences.map((exp) => ( -
-
- {exp.startDate} — {exp.endDate} -
-
-
-

{exp.role}

- - {exp.company} - -
- {exp.description && ( -

- {exp.description} -

- )} -
    - {exp.mission.map((m, idx) => ( -
  • - {m} -
  • - ))} -
-
-
- ))} -
-
+ {data.experiences.length > 0 && ( +
+

+ {t("sections.experience")} +

+
+ {data.experiences.map((exp) => ( +
+
+ {exp.startDate} — {exp.endDate} +
+
+
+

{exp.role}

+ + {exp.company} + +
+ {exp.description && ( +

+ {exp.description} +

+ )} +
    + {exp.mission.map((m, idx) => ( +
  • + {m} +
  • + ))} +
+
+
+ ))} +
+
+ )} - {data.educations.length > 0 && ( -
-

- {t("sections.education")} -

-
- {data.educations.map((edu) => ( -
-
- {edu.year} -
-
-
-

{edu.degree}

- - {edu.school} - -
-
-
- ))} -
-
- )} + {data.educations.length > 0 && ( +
+

+ {t("sections.education")} +

+
+ {data.educations.map((edu) => ( +
+
+ {edu.year} +
+
+
+

{edu.degree}

+ + {edu.school} + +
+
+
+ ))} +
+
+ )} -
- {data.skills.length > 0 && ( -
-

- {t("sections.skills")} -

-
- {data.skills.join(" • ")} -
-
- )} +
+ {data.skills.length > 0 && ( +
+

+ {t("sections.skills")} +

+
+ {data.skills.join(" • ")} +
+
+ )} - {data.languages.length > 0 && ( -
-

- {t("sections.languages")} -

-
- {data.languages.map((lang) => ( -

- {lang.name}: {lang.level} -

- ))} -
-
- )} -
+ {data.languages.length > 0 && ( +
+

+ {t("sections.languages")} +

+
+ {data.languages.map((lang) => ( +

+ {lang.name}: {lang.level} +

+ ))} +
+
+ )} +
- {data.certifications && data.certifications.length > 0 && ( -
-

- {t("sections.certifications")} -

-
    - {data.certifications.map((cert) => ( -
  • - - {cert.name} - {cert.issuer && ` — ${cert.issuer}`} - - - {cert.year} - -
  • - ))} -
-
- )} -
+ {data.certifications && data.certifications.length > 0 && ( +
+

+ {t("sections.certifications")} +

+
    + {data.certifications.map((cert) => ( +
  • + + {cert.name} + {cert.issuer && ` — ${cert.issuer}`} + + + {cert.year} + +
  • + ))} +
+
+ )} +
- -
- ); + + + ); }; diff --git a/src/features/cv-preview/themes/HipsterTheme.tsx b/src/features/cv-preview/themes/HipsterTheme.tsx index 3fdbecd..416a5aa 100644 --- a/src/features/cv-preview/themes/HipsterTheme.tsx +++ b/src/features/cv-preview/themes/HipsterTheme.tsx @@ -1,269 +1,266 @@ import { Globe, ExternalLink, Circle, Award } from "lucide-react"; import type { CVData } from "../../../core/domain/cv.types"; import { - CONTACT_ICONS, - SOCIAL_ICONS, - type ContactType, - type SocialType, + CONTACT_ICONS, + SOCIAL_ICONS, + type ContactType, + type SocialType, } from "../../shared/icon"; import { useTranslation } from "react-i18next"; export const HipsterTheme = ({ data }: { data: CVData }) => { - const { t } = useTranslation("theme", { - lng: data.metadata.language || "fr", - }); + const { t } = useTranslation("theme", { + lng: data.metadata.language || "fr", + }); - return ( -
-
-
- {data.personalInfo.photoUrl && ( -
- {data.personalInfo.fullName} -
- )} -

- {t("sections.summary")} -

-

- {data.personalInfo.fullName || t("defaultName")} -

-
+ return ( +
+
+
+ {data.personalInfo.photoUrl && ( +
+ {data.personalInfo.fullName} +
+ )} +

+ {t("sections.summary")} +

+

+ {data.personalInfo.fullName || t("defaultName")} +

+
- {data.personalInfo.summary && ( -
-

- {data.personalInfo.summary} -

-
- )} + {data.personalInfo.summary && ( +
+

+ {data.personalInfo.summary} +

+
+ )} -
-

- Contact -

-
- {data.personalInfo.contacts.map((c) => { - const Icon = - CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; - return ( -
-
- -
-
-

- {c.label} -

-

{c.value || "—"}

-
-
- ); - })} -
-
+ {data.personalInfo.contacts.length > 0 && ( +
+

+ Contact +

+
+ {data.personalInfo.contacts.map((c) => { + const Icon = + CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; + return ( +
+
+ +
+
+

+ {c.label} +

+

{c.value || "—"}

+
+
+ ); + })} +
+
+ )} - {data.personalInfo.socials.length > 0 && ( -
-

- {t("sections.socials") || "Social"} -

-
- {data.personalInfo.socials.map((social) => { - const Icon = - SOCIAL_ICONS[social.platform.toLowerCase() as SocialType] || - ExternalLink; - const displayUrl = social.url - .replace(/^https?:\/\//, "") - .replace(/^www\./, "") - .replace(/\/$/, ""); - return ( -
-
- -
-
-

- {social.platform} -

-

{displayUrl}

-
-
- ); - })} -
-
- )} + {data.personalInfo.socials.length > 0 && ( +
+

+ {t("sections.socials") || "Social"} +

+
+ {data.personalInfo.socials.map((social) => { + const Icon = + SOCIAL_ICONS[social.platform.toLowerCase() as SocialType] || + ExternalLink; + const displayUrl = social.url + .replace(/^https?:\/\//, "") + .replace(/^www\./, "") + .replace(/\/$/, ""); + return ( +
+
+ +
+
+

+ {social.platform} +

+

{displayUrl}

+
+
+ ); + })} +
+
+ )} - {data.skills.length > 0 && ( -
-

- {t("sections.skills")} -

-
- {data.skills.map((s, i) => ( - - {s} - - ))} -
-
- )} + {data.skills.length > 0 && ( +
+

+ {t("sections.skills")} +

+
+ {data.skills.map((s, i) => ( + + {s} + + ))} +
+
+ )} - {data.languages.length > 0 && ( -
-

- {t("sections.languages")} -

-
- {data.languages.map((lang) => ( -
- - {lang.name} - - - {lang.level} - -
- ))} -
-
- )} -
+ {data.languages.length > 0 && ( +
+

+ {t("sections.languages")} +

+
+ {data.languages.map((lang) => ( +
+ + {lang.name} + + + {lang.level} + +
+ ))} +
+
+ )} +
-
-
-

- {data.personalInfo.title || t("defaultTitle")} -

-
-
+
+
+

+ {data.personalInfo.title || t("defaultTitle")} +

+
+
-
-

- {" "} - {t("sections.experience")} -

-
- {data.experiences.map((exp) => ( -
-
+ {data.experiences.length > 0 && ( +
+

+ {" "} + {t("sections.experience")} +

+
+ {data.experiences.map((exp) => ( +
+
-
-
-

- {exp.role} -

-

- {exp.company} -

-
- - {exp.startDate} — {exp.endDate} - -
+
+
+

+ {exp.role} +

+

+ {exp.company} +

+
+ + {exp.startDate} — {exp.endDate} + +
- {exp.description && ( -

- {exp.description} -

- )} + {exp.description && ( +

+ {exp.description} +

+ )} -
    - {exp.mission.map((m, i) => ( -
  • - - {m} -
  • - ))} -
-
- ))} -
-
+
    + {exp.mission.map((m, i) => ( +
  • + + {m} +
  • + ))} +
+
+ ))} +
+
+ )} - {data.educations.length > 0 && ( -
-

- {" "} - {t("sections.education")} -

-
- {data.educations.map((edu) => ( -
-
-

- {edu.degree} -

-

- {edu.school} -

-
- - {edu.year} - -
- ))} -
-
- )} + {data.educations.length > 0 && ( +
+

+ {" "} + {t("sections.education")} +

+
+ {data.educations.map((edu) => ( +
+
+

+ {edu.degree} +

+

+ {edu.school} +

+
+ + {edu.year} + +
+ ))} +
+
+ )} - {data.certifications && data.certifications.length > 0 && ( -
-

- {" "} - {t("sections.certifications")} -

-
- {data.certifications.map((cert) => ( -
-
- -
-
-
-

- {cert.name} -

- - {cert.year} - -
-

- {cert.issuer} -

-
-
- ))} -
-
- )} -
-
- ); + {data.certifications && data.certifications.length > 0 && ( +
+

+ {" "} + {t("sections.certifications")} +

+
+ {data.certifications.map((cert) => ( +
+
+ +
+
+
+

+ {cert.name} +

+ + {cert.year} + +
+

+ {cert.issuer} +

+
+
+ ))} +
+
+ )} +
+
+ ); }; diff --git a/src/features/cv-preview/themes/ModernTheme.tsx b/src/features/cv-preview/themes/ModernTheme.tsx index 9000318..65af4cd 100644 --- a/src/features/cv-preview/themes/ModernTheme.tsx +++ b/src/features/cv-preview/themes/ModernTheme.tsx @@ -1,276 +1,272 @@ import { Globe, ExternalLink, Award } from "lucide-react"; import type { CVData } from "../../../core/domain/cv.types"; import { - CONTACT_ICONS, - SOCIAL_ICONS, - type ContactType, - type SocialType, + CONTACT_ICONS, + SOCIAL_ICONS, + type ContactType, + type SocialType, } from "../../shared/icon"; import { useTranslation } from "react-i18next"; export const ModernTheme = ({ data }: { data: CVData }) => { - const { t } = useTranslation("theme", { - lng: data.metadata.language || "fr", - }); + const { t } = useTranslation("theme", { + lng: data.metadata.language || "fr", + }); - return ( -
-
-
- {data.personalInfo.photoUrl && ( -
- {data.personalInfo.fullName} -
-
- )} -

- {data.personalInfo.fullName || t("defaultName")} -

-

- {data.personalInfo.title || t("defaultTitle")} -

-
+ return ( +
+
+
+ {data.personalInfo.photoUrl && ( +
+ {data.personalInfo.fullName} +
+
+ )} +

+ {data.personalInfo.fullName || t("defaultName")} +

+

+ {data.personalInfo.title || t("defaultTitle")} +

+
-
-

- Contact -

-
- {data.personalInfo.contacts.map((c) => { - const Icon = - CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; - return ( -
-
- -
-
-

- {c.label} -

-

{c.value || "—"}

-
-
- ); - })} -
-
+ {data.personalInfo.contacts.length > 0 && ( +
+

+ Contact +

+
+ {data.personalInfo.contacts.map((c) => { + const Icon = + CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; + return ( +
+
+ +
+
+

+ {c.label} +

+

{c.value || "—"}

+
+
+ ); + })} +
+
+ )} - {data.personalInfo.socials.length > 0 && ( -
-

- {t("sections.socials") || "Réseaux Sociaux"} -

-
- {data.personalInfo.socials.map((social) => { - const Icon = - SOCIAL_ICONS[social.platform.toLowerCase() as SocialType] || - ExternalLink; - const hrefUrl = social.url.startsWith("http") - ? social.url - : `https://${social.url}`; - const displayUrl = social.url - .replace(/^https?:\/\//, "") - .replace(/^www\./, "") - .replace(/\/$/, ""); - return ( -
-
- -
-
-

- {social.platform} -

- - {displayUrl} - -
-
- ); - })} -
-
- )} + {data.personalInfo.socials.length > 0 && ( +
+

+ {t("sections.socials") || "Réseaux Sociaux"} +

+
+ {data.personalInfo.socials.map((social) => { + const Icon = + SOCIAL_ICONS[social.platform.toLowerCase() as SocialType] || + ExternalLink; + const hrefUrl = social.url.startsWith("http") + ? social.url + : `https://${social.url}`; + const displayUrl = social.url + .replace(/^https?:\/\//, "") + .replace(/^www\./, "") + .replace(/\/$/, ""); + return ( +
+
+ +
+
+

+ {social.platform} +

+ + {displayUrl} + +
+
+ ); + })} +
+
+ )} - {data.skills.length > 0 && ( -
-

- {t("sections.skills")} -

-
- {data.skills.map((s, i) => ( - - {s} - - ))} -
-
- )} + {data.skills.length > 0 && ( +
+

+ {t("sections.skills")} +

+
+ {data.skills.map((s, i) => ( + + {s} + + ))} +
+
+ )} - {data.languages && data.languages.length > 0 && ( -
-

- {t("sections.languages")} -

-
- {data.languages.map((lang) => ( -
- - {lang.name} - - - {lang.level} - -
- ))} -
-
- )} -
+ {data.languages && data.languages.length > 0 && ( +
+

+ {t("sections.languages")} +

+
+ {data.languages.map((lang) => ( +
+ + {lang.name} + + + {lang.level} + +
+ ))} +
+
+ )} +
-
- {data.personalInfo.summary && ( -
-

- {" "} - {t("sections.summary")} -

-

- "{data.personalInfo.summary}" -

-
- )} +
+ {data.personalInfo.summary && ( +
+

+ {" "} + {t("sections.summary")} +

+

+ "{data.personalInfo.summary}" +

+
+ )} -
-

- {" "} - {t("sections.experience")} -

-
- {data.experiences.map((exp) => ( -
-
-
-
-

- {exp.role} -

-

- {exp.company} -

-
- - {exp.startDate} — {exp.endDate} - -
-
    - {exp.mission.map((m, i) => ( -
  • - {m} -
  • - ))} -
-
- ))} -
-
+ {data.experiences.length > 0 && ( +
+

+ {" "} + {t("sections.experience")} +

+
+ {data.experiences.map((exp) => ( +
+
+
+
+

+ {exp.role} +

+

+ {exp.company} +

+
+ + {exp.startDate} — {exp.endDate} + +
+
    + {exp.mission.map((m, i) => ( +
  • + {m} +
  • + ))} +
+
+ ))} +
+
+ )} - {data.educations.length > 0 && ( -
-

- {" "} - {t("sections.education")} -

-
- {data.educations.map((edu) => ( -
-
-

- {edu.degree} -

-

- {edu.school} -

-
-

- {edu.year} -

-
- ))} -
-
- )} + {data.educations.length > 0 && ( +
+

+ {" "} + {t("sections.education")} +

+
+ {data.educations.map((edu) => ( +
+
+

+ {edu.degree} +

+

+ {edu.school} +

+
+

+ {edu.year} +

+
+ ))} +
+
+ )} - {data.certifications && data.certifications.length > 0 && ( -
-

- {" "} - {t("sections.certifications")} -

-
- {data.certifications.map((cert) => ( -
-
- -
-
-
-

- {cert.name} -

- - {cert.year} - -
- {cert.issuer && ( -

- {cert.issuer} -

- )} -
-
- ))} -
-
- )} -
-
- ); + {data.certifications && data.certifications.length > 0 && ( +
+

+ {" "} + {t("sections.certifications")} +

+
+ {data.certifications.map((cert) => ( +
+
+ +
+
+
+

+ {cert.name} +

+ + {cert.year} + +
+ {cert.issuer && ( +

+ {cert.issuer} +

+ )} +
+
+ ))} +
+
+ )} +
+
+ ); }; diff --git a/src/features/cv-preview/themes/NeoBentoTheme.tsx b/src/features/cv-preview/themes/NeoBentoTheme.tsx index 90115bf..17a191e 100644 --- a/src/features/cv-preview/themes/NeoBentoTheme.tsx +++ b/src/features/cv-preview/themes/NeoBentoTheme.tsx @@ -14,17 +14,19 @@ export const NeoBentoTheme = ({ data }: { data: CVData }) => { }); return ( -
-
+
{data.personalInfo.photoUrl && ( - {data.personalInfo.fullName} +
+ {`Photo +
)}

@@ -33,169 +35,192 @@ export const NeoBentoTheme = ({ data }: { data: CVData }) => {

{data.personalInfo.title || t("defaultTitle")}

-
- {data.personalInfo.contacts.map((c) => { - const Icon = - CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; - - return ( - - {c.value} - - ); - })} -
-

-
- -
-
-
-

- {t("sections.summary")} -

-

- {data.personalInfo.summary} -

-
- -
-

- {t("sections.skills")} -

-
- {data.skills.map((s, i) => ( - - {s} - - ))} -
-
- -
-

- {t("sections.socials") || "RESEAUX & LIENS"} -

-
- {data.personalInfo.socials.map((social) => { - const Icon = - SOCIAL_ICONS[social.platform.toLowerCase() as SocialType] || - ExternalLink; + {data.personalInfo.contacts?.length > 0 && ( +
+ {data.personalInfo.contacts.map((c) => { + const Icon = CONTACT_ICONS[c.label.toLowerCase() as ContactType] || Globe; return ( -
- - - {social.url.replace(/^https?:\/\/(www\.)?/, "")} - -
+
-
- -
-

- {t("sections.languages")} -

-
- {data.languages?.map((lang) => ( -
- {lang.name} - {lang.level} -
- ))} -
-
+ + )}
+ -
-
-

- {t("sections.experience")} -

-
- {data.experiences.map((exp) => ( -
-
-

- {exp.role} -

- - {exp.startDate} — {exp.endDate} - -
-

- {exp.company} -

-
    - {exp.mission.map((m, i) => ( -
  • +
- ))} -
-
-
-

- {t("sections.education")} -

- {data.educations.map((edu) => ( -
-
-

- {edu.degree} -

- - {edu.year} - -
-

- {edu.school} -

+
+ + ); + })} + + + )} + + {data.languages?.length > 0 && ( +
+

+ {t("sections.languages")} +

+
+ {data.languages.map((lang) => ( +
+
{lang.name}
+
{lang.level}
+
+ ))} +
+
+ )} + + +
+ {data.experiences?.length > 0 && ( +
+

+ {t("sections.experience")} +

+
+ {data.experiences.map((exp) => ( +
+
+
+

+ {exp.role} +

+

+ {exp.company} +

+
+ +
+ {exp.mission?.length > 0 && ( +
    + {exp.mission.map((m, i) => ( +
  • + • {m} +
  • + ))} +
+ )} +
+ ))}
- ))} -
+ + )} -
-

- {t("sections.certifications")} -

- {data.certifications?.map((cert) => ( -
-
-

- {cert.name} -

- - {cert.year} - -
-

- {cert.issuer} -

+ {data.educations?.length > 0 && ( +
+

+ {t("sections.education")} +

+
+ {data.educations.map((edu) => ( +
+
+

+ {edu.degree} +

+

+ {edu.school} +

+
+ +
+ ))}
- ))} -
+ + )} + + {data.certifications?.length > 0 && ( +
+

+ {t("sections.certifications")} +

+
+ {data.certifications.map((cert) => ( +
+
+

+ {cert.name} +

+

+ {cert.issuer} +

+
+ +
+ ))} +
+
+ )}
-
+ +
+ {t("lastModified")} {new Date(data.metadata.lastModified).toLocaleDateString()} +
+ ); -}; +}; \ No newline at end of file diff --git a/src/features/cv-preview/themes/StandardTheme.tsx b/src/features/cv-preview/themes/StandardTheme.tsx index be1036c..3b1ff6c 100644 --- a/src/features/cv-preview/themes/StandardTheme.tsx +++ b/src/features/cv-preview/themes/StandardTheme.tsx @@ -79,7 +79,7 @@ export const StandardTheme = ({ data }: { data: CVData }) => {
-
+ {data.experiences?.length > 0 &&

{t("sections.experience")}

@@ -120,7 +120,7 @@ export const StandardTheme = ({ data }: { data: CVData }) => {
))}
- + } {data.educations.length > 0 && (