@ginia/ui 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/components/domain/resume/resume-preview/resume-preview.cjs +23 -19
  2. package/dist/components/domain/resume/resume-preview/resume-preview.cjs.map +1 -1
  3. package/dist/components/domain/resume/resume-preview/resume-preview.js +23 -19
  4. package/dist/components/domain/resume/resume-preview/resume-preview.js.map +1 -1
  5. package/dist/components/domain/resume/resume-preview/sections/experience-education.cjs +32 -4
  6. package/dist/components/domain/resume/resume-preview/sections/experience-education.cjs.map +1 -1
  7. package/dist/components/domain/resume/resume-preview/sections/experience-education.js +32 -4
  8. package/dist/components/domain/resume/resume-preview/sections/experience-education.js.map +1 -1
  9. package/dist/components/domain/resume/resume-preview/sections/header-preview.cjs +2 -2
  10. package/dist/components/domain/resume/resume-preview/sections/header-preview.cjs.map +1 -1
  11. package/dist/components/domain/resume/resume-preview/sections/header-preview.js +2 -2
  12. package/dist/components/domain/resume/resume-preview/sections/header-preview.js.map +1 -1
  13. package/dist/components/domain/resume/resume.cjs +33 -1
  14. package/dist/components/domain/resume/resume.cjs.map +1 -1
  15. package/dist/components/domain/resume/resume.js +33 -1
  16. package/dist/components/domain/resume/resume.js.map +1 -1
  17. package/dist/components/ui/background/background.cjs +80 -0
  18. package/dist/components/ui/background/background.cjs.map +1 -0
  19. package/dist/components/ui/background/background.d.cts +23 -0
  20. package/dist/components/ui/background/background.d.ts +23 -0
  21. package/dist/components/ui/background/background.js +44 -0
  22. package/dist/components/ui/background/background.js.map +1 -0
  23. package/dist/components/ui/background/index.cjs +33 -0
  24. package/dist/components/ui/background/index.cjs.map +1 -0
  25. package/dist/components/ui/background/index.d.cts +2 -0
  26. package/dist/components/ui/background/index.d.ts +2 -0
  27. package/dist/components/ui/background/index.js +7 -0
  28. package/dist/components/ui/background/index.js.map +1 -0
  29. package/dist/components/ui/index.cjs +2 -0
  30. package/dist/components/ui/index.cjs.map +1 -1
  31. package/dist/components/ui/index.d.cts +1 -0
  32. package/dist/components/ui/index.d.ts +1 -0
  33. package/dist/components/ui/index.js +1 -0
  34. package/dist/components/ui/index.js.map +1 -1
  35. package/dist/index.d.cts +1 -0
  36. package/dist/index.d.ts +1 -0
  37. package/package.json +1 -1
@@ -33,6 +33,7 @@ __export(resume_preview_exports, {
33
33
  module.exports = __toCommonJS(resume_preview_exports);
34
34
  var import_jsx_runtime = require("react/jsx-runtime");
35
35
  var React = __toESM(require("react"), 1);
36
+ var import_ui = require("../../../ui");
36
37
  var import_header_preview = require("./sections/header-preview");
37
38
  var import_contact_skills = require("./sections/contact-skills");
38
39
  var import_experience_education = require("./sections/experience-education");
@@ -47,6 +48,7 @@ const ResumePreview = React.forwardRef(
47
48
  id: "resume-capture-area",
48
49
  className: "relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16",
49
50
  children: [
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ui.Background, {}),
50
52
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51
53
  "div",
52
54
  {
@@ -54,29 +56,31 @@ const ResumePreview = React.forwardRef(
54
56
  style: themeStyle
55
57
  }
56
58
  ),
57
- !hideSections.includes("Informaci\xF3n personal") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
58
- import_header_preview.HeaderPreview,
59
- {
60
- data,
61
- headerSlot,
62
- theme,
63
- hideFields
64
- }
65
- ),
66
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12", children: [
67
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-8 lg:col-span-4 lg:pr-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_contact_skills.ContactSkills, { data, hideFields, hideSections }) }),
68
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block" }),
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-8 lg:col-span-8", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
70
- import_experience_education.ExperienceEducation,
59
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative z-10", children: [
60
+ !hideSections.includes("Informaci\xF3n personal") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
61
+ import_header_preview.HeaderPreview,
71
62
  {
72
63
  data,
64
+ headerSlot,
73
65
  theme,
74
- hideFields,
75
- hideSections
66
+ hideFields
76
67
  }
77
- ) })
78
- ] }),
79
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_footer_preview.FooterPreview, {})
68
+ ),
69
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12", children: [
70
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-8 lg:col-span-4 lg:pr-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_contact_skills.ContactSkills, { data, hideFields, hideSections }) }),
71
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block" }),
72
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-8 lg:col-span-8", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
73
+ import_experience_education.ExperienceEducation,
74
+ {
75
+ data,
76
+ theme,
77
+ hideFields,
78
+ hideSections
79
+ }
80
+ ) })
81
+ ] }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_footer_preview.FooterPreview, {})
83
+ ] })
80
84
  ]
81
85
  }
