feat: complete phase 3 career workspace
CI and Deploy / test (push) Failing after 1m6s
CI and Deploy / deploy (push) Has been skipped

This commit is contained in:
cesnimda
2026-07-30 22:19:13 +02:00
parent f8a7cf5205
commit 4cf26405f6
18 changed files with 215 additions and 20 deletions
+8
View File
@@ -252,6 +252,10 @@ export const translations = {
profileCvStructuredSummary: "Professional summary",
profileCvStructuredSkills: "Skills",
profileCvStructuredInterests: "Interests",
profileCvStructuredAwards: "Awards",
profileCvStructuredPublications: "Publications",
profileCvStructuredOrganisations: "Organisations",
profileCvStructuredReferences: "References",
profileCvStructuredLanguages: "Languages",
profileCvStructuredJobs: "Work experience",
profileCvStructuredEducation: "Education",
@@ -1325,6 +1329,10 @@ export const translations = {
profileCvStructuredSummary: "Sammendrags-punkter",
profileCvStructuredSkills: "Kjernekompetanse",
profileCvStructuredInterests: "Interesser",
profileCvStructuredAwards: "Priser og utmerkelser",
profileCvStructuredPublications: "Publikasjoner",
profileCvStructuredOrganisations: "Organisasjoner",
profileCvStructuredReferences: "Referanser",
profileCvStructuredLanguages: "Språk",
profileCvStructuredJobs: "Arbeidserfaring",
profileCvStructuredEducation: "Utdanning",
+16
View File
@@ -93,6 +93,10 @@ export type StructuredCvProfile = {
skills: string[];
languages: StructuredCvLanguage[];
interests: string[];
awards: string[];
publications: string[];
organisations: string[];
references: string[];
otherSections: StructuredCvOtherSection[];
sections: ParsedCvSection[];
};
@@ -121,6 +125,10 @@ export function emptyStructuredCv(): StructuredCvProfile {
skills: [],
languages: [],
interests: [],
awards: [],
publications: [],
organisations: [],
references: [],
otherSections: [],
sections: [],
};
@@ -183,6 +191,10 @@ function buildLegacyStructuredCv(sections: ParsedCvSection[]): StructuredCvProfi
skills,
languages,
interests,
awards: linesFromSection(sections, ["awards", "honours", "honors"]),
publications: linesFromSection(sections, ["publications"]),
organisations: linesFromSection(sections, ["organisations", "organizations", "memberships"]),
references: linesFromSection(sections, ["references"]),
sections,
};
}
@@ -274,6 +286,10 @@ export function normalizeStructuredCv(value: unknown): StructuredCvProfile {
}))
: [],
interests: normalizeList(source.interests),
awards: normalizeList(source.awards),
publications: normalizeList(source.publications),
organisations: normalizeList(source.organisations),
references: normalizeList(source.references),
otherSections: Array.isArray(source.otherSections)
? source.otherSections.map((section: any) => ({
title: normalizeString(section?.title),
@@ -18,6 +18,7 @@ import {
EducationSection,
InterestsSection,
LanguagesSection,
LongTailSections,
OtherSectionsSection,
PersonalInformationSection,
ProfessionalSummarySection,
@@ -647,6 +648,8 @@ export default function CareerProfilePage() {
<InterestsSection value={structuredCv.interests} onChange={(next) => setStructuredCv((prev) => ({ ...prev, interests: next }))} getMetadata={metaFor} />
</Box>
<LongTailSections values={{ awards: structuredCv.awards, publications: structuredCv.publications, organisations: structuredCv.organisations, references: structuredCv.references }} onChange={(key, next) => setStructuredCv((prev) => ({ ...prev, [key]: next }))} />
<LanguagesSection value={structuredCv.languages} onChange={(next) => setStructuredCv((prev) => ({ ...prev, languages: next }))} getMetadata={metaFor} />
<WorkExperienceSection value={structuredCv.jobs} onChange={(next) => setStructuredCv((prev) => ({ ...prev, jobs: next }))} />
@@ -122,6 +122,12 @@ export function InterestsSection({ value, onChange, getMetadata }: { value: stri
return <LinesField label={t("profileCvStructuredInterests")} value={value} onChange={onChange} metadata={getMetadata("interests")} minRows={4} />;
}
export function LongTailSections({ values, onChange }: { values: Record<"awards" | "publications" | "organisations" | "references", string[]>; onChange: (key: keyof typeof values, next: string[]) => void }) {
const { t } = useI18n();
const labels = { awards: t("profileCvStructuredAwards"), publications: t("profileCvStructuredPublications"), organisations: t("profileCvStructuredOrganisations"), references: t("profileCvStructuredReferences") };
return <Box sx={{ mt: 2, display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5 }}>{(Object.keys(values) as (keyof typeof values)[]).map((key) => <LinesField key={key} label={labels[key]} value={values[key]} onChange={(next) => onChange(key, next)} minRows={3} />)}</Box>;
}
export function LanguagesSection({ value, onChange, getMetadata }: { value: StructuredCvLanguage[]; onChange: (next: StructuredCvLanguage[]) => void; getMetadata: MetadataLookup }) {
const { t } = useI18n();
const update = (index: number, patch: Partial<StructuredCvLanguage>) => onChange(value.map((entry, i) => (i === index ? { ...entry, ...patch } : entry)));