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:
@@ -0,0 +1,58 @@
|
||||
import Link from "next/link";
|
||||
import type { ProjectType } from "@prisma/client";
|
||||
import type { Locale } from "@/lib/i18n";
|
||||
import { getProjectDirectoryCopy, getProjectPath } from "@/lib/project-content";
|
||||
import { getProjectCategories, getPublishedProjects } from "@/lib/project-queries";
|
||||
import ProjectCard from "@/components/public/project-card";
|
||||
|
||||
type ProjectDirectoryProps = {
|
||||
locale: Locale;
|
||||
type: ProjectType;
|
||||
categorySlug?: string;
|
||||
};
|
||||
|
||||
export default async function ProjectDirectory({ locale, type, categorySlug }: ProjectDirectoryProps) {
|
||||
const [projects, categories] = await Promise.all([getPublishedProjects(type, categorySlug), getProjectCategories()]);
|
||||
const copy = getProjectDirectoryCopy(locale, type);
|
||||
const allHref = getProjectPath(locale, type);
|
||||
|
||||
return (
|
||||
<section className="mx-auto w-full max-w-6xl space-y-8 px-4 py-10 sm:px-6 lg:px-8">
|
||||
<header className="max-w-3xl space-y-3">
|
||||
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-brand-2">{copy.eyebrow}</p>
|
||||
<h1 className="text-4xl font-semibold tracking-tight sm:text-5xl">{copy.title}</h1>
|
||||
<p className="text-lg leading-8 text-muted-foreground">{copy.description}</p>
|
||||
</header>
|
||||
|
||||
{categories.length > 0 ? (
|
||||
<nav aria-label={locale === "ar" ? "فلترة التصنيفات" : "Filter by category"} className="flex flex-wrap gap-2">
|
||||
<Link
|
||||
href={allHref}
|
||||
className={!categorySlug ? "rounded-full bg-primary px-4 py-2 text-sm text-primary-foreground" : "rounded-full border border-border px-4 py-2 text-sm text-muted-foreground hover:bg-accent"}
|
||||
>
|
||||
{locale === "ar" ? "الكل" : "All"}
|
||||
</Link>
|
||||
{categories.map((category) => (
|
||||
<Link
|
||||
key={category.id}
|
||||
href={`${allHref}?category=${category.slug}`}
|
||||
className={categorySlug === category.slug ? "rounded-full bg-primary px-4 py-2 text-sm text-primary-foreground" : "rounded-full border border-border px-4 py-2 text-sm text-muted-foreground hover:bg-accent"}
|
||||
>
|
||||
{locale === "ar" ? category.nameAr : category.nameEn}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
) : null}
|
||||
|
||||
{projects.length === 0 ? (
|
||||
<div className="rounded-xl border border-dashed border-border bg-card p-10 text-center text-muted-foreground">{copy.empty}</div>
|
||||
) : (
|
||||
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||
{projects.map((project) => (
|
||||
<ProjectCard key={project.id} locale={locale} type={type} project={project} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user