Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Failing after 9m26s
95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
|
import ProjectsPageClient, { ProjectListItem } from "@/app/_ui/ProjectsPageClient";
|
|
import type { Metadata } from "next";
|
|
import { getLanguageAlternates, toAbsoluteUrl } from "@/lib/seo";
|
|
import { getProjects as getDirectusProjects } from "@/lib/directus";
|
|
|
|
export const revalidate = 300;
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}): Promise<Metadata> {
|
|
const { locale } = await params;
|
|
const languages = getLanguageAlternates({ pathWithoutLocale: "projects" });
|
|
return {
|
|
alternates: {
|
|
canonical: toAbsoluteUrl(`/${locale}/projects`),
|
|
languages,
|
|
},
|
|
};
|
|
}
|
|
|
|
export default async function ProjectsPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}) {
|
|
const { locale } = await params;
|
|
|
|
// Fetch from PostgreSQL
|
|
const dbProjects = await prisma.project.findMany({
|
|
where: { published: true },
|
|
orderBy: { createdAt: "desc" },
|
|
include: {
|
|
translations: {
|
|
select: { title: true, description: true, locale: true },
|
|
},
|
|
},
|
|
});
|
|
|
|
// Fetch from Directus
|
|
let directusProjects: ProjectListItem[] = [];
|
|
try {
|
|
const fetched = await getDirectusProjects(locale, { published: true });
|
|
if (fetched) {
|
|
directusProjects = fetched.map(p => ({
|
|
...p,
|
|
id: typeof p.id === 'string' ? (parseInt(p.id) || 0) : p.id,
|
|
})) as ProjectListItem[];
|
|
}
|
|
} catch (err) {
|
|
console.error("Directus projects fetch failed:", err);
|
|
}
|
|
|
|
const localizedDb: ProjectListItem[] = dbProjects.map((p) => {
|
|
const trPreferred = p.translations?.find((t) => t.locale === locale && (t?.title || t?.description));
|
|
const trDefault = p.translations?.find(
|
|
(t) => t.locale === p.defaultLocale && (t?.title || t?.description),
|
|
);
|
|
const tr = trPreferred ?? trDefault;
|
|
return {
|
|
id: p.id,
|
|
slug: p.slug,
|
|
title: tr?.title ?? p.title,
|
|
description: tr?.description ?? p.description,
|
|
tags: p.tags,
|
|
category: p.category,
|
|
date: p.date,
|
|
createdAt: p.createdAt.toISOString(),
|
|
imageUrl: p.imageUrl,
|
|
};
|
|
});
|
|
|
|
// Merge projects, prioritizing DB ones if slugs match
|
|
const allProjects: ProjectListItem[] = [...localizedDb];
|
|
const dbSlugs = new Set(localizedDb.map(p => p.slug));
|
|
|
|
for (const dp of directusProjects) {
|
|
if (!dbSlugs.has(dp.slug)) {
|
|
allProjects.push(dp);
|
|
}
|
|
}
|
|
|
|
// Final sort by date
|
|
allProjects.sort((a, b) => {
|
|
const dateA = new Date(a.date || a.createdAt || 0).getTime();
|
|
const dateB = new Date(b.date || b.createdAt || 0).getTime();
|
|
return dateB - dateA;
|
|
});
|
|
|
|
return <ProjectsPageClient projects={allProjects} locale={locale} />;
|
|
}
|
|
|