pimped the site a little but and fixed impress
This commit is contained in:
1 parent
f543a5e2f3
commit
888fb6289d
14 files changed
+1502
-1162
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { Component} from '@angular/core';
|
||||
import { Component, computed, signal } from '@angular/core';
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
@@ -11,6 +11,18 @@ import {AssetsConstants} from '../../constants/AssetsConstants';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {SharedFunctions} from '../../shared/SharedFunctions';
|
||||
|
||||
/** One role. Consecutive entries sharing a `company` render as a single employer block. */
|
||||
interface ExperienceEntry {
|
||||
key: string;
|
||||
company: string;
|
||||
logo: string;
|
||||
highlightCount: number;
|
||||
}
|
||||
|
||||
interface SkillGroup {
|
||||
titleKey: string;
|
||||
skillKeys: string[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-about',
|
||||
@@ -29,51 +41,83 @@ import {SharedFunctions} from '../../shared/SharedFunctions';
|
||||
})
|
||||
export class AboutComponent {
|
||||
|
||||
xpKeys = [
|
||||
/** Roles older than the current decade are hidden until the reader asks for them. */
|
||||
readonly showEarlierExperience = signal(false);
|
||||
readonly showEarlierEducation = signal(false);
|
||||
|
||||
readonly recentExperience: ExperienceEntry[] = [
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY9',
|
||||
company: 'colordigital',
|
||||
logo: AssetsConstants.COLORDIGITAL_LOGO,
|
||||
no_highlights: false
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY8',
|
||||
logo: AssetsConstants.TERAPORT_LOGO
|
||||
company: 'teraport',
|
||||
logo: AssetsConstants.TERAPORT_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY7',
|
||||
logo: AssetsConstants.COLORDIGITAL_LOGO
|
||||
company: 'colordigital-earlier',
|
||||
logo: AssetsConstants.COLORDIGITAL_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY6',
|
||||
logo: AssetsConstants.COLORDIGITAL_LOGO
|
||||
company: 'colordigital-earlier',
|
||||
logo: AssetsConstants.COLORDIGITAL_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY5',
|
||||
logo: AssetsConstants.ASSYST_LOGO
|
||||
company: 'assyst',
|
||||
logo: AssetsConstants.ASSYST_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY4',
|
||||
logo: AssetsConstants.ASSYST_LOGO
|
||||
company: 'assyst',
|
||||
logo: AssetsConstants.ASSYST_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY3',
|
||||
logo: AssetsConstants.ASSYST_LOGO
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY2',
|
||||
logo: AssetsConstants.TH_BINGEN_LOGO
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY1',
|
||||
logo: AssetsConstants.TH_BINGEN_LOGO
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY0',
|
||||
logo: AssetsConstants.CHAMAELEON_LOGO
|
||||
company: 'assyst',
|
||||
logo: AssetsConstants.ASSYST_LOGO,
|
||||
highlightCount: 3
|
||||
}
|
||||
];
|
||||
|
||||
projectKeys = [
|
||||
readonly earlierExperience: ExperienceEntry[] = [
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY2',
|
||||
company: 'th-bingen',
|
||||
logo: AssetsConstants.TH_BINGEN_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY1',
|
||||
company: 'th-bingen',
|
||||
logo: AssetsConstants.TH_BINGEN_LOGO,
|
||||
highlightCount: 3
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.XP.COMPANY0',
|
||||
company: 'chamaeleon',
|
||||
logo: AssetsConstants.CHAMAELEON_LOGO,
|
||||
highlightCount: 3
|
||||
}
|
||||
];
|
||||
|
||||
readonly projectKeys = [
|
||||
{
|
||||
key: 'ABOUT.PROJECT.CLAUDE_BOX',
|
||||
externalLink: '',
|
||||
internalLink: 'projects',
|
||||
identifier: 'claude-in-a-box',
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.PROJECT.P2',
|
||||
externalLink: 'https://andreas-dahm.eu/',
|
||||
@@ -106,59 +150,114 @@ export class AboutComponent {
|
||||
}
|
||||
];
|
||||
|
||||
educationKeys = [
|
||||
readonly recentEducationKeys = [
|
||||
'ABOUT.EDUCATION.E6',
|
||||
'ABOUT.EDUCATION.E5',
|
||||
'ABOUT.EDUCATION.E4'
|
||||
];
|
||||
|
||||
readonly earlierEducationKeys = [
|
||||
'ABOUT.EDUCATION.E3',
|
||||
'ABOUT.EDUCATION.E2',
|
||||
'ABOUT.EDUCATION.E1',
|
||||
'ABOUT.EDUCATION.E0'
|
||||
];
|
||||
|
||||
/**
|
||||
* Heading and chips travel together so the two can no longer drift apart —
|
||||
* they used to be declared in separate places and had ended up mismatched.
|
||||
*/
|
||||
readonly skillGroups: SkillGroup[] = [
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E6'
|
||||
titleKey: 'ABOUT.SECTION.LANGUAGES',
|
||||
skillKeys: [
|
||||
'ABOUT.SKILLS.JAVA',
|
||||
'ABOUT.SKILLS.SPRING',
|
||||
'ABOUT.SKILLS.TYPESCRIPT',
|
||||
'ABOUT.SKILLS.ANGULAR',
|
||||
'ABOUT.SKILLS.CSHARP',
|
||||
'ABOUT.SKILLS.PYTHON',
|
||||
'ABOUT.SKILLS.VUE',
|
||||
'ABOUT.SKILLS.REACT'
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E5'
|
||||
titleKey: 'ABOUT.SECTION.ARCH_CLOUD',
|
||||
skillKeys: [
|
||||
'ABOUT.SKILLS.ARCH_MICROSERVICES',
|
||||
'ABOUT.SKILLS.ARCH_CLOUD',
|
||||
'ABOUT.TOOLS.DOCKER',
|
||||
'ABOUT.TOOLS.K8S',
|
||||
'ABOUT.TOOLS.POSTGRES',
|
||||
'ABOUT.TOOLS.MONGO',
|
||||
'ABOUT.TOOLS.GITLAB',
|
||||
'ABOUT.TOOLS.JENKINS'
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E4'
|
||||
titleKey: 'ABOUT.SECTION.SIM_ALGO',
|
||||
skillKeys: [
|
||||
'ABOUT.SKILLS.ENG_ALGO',
|
||||
'ABOUT.SKILLS.ENG_SIM',
|
||||
'ABOUT.SKILLS.ENG_GPU',
|
||||
'ABOUT.SKILLS.ENG_PERF',
|
||||
'ABOUT.SKILLS.UNITY'
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E3'
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E2'
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E1'
|
||||
},
|
||||
{
|
||||
key: 'ABOUT.EDUCATION.E0'
|
||||
titleKey: 'ABOUT.SECTION.AI_ENG',
|
||||
skillKeys: [
|
||||
'ABOUT.SKILLS.AI_AGENTS',
|
||||
'ABOUT.SKILLS.AI_MCP',
|
||||
'ABOUT.SKILLS.AI_CONTEXT',
|
||||
'ABOUT.SKILLS.AI_HARNESS',
|
||||
'ABOUT.SKILLS.AI_GATES'
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
skillsCore = [
|
||||
'ABOUT.SKILLS.JAVA',
|
||||
'ABOUT.SKILLS.SPRING',
|
||||
'ABOUT.SKILLS.ANGULAR',
|
||||
'ABOUT.SKILLS.VUE',
|
||||
'ABOUT.SKILLS.REACT',
|
||||
'ABOUT.SKILLS.TYPESCRIPT',
|
||||
'ABOUT.SKILLS.CSHARP',
|
||||
'ABOUT.SKILLS.PYTHON'
|
||||
];
|
||||
|
||||
skillsArchitecture = [
|
||||
'ABOUT.SKILLS.ARCH_MICROSERVICES',
|
||||
'ABOUT.SKILLS.ARCH_CLOUD',
|
||||
'ABOUT.TOOLS.DOCKER',
|
||||
'ABOUT.TOOLS.K8S',
|
||||
'ABOUT.TOOLS.JENKINS',
|
||||
'ABOUT.TOOLS.POSTGRES',
|
||||
'ABOUT.TOOLS.MONGO',
|
||||
'ABOUT.TOOLS.GITLAB'
|
||||
];
|
||||
readonly visibleExperience = computed(() => {
|
||||
if (this.showEarlierExperience()) {
|
||||
return [...this.recentExperience, ...this.earlierExperience];
|
||||
}
|
||||
return this.recentExperience;
|
||||
});
|
||||
|
||||
skillsEngineering = [
|
||||
'ABOUT.SKILLS.ENG_ALGO',
|
||||
'ABOUT.SKILLS.ENG_SIM',
|
||||
'ABOUT.SKILLS.ENG_GPU',
|
||||
'ABOUT.SKILLS.UNITY',
|
||||
'ABOUT.SKILLS.ENG_PERF'
|
||||
];
|
||||
readonly visibleEducationKeys = computed(() => {
|
||||
if (this.showEarlierEducation()) {
|
||||
return [...this.recentEducationKeys, ...this.earlierEducationKeys];
|
||||
}
|
||||
return this.recentEducationKeys;
|
||||
});
|
||||
|
||||
toggleEarlierExperience(): void {
|
||||
this.showEarlierExperience.update(shown => !shown);
|
||||
}
|
||||
|
||||
toggleEarlierEducation(): void {
|
||||
this.showEarlierEducation.update(shown => !shown);
|
||||
}
|
||||
|
||||
/** The employer header is drawn once per run of consecutive roles at the same company. */
|
||||
isFirstRoleAtCompany(index: number): boolean {
|
||||
if (index === 0) {
|
||||
return true;
|
||||
}
|
||||
const entries = this.visibleExperience();
|
||||
return entries[index - 1].company !== entries[index].company;
|
||||
}
|
||||
|
||||
isLastRoleAtCompany(index: number): boolean {
|
||||
const entries = this.visibleExperience();
|
||||
if (index === entries.length - 1) {
|
||||
return true;
|
||||
}
|
||||
return entries[index + 1].company !== entries[index].company;
|
||||
}
|
||||
|
||||
highlightKeys(entry: ExperienceEntry): string[] {
|
||||
return Array.from({ length: entry.highlightCount }, (_, i) => `${entry.key}.HIGHLIGHTS.P${i + 1}`);
|
||||
}
|
||||
|
||||
protected readonly UrlConstants = UrlConstants;
|
||||
protected readonly AssetsConstants = AssetsConstants;
|
||||
|
||||
Reference in new issue
Block a user