diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index ff6fb8d..f601b28 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -16,7 +16,7 @@ jobs: - name: Rebuild and Deploy with Docker Compose run: | - docker build -t local/gabriel-portfolio:latest . + docker build --build-arg NEXT_PUBLIC_SHOW_FUN_ZONE=false -t local/gabriel-portfolio:latest . docker compose up -d # Clean up any old, unused images to save disk space diff --git a/Dockerfile b/Dockerfile index 196a231..fee97cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,8 @@ RUN bun install --frozen-lockfile COPY . . ENV NODE_ENV=production +ARG NEXT_PUBLIC_SHOW_FUN_ZONE=false +ENV NEXT_PUBLIC_SHOW_FUN_ZONE=$NEXT_PUBLIC_SHOW_FUN_ZONE RUN bun run build FROM nginx:alpine diff --git a/app/about/page.tsx b/app/about/page.tsx index 3e65f09..06ce679 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -1,5 +1,8 @@ import Image from "next/image"; +import Link from "next/link"; import Chip from "@/components/chip"; +import WritingsList from "@/components/writings-list"; +import { writings } from "@/lib/data"; import { Metadata } from "next"; import { Check } from "lucide-react"; @@ -7,9 +10,24 @@ export const metadata: Metadata = { title: "About Me | Gabriel Kaszewski", description: "Learn more about Gabriel Kaszewski, his skills, and his journey as a developer.", + alternates: { + canonical: "https://gabrielkaszewski.dev/about", + }, + openGraph: { + title: "About Me | Gabriel Kaszewski", + description: + "Learn more about Gabriel Kaszewski, his skills, and his journey as a developer.", + url: "https://gabrielkaszewski.dev/about", + }, + twitter: { + card: "summary", + 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 hobbies = ["Programming", "Filmmaking", "Photography", "Gaming", "Playing guitar"]; const interests = [ "Computer Science", "Sci-Fi Books", @@ -82,7 +100,7 @@ const AboutPage = () => {
-

More info about me!

