Refactor project slug handling and improve project retrieval logic
All checks were successful
Build and Deploy Gabriel Kaszewski Portfolio / build-and-deploy-local (push) Successful in 1m46s

This commit is contained in:
2026-08-21 15:46:33 +02:00
parent 39f1982fc9
commit 4d0cbb7fb2
5 changed files with 25 additions and 15 deletions

View File

@@ -1,5 +1,4 @@
import { projects } from "@/lib/data";
import { Project } from "@/lib/types";
import { getProjectBySlug, projects, projectSlug } from "@/lib/data";
import Chip from "@/components/chip";
import MarkdownContent from "@/components/markdown-content";
import { Metadata } from "next";
@@ -7,16 +6,9 @@ import Image from "next/image";
import { Github, Eye, CloudDownload } from "lucide-react";
import { notFound } from "next/navigation";
function getProjectByName(name: string): Project | undefined {
const decodedName = decodeURIComponent(name.replace(/\+/g, " "));
return projects.find(
(p) => p.name.toLowerCase() === decodedName.toLowerCase()
);
}
export async function generateStaticParams() {
return projects.map((project) => ({
projectName: encodeURIComponent(project.name.replace(/\s/g, "+")),
projectName: projectSlug(project),
}));
}
@@ -26,13 +18,13 @@ export async function generateMetadata({
params: Promise<{ projectName: string }>;
}): Promise<Metadata> {
const { projectName } = await params;
const project = getProjectByName(projectName);
const project = getProjectBySlug(projectName);
if (!project) {
return { title: "Project Not Found" };
}
const slug = encodeURIComponent(project.name.replace(/\s/g, "+"));
const slug = projectSlug(project);
return {
title: `${project.name} | Gabriel Kaszewski`,
@@ -70,7 +62,7 @@ export default async function ProjectDetailPage({
params: Promise<{ projectName: string }>;
}) {
const { projectName } = await params;
const project = getProjectByName(projectName);
const project = getProjectBySlug(projectName);
if (!project) {
notFound();

View File

@@ -2,6 +2,7 @@ import Link from "next/link";
import { Project } from "@/lib/types";
import Chip from "@/components/chip";
import { Eye } from "lucide-react";
import { projectSlug } from "@/lib/data";
const CommercialProjectCard = ({ project }: { project: Project }) => {
return (
@@ -34,7 +35,7 @@ const CommercialProjectCard = ({ project }: { project: Project }) => {
<div className="flex gap-3 mt-auto">
<Link
href={`/projects/${project.name}`}
href={`/projects/${projectSlug(project)}`}
className="flex-1 px-4 py-3 text-center font-bold text-black bg-yellow-400 rounded-xl hover:bg-yellow-500 transition-colors glass-effect glossy-effect bottom gloss-highlight"
>
Read more

View File

@@ -1,4 +1,5 @@
import Link from "next/link";
import { projectSlug } from "@/lib/data";
import { Project } from "@/lib/types";
import Chip from "@/components/chip";
import ImageCarousel from "@/components/image-carousel";
@@ -64,7 +65,7 @@ const ProjectItem = ({ project }: ProjectItemProps) => {
</div>
<Link
href={`/projects/${project.name}`}
href={`/projects/${projectSlug(project)}`}
className="text-center glass-effect glossy-effect bottom gloss-highlight p-2 rounded-2xl bg-yellow-400 hover:bg-yellow-500 text-black font-bold"
>
Read more

View File

@@ -1,4 +1,5 @@
import { Skill, Job, Project, FunZoneItem, Writing, Photo } from "@/lib/types";
import { slugify } from "@/lib/slug";
export const skills: Skill[] = [
{ name: "Angular" },
@@ -628,3 +629,8 @@ export const photos: Photo[] = [
height: 2000,
},
];
export const projectSlug = (project: Project): string => slugify(project.name);
export const getProjectBySlug = (slug: string): Project | undefined =>
projects.find((project) => projectSlug(project) === slug);

10
lib/slug.ts Normal file
View File

@@ -0,0 +1,10 @@
export function slugify(value: string): string {
return value
.normalize("NFD")
.replace(/\p{Diacritic}/gu, "")
.replace(/ł/g, "l")
.replace(/Ł/g, "L")
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
}