100 lines
4.2 KiB
TypeScript
100 lines
4.2 KiB
TypeScript
import { notFound } from "next/navigation";
|
|
import CourseVisitGallery from "@/components/CourseVisitGallery";
|
|
import InfoPageShell from "@/components/InfoPageShell";
|
|
import { getOpinionArticleBySlug, type CourseVisitBodyBlock } from "@/content/courseVisits";
|
|
import {
|
|
createBreadcrumbJsonLd,
|
|
createCollectionPageJsonLd,
|
|
createPageMetadata,
|
|
} from "@/app/seo";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
const articleSlug = "note-to-self-lenker-til-viktige-turneringer-i-golfbox";
|
|
const pageTitle = "Turneringer";
|
|
const pageIntro = "Her er alle turneringene vi ikke vet hvordan vi skal finne i Golfbox (og andre steder). God golfsesong!";
|
|
function renderBlock(block: CourseVisitBodyBlock, index: number) {
|
|
if (block.type !== "richText") {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<section key={index} className="surface-card rounded-[2rem] p-6 sm:p-8">
|
|
{block.title ? (
|
|
<h2 className="text-3xl font-black text-[#112015] sm:text-4xl">{block.title}</h2>
|
|
) : null}
|
|
<div
|
|
className={`course-visit-richtext space-y-4 text-base leading-8 text-[#334238] [&_a]:font-black [&_a]:text-[#112015] [&_a]:underline [&_a]:underline-offset-4 [&_em]:italic [&_h2]:mt-12 [&_h2]:text-3xl [&_h2]:font-black [&_h2]:text-[#112015] [&_h3]:mt-10 [&_h3]:text-2xl [&_h3]:font-black [&_iframe]:mt-5 [&_iframe]:aspect-video [&_iframe]:w-full [&_iframe]:rounded-[1.5rem] [&_iframe]:border [&_iframe]:border-[#112015]/8 [&_iframe]:shadow-[0_12px_30px_rgba(17,32,21,0.08)] [&_img]:mt-5 [&_img]:w-full [&_img]:rounded-[1.5rem] [&_img]:border [&_img]:border-[#112015]/8 [&_img]:shadow-[0_12px_30px_rgba(17,32,21,0.08)] [&_li]:mt-2 [&_p]:mt-4 [&_table]:mt-6 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-[#112015]/10 [&_td]:px-3 [&_td]:py-2 [&_th]:border [&_th]:border-[#112015]/10 [&_th]:bg-[#F4F7EE] [&_th]:px-3 [&_th]:py-2 [&_th]:text-left [&_ul]:mt-4 [&_ul]:list-disc [&_ul]:pl-6 ${
|
|
block.title ? "mt-4" : ""
|
|
}`}
|
|
dangerouslySetInnerHTML={{ __html: block.html }}
|
|
/>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
export async function generateMetadata() {
|
|
const article = await getOpinionArticleBySlug(articleSlug);
|
|
|
|
return createPageMetadata({
|
|
title: pageTitle,
|
|
description: article?.description || "Viktige turneringslenker i Golfbox samlet på TeeOff.",
|
|
path: "/turneringer",
|
|
image: article?.heroImages[0]?.src,
|
|
});
|
|
}
|
|
|
|
export default async function TournamentsPage() {
|
|
const article = await getOpinionArticleBySlug(articleSlug);
|
|
|
|
if (!article) {
|
|
notFound();
|
|
}
|
|
|
|
const collectionJsonLd = createCollectionPageJsonLd({
|
|
name: pageTitle,
|
|
description: article.description,
|
|
path: "/turneringer",
|
|
});
|
|
const breadcrumbJsonLd = createBreadcrumbJsonLd([
|
|
{ name: "Hjem", path: "/" },
|
|
{ name: "Turneringer", path: "/turneringer" },
|
|
]);
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(collectionJsonLd) }}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbJsonLd) }}
|
|
/>
|
|
<InfoPageShell eyebrow="Turneringer" title={article.title} intro={pageIntro}>
|
|
<div className="space-y-6">
|
|
<CourseVisitGallery title={article.title} media={article.mediaGallery.slice(0, 1)} />
|
|
{article.blocks.map((block, index) => renderBlock(block, index))}
|
|
{article.mediaGallery.length > 1 ? (
|
|
<section className="space-y-4">
|
|
<div className="flex items-end justify-between gap-4">
|
|
<div>
|
|
<p className="text-[11px] font-black uppercase tracking-[0.24em] text-[#8BC34A]">
|
|
Galleri
|
|
</p>
|
|
<h2 className="mt-3 text-3xl font-black text-[#112015] sm:text-4xl">
|
|
Bilder og video
|
|
</h2>
|
|
</div>
|
|
<p className="text-sm font-bold text-[#5A685C]">
|
|
{article.mediaGallery.length} elementer
|
|
</p>
|
|
</div>
|
|
<CourseVisitGallery title={article.title} media={article.mediaGallery} />
|
|
</section>
|
|
) : null}
|
|
</div>
|
|
</InfoPageShell>
|
|
</>
|
|
);
|
|
}
|