+

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 @@ -105,7 +123,7 @@ const AboutPage = () => { processes using cellular automata" is available{" "} here @@ -136,8 +154,18 @@ const AboutPage = () => {

+
+

+ I also enjoy photography. You can see some of my shots{" "} + + here + + . +

+
+
-

My Philosophy

+

My Philosophy

I believe much of today's software is bloated, inefficient, and disrespectful of the user's resources. My passion, which @@ -150,35 +178,8 @@ const AboutPage = () => {

-
-

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

+

Future Goals

I'm always eager to learn and grow. My goal is to continue honing my skills in backend development and system architecture. @@ -194,8 +195,16 @@ const AboutPage = () => {

+
+

Writings

+

Sometimes I dabble in writing, here are some of my works

+
+ +
+
+
-

FAQ

+

FAQ

{faqItems.map((item) => (
diff --git a/app/fun-zone/page.tsx b/app/fun-zone/page.tsx new file mode 100644 index 0000000..4b94bf5 --- /dev/null +++ b/app/fun-zone/page.tsx @@ -0,0 +1,46 @@ +import FunZoneCarousel from "@/components/fun-zone-carousel"; +import { funZoneItems } from "@/lib/data"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Fun Zone | Gabriel Kaszewski", + description: "Games, tools, and toys I built for fun. Try them out!", + keywords: [ + "games", + "pixel canvas", + "wordle", + "game jam", + "interactive", + "playground", + ], + alternates: { + canonical: "https://gabrielkaszewski.dev/fun-zone", + }, + openGraph: { + title: "Fun Zone | Gabriel Kaszewski", + description: "Games, tools, and toys I built for fun. Try them out!", + url: "https://gabrielkaszewski.dev/fun-zone", + }, + twitter: { + card: "summary", + title: "Fun Zone | Gabriel Kaszewski", + description: "Games, tools, and toys I built for fun. Try them out!", + }, +}; + +const FunZonePage = () => { + return ( +
+
+

+ Fun Zone +

+

stuff I made for fun

+
+ + +
+ ); +}; + +export default FunZonePage; diff --git a/app/k-suite/page.tsx b/app/k-suite/page.tsx index 60c85e8..f9ed137 100644 --- a/app/k-suite/page.tsx +++ b/app/k-suite/page.tsx @@ -1,6 +1,28 @@ +import { Metadata } from "next"; import Image from "next/image"; import { ExternalLink, Github } from "lucide-react"; +export const metadata: Metadata = { + title: "K-Suite | Gabriel Kaszewski", + description: + "A cohesive ecosystem of open-source, self-hosted applications designed to restore digital sovereignty to the user.", + alternates: { + canonical: "https://gabrielkaszewski.dev/k-suite", + }, + openGraph: { + title: "K-Suite | Gabriel Kaszewski", + description: + "A cohesive ecosystem of open-source, self-hosted applications designed to restore digital sovereignty to the user.", + url: "https://gabrielkaszewski.dev/k-suite", + }, + twitter: { + card: "summary", + title: "K-Suite | Gabriel Kaszewski", + description: + "A cohesive ecosystem of open-source, self-hosted applications designed to restore digital sovereignty to the user.", + }, +}; + interface KSuiteApp { id: number; name: string; diff --git a/app/layout.tsx b/app/layout.tsx index 57cbc98..06bef73 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -101,7 +101,7 @@ export default function RootLayout({ /> - {children} +
{children}
diff --git a/app/movie-corner/page.tsx b/app/movie-corner/page.tsx index 314f922..f8c3845 100644 --- a/app/movie-corner/page.tsx +++ b/app/movie-corner/page.tsx @@ -1,9 +1,24 @@ import { Metadata } from "next"; export const metadata: Metadata = { - title: "Movie Corner", + title: "Movie Corner | Gabriel Kaszewski", description: "My personal cinema journal — what I watch and how I feel about it.", + alternates: { + canonical: "https://gabrielkaszewski.dev/movie-corner", + }, + openGraph: { + title: "Movie Corner | Gabriel Kaszewski", + description: + "My personal cinema journal — what I watch and how I feel about it.", + url: "https://gabrielkaszewski.dev/movie-corner", + }, + twitter: { + card: "summary", + title: "Movie Corner | Gabriel Kaszewski", + description: + "My personal cinema journal — what I watch and how I feel about it.", + }, }; const MOVIE_REVIEWS_URL = diff --git a/app/page.tsx b/app/page.tsx index 5458528..150f9e1 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,9 +1,33 @@ +import { Metadata } from "next"; import AboutSummary from "@/components/about-summary"; + +export const metadata: Metadata = { + title: "Gabriel Kaszewski | Software Engineer", + description: + "Portfolio of Gabriel Kaszewski, a software engineer building fast, reliable software with Rust, Python, and modern web technologies.", + alternates: { + canonical: "https://gabrielkaszewski.dev", + }, + openGraph: { + title: "Gabriel Kaszewski | Software Engineer", + description: + "Portfolio of Gabriel Kaszewski, a software engineer building fast, reliable software with Rust, Python, and modern web technologies.", + url: "https://gabrielkaszewski.dev", + }, + twitter: { + card: "summary_large_image", + title: "Gabriel Kaszewski | Software Engineer", + description: + "Portfolio of Gabriel Kaszewski, a software engineer building fast, reliable software with Rust, Python, and modern web technologies.", + }, +}; import CommercialProjects from "@/components/commercial-projects"; import Experience from "@/components/experience"; +import FunZoneCta from "@/components/fun-zone-cta"; import Hero from "@/components/hero"; import Skills from "@/components/skills"; import { skills, jobs } from "@/lib/data"; +import { featureFlags } from "@/lib/feature-flags"; export default function Home() { return ( @@ -13,6 +37,7 @@ export default function Home() { + {featureFlags.funZone && }
diff --git a/app/photos/page.tsx b/app/photos/page.tsx new file mode 100644 index 0000000..6eb9cc9 --- /dev/null +++ b/app/photos/page.tsx @@ -0,0 +1,39 @@ +import PhotoGallery from "@/components/photo-gallery"; +import { photos } from "@/lib/data"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Photos | Gabriel Kaszewski", + description: "A small collection of photos taken by Gabriel Kaszewski.", + keywords: ["photography", "Sony a6400", "Nikon D5300", "photo gallery"], + alternates: { + canonical: "https://gabrielkaszewski.dev/photos", + }, + openGraph: { + title: "Photos | Gabriel Kaszewski", + description: "A small collection of photos taken by Gabriel Kaszewski.", + url: "https://gabrielkaszewski.dev/photos", + }, + twitter: { + card: "summary", + title: "Photos | Gabriel Kaszewski", + description: "A small collection of photos taken by Gabriel Kaszewski.", + }, +}; + +const PhotosPage = () => { + return ( +
+
+

+ Photos +

+

shot on Sony a6400 and Nikon D5300

+
+ + +
+ ); +}; + +export default PhotosPage; diff --git a/app/projects/[projectName]/page.tsx b/app/projects/[projectName]/page.tsx index 24d480f..979c05f 100644 --- a/app/projects/[projectName]/page.tsx +++ b/app/projects/[projectName]/page.tsx @@ -23,7 +23,7 @@ export async function generateStaticParams() { export async function generateMetadata({ params, }: { - params: { projectName: string }; + params: Promise<{ projectName: string }>; }): Promise { const { projectName } = await params; const project = getProjectByName(projectName); @@ -32,12 +32,18 @@ export async function generateMetadata({ return { title: "Project Not Found" }; } + const slug = encodeURIComponent(project.name.replace(/\s/g, "+")); + return { title: `${project.name} | Gabriel Kaszewski`, description: project.short_description, + alternates: { + canonical: `https://gabrielkaszewski.dev/projects/${slug}`, + }, openGraph: { title: project.name, description: project.short_description, + url: `https://gabrielkaszewski.dev/projects/${slug}`, images: project.thumbnails && project.thumbnails.length > 0 ? [ @@ -50,13 +56,18 @@ export async function generateMetadata({ ] : undefined, }, + twitter: { + card: "summary", + title: project.name, + description: project.short_description, + }, }; } export default async function ProjectDetailPage({ params, }: { - params: { projectName: string }; + params: Promise<{ projectName: string }>; }) { const { projectName } = await params; const project = getProjectByName(projectName); diff --git a/app/projects/page.tsx b/app/projects/page.tsx index e05fecf..c93b7b5 100644 --- a/app/projects/page.tsx +++ b/app/projects/page.tsx @@ -6,6 +6,21 @@ export const metadata: Metadata = { title: "My Projects | Gabriel Kaszewski", description: "A showcase of my work, including web applications, games, and developer tools built with Rust, Next.js, and more.", + alternates: { + canonical: "https://gabrielkaszewski.dev/projects", + }, + openGraph: { + title: "My Projects | Gabriel Kaszewski", + description: + "A showcase of my work, including web applications, games, and developer tools built with Rust, Next.js, and more.", + url: "https://gabrielkaszewski.dev/projects", + }, + twitter: { + card: "summary", + title: "My Projects | Gabriel Kaszewski", + description: + "A showcase of my work, including web applications, games, and developer tools built with Rust, Next.js, and more.", + }, }; const ProjectsPage = () => { diff --git a/components/about-summary.tsx b/components/about-summary.tsx index d85759f..990588b 100644 --- a/components/about-summary.tsx +++ b/components/about-summary.tsx @@ -4,35 +4,34 @@ const AboutSummary = () => { id="who-am-i" className="flex flex-col items-center justify-center gap-4 p-4 rounded w-full" > -

+

Who am I? -

+

- Hi, I'm Gabriel Kaszewski — a Bioinformatics graduate and a - software engineer by trade. I’ve been obsessed with programming since - I was 11, and I thrive on building software that solves complex, - real-world problems. + Hi, I'm Gabriel Kaszewski. I studied Bioinformatics and work as + a software engineer. I've been programming since I was 11 and + I still enjoy it just as much.

- My most ambitious project to date is my first game. You can check out - the Steam preview below — if it catches your eye, I’d love for you to - add it to your wishlist! + I'm currently working on my first game. If it looks interesting, + consider wishlisting it!

- Currently, I am a Software Engineer at{" "} - WPP Media. When I’m not - at my day job, I’m usually deep-diving into new technologies or - bringing my own side projects to life. + By day I work at{" "} + WPP Media. Outside of + that I'm usually tinkering with side projects or picking up + something new.

diff --git a/components/commercial-projects.tsx b/components/commercial-projects.tsx index 5e39b09..1ebd6ab 100644 --- a/components/commercial-projects.tsx +++ b/components/commercial-projects.tsx @@ -10,9 +10,9 @@ const CommercialProjects = () => { className="flex flex-col items-center justify-center gap-8 p-4 w-full" >
-

+

Commissioned Work -

+

Selected commercial projects and freelance commissions.

diff --git a/components/experience.tsx b/components/experience.tsx index 4d3f710..196eba9 100644 --- a/components/experience.tsx +++ b/components/experience.tsx @@ -6,9 +6,9 @@ const Experience = ({ jobs }: { jobs: Job[] }) => ( id="experience" className="flex flex-col items-center gap-8 p-4 w-full" > -

+

Experience -

+
); diff --git a/components/footer.tsx b/components/footer.tsx index 7844e21..082f100 100644 --- a/components/footer.tsx +++ b/components/footer.tsx @@ -25,7 +25,7 @@ const Footer = () => { return (