feat: full site build — Project/Melody schema (Option A), admin CRUD, public sections, uploads, email+SMTP, internal analytics, legal pages, docs

This commit is contained in:
2026-08-05 20:53:40 +02:00
parent d87f3033c6
commit c26f41511f
122 changed files with 15068 additions and 41 deletions
+25
View File
@@ -0,0 +1,25 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import ProjectDetail from "@/components/public/project-detail";
import { getActiveLocale, isLocale, type Locale } from "@/lib/i18n";
import { getProjectDirectoryCopy } from "@/lib/project-content";
import { getPublishedProject } from "@/lib/project-queries";
type DesignDetailPageProps = {
params: { locale: string; slug: string };
};
export function generateMetadata({ params }: DesignDetailPageProps): Metadata {
if (!isLocale(params.locale)) return {};
const locale = getActiveLocale(params.locale as Locale);
const copy = getProjectDirectoryCopy(locale, "DESIGN");
return { title: copy.eyebrow, description: copy.description };
}
export default async function DesignDetailPage({ params }: DesignDetailPageProps) {
if (!isLocale(params.locale)) notFound();
const locale = getActiveLocale(params.locale as Locale);
const project = await getPublishedProject("DESIGN", params.slug);
if (!project) notFound();
return <ProjectDetail locale={locale} type="DESIGN" project={project} />;
}
+23
View File
@@ -0,0 +1,23 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import ProjectDirectory from "@/components/public/project-directory";
import { getActiveLocale, isLocale, type Locale } from "@/lib/i18n";
import { getProjectDirectoryCopy } from "@/lib/project-content";
type DesignsPageProps = {
params: { locale: string };
searchParams: { category?: string };
};
export function generateMetadata({ params }: { params: { locale: string } }): Metadata {
if (!isLocale(params.locale)) return {};
const locale = getActiveLocale(params.locale as Locale);
const copy = getProjectDirectoryCopy(locale, "DESIGN");
return { title: copy.title, description: copy.description };
}
export default function DesignsPage({ params, searchParams }: DesignsPageProps) {
if (!isLocale(params.locale)) notFound();
const locale = getActiveLocale(params.locale as Locale);
return <ProjectDirectory locale={locale} type="DESIGN" categorySlug={searchParams.category} />;
}