From a99b6353becd01b3102eeb7488de6c25c0e50848 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Mon, 8 Sep 2025 19:12:30 +0200 Subject: [PATCH] feat: add AboutSummary component with personal introduction and game preview feat: create Chip component for displaying technology tags feat: implement ExperienceCard component to showcase job experiences feat: add Experience component to list multiple job experiences feat: create Footer component with social links and copyright information feat: implement Hero component for the landing section with social links feat: add ImageCarousel component for displaying project images feat: create Navbar component with scroll effect and navigation links feat: implement ProjectItem component to display individual project details feat: add Skills component to showcase technical skills feat: create data module with skills, jobs, and projects information feat: define types for Skill, Job, and Project in types module chore: update package.json with new dependencies for Tailwind CSS and Lucide icons chore: add CV PDF file to public directory chore: remove unused SVG files from public directory chore: add new images for background and hero sections feat: implement formatDate utility function for date formatting --- app/about/page.tsx | 206 +++++++++++++++++++++++++ app/favicon.ico | Bin 25931 -> 4286 bytes app/globals.css | 166 +++++++++++++++++++- app/layout.tsx | 11 +- app/page.tsx | 109 ++----------- app/projects/[projectName]/page.tsx | 139 +++++++++++++++++ app/projects/page.tsx | 29 ++++ bun.lock | 153 ++++++++++++++++++ components/about-summary.tsx | 40 +++++ components/chip.tsx | 13 ++ components/experience-card.tsx | 30 ++++ components/experience.tsx | 22 +++ components/footer.tsx | 88 +++++++++++ components/hero.tsx | 66 ++++++++ components/image-carousel.tsx | 60 ++++++++ components/navbar.tsx | 78 ++++++++++ components/project-item.tsx | 114 ++++++++++++++ components/skills.tsx | 31 ++++ lib/data.ts | 230 ++++++++++++++++++++++++++++ lib/types.ts | 26 ++++ package.json | 7 +- public/cv.pdf | Bin 0 -> 46167 bytes public/file.svg | 1 - public/globe.svg | 1 - public/images/background.avif | Bin 0 -> 18118 bytes public/images/favicon.ico | Bin 0 -> 270398 bytes public/images/hero.avif | Bin 0 -> 116780 bytes public/images/ja.avif | Bin 0 -> 11998 bytes public/next.svg | 1 - public/vercel.svg | 1 - public/window.svg | 1 - utils/format-date.ts | 6 + 32 files changed, 1522 insertions(+), 107 deletions(-) create mode 100644 app/about/page.tsx create mode 100644 app/projects/[projectName]/page.tsx create mode 100644 app/projects/page.tsx create mode 100644 components/about-summary.tsx create mode 100644 components/chip.tsx create mode 100644 components/experience-card.tsx create mode 100644 components/experience.tsx create mode 100644 components/footer.tsx create mode 100644 components/hero.tsx create mode 100644 components/image-carousel.tsx create mode 100644 components/navbar.tsx create mode 100644 components/project-item.tsx create mode 100644 components/skills.tsx create mode 100644 lib/data.ts create mode 100644 lib/types.ts create mode 100644 public/cv.pdf delete mode 100644 public/file.svg delete mode 100644 public/globe.svg create mode 100644 public/images/background.avif create mode 100644 public/images/favicon.ico create mode 100644 public/images/hero.avif create mode 100644 public/images/ja.avif delete mode 100644 public/next.svg delete mode 100644 public/vercel.svg delete mode 100644 public/window.svg create mode 100644 utils/format-date.ts diff --git a/app/about/page.tsx b/app/about/page.tsx new file mode 100644 index 0000000..9574a18 --- /dev/null +++ b/app/about/page.tsx @@ -0,0 +1,206 @@ +import Image from "next/image"; +import Chip from "@/components/chip"; +import { Metadata } from "next"; +import { Check } from "lucide-react"; + +export const metadata: Metadata = { + title: "About Me | Gabriel Kaszewski", + description: + "Learn more about Gabriel Kaszewski, his skills, and his journey as a developer.", +}; + +const hobbies = [ + "Programming 💻", + "Filmmaking 🎥", + "Gaming 🕹️", + "Playing guitar 🎸", +]; +const interests = [ + "Computer Science 💾", + "Sci-Fi Books📚", + "Astronomy 🔭", + "Sports 🏅", + "History 🏰", +]; +const futureGoals = [ + "Deepen my expertise in Rust for high-performance applications.", + "Contribute to impactful open-source projects.", + "Develop and release my first full-fledged indie game.", +]; +const faqItems = [ + { + q: "How old were you when you started programming?", + a: "I was 11 years old 🧑‍💻.", + }, + { + q: "How did you learn programming?", + a: "I read books 📖 and practiced a lot.", + }, + { + q: "Are you studying Computer Science?", + a: "No, I have a degree in Bioinformatics, which is a closely related field.", + }, + { + q: "Which programming language do you recommend for a beginner?", + a: "The language doesn't really matter, just choose one you like and dive in 🌊.", + }, + { + q: "What was your first programming language?", + a: "My journey began with C++ 🖥️.", + }, + { + q: "What is your favorite programming language?", + a: "I enjoy writing in C, Rust, and Python 🐍. But Rust is the best 💖🦀", + }, +]; + +const calculateAge = (birthDate: string): number => { + const today = new Date(); + const birth = new Date(birthDate); + let age = today.getFullYear() - birth.getFullYear(); + const monthDifference = today.getMonth() - birth.getMonth(); + if ( + monthDifference < 0 || + (monthDifference === 0 && today.getDate() < birth.getDate()) + ) { + age--; + } + return age; +}; + +const AboutPage = () => { + const age = calculateAge("2002-02-27"); + + return ( +
+
+ A photo of Gabriel Kaszewski +

Hello, I'm Gabriel! 👋

+
+ +
+
+

More info about me! 💡

+

+ Hi! I am Gabriel and I am {age} years old. I graduated in + Bioinformatics from the University of Gdańsk 🏫. I'm fluent in + Polish and English and currently work as a Python Developer at + digimonkeys.com 🐒💻. +

+

+ I have co-authored one scientific article, which you can read{" "} + + here + + . +

+
+ +
+
+

Hobbies 🎮🎸

+
+ {hobbies.map((hobby) => ( + + ))} +
+
+
+

Interests 🌌📚

+
+ {interests.map((interest) => ( + + ))} +
+
+
+ +
+

My Philosophy 🧠

+

+ I believe much of today's software is bloated, inefficient, and + disrespectful of the user's resources. My passion, which + started with a simple curiosity at age 11, is to build a better + alternative. I focus on creating software that is{" "} + + fast, reliable, and genuinely intuitive + + , guided by the principles of clean and efficient code. +

+
+ +
+

My Toolkit 🛠️

+
+
+
+

OS & Hardware

+

+ Arch Linux, Custom-built PC (Ryzen 7 5800X3D, RTX 4070 Ti, + 48GB RAM) +

+
+
+

Editor

+

Jetbrains IDEs (Pycharm, Rider) & VS Code

+
+
+

Primary Languages

+

Rust, Python, C#, TypeScript

+
+
+

Favorite Tech

+

Axum, Godot, React, TailwindCSS

+
+
+
+
+ +
+

Future Goals 🚀

+

+ I'm always eager to learn and grow. My goal is to continue + honing my skills in backend development and system architecture. + Here's what's on my radar: +

+
    + {futureGoals.map((goal) => ( +
  • + + {goal} +
  • + ))} +
+
+ +
+

FAQ ❓

+
+ {faqItems.map((item) => ( +
+

{item.q}

+

{item.a}

+
+ ))} +
+
+
+
+ ); +}; + +export default AboutPage; diff --git a/app/favicon.ico b/app/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..ac27b5f8a3ff4c7a69c56ec8824c9fcf85aa850b 100644 GIT binary patch literal 4286 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 literal 25931 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 LrJugUA?W`A8`#=m diff --git a/app/globals.css b/app/globals.css index a2dc41e..02be7db 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,4 +1,6 @@ @import "tailwindcss"; +@plugin "@tailwindcss/typography"; +@plugin "tailwindcss-motion"; :root { --background: #ffffff; @@ -6,10 +8,30 @@ } @theme inline { + --card: hsl(0 0% 100%); + --color-background: var(--background); --color-foreground: var(--foreground); + --color-card: var(--card); --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); + + --gradient-fa-blue: 135deg, hsl(217 91% 60%) 0%, hsl(200 90% 70%) 100%; + --gradient-fa-green: 135deg, hsl(155 70% 55%) 0%, hsl(170 80% 65%) 100%; + --gradient-fa-card: 180deg, hsl(var(--card)) 0%, hsl(var(--card)) 90%, + hsl(var(--card)) 100%; + --gradient-fa-gloss: 135deg, rgba(255, 255, 255, 0.2) 0%, + rgba(255, 255, 255, 0) 100%; + + --shadow-fa-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06); + --shadow-fa-md: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06); + --shadow-fa-lg: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05); + --fa-inner: inset 0 1px 2px rgba(0, 0, 0, 0.1); + + --text-shadow-default: 0 1px 1px rgba(0, 0, 0, 0.2); + --text-shadow-sm: 0 1px 0px rgba(255, 255, 255, 0.4); + --text-shadow-md: 0 2px 2px rgba(0, 0, 0, 0.2); + --text-shadow-lg: 0 4px 4px rgba(0, 0, 0, 0.2); } @media (prefers-color-scheme: dark) { @@ -20,7 +42,149 @@ } body { - background: var(--background); + /* background: var(--background); */ + background-image: url("/images/background.avif"); + background-size: cover; + background-attachment: fixed; + background-position: center; color: var(--foreground); font-family: Arial, Helvetica, sans-serif; } + +@layer base { + glossy-effect::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + border-radius: inherit; + background: linear-gradient( + 180deg, + rgba(255, 255, 255, 0.4) 0%, + rgba(255, 255, 255, 0.1) 100% + ); + opacity: 0.8; + pointer-events: none; + z-index: 1; + } + + .glossy-effect.bottom::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 30%; + border-radius: inherit; + background: linear-gradient( + 0deg, + rgba(0, 0, 0, 0.1) 0%, + rgba(0, 0, 0, 0) 100% + ); + pointer-events: none; + z-index: 1; + } + + .fa-gradient-blue { + background: linear-gradient(var(--gradient-fa-blue)); + } + .fa-gradient-green { + background: linear-gradient(var(--gradient-fa-green)); + } + .fa-gradient-card { + background: linear-gradient(var(--gradient-fa-card)); + } + .fa-gloss { + position: relative; + } + .fa-gloss::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + border-radius: inherit; + background: linear-gradient(var(--gradient-fa-gloss)); + opacity: 0.8; + pointer-events: none; + z-index: 1; + } + .fa-gloss.bottom::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 30%; + border-radius: inherit; + background: linear-gradient( + 0deg, + rgba(0, 0, 0, 0.1) 0%, + rgba(0, 0, 0, 0) 100% + ); + pointer-events: none; + z-index: 1; + } +} + +@layer components { + .shadow-fa-sm { + box-shadow: var(--shadow-fa-sm), var(--fa-inner); + } + .shadow-fa-md { + box-shadow: var(--shadow-fa-md), var(--fa-inner); + } + .shadow-fa-lg { + box-shadow: var(--shadow-fa-lg), var(--fa-inner); + } + .text-shadow-default { + text-shadow: var(--text-shadow-default); + } + .text-shadow-sm { + text-shadow: var(--text-shadow-sm); + } + .text-shadow-md { + text-shadow: var(--text-shadow-md); + } + .text-shadow-lg { + text-shadow: var(--text-shadow-lg); + } + + .glass-effect { + @apply backdrop-blur-lg border border-white/20 shadow-fa-lg; + } + + .gloss-highlight::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 60%; + border-radius: inherit; + background: linear-gradient( + 180deg, + rgba(255, 255, 255, 0.5) 0%, + rgba(255, 255, 255, 0) 100% + ); + pointer-events: none; + z-index: 1; + } +} + +@layer utilities { + .my-animate { + opacity: 1 !important; + transform: translateY(0) !important; + transition: opacity 0.3s ease, transform 0.3s ease; + } + + .hidden-for-animation { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.3s ease, transform 0.3s ease; + } +} diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..d560fb2 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,9 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; +import Navbar from "@/components/navbar"; +import Footer from "@/components/footer"; +import Image from "next/image"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -13,8 +16,8 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Gabriel Kaszewski", + description: "Welcome to my portfolio", }; export default function RootLayout({ @@ -25,9 +28,11 @@ export default function RootLayout({ return ( + {children} +