Skip to content

Commit 4288068

Browse files
committed
feat: refactor date sorting utility and update usage in CV templates
1 parent ce9a3bb commit 4288068

2 files changed

Lines changed: 54 additions & 50 deletions

File tree

backend/src/shared/utils.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
export function sortByStartDateAsc<
2-
T extends { startDate?: string | number | null },
3-
>(items: T[], order: "asc" | "desc" = "asc"): T[] {
1+
type Order = "asc" | "desc";
2+
3+
export function sortByDate<T>(
4+
items: T[],
5+
getDate: (item: T) => string | number | null | undefined,
6+
order: Order = "asc",
7+
): T[] {
48
return [...items].sort((a, b) => {
5-
const da = a.startDate ? new Date(a.startDate).getTime() : 0;
6-
const db = b.startDate ? new Date(b.startDate).getTime() : 0;
9+
const da = getDate(a) ? new Date(getDate(a)!).getTime() : 0;
10+
const db = getDate(b) ? new Date(getDate(b)!).getTime() : 0;
711

812
return order === "asc" ? da - db : db - da;
913
});

backend/src/templates/examples/example1.ts

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CreateCVDto } from "src/cvs/dto/create-cv.dto";
2-
import { sortByStartDateAsc } from "src/shared/utils";
2+
import { sortByDate } from "src/shared/utils";
33

44
import type { LocaleContent } from "../locales";
55

@@ -272,7 +272,7 @@ ${
272272
? `
273273
<section>
274274
<h2>${localeContent.Experience}</h2>
275-
${sortByStartDateAsc(dto.experience)
275+
${sortByDate(dto.experience, (e) => e.startDate, "desc")
276276
.map(
277277
(e) => `
278278
<div class="item">
@@ -294,9 +294,9 @@ ${
294294
? `
295295
<section>
296296
<h2>${localeContent.Education}</h2>
297-
${dto.education
298-
.map(
299-
(e) => `
297+
${sortByDate(dto.education, (e) => e.startDate, "desc")
298+
.map(
299+
(e) => `
300300
<div class="item">
301301
<div class="item-title">${e.degree} em ${e.fieldOfStudy}</div>
302302
<div class="item-subtitle">${e.institution}</div>
@@ -307,8 +307,8 @@ ${
307307
${e.grade ? `<p>${localeContent.Grade}: ${e.grade}</p>` : ""}
308308
${e.description ? `<p>${e.description}</p>` : ""}
309309
</div>`,
310-
)
311-
.join("")}
310+
)
311+
.join("")}
312312
</section>`
313313
: ""
314314
}
@@ -318,18 +318,18 @@ ${
318318
? `
319319
<section>
320320
<h2>${localeContent.Projects}</h2>
321-
${sortByStartDateAsc(dto.projects)
321+
${sortByDate(dto.projects, (p) => p.startDate, "desc")
322322
.map(
323323
(p) => `
324-
<div class="item">
325-
<div class="item-title">${p.name}</div>
326-
<div class="dates">
327-
${p.startDate} ${p.endDate ? `– ${p.endDate}` : ""}
328-
${p.location ? ` | ${p.location}` : ""}
329-
</div>
330-
<p>${p.description}</p>
331-
${p.link ? `<a href="${p.link}">${p.link}</a>` : ""}
332-
</div>`,
324+
<div class="item">
325+
<div class="item-title">${p.name}</div>
326+
<div class="dates">
327+
${p.startDate} ${p.endDate ? `– ${p.endDate}` : ""}
328+
${p.location ? ` | ${p.location}` : ""}
329+
</div>
330+
<p>${p.description}</p>
331+
${p.link ? `<a href="${p.link}">${p.link}</a>` : ""}
332+
</div>`,
333333
)
334334
.join("")}
335335
</section>`
@@ -341,21 +341,21 @@ ${
341341
? `
342342
<section>
343343
<h2>${localeContent.Certifications}</h2>
344-
${dto.certifications
345-
.map(
346-
(c) => `
347-
<div class="item">
348-
<div class="item-title">${c.name}</div>
349-
<div class="item-subtitle">${c.issuingOrganization}</div>
350-
<div class="dates">
351-
${c.issueDate}
352-
${c.expirationDate ? `– ${c.expirationDate}` : ""}
353-
</div>
354-
${c.credentialID ? `<p>ID: ${c.credentialID}</p>` : ""}
355-
${c.credentialURL ? `<a href="${c.credentialURL}">${c.credentialURL}</a>` : ""}
356-
</div>`,
357-
)
358-
.join("")}
344+
${sortByDate(dto.certifications, (c) => c.issueDate, "desc")
345+
.map(
346+
(c) => `
347+
<div class="item">
348+
<div class="item-title">${c.name}</div>
349+
<div class="item-subtitle">${c.issuingOrganization}</div>
350+
<div class="dates">
351+
${c.issueDate}
352+
${c.expirationDate ? `– ${c.expirationDate}` : ""}
353+
</div>
354+
${c.credentialID ? `<p>ID: ${c.credentialID}</p>` : ""}
355+
${c.credentialURL ? `<a href="${c.credentialURL}">${c.credentialURL}</a>` : ""}
356+
</div>`,
357+
)
358+
.join("")}
359359
</section>`
360360
: ""
361361
}
@@ -365,19 +365,19 @@ ${
365365
? `
366366
<section>
367367
<h2>${localeContent.OtherExperiences}</h2>
368-
${dto.otherExperiences
369-
.map(
370-
(o) => `
371-
<div class="item">
372-
<div class="item-title">${o.title}</div>
373-
<div class="dates">
374-
${o.startDate ?? ""} ${o.endDate ? `– ${o.endDate}` : ""}
375-
${o.location ? ` | ${o.location}` : ""}
376-
</div>
377-
<p>${o.description}</p>
378-
</div>`,
379-
)
380-
.join("")}
368+
${sortByDate(dto.otherExperiences, (o) => o.startDate, "desc")
369+
.map(
370+
(o) => `
371+
<div class="item">
372+
<div class="item-title">${o.title}</div>
373+
<div class="dates">
374+
${o.startDate ?? ""} ${o.endDate ? `– ${o.endDate}` : ""}
375+
${o.location ? ` | ${o.location}` : ""}
376+
</div>
377+
<p>${o.description}</p>
378+
</div>`,
379+
)
380+
.join("")}
381381
</section>`
382382
: ""
383383
}

0 commit comments

Comments
 (0)