import { prisma } from "@/lib/prisma"; import ProjectDetailClient from "@/app/_ui/ProjectDetailClient"; import { notFound } from "next/navigation"; import type { Metadata } from "next"; import { getLanguageAlternates, toAbsoluteUrl } from "@/lib/seo"; export const revalidate = 300; export async function generateMetadata({ params, }: { params: Promise<{ locale: string; slug: string }>; }): Promise { const { locale, slug } = await params; const languages = getLanguageAlternates({ pathWithoutLocale: `projects/${slug}` }); return { alternates: { canonical: toAbsoluteUrl(`/${locale}/projects/${slug}`), languages, }, }; } export default async function ProjectPage({ params, }: { params: Promise<{ locale: string; slug: string }>; }) { const { locale, slug } = await params; const project = await prisma.project.findFirst({ where: { slug, published: true }, include: { translations: { select: { title: true, description: true, content: true, locale: true }, }, }, }); if (!project) return notFound(); const trPreferred = project.translations?.find((t) => t.locale === locale && (t?.title || t?.description)); const trDefault = project.translations?.find( (t) => t.locale === project.defaultLocale && (t?.title || t?.description), ); const tr = trPreferred ?? trDefault; const { translations: _translations, ...rest } = project; const localizedContent = (() => { if (typeof tr?.content === "string") return tr.content; if (tr?.content && typeof tr.content === "object" && "markdown" in tr.content) { const markdown = (tr.content as Record).markdown; if (typeof markdown === "string") return markdown; } return project.content; })(); const localized = { ...rest, title: tr?.title ?? project.title, description: tr?.description ?? project.description, content: localizedContent, }; const jsonLd = { "@context": "https://schema.org", "@type": "SoftwareSourceCode", "name": localized.title, "description": localized.description, "codeRepository": localized.github, "programmingLanguage": localized.technologies, "author": { "@type": "Person", "name": "Dennis Konkol" }, "dateCreated": project.date, "url": toAbsoluteUrl(`/${locale}/projects/${slug}`), "image": localized.imageUrl ? toAbsoluteUrl(localized.imageUrl) : undefined, }; return ( <>