82
86
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/domain/resume/resume-preview/resume-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../types\";\nimport { HeaderPreview } from \"./sections/header-preview\";\nimport { ContactSkills } from \"./sections/contact-skills\";\nimport { ExperienceEducation } from \"./sections/experience-education\";\nimport { FooterPreview } from \"./sections/footer-preview\";\n\nexport interface ResumePreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport const ResumePreview = React.forwardRef<HTMLDivElement, ResumePreviewProps>(\n function ResumePreview({ data, headerSlot, theme, hideFields = [], hideSections = [] }, ref) {\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div\n ref={ref}\n id=\"resume-capture-area\"\n className=\"relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16\"\n >\n {/* Subtle decorative top bar */}\n <div\n className={`absolute left-0 top-0 h-2 w-full ${theme ? \"\" : \"bg-gradient-to-r from-primary to-primary/50\"}`}\n style={themeStyle}\n />\n\n {/* Header Profile */}\n {!hideSections.includes(\"Información personal\") && (\n <HeaderPreview\n data={data}\n headerSlot={headerSlot}\n theme={theme}\n hideFields={hideFields}\n />\n )}\n\n {/* Main Content Layout */}\n <div className=\"mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12\">\n {/* Left Column (4/12) */}\n <div className=\"space-y-8 lg:col-span-4 lg:pr-6\">\n <ContactSkills data={data} hideFields={hideFields} hideSections={hideSections} />\n </div>\n\n {/* Vertical Divider for desktop */}\n <div className=\"absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block\" />\n\n {/* Right Column (8/12) */}\n <div className=\"space-y-8 lg:col-span-8\">\n <ExperienceEducation\n data={data}\n theme={theme}\n hideFields={hideFields}\n hideSections={hideSections}\n />\n </div>\n </div>\n\n <FooterPreview />\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BQ;AA1BR,YAAuB;AAEvB,4BAA8B;AAC9B,4BAA8B;AAC9B,kCAAoC;AACpC,4BAA8B;AAUvB,MAAM,gBAAgB,MAAM;AAAA,EACjC,SAASA,eAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK;AAC3F,UAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAG;AAAA,QACH,WAAU;AAAA,QAGV;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,oCAAoC,QAAQ,KAAK,6CAA6C;AAAA,cACzG,OAAO;AAAA;AAAA,UACT;AAAA,UAGC,CAAC,aAAa,SAAS,yBAAsB,KAC5C;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA;AAAA,UACF;AAAA,UAIF,6CAAC,SAAI,WAAU,gDAEb;AAAA,wDAAC,SAAI,WAAU,mCACb,sDAAC,uCAAc,MAAY,YAAwB,cAA4B,GACjF;AAAA,YAGA,4CAAC,SAAI,WAAU,6EAA4E;AAAA,YAG3F,4CAAC,SAAI,WAAU,2BACb;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF,GACF;AAAA,aACF;AAAA,UAEA,4CAAC,uCAAc;AAAA;AAAA;AAAA,IACjB;AAAA,EAEJ;AACF;","names":["ResumePreview"]}
1
+ {"version":3,"sources":["../../../../../src/components/domain/resume/resume-preview/resume-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../types\";\nimport { Background } from \"../../../ui\";\nimport { HeaderPreview } from \"./sections/header-preview\";\nimport { ContactSkills } from \"./sections/contact-skills\";\nimport { ExperienceEducation } from \"./sections/experience-education\";\nimport { FooterPreview } from \"./sections/footer-preview\";\n\nexport interface ResumePreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport const ResumePreview = React.forwardRef<HTMLDivElement, ResumePreviewProps>(\n function ResumePreview({ data, headerSlot, theme, hideFields = [], hideSections = [] }, ref) {\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div\n ref={ref}\n id=\"resume-capture-area\"\n className=\"relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16\"\n >\n <Background />\n <div\n className={`absolute left-0 top-0 h-2 w-full ${theme ? \"\" : \"bg-gradient-to-r from-primary to-primary/50\"}`}\n style={themeStyle}\n />\n {/* Content layer — above background */}\n <div className=\"relative z-10\">\n {/* Subtle decorative top bar */}\n\n\n {/* Header Profile */}\n {!hideSections.includes(\"Información personal\") && (\n <HeaderPreview\n data={data}\n headerSlot={headerSlot}\n theme={theme}\n hideFields={hideFields}\n />\n )}\n\n {/* Main Content Layout */}\n <div className=\"mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12\">\n {/* Left Column (4/12) */}\n <div className=\"space-y-8 lg:col-span-4 lg:pr-6\">\n <ContactSkills data={data} hideFields={hideFields} hideSections={hideSections} />\n </div>\n\n {/* Vertical Divider for desktop */}\n <div className=\"absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block\" />\n\n {/* Right Column (8/12) */}\n <div className=\"space-y-8 lg:col-span-8\">\n <ExperienceEducation\n data={data}\n theme={theme}\n hideFields={hideFields}\n hideSections={hideSections}\n />\n </div>\n </div>\n\n <FooterPreview />\n </div>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BQ;AA1BR,YAAuB;AAEvB,gBAA2B;AAC3B,4BAA8B;AAC9B,4BAA8B;AAC9B,kCAAoC;AACpC,4BAA8B;AAUvB,MAAM,gBAAgB,MAAM;AAAA,EACjC,SAASA,eAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK;AAC3F,UAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAG;AAAA,QACH,WAAU;AAAA,QAEV;AAAA,sDAAC,wBAAW;AAAA,UACZ;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,oCAAoC,QAAQ,KAAK,6CAA6C;AAAA,cACzG,OAAO;AAAA;AAAA,UACT;AAAA,UAEA,6CAAC,SAAI,WAAU,iBAKZ;AAAA,aAAC,aAAa,SAAS,yBAAsB,KAC5C;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF;AAAA,YAIF,6CAAC,SAAI,WAAU,gDAEb;AAAA,0DAAC,SAAI,WAAU,mCACb,sDAAC,uCAAc,MAAY,YAAwB,cAA4B,GACjF;AAAA,cAGA,4CAAC,SAAI,WAAU,6EAA4E;AAAA,cAG3F,4CAAC,SAAI,WAAU,2BACb;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA;AAAA,cACF,GACF;AAAA,eACF;AAAA,YAEA,4CAAC,uCAAc;AAAA,aACjB;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;","names":["ResumePreview"]}
@@ -1,5 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
+ import { Background } from "../../../ui";
3
4
  import { HeaderPreview } from "./sections/header-preview";
4
5
  import { ContactSkills } from "./sections/contact-skills";
5
6
  import { ExperienceEducation } from "./sections/experience-education";
@@ -14,6 +15,7 @@ const ResumePreview = React.forwardRef(
14
15
  id: "resume-capture-area",
15
16
  className: "relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16",
16
17
  children: [
18
+ /* @__PURE__ */ jsx(Background, {}),
17
19
  /* @__PURE__ */ jsx(
18
20
  "div",
19
21
  {
@@ -21,29 +23,31 @@ const ResumePreview = React.forwardRef(
21
23
  style: themeStyle
22
24
  }
23
25
  ),
24
- !hideSections.includes("Informaci\xF3n personal") && /* @__PURE__ */ jsx(
25
- HeaderPreview,
26
- {
27
- data,
28
- headerSlot,
29
- theme,
30
- hideFields
31
- }
32
- ),
33
- /* @__PURE__ */ jsxs("div", { className: "mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12", children: [
34
- /* @__PURE__ */ jsx("div", { className: "space-y-8 lg:col-span-4 lg:pr-6", children: /* @__PURE__ */ jsx(ContactSkills, { data, hideFields, hideSections }) }),
35
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block" }),
36
- /* @__PURE__ */ jsx("div", { className: "space-y-8 lg:col-span-8", children: /* @__PURE__ */ jsx(
37
- ExperienceEducation,
26
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10", children: [
27
+ !hideSections.includes("Informaci\xF3n personal") && /* @__PURE__ */ jsx(
28
+ HeaderPreview,
38
29
  {
39
30
  data,
31
+ headerSlot,
40
32
  theme,
41
- hideFields,
42
- hideSections
33
+ hideFields
43
34
  }
44
- ) })
45
- ] }),
46
- /* @__PURE__ */ jsx(FooterPreview, {})
35
+ ),
36
+ /* @__PURE__ */ jsxs("div", { className: "mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12", children: [
37
+ /* @__PURE__ */ jsx("div", { className: "space-y-8 lg:col-span-4 lg:pr-6", children: /* @__PURE__ */ jsx(ContactSkills, { data, hideFields, hideSections }) }),
38
+ /* @__PURE__ */ jsx("div", { className: "absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block" }),
39
+ /* @__PURE__ */ jsx("div", { className: "space-y-8 lg:col-span-8", children: /* @__PURE__ */ jsx(
40
+ ExperienceEducation,
41
+ {
42
+ data,
43
+ theme,
44
+ hideFields,
45
+ hideSections
46
+ }
47
+ ) })
48
+ ] }),
49
+ /* @__PURE__ */ jsx(FooterPreview, {})
50
+ ] })
47
51
  ]
48
52
  }
