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 { useEffect } from "react";
|
||||
import Layout from "../components/Blog/Layout";
|
||||
import * as phosphorIcons from "phosphor-react";
|
||||
|
||||
import styles from "../styles/Blog/AboutMe.module.scss";
|
||||
import skills from "../data/skills.json";
|
||||
|
||||
interface Skill {
|
||||
name: string;
|
||||
icons: string[];
|
||||
pct: number;
|
||||
}
|
||||
import skills, { AdditionalSkill, Skill, SkillCard } from "../data/skills";
|
||||
import achievements from "../data/achievements";
|
||||
|
||||
interface AdditionalSkills {
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
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 Badge: NextPage<{ additional: AdditionalSkill }> = ({ additional }) => {
|
||||
return <div className={styles.badge}>
|
||||
{additional.icon || null} {additional.name}
|
||||
</div>;
|
||||
};
|
||||
|
||||
const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => {
|
||||
return <div className={styles.bar}>
|
||||
<div className={styles.barName}>{skill.name}{skill.icons.map(getIcon)}</div>
|
||||
<div className={styles.barPct}>{skill.pct}%</div>
|
||||
return <div className={styles.skillBar}>
|
||||
<div className={styles.barName}>{skill.name}{skill.icon || null}</div>
|
||||
<div className={styles.percentBar} style={{"--barPct": skill.pct + "%"} as React.CSSProperties}>
|
||||
<div className={`${styles.front} vpAnimated`}></div>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
||||
const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => {
|
||||
return <div className={styles.card}>
|
||||
<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} />
|
||||
)}
|
||||
)}<br/>
|
||||
{card.additional?.map((skill, i) => <Badge additional={skill} key={i} />)}
|
||||
</div>;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
return <Layout>
|
||||
@ -59,10 +60,14 @@ const AboutMe: NextPage = () => {
|
||||
Hi! My name is <strong>Daniel</strong> and I'm an automation engineer from Germany.
|
||||
</p>
|
||||
<p>
|
||||
I'm currently studying <strong>Information Systems Engineering</strong> at the <strong>TU Dresden</strong><br/>
|
||||
Currently I'm {age} years old.
|
||||
I'm currently {age} years old and studying <strong>Information Systems Engineering</strong> at the <strong>TU Dresden</strong>.
|
||||
</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>;
|
||||
|
||||
};
|
||||
|
@ -1,3 +1,30 @@
|
||||
.preText {
|
||||
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