feat: stricter lint, check pipelines, docker-containers, pnpm
This commit is contained in:
@@ -5,7 +5,7 @@ import Achievements from "@/src/portfolio/sections/Achievements";
|
||||
import Footer from "@/src/portfolio/sections/Footer";
|
||||
import SkillsAndLinks from "@/src/portfolio/sections/SkillsAndLinks";
|
||||
|
||||
const MainPage = () => {
|
||||
const MainPage = (): JSX.Element => {
|
||||
return (
|
||||
<div>
|
||||
<Intro/>
|
||||
@@ -18,4 +18,4 @@ const MainPage = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default MainPage;
|
||||
export default MainPage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {AwardArgs} from "@/src/portfolio/helpers/Certificate";
|
||||
import { AwardArgs } from "@/src/portfolio/helpers/Certificate";
|
||||
|
||||
const certificateData : AwardArgs[] = [
|
||||
{
|
||||
@@ -16,21 +16,21 @@ const certificateData : AwardArgs[] = [
|
||||
city: "Warsaw",
|
||||
awardDate: "July 2020",
|
||||
notes: [
|
||||
"Overall: 7.5 / 9.0, equivalent to C1",
|
||||
"Overall: 7.5 / 9.0, equivalent to C1"
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Project Management Fundamentals",
|
||||
institution: "Project Management Institute",
|
||||
city: "Warsaw",
|
||||
awardDate: "April 2019",
|
||||
awardDate: "April 2019"
|
||||
},
|
||||
{
|
||||
title: "Project Management Principles",
|
||||
institution: "Project Management Institute",
|
||||
city: "Warsaw",
|
||||
awardDate: "April 2019",
|
||||
awardDate: "April 2019"
|
||||
}
|
||||
];
|
||||
|
||||
export default certificateData;
|
||||
export default certificateData;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {EducationArgs} from "@/src/portfolio/helpers/Education";
|
||||
import { EducationArgs } from "@/src/portfolio/helpers/Education";
|
||||
|
||||
const educationData : EducationArgs[] = [
|
||||
{
|
||||
@@ -39,8 +39,8 @@ const educationData : EducationArgs[] = [
|
||||
"Final exam in Physics: 97% percentile",
|
||||
"Final exam in Mathematics: 92% percentile"
|
||||
],
|
||||
useWith: true, //todo fix this (i.e. this does nothing)
|
||||
useWith: true //todo fix this (i.e. this does nothing)
|
||||
}
|
||||
];
|
||||
|
||||
export default educationData;
|
||||
export default educationData;
|
||||
|
||||
@@ -63,4 +63,4 @@ export const modulesTaken : {
|
||||
level: "UG",
|
||||
score: 86
|
||||
}
|
||||
];
|
||||
];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ProjectArguments, SkillEnum} from "@/src/portfolio/helpers/Project";
|
||||
import { IProjectArguments, SkillEnum } from "@/src/portfolio/helpers/Project";
|
||||
|
||||
const projectData : ProjectArguments[] = [
|
||||
const projectData : IProjectArguments[] = [
|
||||
{
|
||||
imagePath: "expertAgents.png",
|
||||
tech: [
|
||||
@@ -55,7 +55,7 @@ const projectData : ProjectArguments[] = [
|
||||
title: "Natural Computing: Implementing and analysis of PSO, GA and GP",
|
||||
tech: [
|
||||
SkillEnum.python,
|
||||
SkillEnum.numpy,
|
||||
SkillEnum.numpy
|
||||
],
|
||||
text: "During my Master's program, I had the opportunity to take a course on Natural Computing, where I implemented and analyzed three major algorithms: Particle Swarm Optimization (PSO), Genetic Algorithms (GA), and Genetic Programming (GP). This coursework allowed me to gain hands-on experience with these powerful optimization techniques, which are inspired by natural phenomena such as swarm intelligence and evolution. Through this project, I developed a deep understanding of the underlying principles of natural computing and its potential applications in various fields, such as engineering, finance, and biology. I am excited to showcase my implementation and analysis of PSO, GA, and GP on my website and demonstrate my proficiency in natural computing techniques.",
|
||||
github: "https://github.com/KuchtaVR6/nat_coursework",
|
||||
@@ -70,7 +70,7 @@ const projectData : ProjectArguments[] = [
|
||||
SkillEnum.react,
|
||||
SkillEnum.html,
|
||||
SkillEnum.css,
|
||||
SkillEnum.express,
|
||||
SkillEnum.express
|
||||
],
|
||||
github: "https://github.com/KuchtaVR6/Learnopedia"
|
||||
},
|
||||
@@ -148,7 +148,13 @@ const projectData : ProjectArguments[] = [
|
||||
// {
|
||||
// imagePath: "port1.png",
|
||||
// title: "My previous portfolio website",
|
||||
// text: "This website was created as a challenge to myself to create an eye-pleasing and portable website with limited time. I decided to make it purely using HTML and CSS, and for the portability, I have used Bootstrap CSS. The resulting product is an informative, simple and good looking portfolio, which I was quite happy with. Throughout this academic year, I have gained more confidence in using React, I have decided to remake my portfolio this time with a more interesting and responsive design in mind, whilst maintaining the readability of the older version.",
|
||||
// text: "This website was created as a challenge to myself to create an eye-pleasing " +
|
||||
// "and portable website with limited time. I decided to make it purely using HTML and CSS, " +
|
||||
// "and for the portability, I have used Bootstrap CSS. The resulting product is an " +
|
||||
// "informative, simple and good looking portfolio, which I was quite happy with. " +
|
||||
// "Throughout this academic year, I have gained more confidence in using React, I have " +
|
||||
// "decided to remake my portfolio this time with a more interesting and responsive design " +
|
||||
// "in mind, whilst maintaining the readability of the older version.",
|
||||
// tech: [
|
||||
// SkillEnum.html,
|
||||
// SkillEnum.css,
|
||||
@@ -177,11 +183,17 @@ const projectData : ProjectArguments[] = [
|
||||
SkillEnum.linux,
|
||||
SkillEnum.design3d
|
||||
]
|
||||
},
|
||||
}
|
||||
// {
|
||||
// imagePath: "port3.png",
|
||||
// title: "My current portfolio website",
|
||||
// text: "And finally, this website is my most recent project. Design-wise I wanted to keep the website minimalistic but stunning at the same time to show my skills, and I have kept accessibility in mind. I had created this project with plentiful react to experience and I created this website with a very high standard of code and with reusability in mind so that I don't have to rewrite this website in the future. Admittedly I will probably end up doing it anyway because I love coding and improving my websites. ",
|
||||
// text: "And finally, this website is my most recent project. Design-wise I wanted to " +
|
||||
// "keep the website minimalistic but stunning at the same time to show my skills, and I " +
|
||||
// "have kept accessibility in mind. I had created this project with plentiful react to " +
|
||||
// "experience and I created this website with a very high standard of code and with " +
|
||||
// "reusability in mind so that I don't have to rewrite this website in the future. " +
|
||||
// "Admittedly I will probably end up doing it anyway because I love coding and " +
|
||||
// "improving my websites. ",
|
||||
// tech: [
|
||||
// SkillEnum.react,
|
||||
// SkillEnum.html,
|
||||
@@ -193,4 +205,4 @@ const projectData : ProjectArguments[] = [
|
||||
// }
|
||||
];
|
||||
|
||||
export default projectData;
|
||||
export default projectData;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {SkillEnum} from "@/src/portfolio/helpers/Project";
|
||||
import {ProficiencyLevel} from "@/src/portfolio/helpers/SkillDisplay";
|
||||
import { SkillEnum } from "@/src/portfolio/helpers/Project";
|
||||
import { ProficiencyLevel } from "@/src/portfolio/helpers/SkillDisplay";
|
||||
|
||||
export const skillsInCategories = {
|
||||
"Programming Languages": [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {WorkExperienceArgs} from "@/src/portfolio/helpers/WorkExperience";
|
||||
import { WorkExperienceArgs } from "@/src/portfolio/helpers/WorkExperience";
|
||||
|
||||
const workExperienceData : WorkExperienceArgs[] = [
|
||||
{
|
||||
@@ -97,7 +97,7 @@ const workExperienceData : WorkExperienceArgs[] = [
|
||||
country: "Poland",
|
||||
startDate: "July 2018",
|
||||
endDate: "August 2018"
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
export const workExperienceParagraph =
|
||||
@@ -114,4 +114,4 @@ export const workExperienceParagraph =
|
||||
"working on several AI projects, applying my theoretical machine learning knowledge to real-world problems. " +
|
||||
"Across these diverse roles, I have developed a strong work ethic and a broad set of transferable skills.";
|
||||
|
||||
export default workExperienceData;
|
||||
export default workExperienceData;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, {FC, useState} from "react";
|
||||
import React, { FC, useState } from "react";
|
||||
import { CSSTransition } from "react-transition-group";
|
||||
|
||||
type args = {
|
||||
type AccordionArgs = {
|
||||
title : string,
|
||||
children : React.ReactNode,
|
||||
}
|
||||
|
||||
const Accordion : FC<args> = ({ title, children }) => {
|
||||
const Accordion : FC<AccordionArgs> = ({ title, children }): JSX.Element => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleAccordion = () => {
|
||||
const toggleAccordion = (): void => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {FC} from "react";
|
||||
import { FC } from "react";
|
||||
import styles from "../styling/achievements.module.scss";
|
||||
|
||||
export type AwardArgs = {
|
||||
@@ -11,7 +11,7 @@ export type AwardArgs = {
|
||||
|
||||
const Award : FC<AwardArgs> = (props) => {
|
||||
|
||||
const getCountryEmoji = () => {
|
||||
const getCountryEmoji = (): string => {
|
||||
switch (props.city) {
|
||||
case "Warsaw":
|
||||
return ", PL";
|
||||
@@ -48,4 +48,4 @@ const Award : FC<AwardArgs> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Award;
|
||||
export default Award;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {FC} from "react";
|
||||
import { FC } from "react";
|
||||
import styles from "../styling/achievements.module.scss";
|
||||
|
||||
export type EducationArgs = {
|
||||
@@ -14,7 +14,7 @@ export type EducationArgs = {
|
||||
|
||||
const Education : FC<EducationArgs> = (props) => {
|
||||
|
||||
const getCountryEmoji = () => {
|
||||
const getCountryEmoji = (): string => {
|
||||
switch (props.city) {
|
||||
case "Warsaw":
|
||||
return ", Poland";
|
||||
@@ -26,7 +26,7 @@ const Education : FC<EducationArgs> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{fontSize: "1.1em"}} className={styles.education} data-aos={"fade-right"}>
|
||||
<div style={{ fontSize: "1.1em" }} className={styles.education} data-aos={"fade-right"}>
|
||||
<div>
|
||||
<span className={styles.title}>{props.title}</span> in <b>{props.subtitle}</b>
|
||||
<br/>
|
||||
@@ -48,10 +48,10 @@ const Education : FC<EducationArgs> = (props) => {
|
||||
{props.endDate ?
|
||||
<>
|
||||
<i>From: </i>
|
||||
<span style={{float:"right"}}>{props.startDate}</span>
|
||||
<span style={{ float:"right" }}>{props.startDate}</span>
|
||||
<br/>
|
||||
<i>To: </i>
|
||||
<span style={{float:"right"}}>{props.endDate}</span>
|
||||
<span style={{ float:"right" }}>{props.endDate}</span>
|
||||
</>:
|
||||
"Since " + props.startDate
|
||||
}
|
||||
@@ -60,4 +60,4 @@ const Education : FC<EducationArgs> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Education;
|
||||
export default Education;
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
import {FC, MutableRefObject, useEffect, useRef, useState} from "react";
|
||||
import { FC, MutableRefObject, useEffect, useRef, useState } from "react";
|
||||
|
||||
|
||||
type args = {
|
||||
type ProgressBarArgs = {
|
||||
percentage : number,
|
||||
customScore? : string,
|
||||
}
|
||||
const ProgressBar : FC<args> = ({percentage,customScore}) => {
|
||||
const ProgressBar : FC<ProgressBarArgs> = ({ percentage,customScore }): JSX.Element => {
|
||||
const ref = useRef<HTMLDivElement>() as MutableRefObject<HTMLDivElement>;
|
||||
const onScreen = useOnScreen(ref);
|
||||
|
||||
const [current,setCurrent] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
if(onScreen && current==0)
|
||||
useEffect(() => {
|
||||
if (onScreen && current==0)
|
||||
{
|
||||
let counter = 0;
|
||||
const id = setInterval(() => {
|
||||
if(counter<percentage*2)
|
||||
if (counter<percentage*2)
|
||||
{
|
||||
counter += (percentage/100);
|
||||
setCurrent(counter);
|
||||
}
|
||||
else{
|
||||
if(counter>percentage*2)
|
||||
else {
|
||||
if (counter>percentage*2)
|
||||
{
|
||||
setCurrent(percentage*2);
|
||||
}
|
||||
@@ -30,20 +29,20 @@ const ProgressBar : FC<args> = ({percentage,customScore}) => {
|
||||
}
|
||||
},25);
|
||||
}
|
||||
},[onScreen]);
|
||||
},[onScreen, current, percentage]);
|
||||
|
||||
return (
|
||||
<div className={"pBContainer"} ref={ref}>
|
||||
<div className={"progressBar"}>
|
||||
<div className={"inner"} style={{width : `${current/2}%`}}></div>
|
||||
<div className={"inner"} style={{ width : `${current/2}%` }}></div>
|
||||
</div>
|
||||
<div className={"below"} style={{width : customScore? "100%" : `${current/2}%`, textAlign: "right"}}>{customScore? customScore : Math.ceil(current/2)+"%"}</div>
|
||||
<div className={"below"} style={{ width : customScore? "100%" : `${current/2}%`, textAlign: "right" }}>{customScore? customScore : Math.ceil(current/2)+"%"}</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
function useOnScreen(ref : MutableRefObject<HTMLDivElement>, rootMargin = "0px") {
|
||||
function useOnScreen(ref : MutableRefObject<HTMLDivElement>, rootMargin = "0px"): boolean {
|
||||
// State and setter for storing whether element is visible
|
||||
const [isIntersecting, setIntersecting] = useState(false);
|
||||
useEffect(() => {
|
||||
@@ -53,22 +52,25 @@ function useOnScreen(ref : MutableRefObject<HTMLDivElement>, rootMargin = "0px")
|
||||
setIntersecting(entry.isIntersecting);
|
||||
},
|
||||
{
|
||||
rootMargin,
|
||||
rootMargin
|
||||
}
|
||||
);
|
||||
if (ref.current) {
|
||||
observer.observe(ref.current);
|
||||
const currentRef = ref.current;
|
||||
if (currentRef) {
|
||||
observer.observe(currentRef);
|
||||
}
|
||||
return () => {
|
||||
try{
|
||||
observer.unobserve(ref.current);
|
||||
}
|
||||
catch (e) {
|
||||
console.log("REPORTED: observer failure :/");
|
||||
if (currentRef) {
|
||||
try {
|
||||
observer.unobserve(currentRef);
|
||||
}
|
||||
catch {
|
||||
// Observer failure handled silently
|
||||
}
|
||||
}
|
||||
};
|
||||
}, []); // Empty array ensures that effect is only run on mount and unmount
|
||||
}, [ref, rootMargin]);
|
||||
return isIntersecting;
|
||||
}
|
||||
|
||||
export default ProgressBar;
|
||||
export default ProgressBar;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Image from "next/image";
|
||||
import styles from "../styling/projects.module.scss";
|
||||
import {VscGithub} from "react-icons/vsc";
|
||||
import {BsGlobe2, BsFileEarmarkMedical} from "react-icons/bs";
|
||||
import { VscGithub } from "react-icons/vsc";
|
||||
import { BsGlobe2, BsFileEarmarkMedical } from "react-icons/bs";
|
||||
|
||||
export interface ProjectArguments {
|
||||
export interface IProjectArguments {
|
||||
imagePath : string,
|
||||
title : string,
|
||||
text : string,
|
||||
@@ -47,7 +47,7 @@ export enum SkillEnum {
|
||||
english = "English",
|
||||
}
|
||||
|
||||
const Project = ({imagePath, title, text, github, access, document} : ProjectArguments) => {
|
||||
const Project = ({ imagePath, title, text, github, access, document } : IProjectArguments): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.projectDisplay}>
|
||||
<div className={styles.text}>
|
||||
@@ -92,4 +92,4 @@ const Project = ({imagePath, title, text, github, access, document} : ProjectArg
|
||||
);
|
||||
};
|
||||
|
||||
export default Project;
|
||||
export default Project;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {FC} from "react";
|
||||
import { FC } from "react";
|
||||
import styles from "../styling/projects.module.scss";
|
||||
import {SkillEnum} from "@/src/portfolio/helpers/Project";
|
||||
import { SkillEnum } from "@/src/portfolio/helpers/Project";
|
||||
|
||||
type args = {
|
||||
type SkillDisplayArgs = {
|
||||
name : SkillEnum,
|
||||
level? : ProficiencyLevel,
|
||||
}
|
||||
@@ -15,8 +15,7 @@ export enum ProficiencyLevel {
|
||||
master = "Master",
|
||||
}
|
||||
|
||||
|
||||
const SkillDisplay : FC<args> = ({name, level}) => {
|
||||
const SkillDisplay : FC<SkillDisplayArgs> = ({ name, level }): JSX.Element => {
|
||||
const level_to_emoji = {
|
||||
[ProficiencyLevel.beginner]: "🌱",
|
||||
[ProficiencyLevel.intermediate]: "🌳",
|
||||
@@ -29,7 +28,7 @@ const SkillDisplay : FC<args> = ({name, level}) => {
|
||||
return (
|
||||
<div id={name.toLowerCase()} className={styles.technology}>
|
||||
<b>{name} </b>
|
||||
<span style={{float: "right", fontSize: "0.8em"}}>{level} {level_to_emoji[level]}</span>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>{level} {level_to_emoji[level]}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -40,4 +39,4 @@ const SkillDisplay : FC<args> = ({name, level}) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SkillDisplay;
|
||||
export default SkillDisplay;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {FC} from "react";
|
||||
import { FC } from "react";
|
||||
import styles from "../styling/experience.module.scss";
|
||||
|
||||
export type WorkExperienceArgs = {
|
||||
@@ -13,7 +13,7 @@ export type WorkExperienceArgs = {
|
||||
|
||||
const WorkExperience : FC<WorkExperienceArgs> = (props) => {
|
||||
|
||||
const getEmojiForIndustry = () => {
|
||||
const getEmojiForIndustry = (): string | undefined => {
|
||||
switch (props.industry) {
|
||||
case "Education":
|
||||
return "🎓";
|
||||
@@ -43,4 +43,4 @@ const WorkExperience : FC<WorkExperienceArgs> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default WorkExperience;
|
||||
export default WorkExperience;
|
||||
|
||||
@@ -4,7 +4,7 @@ import styles from "../styling/achievements.module.scss";
|
||||
import educationData from "@/src/portfolio/data/educationData";
|
||||
import certificateData from "@/src/portfolio/data/certificateData";
|
||||
|
||||
const Achievements = () => {
|
||||
const Achievements = (): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.section} id={"achievements"}>
|
||||
<div>
|
||||
@@ -27,4 +27,4 @@ const Achievements = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Achievements;
|
||||
export default Achievements;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {Splide, SplideSlide} from "@splidejs/react-splide";
|
||||
import {useEffect, useState} from "react";
|
||||
import { Splide, SplideSlide } from "@splidejs/react-splide";
|
||||
import { useEffect, useState } from "react";
|
||||
import styles from "../styling/experience.module.scss";
|
||||
import WorkExperience from "@/src/portfolio/helpers/WorkExperience";
|
||||
import workExperienceData, {workExperienceParagraph} from "@/src/portfolio/data/workExperienceData";
|
||||
import workExperienceData, { workExperienceParagraph } from "@/src/portfolio/data/workExperienceData";
|
||||
|
||||
const Experience = () => {
|
||||
const calcPagesOnWidth = (width : number) => {
|
||||
const Experience = (): JSX.Element => {
|
||||
const calcPagesOnWidth = (width : number): number => {
|
||||
return Math.floor(width / 800 + 1);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ const Experience = () => {
|
||||
useEffect(() => {
|
||||
|
||||
setPages(calcPagesOnWidth(window.innerWidth));
|
||||
const handleResize = () => {
|
||||
const handleResize = (): void => {
|
||||
setPages(calcPagesOnWidth(window.innerWidth));
|
||||
};
|
||||
|
||||
@@ -53,4 +53,4 @@ const Experience = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Experience;
|
||||
export default Experience;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import styles from "../styling/footer.module.scss";
|
||||
|
||||
const Footer = () => {
|
||||
const Footer = (): JSX.Element => {
|
||||
return (
|
||||
<footer className={styles.section}>
|
||||
Copyright © Patryk Kuchta {new Date().getFullYear()}
|
||||
@@ -8,4 +8,4 @@ const Footer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
export default Footer;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import styles from "../styling/intro.module.scss";
|
||||
import Image from "next/image";
|
||||
import profilePic from "../../../public/portfolio/profile.png";
|
||||
import logo from "../../../public/portfolio/logo.svg";
|
||||
|
||||
const Intro = () => {
|
||||
|
||||
const greeting = () => {
|
||||
const hour = new Date().getHours();
|
||||
if (hour > 4 && hour < 12) {
|
||||
return "Good Morning!";
|
||||
} else if (hour < 18) {
|
||||
return "Good Afternoon!";
|
||||
} else {
|
||||
return "Good Evening!";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<section className={styles.section}>
|
||||
<header className={styles.topBar} data-aos={"zoom-in-down"} data-aos-duration={"500"}>
|
||||
<div className={styles.row}>
|
||||
<div className={styles.logoContainer}>
|
||||
<Image src={logo} alt={"Kuchta logo"} fill={true}/>
|
||||
</div>
|
||||
<a href={"#achievements"}>Achievements</a>
|
||||
<a href={"#experience"}>Experience</a>
|
||||
<a href={"#projects"}>Projects</a>
|
||||
<a href={"#skills"}>Skills</a>
|
||||
</div>
|
||||
<div className={styles.left}>
|
||||
<a href={"mailto: patrick@kuchta.uk"}>patrick@kuchta.uk</a>
|
||||
<span>/</span>
|
||||
<a href={"mailto: patryk@kuchta.uk"}>patryk@kuchta.uk</a>
|
||||
</div>
|
||||
</header>
|
||||
<div className={styles.mainContent}>
|
||||
<div className={styles.text} data-aos={"fade-in"} data-aos-duration={"500"}>
|
||||
<div className={styles.larger}>
|
||||
<span className={styles.greeting}>
|
||||
{greeting()}
|
||||
</span>
|
||||
<br/>
|
||||
I am
|
||||
<b> Patryk Kuchta, </b>
|
||||
an aspiring
|
||||
<br/>
|
||||
<b>Artificial Intelligence Scientist</b>.
|
||||
</div>
|
||||
<span data-aos={"fade-in"} data-aos-offset={"200"}><i>and yes, the greeting is synced to your time.</i></span>
|
||||
</div>
|
||||
<div className={styles.profileContainer}>
|
||||
<Image
|
||||
src={profilePic}
|
||||
alt={"Frontal image showing Patryk Kuchta"}
|
||||
fill={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Intro;
|
||||
17
src/portfolio/sections/Intro/Intro.tsx
Normal file
17
src/portfolio/sections/Intro/Intro.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import styles from "../../styling/intro.module.scss";
|
||||
import TopBar from "./TopBar";
|
||||
import IntroContent from "./IntroContent";
|
||||
import { getGreeting } from "./helpers";
|
||||
|
||||
const Intro = (): JSX.Element => {
|
||||
const greeting = getGreeting();
|
||||
|
||||
return (
|
||||
<section className={styles.section}>
|
||||
<TopBar/>
|
||||
<IntroContent greeting={greeting}/>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Intro;
|
||||
39
src/portfolio/sections/Intro/IntroContent.tsx
Normal file
39
src/portfolio/sections/Intro/IntroContent.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import Image from "next/image";
|
||||
import styles from "../../styling/intro.module.scss";
|
||||
import profilePic from "../../../../public/portfolio/profile.png";
|
||||
|
||||
interface IIntroContentProps {
|
||||
greeting: string;
|
||||
}
|
||||
|
||||
const IntroContent = ({ greeting }: IIntroContentProps): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.mainContent}>
|
||||
<div className={styles.text} data-aos={"fade-in"} data-aos-duration={"500"}>
|
||||
<div className={styles.larger}>
|
||||
<span className={styles.greeting}>
|
||||
{greeting}
|
||||
</span>
|
||||
<br/>
|
||||
I am
|
||||
<b> Patryk Kuchta, </b>
|
||||
an aspiring
|
||||
<br/>
|
||||
<b>Artificial Intelligence Scientist</b>.
|
||||
</div>
|
||||
<span data-aos={"fade-in"} data-aos-offset={"200"}>
|
||||
<i>and yes, the greeting is synced to your time.</i>
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.profileContainer}>
|
||||
<Image
|
||||
src={profilePic}
|
||||
alt={"Frontal image showing Patryk Kuchta"}
|
||||
fill={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IntroContent;
|
||||
26
src/portfolio/sections/Intro/TopBar.tsx
Normal file
26
src/portfolio/sections/Intro/TopBar.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import Image from "next/image";
|
||||
import styles from "../../styling/intro.module.scss";
|
||||
import logo from "../../../../public/portfolio/logo.svg";
|
||||
|
||||
const TopBar = (): JSX.Element => {
|
||||
return (
|
||||
<header className={styles.topBar} data-aos={"zoom-in-down"} data-aos-duration={"500"}>
|
||||
<div className={styles.row}>
|
||||
<div className={styles.logoContainer}>
|
||||
<Image src={logo} alt={"Kuchta logo"} fill={true}/>
|
||||
</div>
|
||||
<a href={"#achievements"}>Achievements</a>
|
||||
<a href={"#experience"}>Experience</a>
|
||||
<a href={"#projects"}>Projects</a>
|
||||
<a href={"#skills"}>Skills</a>
|
||||
</div>
|
||||
<div className={styles.left}>
|
||||
<a href={"mailto: patrick@kuchta.uk"}>patrick@kuchta.uk</a>
|
||||
<span>/</span>
|
||||
<a href={"mailto: patryk@kuchta.uk"}>patryk@kuchta.uk</a>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopBar;
|
||||
10
src/portfolio/sections/Intro/helpers.ts
Normal file
10
src/portfolio/sections/Intro/helpers.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export const getGreeting = (): string => {
|
||||
const hour = new Date().getHours();
|
||||
if (hour > 4 && hour < 12) {
|
||||
return "Good Morning!";
|
||||
} else if (hour < 18) {
|
||||
return "Good Afternoon!";
|
||||
} else {
|
||||
return "Good Evening!";
|
||||
}
|
||||
};
|
||||
1
src/portfolio/sections/Intro/index.ts
Normal file
1
src/portfolio/sections/Intro/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from "./Intro";
|
||||
@@ -1,16 +1,16 @@
|
||||
import {Splide, SplideSlide} from "@splidejs/react-splide";
|
||||
import { Splide, SplideSlide } from "@splidejs/react-splide";
|
||||
import Project from "@/src/portfolio/helpers/Project";
|
||||
import projectData from "@/src/portfolio/data/projectData";
|
||||
import styles from "../styling/projects.module.scss";
|
||||
|
||||
const Projects = () => {
|
||||
const Projects = (): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.section} id={"projects"}>
|
||||
<Splide
|
||||
options={{
|
||||
rewind: true,
|
||||
type: "slide",
|
||||
perPage: 1,
|
||||
perPage: 1
|
||||
}}
|
||||
>
|
||||
{ projectData.map((entry, key) => {
|
||||
@@ -24,4 +24,4 @@ const Projects = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Projects;
|
||||
export default Projects;
|
||||
|
||||
@@ -1,107 +1 @@
|
||||
import styles from "../styling/skillsLinks.module.scss";
|
||||
import SkillDisplay from "@/src/portfolio/helpers/SkillDisplay";
|
||||
import Accordion from "@/src/portfolio/helpers/Accordion";
|
||||
import {skillsInCategories} from "@/src/portfolio/data/skillsData";
|
||||
import {modulesTaken} from "@/src/portfolio/data/modulesTaken";
|
||||
|
||||
const SkillsAndLinks = () => {
|
||||
const moreInfoLinks = [
|
||||
{
|
||||
title: "Github",
|
||||
link: "https://github.com/KuchtaVR6/"
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
},
|
||||
{
|
||||
title: "Curriculum Vitae",
|
||||
link: "/PatrykKuchta_CV.pdf"
|
||||
}
|
||||
];
|
||||
|
||||
const contactLinks = [
|
||||
{
|
||||
title: "Email",
|
||||
link: "mailto:patryk@kuchta.uk"
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.section} id={"skills"}>
|
||||
<div data-aos = {"fade-left"} className={styles.skills}>
|
||||
<div>
|
||||
<i>Press the "+" to expand a section</i> 👀
|
||||
</div>
|
||||
<div className={styles.innerskills}>
|
||||
{
|
||||
Object.entries(skillsInCategories).map(([category, skills]) => {
|
||||
console.log(skills);
|
||||
return <Accordion title={category} key={category}>
|
||||
{
|
||||
skills.map((skill) => {
|
||||
return <SkillDisplay {...skill} key={skill.name} />;
|
||||
})
|
||||
}
|
||||
</Accordion>;
|
||||
})
|
||||
}
|
||||
|
||||
<Accordion title={"Modules Taken"}>
|
||||
{
|
||||
modulesTaken.map(({name, level, score}) => {
|
||||
return <div id={name.toLowerCase()}
|
||||
className={styles.technology}
|
||||
key={name}>
|
||||
<b>{name} </b>
|
||||
<span style={{float: "right", fontSize: "0.8em"}}>
|
||||
{score>=0? score + "%" : "🔮"} <i>{level}</i>
|
||||
</span>
|
||||
</div>;
|
||||
})
|
||||
}
|
||||
</Accordion>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div data-aos = {"fade-right"} className={styles.otherLinks}>
|
||||
<h2>Find out more about me:</h2>
|
||||
<ul>
|
||||
{
|
||||
moreInfoLinks.map(({title, link}, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
<h2>Contact me through:</h2>
|
||||
<ul>
|
||||
{
|
||||
contactLinks.map(({title, link}, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SkillsAndLinks;
|
||||
export { default } from "./SkillsAndLinks/SkillsAndLinks";
|
||||
|
||||
71
src/portfolio/sections/SkillsAndLinks/LinksSection.tsx
Normal file
71
src/portfolio/sections/SkillsAndLinks/LinksSection.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import styles from "../../styling/skillsLinks.module.scss";
|
||||
|
||||
interface ILink {
|
||||
title: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
const moreInfoLinks: ILink[] = [
|
||||
{
|
||||
title: "Github",
|
||||
link: "https://github.com/KuchtaVR6/"
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
},
|
||||
{
|
||||
title: "Curriculum Vitae",
|
||||
link: "/PatrykKuchta_CV.pdf"
|
||||
}
|
||||
];
|
||||
|
||||
const contactLinks: ILink[] = [
|
||||
{
|
||||
title: "Email",
|
||||
link: "mailto:patryk@kuchta.uk"
|
||||
},
|
||||
{
|
||||
title: "LinkedIn",
|
||||
link: "https://linkedin.com/in/kuchtap"
|
||||
}
|
||||
];
|
||||
|
||||
const LinksSection = (): JSX.Element => {
|
||||
return (
|
||||
<div data-aos = {"fade-right"} className={styles.otherLinks}>
|
||||
<h2>Find out more about me:</h2>
|
||||
<ul>
|
||||
{
|
||||
moreInfoLinks.map(({ title, link }, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
<h2>Contact me through:</h2>
|
||||
<ul>
|
||||
{
|
||||
contactLinks.map(({ title, link }, key) => {
|
||||
return (
|
||||
<li key = {key}>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LinksSection;
|
||||
14
src/portfolio/sections/SkillsAndLinks/SkillsAndLinks.tsx
Normal file
14
src/portfolio/sections/SkillsAndLinks/SkillsAndLinks.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import styles from "../../styling/skillsLinks.module.scss";
|
||||
import SkillsSection from "./SkillsSection";
|
||||
import LinksSection from "./LinksSection";
|
||||
|
||||
const SkillsAndLinks = (): JSX.Element => {
|
||||
return (
|
||||
<div className={styles.section} id={"skills"}>
|
||||
<SkillsSection/>
|
||||
<LinksSection/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SkillsAndLinks;
|
||||
45
src/portfolio/sections/SkillsAndLinks/SkillsSection.tsx
Normal file
45
src/portfolio/sections/SkillsAndLinks/SkillsSection.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import styles from "../../styling/skillsLinks.module.scss";
|
||||
import SkillDisplay from "@/src/portfolio/helpers/SkillDisplay";
|
||||
import Accordion from "@/src/portfolio/helpers/Accordion";
|
||||
import { skillsInCategories } from "@/src/portfolio/data/skillsData";
|
||||
import { modulesTaken } from "@/src/portfolio/data/modulesTaken";
|
||||
|
||||
const SkillsSection = (): JSX.Element => {
|
||||
return (
|
||||
<div data-aos = {"fade-left"} className={styles.skills}>
|
||||
<div>
|
||||
<i>Press the "+" to expand a section</i> 👀
|
||||
</div>
|
||||
<div className={styles.innerskills}>
|
||||
{
|
||||
Object.entries(skillsInCategories).map(([category, skills]) => {
|
||||
return <Accordion title={category} key={category}>
|
||||
{
|
||||
skills.map((skill) => {
|
||||
return <SkillDisplay {...skill} key={skill.name} />;
|
||||
})
|
||||
}
|
||||
</Accordion>;
|
||||
})
|
||||
}
|
||||
|
||||
<Accordion title={"Modules Taken"}>
|
||||
{
|
||||
modulesTaken.map(({ name, level, score }) => {
|
||||
return <div id={name.toLowerCase()}
|
||||
className={styles.technology}
|
||||
key={name}>
|
||||
<b>{name} </b>
|
||||
<span style={{ float: "right", fontSize: "0.8em" }}>
|
||||
{score>=0? score + "%" : "🔮"} <i>{level}</i>
|
||||
</span>
|
||||
</div>;
|
||||
})
|
||||
}
|
||||
</Accordion>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SkillsSection;
|
||||
1
src/portfolio/sections/SkillsAndLinks/index.ts
Normal file
1
src/portfolio/sections/SkillsAndLinks/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from "./SkillsAndLinks";
|
||||
Reference in New Issue
Block a user