49
53
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/domain/resume/resume-preview/resume-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../types\";\nimport { HeaderPreview } from \"./sections/header-preview\";\nimport { ContactSkills } from \"./sections/contact-skills\";\nimport { ExperienceEducation } from \"./sections/experience-education\";\nimport { FooterPreview } from \"./sections/footer-preview\";\n\nexport interface ResumePreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport const ResumePreview = React.forwardRef<HTMLDivElement, ResumePreviewProps>(\n function ResumePreview({ data, headerSlot, theme, hideFields = [], hideSections = [] }, ref) {\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div\n ref={ref}\n id=\"resume-capture-area\"\n className=\"relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16\"\n >\n {/* Subtle decorative top bar */}\n <div\n className={`absolute left-0 top-0 h-2 w-full ${theme ? \"\" : \"bg-gradient-to-r from-primary to-primary/50\"}`}\n style={themeStyle}\n />\n\n {/* Header Profile */}\n {!hideSections.includes(\"Información personal\") && (\n <HeaderPreview\n data={data}\n headerSlot={headerSlot}\n theme={theme}\n hideFields={hideFields}\n />\n )}\n\n {/* Main Content Layout */}\n <div className=\"mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12\">\n {/* Left Column (4/12) */}\n <div className=\"space-y-8 lg:col-span-4 lg:pr-6\">\n <ContactSkills data={data} hideFields={hideFields} hideSections={hideSections} />\n </div>\n\n {/* Vertical Divider for desktop */}\n <div className=\"absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block\" />\n\n {/* Right Column (8/12) */}\n <div className=\"space-y-8 lg:col-span-8\">\n <ExperienceEducation\n data={data}\n theme={theme}\n hideFields={hideFields}\n hideSections={hideSections}\n />\n </div>\n </div>\n\n <FooterPreview />\n </div>\n );\n },\n);\n"],"mappings":"AA0BQ,cAgBA,YAhBA;AA1BR,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAUvB,MAAM,gBAAgB,MAAM;AAAA,EACjC,SAASA,eAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK;AAC3F,UAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAG;AAAA,QACH,WAAU;AAAA,QAGV;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,oCAAoC,QAAQ,KAAK,6CAA6C;AAAA,cACzG,OAAO;AAAA;AAAA,UACT;AAAA,UAGC,CAAC,aAAa,SAAS,yBAAsB,KAC5C;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA;AAAA,UACF;AAAA,UAIF,qBAAC,SAAI,WAAU,gDAEb;AAAA,gCAAC,SAAI,WAAU,mCACb,8BAAC,iBAAc,MAAY,YAAwB,cAA4B,GACjF;AAAA,YAGA,oBAAC,SAAI,WAAU,6EAA4E;AAAA,YAG3F,oBAAC,SAAI,WAAU,2BACb;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF,GACF;AAAA,aACF;AAAA,UAEA,oBAAC,iBAAc;AAAA;AAAA;AAAA,IACjB;AAAA,EAEJ;AACF;","names":["ResumePreview"]}
1
+ {"version":3,"sources":["../../../../../src/components/domain/resume/resume-preview/resume-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../types\";\nimport { Background } from \"../../../ui\";\nimport { HeaderPreview } from \"./sections/header-preview\";\nimport { ContactSkills } from \"./sections/contact-skills\";\nimport { ExperienceEducation } from \"./sections/experience-education\";\nimport { FooterPreview } from \"./sections/footer-preview\";\n\nexport interface ResumePreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport const ResumePreview = React.forwardRef<HTMLDivElement, ResumePreviewProps>(\n function ResumePreview({ data, headerSlot, theme, hideFields = [], hideSections = [] }, ref) {\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div\n ref={ref}\n id=\"resume-capture-area\"\n className=\"relative mx-auto flex min-h-[1056px] w-full flex-col rounded-sm border border-border bg-card p-8 text-card-foreground shadow-2xl sm:p-12 md:p-16\"\n >\n <Background />\n <div\n className={`absolute left-0 top-0 h-2 w-full ${theme ? \"\" : \"bg-gradient-to-r from-primary to-primary/50\"}`}\n style={themeStyle}\n />\n {/* Content layer — above background */}\n <div className=\"relative z-10\">\n {/* Subtle decorative top bar */}\n\n\n {/* Header Profile */}\n {!hideSections.includes(\"Información personal\") && (\n <HeaderPreview\n data={data}\n headerSlot={headerSlot}\n theme={theme}\n hideFields={hideFields}\n />\n )}\n\n {/* Main Content Layout */}\n <div className=\"mt-8 grid grid-cols-1 gap-10 lg:grid-cols-12\">\n {/* Left Column (4/12) */}\n <div className=\"space-y-8 lg:col-span-4 lg:pr-6\">\n <ContactSkills data={data} hideFields={hideFields} hideSections={hideSections} />\n </div>\n\n {/* Vertical Divider for desktop */}\n <div className=\"absolute bottom-16 left-[33.33%] top-48 hidden w-px bg-border/40 lg:block\" />\n\n {/* Right Column (8/12) */}\n <div className=\"space-y-8 lg:col-span-8\">\n <ExperienceEducation\n data={data}\n theme={theme}\n hideFields={hideFields}\n hideSections={hideSections}\n />\n </div>\n </div>\n\n <FooterPreview />\n </div>\n </div>\n );\n },\n);\n"],"mappings":"AA0BQ,cAqBE,YArBF;AA1BR,YAAY,WAAW;AAEvB,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAUvB,MAAM,gBAAgB,MAAM;AAAA,EACjC,SAASA,eAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK;AAC3F,UAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAG;AAAA,QACH,WAAU;AAAA,QAEV;AAAA,8BAAC,cAAW;AAAA,UACZ;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,oCAAoC,QAAQ,KAAK,6CAA6C;AAAA,cACzG,OAAO;AAAA;AAAA,UACT;AAAA,UAEA,qBAAC,SAAI,WAAU,iBAKZ;AAAA,aAAC,aAAa,SAAS,yBAAsB,KAC5C;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF;AAAA,YAIF,qBAAC,SAAI,WAAU,gDAEb;AAAA,kCAAC,SAAI,WAAU,mCACb,8BAAC,iBAAc,MAAY,YAAwB,cAA4B,GACjF;AAAA,cAGA,oBAAC,SAAI,WAAU,6EAA4E;AAAA,cAG3F,oBAAC,SAAI,WAAU,2BACb;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA;AAAA,cACF,GACF;AAAA,eACF;AAAA,YAEA,oBAAC,iBAAc;AAAA,aACjB;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;","names":["ResumePreview"]}
@@ -23,16 +23,44 @@ __export(experience_education_exports, {
23
23
  module.exports = __toCommonJS(experience_education_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_lucide_react = require("lucide-react");
26
+ function parseDateToSortValue(dateStr) {
27
+ if (!dateStr || dateStr.toLowerCase() === "presente") return 0;
28
+ const mmYyyy = dateStr.match(/^(\d{1,2})\/(\d{4})$/);
29
+ if (mmYyyy) return parseInt(mmYyyy[2], 10) * 12 + parseInt(mmYyyy[1], 10);
30
+ const yyyyMm = dateStr.match(/^(\d{4})-(\d{1,2})/);
31
+ if (yyyyMm) return parseInt(yyyyMm[1], 10) * 12 + parseInt(yyyyMm[2], 10);
32
+ const year = dateStr.match(/\d{4}/);
33
+ if (year) return parseInt(year[0], 10) * 12;
34
+ return 0;
35
+ }
36
+ function sortByDateDesc(items) {
37
+ return [...items].sort((a, b) => {
38
+ const aEnd = a.end_date?.toLowerCase();
39
+ const bEnd = b.end_date?.toLowerCase();
40
+ const aOngoing = !a.end_date || aEnd === "presente";
41
+ const bOngoing = !b.end_date || bEnd === "presente";
42
+ const aVal = aOngoing ? parseDateToSortValue(a.start_date) + 9999 * 12 : parseDateToSortValue(a.end_date);
43
+ const bVal = bOngoing ? parseDateToSortValue(b.start_date) + 9999 * 12 : parseDateToSortValue(b.end_date);
44
+ return bVal - aVal;
45
+ });
46
+ }
47
+ function sortCertificationsByDateDesc(items) {
48
+ return [...items].sort((a, b) => {
49
+ const aVal = parseDateToSortValue(a.date_awarded);
50
+ const bVal = parseDateToSortValue(b.date_awarded);
51
+ return bVal - aVal;
52
+ });
53
+ }
26
54
  function ExperienceEducation({
27
55
  data,
28
56
  theme,
29
57
  hideFields = [],
30
58
  hideSections = []
31
59
  }) {
32
- const experiences = data.work_experience || [];
33
- const education = data.education || [];
34
- const activities = data.activities || [];
35
- const certifications = data.certifications || [];
60
+ const experiences = sortByDateDesc(data.work_experience || []);
61
+ const education = sortByDateDesc(data.education || []);
62
+ const activities = sortByDateDesc(data.activities || []);
63
+ const certifications = sortCertificationsByDateDesc(data.certifications || []);
36
64
  const themeStyle = theme ? { backgroundColor: theme } : void 0;
37
65
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-12", children: [
38
66
  experiences.length > 0 && !hideSections.includes("Experiencia laboral") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-6", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/experience-education.tsx"],"sourcesContent":["import { CandidateProfile } from \"../../types\";\nimport { GraduationCap, Briefcase, Trophy, Award } from \"lucide-react\";\n\ninterface ExperienceEducationProps {\n data: CandidateProfile;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport function ExperienceEducation({\n data,\n theme,\n hideFields = [],\n hideSections = [],\n}: ExperienceEducationProps) {\n const experiences = data.work_experience || [];\n const education = data.education || [];\n const activities = data.activities || [];\n const certifications = data.certifications || [];\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"space-y-12\">\n {/* Experience */}\n {experiences.length > 0 && !hideSections.includes(\"Experiencia laboral\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Briefcase className=\"h-6 w-6 text-primary\" />\n Experiencia Laboral\n </h3>\n <div className=\"space-y-8\">\n {experiences.map((exp) => (\n <div\n key={exp.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"experience.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{exp.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"experience.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {exp.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"experience.start_date\") ||\n !hideFields.includes(\"experience.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"experience.start_date\") && exp.start_date}\n {!hideFields.includes(\"experience.end_date\") && (\n <> {exp.end_date ? `- ${exp.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {exp.description && !hideFields.includes(\"experience.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {exp.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Education */}\n {education.length > 0 && !hideSections.includes(\"Educación\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <GraduationCap className=\"h-6 w-6 text-primary\" />\n Educación\n </h3>\n <div className=\"space-y-8\">\n {education.map((edu) => (\n <div\n key={edu.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"education.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{edu.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"education.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {edu.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"education.start_date\") ||\n !hideFields.includes(\"education.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"education.start_date\") && edu.start_date}\n {!hideFields.includes(\"education.end_date\") && (\n <> {edu.end_date ? `- ${edu.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {edu.description && !hideFields.includes(\"education.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {edu.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Activities */}\n {activities.length > 0 && !hideSections.includes(\"Actividades y Logros\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Trophy className=\"h-6 w-6 text-primary\" />\n Actividades y Logros\n </h3>\n <div className=\"space-y-8\">\n {activities.map((act) => (\n <div\n key={act.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"activities.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{act.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"activities.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {act.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"activities.start_date\") ||\n !hideFields.includes(\"activities.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"activities.start_date\") && act.start_date}\n {!hideFields.includes(\"activities.end_date\") && (\n <> {act.end_date ? `- ${act.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {act.description && !hideFields.includes(\"activities.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {act.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Certifications */}\n {certifications.length > 0 && !hideSections.includes(\"Certificaciones\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Award className=\"h-6 w-6 text-primary\" />\n Certificaciones\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {certifications.map((cert) => (\n <div\n key={cert.id}\n className=\"rounded-lg border border-border/60 bg-card p-4 shadow-sm transition-colors hover:border-primary/30 hover:shadow-md\"\n >\n {!hideFields.includes(\"certifications.title\") && (\n <h4\n className=\"line-clamp-1 text-base font-bold text-foreground\"\n title={cert.title}\n >\n {cert.title}\n </h4>\n )}\n {!hideFields.includes(\"certifications.institution_name\") && (\n <p className=\"mt-1 line-clamp-1 text-sm text-muted-foreground\">\n {cert.institution_name}\n </p>\n )}\n <div className=\"mt-4 flex items-center justify-between\">\n {!hideFields.includes(\"certifications.date_awarded\") && (\n <span className=\"rounded-md bg-muted/50 px-2 py-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {cert.date_awarded}\n </span>\n )}\n {cert.verified && !hideFields.includes(\"certifications.verified\") && (\n <span\n className=\"pdf-badge rounded-full border px-2.5 py-1 text-xs font-bold transition-colors\"\n style={{\n backgroundColor: theme?.startsWith(\"#\") ? `${theme}15` : undefined,\n color: theme,\n borderColor: theme?.startsWith(\"#\") ? `${theme}30` : theme,\n }}\n >\n Verificado\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/experience-education.tsx"],"sourcesContent":["import { CandidateProfile } from \"../../types\";\nimport type { CVExperienceBaseItem, CVCertificationItem } from \"../../types\";\nimport { GraduationCap, Briefcase, Trophy, Award } from \"lucide-react\";\n\n/** Parsea una fecha (MM/YYYY, YYYY-MM o YYYY) a un valor numérico para ordenar (mayor = más reciente) */\nfunction parseDateToSortValue(dateStr: string | undefined): number {\n if (!dateStr || dateStr.toLowerCase() === \"presente\") return 0;\n // MM/YYYY\n const mmYyyy = dateStr.match(/^(\\d{1,2})\\/(\\d{4})$/);\n if (mmYyyy) return parseInt(mmYyyy[2], 10) * 12 + parseInt(mmYyyy[1], 10);\n // YYYY-MM o YYYY-MM-DD\n const yyyyMm = dateStr.match(/^(\\d{4})-(\\d{1,2})/);\n if (yyyyMm) return parseInt(yyyyMm[1], 10) * 12 + parseInt(yyyyMm[2], 10);\n // Solo año\n const year = dateStr.match(/\\d{4}/);\n if (year) return parseInt(year[0], 10) * 12;\n return 0;\n}\n\n/** Ordena descendente por fecha de fin; si no hay end_date (Presente), usa start_date y prioriza como más reciente */\nfunction sortByDateDesc<T extends CVExperienceBaseItem>(items: T[]): T[] {\n return [...items].sort((a, b) => {\n const aEnd = a.end_date?.toLowerCase();\n const bEnd = b.end_date?.toLowerCase();\n const aOngoing = !a.end_date || aEnd === \"presente\";\n const bOngoing = !b.end_date || bEnd === \"presente\";\n const aVal = aOngoing ? parseDateToSortValue(a.start_date) + 9999 * 12 : parseDateToSortValue(a.end_date);\n const bVal = bOngoing ? parseDateToSortValue(b.start_date) + 9999 * 12 : parseDateToSortValue(b.end_date);\n return bVal - aVal;\n });\n}\n\n/** Ordena certificaciones descendente por date_awarded */\nfunction sortCertificationsByDateDesc(items: CVCertificationItem[]): CVCertificationItem[] {\n return [...items].sort((a, b) => {\n const aVal = parseDateToSortValue(a.date_awarded);\n const bVal = parseDateToSortValue(b.date_awarded);\n return bVal - aVal;\n });\n}\n\ninterface ExperienceEducationProps {\n data: CandidateProfile;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport function ExperienceEducation({\n data,\n theme,\n hideFields = [],\n hideSections = [],\n}: ExperienceEducationProps) {\n const experiences = sortByDateDesc(data.work_experience || []);\n const education = sortByDateDesc(data.education || []);\n const activities = sortByDateDesc(data.activities || []);\n const certifications = sortCertificationsByDateDesc(data.certifications || []);\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"space-y-12\">\n {/* Experience */}\n {experiences.length > 0 && !hideSections.includes(\"Experiencia laboral\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Briefcase className=\"h-6 w-6 text-primary\" />\n Experiencia Laboral\n </h3>\n <div className=\"space-y-8\">\n {experiences.map((exp) => (\n <div\n key={exp.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"experience.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{exp.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"experience.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {exp.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"experience.start_date\") ||\n !hideFields.includes(\"experience.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"experience.start_date\") && exp.start_date}\n {!hideFields.includes(\"experience.end_date\") && (\n <> {exp.end_date ? `- ${exp.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {exp.description && !hideFields.includes(\"experience.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {exp.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Education */}\n {education.length > 0 && !hideSections.includes(\"Educación\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <GraduationCap className=\"h-6 w-6 text-primary\" />\n Educación\n </h3>\n <div className=\"space-y-8\">\n {education.map((edu) => (\n <div\n key={edu.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"education.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{edu.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"education.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {edu.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"education.start_date\") ||\n !hideFields.includes(\"education.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"education.start_date\") && edu.start_date}\n {!hideFields.includes(\"education.end_date\") && (\n <> {edu.end_date ? `- ${edu.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {edu.description && !hideFields.includes(\"education.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {edu.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Activities */}\n {activities.length > 0 && !hideSections.includes(\"Actividades y Logros\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Trophy className=\"h-6 w-6 text-primary\" />\n Actividades y Logros\n </h3>\n <div className=\"space-y-8\">\n {activities.map((act) => (\n <div\n key={act.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"activities.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{act.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"activities.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {act.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"activities.start_date\") ||\n !hideFields.includes(\"activities.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"activities.start_date\") && act.start_date}\n {!hideFields.includes(\"activities.end_date\") && (\n <> {act.end_date ? `- ${act.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {act.description && !hideFields.includes(\"activities.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {act.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Certifications */}\n {certifications.length > 0 && !hideSections.includes(\"Certificaciones\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Award className=\"h-6 w-6 text-primary\" />\n Certificaciones\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {certifications.map((cert) => (\n <div\n key={cert.id}\n className=\"rounded-lg border border-border/60 bg-card p-4 shadow-sm transition-colors hover:border-primary/30 hover:shadow-md\"\n >\n {!hideFields.includes(\"certifications.title\") && (\n <h4\n className=\"line-clamp-1 text-base font-bold text-foreground\"\n title={cert.title}\n >\n {cert.title}\n </h4>\n )}\n {!hideFields.includes(\"certifications.institution_name\") && (\n <p className=\"mt-1 line-clamp-1 text-sm text-muted-foreground\">\n {cert.institution_name}\n </p>\n )}\n <div className=\"mt-4 flex items-center justify-between\">\n {!hideFields.includes(\"certifications.date_awarded\") && (\n <span className=\"rounded-md bg-muted/50 px-2 py-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {cert.date_awarded}\n </span>\n )}\n {cert.verified && !hideFields.includes(\"certifications.verified\") && (\n <span\n className=\"pdf-badge rounded-full border px-2.5 py-1 text-xs font-bold transition-colors\"\n style={{\n backgroundColor: theme?.startsWith(\"#\") ? `${theme}15` : undefined,\n color: theme,\n borderColor: theme?.startsWith(\"#\") ? `${theme}30` : theme,\n }}\n >\n Verificado\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,15 +1,43 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { GraduationCap, Briefcase, Trophy, Award } from "lucide-react";
3
+ function parseDateToSortValue(dateStr) {
4
+ if (!dateStr || dateStr.toLowerCase() === "presente") return 0;
5
+ const mmYyyy = dateStr.match(/^(\d{1,2})\/(\d{4})$/);
6
+ if (mmYyyy) return parseInt(mmYyyy[2], 10) * 12 + parseInt(mmYyyy[1], 10);
7
+ const yyyyMm = dateStr.match(/^(\d{4})-(\d{1,2})/);
8
+ if (yyyyMm) return parseInt(yyyyMm[1], 10) * 12 + parseInt(yyyyMm[2], 10);
9
+ const year = dateStr.match(/\d{4}/);
10
+ if (year) return parseInt(year[0], 10) * 12;
11
+ return 0;
12
+ }
13
+ function sortByDateDesc(items) {
14
+ return [...items].sort((a, b) => {
15
+ const aEnd = a.end_date?.toLowerCase();
16
+ const bEnd = b.end_date?.toLowerCase();
17
+ const aOngoing = !a.end_date || aEnd === "presente";
18
+ const bOngoing = !b.end_date || bEnd === "presente";
19
+ const aVal = aOngoing ? parseDateToSortValue(a.start_date) + 9999 * 12 : parseDateToSortValue(a.end_date);
20
+ const bVal = bOngoing ? parseDateToSortValue(b.start_date) + 9999 * 12 : parseDateToSortValue(b.end_date);
21
+ return bVal - aVal;
22
+ });
23
+ }
24
+ function sortCertificationsByDateDesc(items) {
25
+ return [...items].sort((a, b) => {
26
+ const aVal = parseDateToSortValue(a.date_awarded);
27
+ const bVal = parseDateToSortValue(b.date_awarded);
28
+ return bVal - aVal;
29
+ });
30
+ }
3
31
  function ExperienceEducation({
4
32
  data,
5
33
  theme,
6
34
  hideFields = [],
7
35
  hideSections = []
8
36
  }) {
9
- const experiences = data.work_experience || [];
10
- const education = data.education || [];
11
- const activities = data.activities || [];
12
- const certifications = data.certifications || [];
37
+ const experiences = sortByDateDesc(data.work_experience || []);
38
+ const education = sortByDateDesc(data.education || []);
39
+ const activities = sortByDateDesc(data.activities || []);
40
+ const certifications = sortCertificationsByDateDesc(data.certifications || []);
13
41
  const themeStyle = theme ? { backgroundColor: theme } : void 0;
14
42
  return /* @__PURE__ */ jsxs("div", { className: "space-y-12", children: [
15
43
  experiences.length > 0 && !hideSections.includes("Experiencia laboral") && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/experience-education.tsx"],"sourcesContent":["import { CandidateProfile } from \"../../types\";\nimport { GraduationCap, Briefcase, Trophy, Award } from \"lucide-react\";\n\ninterface ExperienceEducationProps {\n data: CandidateProfile;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport function ExperienceEducation({\n data,\n theme,\n hideFields = [],\n hideSections = [],\n}: ExperienceEducationProps) {\n const experiences = data.work_experience || [];\n const education = data.education || [];\n const activities = data.activities || [];\n const certifications = data.certifications || [];\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"space-y-12\">\n {/* Experience */}\n {experiences.length > 0 && !hideSections.includes(\"Experiencia laboral\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Briefcase className=\"h-6 w-6 text-primary\" />\n Experiencia Laboral\n </h3>\n <div className=\"space-y-8\">\n {experiences.map((exp) => (\n <div\n key={exp.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"experience.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{exp.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"experience.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {exp.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"experience.start_date\") ||\n !hideFields.includes(\"experience.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"experience.start_date\") && exp.start_date}\n {!hideFields.includes(\"experience.end_date\") && (\n <> {exp.end_date ? `- ${exp.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {exp.description && !hideFields.includes(\"experience.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {exp.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Education */}\n {education.length > 0 && !hideSections.includes(\"Educación\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <GraduationCap className=\"h-6 w-6 text-primary\" />\n Educación\n </h3>\n <div className=\"space-y-8\">\n {education.map((edu) => (\n <div\n key={edu.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"education.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{edu.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"education.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {edu.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"education.start_date\") ||\n !hideFields.includes(\"education.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"education.start_date\") && edu.start_date}\n {!hideFields.includes(\"education.end_date\") && (\n <> {edu.end_date ? `- ${edu.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {edu.description && !hideFields.includes(\"education.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {edu.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Activities */}\n {activities.length > 0 && !hideSections.includes(\"Actividades y Logros\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Trophy className=\"h-6 w-6 text-primary\" />\n Actividades y Logros\n </h3>\n <div className=\"space-y-8\">\n {activities.map((act) => (\n <div\n key={act.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"activities.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{act.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"activities.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {act.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"activities.start_date\") ||\n !hideFields.includes(\"activities.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"activities.start_date\") && act.start_date}\n {!hideFields.includes(\"activities.end_date\") && (\n <> {act.end_date ? `- ${act.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {act.description && !hideFields.includes(\"activities.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {act.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Certifications */}\n {certifications.length > 0 && !hideSections.includes(\"Certificaciones\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Award className=\"h-6 w-6 text-primary\" />\n Certificaciones\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {certifications.map((cert) => (\n <div\n key={cert.id}\n className=\"rounded-lg border border-border/60 bg-card p-4 shadow-sm transition-colors hover:border-primary/30 hover:shadow-md\"\n >\n {!hideFields.includes(\"certifications.title\") && (\n <h4\n className=\"line-clamp-1 text-base font-bold text-foreground\"\n title={cert.title}\n >\n {cert.title}\n </h4>\n )}\n {!hideFields.includes(\"certifications.institution_name\") && (\n <p className=\"mt-1 line-clamp-1 text-sm text-muted-foreground\">\n {cert.institution_name}\n </p>\n )}\n <div className=\"mt-4 flex items-center justify-between\">\n {!hideFields.includes(\"certifications.date_awarded\") && (\n <span className=\"rounded-md bg-muted/50 px-2 py-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {cert.date_awarded}\n </span>\n )}\n {cert.verified && !hideFields.includes(\"certifications.verified\") && (\n <span\n className=\"pdf-badge rounded-full border px-2.5 py-1 text-xs font-bold transition-colors\"\n style={{\n backgroundColor: theme?.startsWith(\"#\") ? `${theme}15` : undefined,\n color: theme,\n borderColor: theme?.startsWith(\"#\") ? `${theme}30` : theme,\n }}\n >\n Verificado\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/experience-education.tsx"],"sourcesContent":["import { CandidateProfile } from \"../../types\";\nimport type { CVExperienceBaseItem, CVCertificationItem } from \"../../types\";\nimport { GraduationCap, Briefcase, Trophy, Award } from \"lucide-react\";\n\n/** Parsea una fecha (MM/YYYY, YYYY-MM o YYYY) a un valor numérico para ordenar (mayor = más reciente) */\nfunction parseDateToSortValue(dateStr: string | undefined): number {\n if (!dateStr || dateStr.toLowerCase() === \"presente\") return 0;\n // MM/YYYY\n const mmYyyy = dateStr.match(/^(\\d{1,2})\\/(\\d{4})$/);\n if (mmYyyy) return parseInt(mmYyyy[2], 10) * 12 + parseInt(mmYyyy[1], 10);\n // YYYY-MM o YYYY-MM-DD\n const yyyyMm = dateStr.match(/^(\\d{4})-(\\d{1,2})/);\n if (yyyyMm) return parseInt(yyyyMm[1], 10) * 12 + parseInt(yyyyMm[2], 10);\n // Solo año\n const year = dateStr.match(/\\d{4}/);\n if (year) return parseInt(year[0], 10) * 12;\n return 0;\n}\n\n/** Ordena descendente por fecha de fin; si no hay end_date (Presente), usa start_date y prioriza como más reciente */\nfunction sortByDateDesc<T extends CVExperienceBaseItem>(items: T[]): T[] {\n return [...items].sort((a, b) => {\n const aEnd = a.end_date?.toLowerCase();\n const bEnd = b.end_date?.toLowerCase();\n const aOngoing = !a.end_date || aEnd === \"presente\";\n const bOngoing = !b.end_date || bEnd === \"presente\";\n const aVal = aOngoing ? parseDateToSortValue(a.start_date) + 9999 * 12 : parseDateToSortValue(a.end_date);\n const bVal = bOngoing ? parseDateToSortValue(b.start_date) + 9999 * 12 : parseDateToSortValue(b.end_date);\n return bVal - aVal;\n });\n}\n\n/** Ordena certificaciones descendente por date_awarded */\nfunction sortCertificationsByDateDesc(items: CVCertificationItem[]): CVCertificationItem[] {\n return [...items].sort((a, b) => {\n const aVal = parseDateToSortValue(a.date_awarded);\n const bVal = parseDateToSortValue(b.date_awarded);\n return bVal - aVal;\n });\n}\n\ninterface ExperienceEducationProps {\n data: CandidateProfile;\n theme?: string;\n hideFields?: string[];\n hideSections?: string[];\n}\n\nexport function ExperienceEducation({\n data,\n theme,\n hideFields = [],\n hideSections = [],\n}: ExperienceEducationProps) {\n const experiences = sortByDateDesc(data.work_experience || []);\n const education = sortByDateDesc(data.education || []);\n const activities = sortByDateDesc(data.activities || []);\n const certifications = sortCertificationsByDateDesc(data.certifications || []);\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"space-y-12\">\n {/* Experience */}\n {experiences.length > 0 && !hideSections.includes(\"Experiencia laboral\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Briefcase className=\"h-6 w-6 text-primary\" />\n Experiencia Laboral\n </h3>\n <div className=\"space-y-8\">\n {experiences.map((exp) => (\n <div\n key={exp.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"experience.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{exp.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"experience.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {exp.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"experience.start_date\") ||\n !hideFields.includes(\"experience.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"experience.start_date\") && exp.start_date}\n {!hideFields.includes(\"experience.end_date\") && (\n <> {exp.end_date ? `- ${exp.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {exp.description && !hideFields.includes(\"experience.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {exp.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Education */}\n {education.length > 0 && !hideSections.includes(\"Educación\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <GraduationCap className=\"h-6 w-6 text-primary\" />\n Educación\n </h3>\n <div className=\"space-y-8\">\n {education.map((edu) => (\n <div\n key={edu.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"education.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{edu.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"education.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {edu.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"education.start_date\") ||\n !hideFields.includes(\"education.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"education.start_date\") && edu.start_date}\n {!hideFields.includes(\"education.end_date\") && (\n <> {edu.end_date ? `- ${edu.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {edu.description && !hideFields.includes(\"education.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {edu.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Activities */}\n {activities.length > 0 && !hideSections.includes(\"Actividades y Logros\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Trophy className=\"h-6 w-6 text-primary\" />\n Actividades y Logros\n </h3>\n <div className=\"space-y-8\">\n {activities.map((act) => (\n <div\n key={act.id}\n className=\"relative pl-6 after:absolute after:bottom-[-24px] after:left-[3px] after:top-4 after:w-[2px] after:bg-border last:after:hidden\"\n >\n <div\n className=\"pdf-line-v absolute left-0 top-2 h-2 w-2 rounded-full bg-primary\"\n style={themeStyle}\n />\n {!hideFields.includes(\"activities.title\") && (\n <h4 className=\"text-lg font-bold text-foreground\">{act.title}</h4>\n )}\n <div className=\"mb-2 flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n {!hideFields.includes(\"activities.institution_name\") && (\n <span className=\"text-base font-semibold text-primary\">\n {act.institution_name}\n </span>\n )}\n {(!hideFields.includes(\"activities.start_date\") ||\n !hideFields.includes(\"activities.end_date\")) && (\n <span className=\"mt-1 w-fit rounded-md bg-muted/30 px-2 py-0.5 text-sm font-medium text-muted-foreground sm:mt-0\">\n {!hideFields.includes(\"activities.start_date\") && act.start_date}\n {!hideFields.includes(\"activities.end_date\") && (\n <> {act.end_date ? `- ${act.end_date}` : \"- Presente\"}</>\n )}\n </span>\n )}\n </div>\n {act.description && !hideFields.includes(\"activities.description\") && (\n <p className=\"mt-3 whitespace-pre-wrap text-base leading-relaxed text-foreground/80\">\n {act.description}\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Certifications */}\n {certifications.length > 0 && !hideSections.includes(\"Certificaciones\") && (\n <div className=\"space-y-6\">\n <h3 className=\"flex items-center gap-2 border-b-2 border-primary/20 pb-2 text-2xl font-bold text-primary\">\n <Award className=\"h-6 w-6 text-primary\" />\n Certificaciones\n </h3>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {certifications.map((cert) => (\n <div\n key={cert.id}\n className=\"rounded-lg border border-border/60 bg-card p-4 shadow-sm transition-colors hover:border-primary/30 hover:shadow-md\"\n >\n {!hideFields.includes(\"certifications.title\") && (\n <h4\n className=\"line-clamp-1 text-base font-bold text-foreground\"\n title={cert.title}\n >\n {cert.title}\n </h4>\n )}\n {!hideFields.includes(\"certifications.institution_name\") && (\n <p className=\"mt-1 line-clamp-1 text-sm text-muted-foreground\">\n {cert.institution_name}\n </p>\n )}\n <div className=\"mt-4 flex items-center justify-between\">\n {!hideFields.includes(\"certifications.date_awarded\") && (\n <span className=\"rounded-md bg-muted/50 px-2 py-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {cert.date_awarded}\n </span>\n )}\n {cert.verified && !hideFields.includes(\"certifications.verified\") && (\n <span\n className=\"pdf-badge rounded-full border px-2.5 py-1 text-xs font-bold transition-colors\"\n style={{\n backgroundColor: theme?.startsWith(\"#\") ? `${theme}15` : undefined,\n color: theme,\n borderColor: theme?.startsWith(\"#\") ? `${theme}30` : theme,\n }}\n >\n Verificado\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -37,12 +37,12 @@ function HeaderPreview({ data, headerSlot, theme, hideFields = [] }) {
37
37
  ].filter(Boolean).join(" ") || "Sin nombre";
38
38
  const themeStyle = theme ? { backgroundColor: theme } : void 0;
39
39
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start", children: [
40
- !hideFields.includes("photo_url") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ui.Avatar, { className: "h-32 w-32 flex-shrink-0 border-4 border-background shadow-lg", children: [
40
+ !hideFields.includes("photo_url") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ui.Avatar, { className: "h-32 w-32 flex-shrink-0 rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none border-4 border-background shadow-lg", children: [
41
41
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ui.AvatarImage, { src: data.photo_url || void 0, alt: fullName, className: "object-cover" }),
42
42
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
43
43
  import_ui.AvatarFallback,
44
44
  {
45
- className: "pdf-header-initials text-3xl font-semibold text-primary-foreground",
45
+ className: "pdf-header-initials rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none text-3xl font-semibold text-primary-foreground",
46
46
  style: themeStyle || { backgroundColor: "hsl(var(--primary))" },
47
47
  children: getInitials()
48
48
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/header-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../../types\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../../../../ui\";\n\ninterface HeaderPreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n}\n\nexport function HeaderPreview({ data, headerSlot, theme, hideFields = [] }: HeaderPreviewProps) {\n const getInitials = () => {\n const f = hideFields.includes(\"first_name\") ? \"\" : data.first_name?.[0] || \"\";\n const l = data.last_name?.[0] || \"\";\n return `${f}${l}`.toUpperCase() || \"CN\";\n };\n\n const fullName =\n [\n hideFields.includes(\"first_name\") ? null : data.first_name,\n hideFields.includes(\"middle_name\") ? null : data.middle_name,\n hideFields.includes(\"last_name\") ? null : data.last_name,\n hideFields.includes(\"second_last_name\") ? null : data.second_last_name,\n ]\n .filter(Boolean)\n .join(\" \") || \"Sin nombre\";\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start\">\n {!hideFields.includes(\"photo_url\") && (\n <Avatar className=\"h-32 w-32 flex-shrink-0 border-4 border-background shadow-lg\">\n <AvatarImage src={data.photo_url || undefined} alt={fullName} className=\"object-cover\" />\n <AvatarFallback\n className=\"pdf-header-initials text-3xl font-semibold text-primary-foreground\"\n style={themeStyle || { backgroundColor: \"hsl(var(--primary))\" }}\n >\n {getInitials()}\n </AvatarFallback>\n </Avatar>\n )}\n\n <div className=\"mt-2 flex w-full flex-1 flex-col justify-between text-center md:mt-4 md:text-left\">\n <div>\n <h1 className=\"mb-3 text-3xl font-extrabold tracking-tight text-foreground md:text-4xl\">\n {fullName}\n </h1>\n {data.summary && !hideFields.includes(\"summary\") && (\n <p className=\"text-md pdf-summary mx-auto max-w-3xl font-medium leading-relaxed text-muted-foreground md:mx-0\">\n {data.summary}\n </p>\n )}\n </div>\n\n {headerSlot && (\n <div className=\"pdf-hidden mt-6 flex w-full items-center justify-center md:justify-end\">\n {headerSlot}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCQ;AA/BR,gBAAoD;AAS7C,SAAS,cAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,EAAE,GAAuB;AAC9F,QAAM,cAAc,MAAM;AACxB,UAAM,IAAI,WAAW,SAAS,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC,KAAK;AAC3E,UAAM,IAAI,KAAK,YAAY,CAAC,KAAK;AACjC,WAAO,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK;AAAA,EACrC;AAEA,QAAM,WACJ;AAAA,IACE,WAAW,SAAS,YAAY,IAAI,OAAO,KAAK;AAAA,IAChD,WAAW,SAAS,aAAa,IAAI,OAAO,KAAK;AAAA,IACjD,WAAW,SAAS,WAAW,IAAI,OAAO,KAAK;AAAA,IAC/C,WAAW,SAAS,kBAAkB,IAAI,OAAO,KAAK;AAAA,EACxD,EACG,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,QAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,SACE,6CAAC,SAAI,WAAU,oEACZ;AAAA,KAAC,WAAW,SAAS,WAAW,KAC/B,6CAAC,oBAAO,WAAU,gEAChB;AAAA,kDAAC,yBAAY,KAAK,KAAK,aAAa,QAAW,KAAK,UAAU,WAAU,gBAAe;AAAA,MACvF;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,cAAc,EAAE,iBAAiB,sBAAsB;AAAA,UAE7D,sBAAY;AAAA;AAAA,MACf;AAAA,OACF;AAAA,IAGF,6CAAC,SAAI,WAAU,qFACb;AAAA,mDAAC,SACC;AAAA,oDAAC,QAAG,WAAU,2EACX,oBACH;AAAA,QACC,KAAK,WAAW,CAAC,WAAW,SAAS,SAAS,KAC7C,4CAAC,OAAE,WAAU,mGACV,eAAK,SACR;AAAA,SAEJ;AAAA,MAEC,cACC,4CAAC,SAAI,WAAU,0EACZ,sBACH;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/header-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../../types\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../../../../ui\";\n\ninterface HeaderPreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n}\n\nexport function HeaderPreview({ data, headerSlot, theme, hideFields = [] }: HeaderPreviewProps) {\n const getInitials = () => {\n const f = hideFields.includes(\"first_name\") ? \"\" : data.first_name?.[0] || \"\";\n const l = data.last_name?.[0] || \"\";\n return `${f}${l}`.toUpperCase() || \"CN\";\n };\n\n const fullName =\n [\n hideFields.includes(\"first_name\") ? null : data.first_name,\n hideFields.includes(\"middle_name\") ? null : data.middle_name,\n hideFields.includes(\"last_name\") ? null : data.last_name,\n hideFields.includes(\"second_last_name\") ? null : data.second_last_name,\n ]\n .filter(Boolean)\n .join(\" \") || \"Sin nombre\";\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start\">\n {!hideFields.includes(\"photo_url\") && (\n <Avatar className=\"h-32 w-32 flex-shrink-0 rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none border-4 border-background shadow-lg\">\n <AvatarImage src={data.photo_url || undefined} alt={fullName} className=\"object-cover\" />\n <AvatarFallback\n className=\"pdf-header-initials rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none text-3xl font-semibold text-primary-foreground\"\n style={themeStyle || { backgroundColor: \"hsl(var(--primary))\" }}\n >\n {getInitials()}\n </AvatarFallback>\n </Avatar>\n )}\n\n <div className=\"mt-2 flex w-full flex-1 flex-col justify-between text-center md:mt-4 md:text-left\">\n <div>\n <h1 className=\"mb-3 text-3xl font-extrabold tracking-tight text-foreground md:text-4xl\">\n {fullName}\n </h1>\n {data.summary && !hideFields.includes(\"summary\") && (\n <p className=\"text-md pdf-summary mx-auto max-w-3xl font-medium leading-relaxed text-muted-foreground md:mx-0\">\n {data.summary}\n </p>\n )}\n </div>\n\n {headerSlot && (\n <div className=\"pdf-hidden mt-6 flex w-full items-center justify-center md:justify-end\">\n {headerSlot}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCQ;AA/BR,gBAAoD;AAS7C,SAAS,cAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,EAAE,GAAuB;AAC9F,QAAM,cAAc,MAAM;AACxB,UAAM,IAAI,WAAW,SAAS,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC,KAAK;AAC3E,UAAM,IAAI,KAAK,YAAY,CAAC,KAAK;AACjC,WAAO,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK;AAAA,EACrC;AAEA,QAAM,WACJ;AAAA,IACE,WAAW,SAAS,YAAY,IAAI,OAAO,KAAK;AAAA,IAChD,WAAW,SAAS,aAAa,IAAI,OAAO,KAAK;AAAA,IACjD,WAAW,SAAS,WAAW,IAAI,OAAO,KAAK;AAAA,IAC/C,WAAW,SAAS,kBAAkB,IAAI,OAAO,KAAK;AAAA,EACxD,EACG,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,QAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,SACE,6CAAC,SAAI,WAAU,oEACZ;AAAA,KAAC,WAAW,SAAS,WAAW,KAC/B,6CAAC,oBAAO,WAAU,2IAChB;AAAA,kDAAC,yBAAY,KAAK,KAAK,aAAa,QAAW,KAAK,UAAU,WAAU,gBAAe;AAAA,MACvF;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,cAAc,EAAE,iBAAiB,sBAAsB;AAAA,UAE7D,sBAAY;AAAA;AAAA,MACf;AAAA,OACF;AAAA,IAGF,6CAAC,SAAI,WAAU,qFACb;AAAA,mDAAC,SACC;AAAA,oDAAC,QAAG,WAAU,2EACX,oBACH;AAAA,QACC,KAAK,WAAW,CAAC,WAAW,SAAS,SAAS,KAC7C,4CAAC,OAAE,WAAU,mGACV,eAAK,SACR;AAAA,SAEJ;AAAA,MAEC,cACC,4CAAC,SAAI,WAAU,0EACZ,sBACH;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}
@@ -14,12 +14,12 @@ function HeaderPreview({ data, headerSlot, theme, hideFields = [] }) {
14
14
  ].filter(Boolean).join(" ") || "Sin nombre";
15
15
  const themeStyle = theme ? { backgroundColor: theme } : void 0;
16
16
  return /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start", children: [
17
- !hideFields.includes("photo_url") && /* @__PURE__ */ jsxs(Avatar, { className: "h-32 w-32 flex-shrink-0 border-4 border-background shadow-lg", children: [
17
+ !hideFields.includes("photo_url") && /* @__PURE__ */ jsxs(Avatar, { className: "h-32 w-32 flex-shrink-0 rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none border-4 border-background shadow-lg", children: [
18
18
  /* @__PURE__ */ jsx(AvatarImage, { src: data.photo_url || void 0, alt: fullName, className: "object-cover" }),
19
19
  /* @__PURE__ */ jsx(
20
20
  AvatarFallback,
21
21
  {
22
- className: "pdf-header-initials text-3xl font-semibold text-primary-foreground",
22
+ className: "pdf-header-initials rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none text-3xl font-semibold text-primary-foreground",
23
23
  style: themeStyle || { backgroundColor: "hsl(var(--primary))" },
24
24
  children: getInitials()
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/header-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../../types\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../../../../ui\";\n\ninterface HeaderPreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n}\n\nexport function HeaderPreview({ data, headerSlot, theme, hideFields = [] }: HeaderPreviewProps) {\n const getInitials = () => {\n const f = hideFields.includes(\"first_name\") ? \"\" : data.first_name?.[0] || \"\";\n const l = data.last_name?.[0] || \"\";\n return `${f}${l}`.toUpperCase() || \"CN\";\n };\n\n const fullName =\n [\n hideFields.includes(\"first_name\") ? null : data.first_name,\n hideFields.includes(\"middle_name\") ? null : data.middle_name,\n hideFields.includes(\"last_name\") ? null : data.last_name,\n hideFields.includes(\"second_last_name\") ? null : data.second_last_name,\n ]\n .filter(Boolean)\n .join(\" \") || \"Sin nombre\";\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start\">\n {!hideFields.includes(\"photo_url\") && (\n <Avatar className=\"h-32 w-32 flex-shrink-0 border-4 border-background shadow-lg\">\n <AvatarImage src={data.photo_url || undefined} alt={fullName} className=\"object-cover\" />\n <AvatarFallback\n className=\"pdf-header-initials text-3xl font-semibold text-primary-foreground\"\n style={themeStyle || { backgroundColor: \"hsl(var(--primary))\" }}\n >\n {getInitials()}\n </AvatarFallback>\n </Avatar>\n )}\n\n <div className=\"mt-2 flex w-full flex-1 flex-col justify-between text-center md:mt-4 md:text-left\">\n <div>\n <h1 className=\"mb-3 text-3xl font-extrabold tracking-tight text-foreground md:text-4xl\">\n {fullName}\n </h1>\n {data.summary && !hideFields.includes(\"summary\") && (\n <p className=\"text-md pdf-summary mx-auto max-w-3xl font-medium leading-relaxed text-muted-foreground md:mx-0\">\n {data.summary}\n </p>\n )}\n </div>\n\n {headerSlot && (\n <div className=\"pdf-hidden mt-6 flex w-full items-center justify-center md:justify-end\">\n {headerSlot}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"AAiCQ,SACE,KADF;AA/BR,SAAS,QAAQ,gBAAgB,mBAAmB;AAS7C,SAAS,cAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,EAAE,GAAuB;AAC9F,QAAM,cAAc,MAAM;AACxB,UAAM,IAAI,WAAW,SAAS,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC,KAAK;AAC3E,UAAM,IAAI,KAAK,YAAY,CAAC,KAAK;AACjC,WAAO,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK;AAAA,EACrC;AAEA,QAAM,WACJ;AAAA,IACE,WAAW,SAAS,YAAY,IAAI,OAAO,KAAK;AAAA,IAChD,WAAW,SAAS,aAAa,IAAI,OAAO,KAAK;AAAA,IACjD,WAAW,SAAS,WAAW,IAAI,OAAO,KAAK;AAAA,IAC/C,WAAW,SAAS,kBAAkB,IAAI,OAAO,KAAK;AAAA,EACxD,EACG,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,QAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,SACE,qBAAC,SAAI,WAAU,oEACZ;AAAA,KAAC,WAAW,SAAS,WAAW,KAC/B,qBAAC,UAAO,WAAU,gEAChB;AAAA,0BAAC,eAAY,KAAK,KAAK,aAAa,QAAW,KAAK,UAAU,WAAU,gBAAe;AAAA,MACvF;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,cAAc,EAAE,iBAAiB,sBAAsB;AAAA,UAE7D,sBAAY;AAAA;AAAA,MACf;AAAA,OACF;AAAA,IAGF,qBAAC,SAAI,WAAU,qFACb;AAAA,2BAAC,SACC;AAAA,4BAAC,QAAG,WAAU,2EACX,oBACH;AAAA,QACC,KAAK,WAAW,CAAC,WAAW,SAAS,SAAS,KAC7C,oBAAC,OAAE,WAAU,mGACV,eAAK,SACR;AAAA,SAEJ;AAAA,MAEC,cACC,oBAAC,SAAI,WAAU,0EACZ,sBACH;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/components/domain/resume/resume-preview/sections/header-preview.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CandidateProfile } from \"../../types\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../../../../ui\";\n\ninterface HeaderPreviewProps {\n data: CandidateProfile;\n headerSlot?: React.ReactNode;\n theme?: string;\n hideFields?: string[];\n}\n\nexport function HeaderPreview({ data, headerSlot, theme, hideFields = [] }: HeaderPreviewProps) {\n const getInitials = () => {\n const f = hideFields.includes(\"first_name\") ? \"\" : data.first_name?.[0] || \"\";\n const l = data.last_name?.[0] || \"\";\n return `${f}${l}`.toUpperCase() || \"CN\";\n };\n\n const fullName =\n [\n hideFields.includes(\"first_name\") ? null : data.first_name,\n hideFields.includes(\"middle_name\") ? null : data.middle_name,\n hideFields.includes(\"last_name\") ? null : data.last_name,\n hideFields.includes(\"second_last_name\") ? null : data.second_last_name,\n ]\n .filter(Boolean)\n .join(\" \") || \"Sin nombre\";\n\n const themeStyle = theme ? { backgroundColor: theme } : undefined;\n\n return (\n <div className=\"mt-4 flex flex-col items-center gap-8 md:flex-row md:items-start\">\n {!hideFields.includes(\"photo_url\") && (\n <Avatar className=\"h-32 w-32 flex-shrink-0 rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none border-4 border-background shadow-lg\">\n <AvatarImage src={data.photo_url || undefined} alt={fullName} className=\"object-cover\" />\n <AvatarFallback\n className=\"pdf-header-initials rounded-none rounded-tl-none rounded-tr-2xl rounded-bl-2xl rounded-br-none text-3xl font-semibold text-primary-foreground\"\n style={themeStyle || { backgroundColor: \"hsl(var(--primary))\" }}\n >\n {getInitials()}\n </AvatarFallback>\n </Avatar>\n )}\n\n <div className=\"mt-2 flex w-full flex-1 flex-col justify-between text-center md:mt-4 md:text-left\">\n <div>\n <h1 className=\"mb-3 text-3xl font-extrabold tracking-tight text-foreground md:text-4xl\">\n {fullName}\n </h1>\n {data.summary && !hideFields.includes(\"summary\") && (\n <p className=\"text-md pdf-summary mx-auto max-w-3xl font-medium leading-relaxed text-muted-foreground md:mx-0\">\n {data.summary}\n </p>\n )}\n </div>\n\n {headerSlot && (\n <div className=\"pdf-hidden mt-6 flex w-full items-center justify-center md:justify-end\">\n {headerSlot}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"AAiCQ,SACE,KADF;AA/BR,SAAS,QAAQ,gBAAgB,mBAAmB;AAS7C,SAAS,cAAc,EAAE,MAAM,YAAY,OAAO,aAAa,CAAC,EAAE,GAAuB;AAC9F,QAAM,cAAc,MAAM;AACxB,UAAM,IAAI,WAAW,SAAS,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC,KAAK;AAC3E,UAAM,IAAI,KAAK,YAAY,CAAC,KAAK;AACjC,WAAO,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,KAAK;AAAA,EACrC;AAEA,QAAM,WACJ;AAAA,IACE,WAAW,SAAS,YAAY,IAAI,OAAO,KAAK;AAAA,IAChD,WAAW,SAAS,aAAa,IAAI,OAAO,KAAK;AAAA,IACjD,WAAW,SAAS,WAAW,IAAI,OAAO,KAAK;AAAA,IAC/C,WAAW,SAAS,kBAAkB,IAAI,OAAO,KAAK;AAAA,EACxD,EACG,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,QAAM,aAAa,QAAQ,EAAE,iBAAiB,MAAM,IAAI;AAExD,SACE,qBAAC,SAAI,WAAU,oEACZ;AAAA,KAAC,WAAW,SAAS,WAAW,KAC/B,qBAAC,UAAO,WAAU,2IAChB;AAAA,0BAAC,eAAY,KAAK,KAAK,aAAa,QAAW,KAAK,UAAU,WAAU,gBAAe;AAAA,MACvF;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,cAAc,EAAE,iBAAiB,sBAAsB;AAAA,UAE7D,sBAAY;AAAA;AAAA,MACf;AAAA,OACF;AAAA,IAGF,qBAAC,SAAI,WAAU,qFACb;AAAA,2BAAC,SACC;AAAA,4BAAC,QAAG,WAAU,2EACX,oBACH;AAAA,QACC,KAAK,WAAW,CAAC,WAAW,SAAS,SAAS,KAC7C,oBAAC,OAAE,WAAU,mGACV,eAAK,SACR;AAAA,SAEJ;AAAA,MAEC,cACC,oBAAC,SAAI,WAAU,0EACZ,sBACH;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}
@@ -166,6 +166,38 @@ function Resume({
166
166
  clonedElement.style.height = "auto";
167
167
  clonedElement.style.overflow = "visible";
168
168
  clonedElement.style.width = "1200px";
169
+ const backgroundGradients = clonedElement.querySelectorAll("[data-pdf-background-gradient]");
170
+ const w = 1200;
171
+ const h = 160;
172
+ const canvas2 = clonedDoc.createElement("canvas");
173
+ canvas2.width = w;
174
+ canvas2.height = h;
175
+ const ctx = canvas2.getContext("2d");
176
+ if (ctx) {
177
+ const hGrad = ctx.createLinearGradient(0, 0, w, 0);
178
+ hGrad.addColorStop(0, "#ffffff");
179
+ hGrad.addColorStop(0.5, "#f3e8ff");
180
+ hGrad.addColorStop(1, "#bfdbfe");
181
+ ctx.fillStyle = hGrad;
182
+ ctx.fillRect(0, 0, w, h);
183
+ ctx.globalCompositeOperation = "destination-in";
184
+ const vGrad = ctx.createLinearGradient(0, 0, 0, h);
185
+ vGrad.addColorStop(0, "rgba(0,0,0,1)");
186
+ vGrad.addColorStop(1, "rgba(0,0,0,0)");
187
+ ctx.fillStyle = vGrad;
188
+ ctx.fillRect(0, 0, w, h);
189
+ ctx.globalCompositeOperation = "source-over";
190
+ }
191
+ const dataUrl = canvas2.toDataURL("image/png");
192
+ backgroundGradients.forEach((el) => {
193
+ if (el instanceof HTMLElement) {
194
+ el.style.maskImage = "none";
195
+ el.style.background = "none";
196
+ el.style.backgroundImage = `url(${dataUrl})`;
197
+ el.style.backgroundSize = "100% 100%";
198
+ el.style.backgroundPosition = "0 0";
199
+ }
200
+ });
169
201
  const objectCoverImages = clonedElement.querySelectorAll("img.object-cover");
170
202
  objectCoverImages.forEach((img) => {
171
203
  if (img instanceof HTMLImageElement) {
@@ -358,7 +390,7 @@ function Resume({
358
390
  variant: "ghost",
359
391
  disabled: isDownloading,
360
392
  onClick: handleDownload,
361
- className: "flex items-center gap-2 rounded-full bg-purple-200 px-4 text-purple-800 text-secondary shadow-xl",
393
+ className: "flex items-center gap-2 rounded-full bg-purple-100 px-4 text-purple-100 text-primary shadow-xl",
362
394
  children: [
363
395
  isDownloading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Download, { className: "h-5 w-5" }),
364
396
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "hidden font-semibold sm:inline", children: isDownloading ? "Generando..." : "Descargar" })