diff --git a/src/pages/ExperiencePage.vue b/src/pages/ExperiencePage.vue index a3982e9..6f86719 100644 --- a/src/pages/ExperiencePage.vue +++ b/src/pages/ExperiencePage.vue @@ -10,86 +10,180 @@
-
-
-
-
-
- +
+ +
+
+ + + +
+
caio@career ~ % career --list --verbose
+
+ + +
+ +
+ $ + career --list --verbose +
+ + +
+
+ Career Summary +
+
+ ══════════════════════════════════════════════════════════ +
+
+ Total Experience: + {{ yearsOfExperience }} years +
+
+ Companies: + {{ totalCompanies }} +
+
+ Current Status: + ● EMPLOYED +
+
+ + +
+ +
+ + + ──── + {{ + !experience.endDate ? "◉" : "○" + }} + ── +
+ + +
+ [{{ String(index + 1).padStart(2, "0") }}] + {{ experience.company }} + (current) +
+ + +
+
+ + Role: + {{ experience.position }} + via {{ getViaName(experience.via) }}
-
- +
+ + Period: + {{ formatDateRange(experience) }} + ({{ calculateDuration(experience) }})
-
-
-

+
+ + Tags: + + [{{ tag }}] + +
+
+ +
+ + +
+ + + {{ highlight }} +
+ +
+ +
+ + +
+ + Stack: + {{ + parseTechnologies(experience.technologies).join(", ") + }} +
+ + +
+ + URL: {{ experience.website }} - {{ experience.company }} - - {{ experience.company }} -

- - {{ experience.position }} - • via {{ getViaName(experience.via) }} - -
-
-
- {{ formatDateRange(experience) }} - {{ calculateDuration(experience) }}
- + + +
+ +
+
+
+ + +
+
+ +
+
+ ... {{ remainingCount }} more entries hidden ... +
+
+
+ $ + +
+
+ + +
@@ -102,38 +196,11 @@ import { experiencesConfig, type Experience } from "../domain/experience/data"; import BadgeGroup from "../components/molecules/BadgeGroup.vue"; - // Dynamically import all logos from assets/logos - const logoModules = import.meta.glob("../assets/logos/*.jpeg", { - eager: true, - import: "default", - }); - - // Build a map from slug to logo URL - const companyLogos: Record = {}; - for (const path in logoModules) { - const slug = path.replace("../assets/logos/", "").replace(".jpeg", ""); - companyLogos[slug] = logoModules[path] as string; - } - - function getCompanyLogo(experience: Experience): string | undefined { - return companyLogos[experience.slug]; - } - - // Via company logos and names mapping - const viaLogos: Record = { - toptal: companyLogos["toptal"], - tw: companyLogos["thoughtworks"], - }; - const viaNames: Record = { toptal: "Toptal", tw: "ThoughtWorks", }; - function getViaLogo(via: string): string | undefined { - return viaLogos[via]; - } - function getViaName(via: string): string { return viaNames[via] || via; } @@ -150,6 +217,15 @@ return currentYear - startYear; }); + const totalCompanies = computed(() => { + const companies = new Set(experiencesConfig.map((exp) => exp.company)); + return companies.size; + }); + + const remainingCount = computed(() => { + return experiencesConfig.length - INITIAL_VISIBLE_COUNT; + }); + const visibleExperiences = computed(() => { if (showAll.value) { return experiencesConfig; @@ -172,7 +248,9 @@ } }); - return Array.from(techSet).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); + return Array.from(techSet).sort((a, b) => + a.toLowerCase().localeCompare(b.toLowerCase()) + ); }); function formatDateRange(experience: Experience): string { @@ -180,37 +258,37 @@ const startStr = formatMonth(startDate); if (!experience.endDate) { - return `${startStr} - present`; + return `${startStr} → present`; } const endDate = new Date(experience.endDate); const endStr = formatMonth(endDate); - return `${startStr} - ${endStr}`; + return `${startStr} → ${endStr}`; } function formatMonth(date: Date): string { const months = [ - "jan", - "feb", - "mar", - "apr", - "may", - "jun", - "jul", - "aug", - "sep", - "oct", - "nov", - "dec", + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", ]; - return `${months[date.getMonth()]}/${date.getFullYear()}`; + return `${months[date.getMonth()]} ${date.getFullYear()}`; } function calculateDuration(experience: Experience): string { const startDate = new Date(experience.startDate); const endDate = experience.endDate ? new Date(experience.endDate) : new Date(); - let months = + const months = (endDate.getFullYear() - startDate.getFullYear()) * 12 + (endDate.getMonth() - startDate.getMonth()); @@ -219,18 +297,14 @@ let duration = ""; if (years > 0) { - duration += `${years} ${years === 1 ? "year" : "years"}`; + duration += `${years}y`; } if (remainingMonths > 0) { - if (duration) duration += ", "; - duration += `${remainingMonths} ${remainingMonths === 1 ? "month" : "months"}`; + if (duration) duration += " "; + duration += `${remainingMonths}m`; } if (!duration) { - duration = "< 1 month"; - } - - if (!experience.endDate) { - duration += " (and counting)"; + duration = "<1m"; } return duration; @@ -239,6 +313,18 @@ function parseTechnologies(technologies: string): string[] { return technologies.split(",").map((tech) => tech.trim()); } + + function getTagClass(tag: string): string { + const classes: Record = { + remote: "tag-remote", + "on-site": "tag-onsite", + fintech: "tag-fintech", + startup: "tag-startup", + contract: "tag-contract", + enterprise: "tag-enterprise", + }; + return classes[tag] || ""; + }