Skip to content

Commit

Permalink
refactor: move uriSegments to app directory
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgoff committed Oct 9, 2024
1 parent 175b89d commit 7c19862
Show file tree
Hide file tree
Showing 50 changed files with 733 additions and 1,283 deletions.
176 changes: 176 additions & 0 deletions app/[locale]/[...uriSegments]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { FunctionComponent } from "react";
import { Metadata, ResolvingMetadata } from "next";
import { draftMode } from "next/headers";
import { notFound, redirect } from "next/navigation";
import { OpenGraph } from "next/dist/lib/metadata/types/opengraph-types";
import striptags from "striptags";
import { getBreadcrumbsById, getEntryMetadataByUri } from "@/lib/api/metadata";
import {
getEntriesByLocale,
getEntrySectionByUri,
} from "@/lib/api/entries/index";
import { getEntryDataByUri } from "@/lib/api/entry";
import { getReleaseOpenGraph } from "@/lib/api/noirlab";
import { resizeCantoImage } from "@/lib/api/canto/resize";
import PageTemplate from "@/components/templates/Page";
import NewsPageTemplate from "@/components/templates/NewsPage";
import GlossaryPageTemplate from "@/components/templates/GlossaryPage";
import SearchPageTemplate from "@/components/templates/SearchPage";
import SlideshowPageTemplate from "@/components/templates/SlideshowPage";
import StaffPageTemplate from "@/components/templates/StaffPage";
import EventPageTemplate from "@/components/templates/EventPage";

const pickFeaturedImage = async (
locale: string,
image?: any,
cantoAsset?: any,
pressReleaseId?: string
): Promise<OpenGraph["images"] | undefined> => {
if (pressReleaseId) {
const releaseOpenGraphImage = await getReleaseOpenGraph(
locale,
pressReleaseId
);

return releaseOpenGraphImage;
}

if (cantoAsset) {
const {
width,
height,
url: { directUrlPreview },
} = cantoAsset;
const url = resizeCantoImage(directUrlPreview, 800);

return { url, width, height };
}

if (image) {
const { url, width, height, altText: alt } = image;

return { url, width, height, alt };
}
};

export async function generateMetadata(
{ params: { locale, uriSegments }, searchParams = {} }: UriSegmentProps,
parent: ResolvingMetadata
): Promise<Metadata> {
const uri = uriSegments.join("/");
let previewToken: string | undefined;

if (draftMode().isEnabled) {
previewToken = Array.isArray(searchParams.preview)
? searchParams.preview[0]
: searchParams?.preview;
}

const { entry } = await getEntryMetadataByUri(uri, locale, previewToken);

if (!entry) {
notFound();
}

const {
title,
description,
image = [],
cantoAssetSingle = [],
pressReleaseId,
} = entry;

const featuredImage = await pickFeaturedImage(
locale,
image[0],
cantoAssetSingle[0],
pressReleaseId
);
const previousImages = (await parent).openGraph?.images || [];

return {
title,
description: striptags(description),
openGraph: {
images: featuredImage || previousImages,
},
};
}

export async function generateStaticParams({
params: { locale },
}: LocaleProps) {
const data = await getEntriesByLocale(locale);

return data.entries.map(({ uri }) => {
return {
locale,
uriSegments: uri.split("/"),
};
});
}

const sectionMap = {
events: EventPageTemplate,
// galleryItems: GalleryPageTemplate,
glossaryTerms: GlossaryPageTemplate,
news: NewsPageTemplate,
searchResults: SearchPageTemplate,
slideshows: SlideshowPageTemplate,
staffProfiles: StaffPageTemplate,
// userProfilePage: UserProfilePageTemplate,
};

const UriSegmentsPage: FunctionComponent<UriSegmentProps> = async ({
params: { locale, uriSegments },
searchParams,
}) => {
const uri = uriSegments.join("/");
let previewToken: string | undefined;

if (draftMode().isEnabled) {
previewToken = Array.isArray(searchParams.preview)
? searchParams.preview[0]
: searchParams?.preview;
}

const entrySectionType = await getEntrySectionByUri(
uri,
locale,
previewToken
);

// Handle 404 if there is no data
if (!entrySectionType) {
notFound();
}

const { sectionHandle: section, typeHandle: type } = entrySectionType;
const data = await getEntryDataByUri(
uri,
section,
type,
locale,
previewToken
);

// Handle redirect if the entry has one
if (data?.typeHandle === "redirectPage" && data?.linkTo?.url) {
redirect(data.linkTo.url, "replace");
}

const currentId = data?.id || data?.entry?.id;

// Handle 404 if there is no data
if (!currentId) {
notFound();
}

const breadcrumbs = await getBreadcrumbsById(parseInt(currentId), locale);

const Template = sectionMap[section] || PageTemplate;

return <Template {...{ section, breadcrumbs, data, previewToken, locale }} />;
};

export default UriSegmentsPage;
2 changes: 0 additions & 2 deletions app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ export const generateStaticParams = () => {
});
};

export const dynamicParams = false;

const LocaleLayout: FunctionComponent<PropsWithChildren<LocaleProps>> = async ({
params: { locale },
children,
Expand Down
6 changes: 2 additions & 4 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { FunctionComponent } from "react";
import { Metadata } from "next";
import { notFound } from "next/navigation";
import { draftMode } from "next/headers";
import { purgeNextjsStaticFiles } from "@/lib/purgeStaticFiles";
import HomePageTemplate from "@/templates/HomePage";
import { Metadata } from "next";
import { getHomepage, getHomepageMetadata } from "@/lib/api/homepage";
import HomePageTemplate from "@/templates/HomePage";

export async function generateMetadata({
params: { locale },
Expand Down Expand Up @@ -41,7 +40,6 @@ const RootPage: FunctionComponent<LocaleProps> = async ({

// Handle 404 if there is no data
if (!data?.id) {
await purgeNextjsStaticFiles(locale);
notFound();
}

Expand Down
16 changes: 14 additions & 2 deletions app/api/app-revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { revalidatePath } from "next/cache";
import tags from "@/lib/api/client/tags";
import { fallbackLng, languages } from "@/lib/i18n/settings";
import { revalidatePath, revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";

const REVALIDATE_SECRET_TOKEN = process.env.CRAFT_REVALIDATE_SECRET_TOKEN;
const CRAFT_HOMEPAGE_URI = "__home__";

export async function GET(request: NextRequest): Promise<NextResponse> {
const uri = request.nextUrl.searchParams.get("uri");
Expand All @@ -24,7 +27,16 @@ export async function GET(request: NextRequest): Promise<NextResponse> {
}

if (uri) {
revalidatePath(`/[locale]/${uri}`, "page");
languages.forEach((locale) => {
const parts: Array<string> = uri === CRAFT_HOMEPAGE_URI ? [] : [uri];
if (locale !== fallbackLng) {
parts.unshift(locale);
}

revalidatePath(`/${parts.join("/")}`);
});

revalidateTag(tags.globals);

return NextResponse.json({ revalidated: true, now: Date.now() });
}
Expand Down
16 changes: 16 additions & 0 deletions app/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";
import { FunctionComponent } from "react";

import Error from "@/components/organisms/Error";
const GlobalError: FunctionComponent<ErrorProps> = ({ error }) => {
return (
<html lang="en">
<head></head>
<body>
<Error title={"Error"} message={error.message} />
</body>
</html>
);
};

export default GlobalError;
67 changes: 0 additions & 67 deletions components/global/Body/index.js

This file was deleted.

Loading

0 comments on commit 7c19862

Please sign in to comment.