diff --git a/data/achievements.tsx b/data/achievements.tsx
new file mode 100644
index 0000000..ac5ac25
--- /dev/null
+++ b/data/achievements.tsx
@@ -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":
+ }, {
+ "description": "Developer of the official testbed for Digital Twins in Industry 4.0 of the TU Dresden",
+ "icon":
+ }
+];
+
+export default achievements;
\ No newline at end of file
diff --git a/data/skills.json b/data/skills.json
deleted file mode 100644
index 743e207..0000000
--- a/data/skills.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "cards": [
- {
- "title": "Web Technologies",
- "skillBars": [
- {
- "name": "JavaScript/TypeScript",
- "icons": ["FileJs", "FileTs"],
- "pct": 100
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/data/skills.tsx b/data/skills.tsx
new file mode 100644
index 0000000..344686c
--- /dev/null
+++ b/data/skills.tsx
@@ -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: ,
+ pct: 100
+ }, {
+ name: "JavaScript",
+ icon: ,
+ pct: 100
+ }, {
+ name: "Java",
+ icon: ,
+ pct: 80
+ }, {
+ name: "Python 3",
+ icon: ,
+ pct: 95
+ }, {
+ name: "PHP",
+ icon: ,
+ pct: 50
+ }, {
+ name: "Bash",
+ icon: ,
+ pct: 60
+ }, {
+ name: "C/C++",
+ icon: ,
+ pct: 60
+ }, {
+ name: "Rust",
+ icon: ,
+ pct: 80
+ }, {
+ name: "C#",
+ icon: ,
+ pct: 40
+ }]
+ }, {
+ title: "Web Technologies",
+ skillBars: [{
+ name: "TypeScript",
+ icon: ,
+ pct: 100
+ }, {
+ name: "JavaScript",
+ icon: ,
+ pct: 100
+ }, {
+ name: "React",
+ icon: ,
+ pct: 80
+ }, {
+ name: "HTML5",
+ icon: ,
+ pct: 80
+ }, {
+ name: "CSS3",
+ icon: ,
+ pct: 90
+ }],
+ additional: [{
+ name: "Express",
+ icon:
+ }, {
+ name: "Sass",
+ icon:
+ }, {
+ name: "Spring Boot",
+ icon:
+ }]
+ }, {
+ title: "Embedded Programming",
+ skillBars: [{
+ name: "C/C++",
+ icon: ,
+ pct: 60
+ }],
+ additional: [{
+ name: "Arduino",
+ icon:
+ }, {
+ name: "ESP",
+ icon:
+ }]
+ }, {
+ title: "Operating Systems",
+ skillBars: [],
+ additional: [{
+ name: "Windows",
+ icon:
+ }, {
+ name: "Linux",
+ icon:
+ }, {
+ name: "Android",
+ icon:
+ }]
+ }, {
+ title: "Languages",
+ skillBars: [{
+ name: "German (native)",
+ icon: 🇩🇪,
+ pct: 100
+ }, {
+ name: "English (C1)",
+ icon: 🇬🇧,
+ pct: 90
+ }, {
+ name: "Russian (basics)",
+ icon: 🇷🇺,
+ pct: 30
+ }],
+ additional: []
+ }]
+ };
+};
+
+export default skills;
\ No newline at end of file
diff --git a/pages/me.tsx b/pages/me.tsx
index 2be242f..13f1ca3 100644
--- a/pages/me.tsx
+++ b/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 ;
+const Badge: NextPage<{ additional: AdditionalSkill }> = ({ additional }) => {
+ return
+ {additional.icon || null} {additional.name}
+
;
};
const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => {
- return
-
{skill.name}{skill.icons.map(getIcon)}
-
{skill.pct}%
+ return
+
{skill.name}{skill.icon || null}
+
;
};
const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => {
return
{card.title}
- {card.skillBars.map((skill, i) =>
+ {card.skillBars.sort((bar1, bar2) => bar2.pct - bar1.pct).map((skill, i) =>
- )}
+ )}
+ {card.additional?.map((skill, i) => )}
;
};
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
@@ -59,10 +60,14 @@ const AboutMe: NextPage = () => {
Hi! My name is Daniel and I'm an automation engineer from Germany.
- I'm currently studying Information Systems Engineering at the TU Dresden
- Currently I'm {age} years old.
+ I'm currently {age} years old and studying Information Systems Engineering at the TU Dresden.
- {skills.cards.map((card, i) => )}
+ Achievements
+ {achievements().map((achievement, i) =>
+ {achievement.icon}{achievement.description}
+
)}
+ Skills
+ {skills().cards.map((card, i) => )}
;
};
diff --git a/styles/Blog/AboutMe.module.scss b/styles/Blog/AboutMe.module.scss
index 6e83af2..90045ff 100644
--- a/styles/Blog/AboutMe.module.scss
+++ b/styles/Blog/AboutMe.module.scss
@@ -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);
+ }
}
\ No newline at end of file