feat: added new project detail page
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { ProjectCaseStudyContent } from "@/components/project-case-study-content";
|
||||
import { ProjectCaseStudyJsonLd } from "@/components/json-ld";
|
||||
import {
|
||||
getProjectCaseStudy,
|
||||
PROJECT_CASE_STUDY_SLUGS,
|
||||
type ProjectCaseStudyLocale,
|
||||
} from "@/data/project-case-studies";
|
||||
import {
|
||||
createAlternates,
|
||||
getAbsoluteUrl,
|
||||
getLocalizedUrl,
|
||||
} from "@/lib/seo";
|
||||
|
||||
type ProjectCaseStudyPageProps = {
|
||||
params: Promise<{ locale: string; slug: string }>;
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return (["tr", "en"] as ProjectCaseStudyLocale[]).flatMap((locale) =>
|
||||
PROJECT_CASE_STUDY_SLUGS.map((slug) => ({ locale, slug })),
|
||||
);
|
||||
}
|
||||
|
||||
export const dynamicParams = false;
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: ProjectCaseStudyPageProps): Promise<Metadata> {
|
||||
const { locale, slug } = await params;
|
||||
const siteLocale: ProjectCaseStudyLocale = locale === "en" ? "en" : "tr";
|
||||
const project = getProjectCaseStudy(slug, siteLocale);
|
||||
|
||||
if (!project) {
|
||||
return {
|
||||
title: siteLocale === "en" ? "Project not found" : "Proje bulunamadı",
|
||||
};
|
||||
}
|
||||
|
||||
const path = `/projects/${project.slug}`;
|
||||
const url = getLocalizedUrl(siteLocale, path);
|
||||
const socialImageUrl = getAbsoluteUrl(project.image);
|
||||
|
||||
return {
|
||||
title: project.title,
|
||||
description: project.summary,
|
||||
alternates: createAlternates(siteLocale, { tr: path, en: path }),
|
||||
openGraph: {
|
||||
title: project.title,
|
||||
description: project.summary,
|
||||
url,
|
||||
siteName: "Poyraz Avsever",
|
||||
type: "website",
|
||||
locale: siteLocale === "en" ? "en_US" : "tr_TR",
|
||||
alternateLocale: siteLocale === "en" ? ["tr_TR"] : ["en_US"],
|
||||
images: [
|
||||
{
|
||||
url: socialImageUrl,
|
||||
width: 1080,
|
||||
height: 1080,
|
||||
alt: project.screenshotAlt,
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: project.title,
|
||||
description: project.summary,
|
||||
creator: "@poyrazavsever",
|
||||
images: [{ url: socialImageUrl, alt: project.screenshotAlt }],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ProjectCaseStudyPage({
|
||||
params,
|
||||
}: ProjectCaseStudyPageProps) {
|
||||
const { locale, slug } = await params;
|
||||
const siteLocale: ProjectCaseStudyLocale = locale === "en" ? "en" : "tr";
|
||||
const project = getProjectCaseStudy(slug, siteLocale);
|
||||
|
||||
if (!project) notFound();
|
||||
|
||||
const url = getLocalizedUrl(siteLocale, `/projects/${project.slug}`);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProjectCaseStudyJsonLd
|
||||
name={project.title}
|
||||
description={project.summary}
|
||||
url={url}
|
||||
liveUrl={project.liveUrl}
|
||||
image={project.image}
|
||||
locale={siteLocale}
|
||||
applicationCategory={project.applicationCategory}
|
||||
technologies={project.technologies}
|
||||
features={project.results.map((result) => result.description)}
|
||||
/>
|
||||
<ProjectCaseStudyContent project={project} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
+23
-1
@@ -2,6 +2,7 @@ import type { MetadataRoute } from "next";
|
||||
import { listAnimationSources } from "@/data/animation-sources";
|
||||
import { isNewsletterCategory } from "@/data/blog";
|
||||
import { listBlogDetails } from "@/data/blog-detail";
|
||||
import { listProjectCaseStudies } from "@/data/project-case-studies";
|
||||
import {
|
||||
getAbsoluteUrl,
|
||||
getLocalizedUrl,
|
||||
@@ -127,5 +128,26 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
||||
},
|
||||
);
|
||||
|
||||
return [...staticRoutes, ...blogRoutes, ...animationSourceRoutes];
|
||||
const projectCaseStudyRoutes: MetadataRoute.Sitemap = LOCALES.flatMap(
|
||||
(locale) =>
|
||||
listProjectCaseStudies(locale).map((project) => {
|
||||
const path = `/projects/${project.slug}`;
|
||||
const paths = { tr: path, en: path };
|
||||
|
||||
return {
|
||||
url: getLocalizedUrl(locale, path),
|
||||
changeFrequency: "monthly" as const,
|
||||
priority: 0.8,
|
||||
alternates: { languages: getLanguageLinks(paths) },
|
||||
images: [getAbsoluteUrl(project.image)],
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return [
|
||||
...staticRoutes,
|
||||
...projectCaseStudyRoutes,
|
||||
...blogRoutes,
|
||||
...animationSourceRoutes,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user