More about me stuff
This commit is contained in:
parent
aa28e1a8a7
commit
4953da3aee
19
data/achievements.tsx
Normal file
19
data/achievements.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import Icon from "@mdi/react";
|
||||||
|
import { mdiSeal, mdiRobotIndustrial } from "@mdi/js";
|
||||||
|
|
||||||
|
interface Achievement {
|
||||||
|
description: string;
|
||||||
|
icon: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const achievements = (size?: string): Achievement[] => [
|
||||||
|
{
|
||||||
|
"description": "Awarded with the Deutschlandstipendium",
|
||||||
|
"icon": <Icon path={mdiSeal} size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
"description": "Developer of the official testbed for Digital Twins in Industry 4.0 of the TU Dresden",
|
||||||
|
"icon": <Icon path={mdiRobotIndustrial} size={size || "2em"} />
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default achievements;
|
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"cards": [
|
|
||||||
{
|
|
||||||
"title": "Web Technologies",
|
|
||||||
"skillBars": [
|
|
||||||
{
|
|
||||||
"name": "JavaScript/TypeScript",
|
|
||||||
"icons": ["FileJs", "FileTs"],
|
|
||||||
"pct": 100
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
148
data/skills.tsx
Normal file
148
data/skills.tsx
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
import Icon from "@mdi/react";
|
||||||
|
import { mdiBash, mdiLanguageCpp, mdiLanguageCsharp, mdiLanguageJava, mdiLanguageJavascript, mdiLanguagePhp, mdiLanguagePython, mdiLanguageRust, mdiLanguageTypescript, mdiReact } from "@mdi/js";
|
||||||
|
import { Android, Arduino, CssThree, Espressif, Express, Html5, Linux, Sass, Springboot, Windows } from "@icons-pack/react-simple-icons";
|
||||||
|
|
||||||
|
export interface Skill {
|
||||||
|
name: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
pct: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AdditionalSkill {
|
||||||
|
name: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkillCard {
|
||||||
|
title: string;
|
||||||
|
skillBars: Skill[];
|
||||||
|
additional?: AdditionalSkill[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkillSet {
|
||||||
|
cards: SkillCard[];
|
||||||
|
additional?: AdditionalSkill[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const skills = (size?: string): SkillSet => {
|
||||||
|
return {
|
||||||
|
cards: [{
|
||||||
|
title: "Programming Languages",
|
||||||
|
skillBars: [{
|
||||||
|
name: "TypeScript",
|
||||||
|
icon: <Icon path={mdiLanguageTypescript} size={size || "2em"} />,
|
||||||
|
pct: 100
|
||||||
|
}, {
|
||||||
|
name: "JavaScript",
|
||||||
|
icon: <Icon path={mdiLanguageJavascript} size={size || "2em"} />,
|
||||||
|
pct: 100
|
||||||
|
}, {
|
||||||
|
name: "Java",
|
||||||
|
icon: <Icon path={mdiLanguageJava} size={size || "2em"} />,
|
||||||
|
pct: 80
|
||||||
|
}, {
|
||||||
|
name: "Python 3",
|
||||||
|
icon: <Icon path={mdiLanguagePython} size={size || "2em"} />,
|
||||||
|
pct: 95
|
||||||
|
}, {
|
||||||
|
name: "PHP",
|
||||||
|
icon: <Icon path={mdiLanguagePhp} size={size || "2em"} />,
|
||||||
|
pct: 50
|
||||||
|
}, {
|
||||||
|
name: "Bash",
|
||||||
|
icon: <Icon path={mdiBash} size={size || "2em"} />,
|
||||||
|
pct: 60
|
||||||
|
}, {
|
||||||
|
name: "C/C++",
|
||||||
|
icon: <Icon path={mdiLanguageCpp} size={size || "2em"} />,
|
||||||
|
pct: 60
|
||||||
|
}, {
|
||||||
|
name: "Rust",
|
||||||
|
icon: <Icon path={mdiLanguageRust} size={size || "2em"} />,
|
||||||
|
pct: 80
|
||||||
|
}, {
|
||||||
|
name: "C#",
|
||||||
|
icon: <Icon path={mdiLanguageCsharp} size={size || "2em"} />,
|
||||||
|
pct: 40
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
title: "Web Technologies",
|
||||||
|
skillBars: [{
|
||||||
|
name: "TypeScript",
|
||||||
|
icon: <Icon path={mdiLanguageTypescript} size={size || "2em"} />,
|
||||||
|
pct: 100
|
||||||
|
}, {
|
||||||
|
name: "JavaScript",
|
||||||
|
icon: <Icon path={mdiLanguageJavascript} size={size || "2em"} />,
|
||||||
|
pct: 100
|
||||||
|
}, {
|
||||||
|
name: "React",
|
||||||
|
icon: <Icon path={mdiReact} size={size || "2em"} />,
|
||||||
|
pct: 80
|
||||||
|
}, {
|
||||||
|
name: "HTML5",
|
||||||
|
icon: <Html5 size={size || "2em"} />,
|
||||||
|
pct: 80
|
||||||
|
}, {
|
||||||
|
name: "CSS3",
|
||||||
|
icon: <CssThree size={size || "2em"} />,
|
||||||
|
pct: 90
|
||||||
|
}],
|
||||||
|
additional: [{
|
||||||
|
name: "Express",
|
||||||
|
icon: <Express size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
name: "Sass",
|
||||||
|
icon: <Sass size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
name: "Spring Boot",
|
||||||
|
icon: <Springboot size={size || "2em"} />
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
title: "Embedded Programming",
|
||||||
|
skillBars: [{
|
||||||
|
name: "C/C++",
|
||||||
|
icon: <Icon path={mdiLanguageCpp} size={size || "2em"} />,
|
||||||
|
pct: 60
|
||||||
|
}],
|
||||||
|
additional: [{
|
||||||
|
name: "Arduino",
|
||||||
|
icon: <Arduino size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
name: "ESP",
|
||||||
|
icon: <Espressif size={size || "2em"} />
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
title: "Operating Systems",
|
||||||
|
skillBars: [],
|
||||||
|
additional: [{
|
||||||
|
name: "Windows",
|
||||||
|
icon: <Windows size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
name: "Linux",
|
||||||
|
icon: <Linux size={size || "2em"} />
|
||||||
|
}, {
|
||||||
|
name: "Android",
|
||||||
|
icon: <Android size={size || "2em"} />
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
title: "Languages",
|
||||||
|
skillBars: [{
|
||||||
|
name: "German (native)",
|
||||||
|
icon: <span style={{ fontSize: size || "2em" }}>🇩🇪</span>,
|
||||||
|
pct: 100
|
||||||
|
}, {
|
||||||
|
name: "English (C1)",
|
||||||
|
icon: <span style={{ fontSize: size || "2em" }}>🇬🇧</span>,
|
||||||
|
pct: 90
|
||||||
|
}, {
|
||||||
|
name: "Russian (basics)",
|
||||||
|
icon: <span style={{ fontSize: size || "2em", fontFamily: "Arial" }}>🇷🇺</span>,
|
||||||
|
pct: 30
|
||||||
|
}],
|
||||||
|
additional: []
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default skills;
|
77
pages/me.tsx
77
pages/me.tsx
@ -1,56 +1,57 @@
|
|||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
|
import { useEffect } from "react";
|
||||||
import Layout from "../components/Blog/Layout";
|
import Layout from "../components/Blog/Layout";
|
||||||
import * as phosphorIcons from "phosphor-react";
|
|
||||||
|
|
||||||
import styles from "../styles/Blog/AboutMe.module.scss";
|
import styles from "../styles/Blog/AboutMe.module.scss";
|
||||||
import skills from "../data/skills.json";
|
|
||||||
|
|
||||||
interface Skill {
|
import skills, { AdditionalSkill, Skill, SkillCard } from "../data/skills";
|
||||||
name: string;
|
import achievements from "../data/achievements";
|
||||||
icons: string[];
|
|
||||||
pct: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AdditionalSkills {
|
const Badge: NextPage<{ additional: AdditionalSkill }> = ({ additional }) => {
|
||||||
name: string;
|
return <div className={styles.badge}>
|
||||||
icon: string;
|
{additional.icon || null} {additional.name}
|
||||||
}
|
</div>;
|
||||||
|
|
||||||
interface SkillCard {
|
|
||||||
title: string;
|
|
||||||
skillBars: Skill[];
|
|
||||||
additional?: AdditionalSkills[];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
interface SkillSet {
|
|
||||||
cards: SkillCard[];
|
|
||||||
additional: AdditionalSkills[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const getIcon = (iconName: string, key?: number) => {
|
|
||||||
const Icon = phosphorIcons[iconName as keyof typeof phosphorIcons] as any;
|
|
||||||
if (!Icon) return null;
|
|
||||||
else return <Icon key={key} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => {
|
const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => {
|
||||||
return <div className={styles.bar}>
|
return <div className={styles.skillBar}>
|
||||||
<div className={styles.barName}>{skill.name}{skill.icons.map(getIcon)}</div>
|
<div className={styles.barName}>{skill.name}{skill.icon || null}</div>
|
||||||
<div className={styles.barPct}>{skill.pct}%</div>
|
<div className={styles.percentBar} style={{"--barPct": skill.pct + "%"} as React.CSSProperties}>
|
||||||
|
<div className={`${styles.front} vpAnimated`}></div>
|
||||||
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => {
|
const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => {
|
||||||
return <div className={styles.card}>
|
return <div className={styles.card}>
|
||||||
<h3>{card.title}</h3>
|
<h3>{card.title}</h3>
|
||||||
{card.skillBars.map((skill, i) =>
|
{card.skillBars.sort((bar1, bar2) => bar2.pct - bar1.pct).map((skill, i) =>
|
||||||
<SkillBar key={i} skill={skill} />
|
<SkillBar key={i} skill={skill} />
|
||||||
)}
|
)}<br/>
|
||||||
|
{card.additional?.map((skill, i) => <Badge additional={skill} key={i} />)}
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const AboutMe: NextPage = () => {
|
const AboutMe: NextPage = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScrollAnimation = () => {
|
||||||
|
document.querySelectorAll(".vpAnimated").forEach((element) => {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const inVp = (
|
||||||
|
rect.top >= 0 &&
|
||||||
|
rect.left >= 0 &&
|
||||||
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||||
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||||
|
);
|
||||||
|
if (inVp) (element as HTMLElement).style.animationPlayState = "running";
|
||||||
|
else (element as HTMLElement).style.animationPlayState = "paused";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleScrollAnimation(); // First time so we don't _need_ scrolling
|
||||||
|
window.addEventListener("scroll", handleScrollAnimation);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const age = new Date().getFullYear() - 1998 - (new Date().getMonth() < 10 ? 1 : 0);
|
const age = new Date().getFullYear() - 1998 - (new Date().getMonth() < 10 ? 1 : 0);
|
||||||
|
|
||||||
return <Layout>
|
return <Layout>
|
||||||
@ -59,10 +60,14 @@ const AboutMe: NextPage = () => {
|
|||||||
Hi! My name is <strong>Daniel</strong> and I'm an automation engineer from Germany.
|
Hi! My name is <strong>Daniel</strong> and I'm an automation engineer from Germany.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
I'm currently studying <strong>Information Systems Engineering</strong> at the <strong>TU Dresden</strong><br/>
|
I'm currently {age} years old and studying <strong>Information Systems Engineering</strong> at the <strong>TU Dresden</strong>.
|
||||||
Currently I'm {age} years old.
|
|
||||||
</p>
|
</p>
|
||||||
{skills.cards.map((card, i) => <SkillCard key={i} card={card} />)}
|
<h2>Achievements</h2>
|
||||||
|
{achievements().map((achievement, i) => <div key={i} className={styles.achievement}>
|
||||||
|
<span>{achievement.icon}</span><span>{achievement.description}</span>
|
||||||
|
</div>)}
|
||||||
|
<h2>Skills</h2>
|
||||||
|
{skills().cards.map((card, i) => <SkillCard key={i} card={card} />)}
|
||||||
</Layout>;
|
</Layout>;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
.preText {
|
.preText {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.percentBar {
|
||||||
|
position: relative;
|
||||||
|
height: 1em;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
border: 1px solid var(--blog_content-border);
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
.front {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
background: var(--blog_color-accent);
|
||||||
|
animation: barFill 2s ease-in-out;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes barFill {
|
||||||
|
0% {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: var(--barPct);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user