Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Failing after 9m19s
Fixed missing types, import errors, and updated test suites to match the new editorial design. Verified Docker container build.
90 lines
2.5 KiB
TypeScript
90 lines
2.5 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: parseInt(p.id) || 0,
|
|
})) as ProjectListItem[];
|
|
}
|
|
} catch (err) {
|
|
console.error("Directus projects fetch failed:", err);
|
|
}
|
|
|
|
const localizedDb = 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;
|
|
const { translations: _translations, ...rest } = p;
|
|
return {
|
|
...rest,
|
|
title: tr?.title ?? p.title,
|
|
description: tr?.description ?? p.description,
|
|
};
|
|
});
|
|
|
|
// Merge projects, prioritizing DB ones if slugs match
|
|
const allProjects: any[] = [...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} />;
|
|
}
|
|
|