Skip to content

Commit

Permalink
Update and improve components and stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish committed Jan 3, 2024
1 parent ef198c7 commit 0352bc0
Show file tree
Hide file tree
Showing 117 changed files with 17,191 additions and 12,145 deletions.
5 changes: 2 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
"plugin:storybook/recommended"
],
"rules": {
"react-hooks/exhaustive-deps": "off",
"react-hooks/rules-of-hooks": "off",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{ "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" }
]
},
"plugins": ["unused-imports"]
"plugins": ["unused-imports"],
"ignorePatterns": ["**/__generated__/**/*"]
}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
.idea

# Yarn files. See https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored.
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# dependencies
/node_modules
/.pnp
Expand Down
893 changes: 893 additions & 0 deletions .yarn/releases/yarn-4.0.2.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.0.2.cjs
46 changes: 0 additions & 46 deletions app/@modal/(.)gallery-image/[filename]/page.tsx

This file was deleted.

35 changes: 35 additions & 0 deletions app/@modal/(.)gallery-image/[uuid]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import InterceptionModal from "@components/elements/interception-modal";
import {randomUUID} from "crypto";
import Image from "next/image";
import {getResource} from "@lib/drupal/get-resource";
import {DrupalGalleryImageMediaType} from "@lib/types";
import {buildUrl} from "@lib/drupal/utils";

const Page = async ({params: {uuid}}: { params: { uuid: string } }) => {
const captionId = randomUUID();
const media = await getResource<DrupalGalleryImageMediaType>('media--stanford_gallery_images', uuid);
if (!media) return null;
return (
<InterceptionModal aria-labelledby={captionId}>
<figure className="h-full w-fit mx-auto table">
<picture>
<Image
src={buildUrl(media.su_gallery_image.uri.url).toString()}
alt={media.su_gallery_image.resourceIdObjMeta?.alt || ''}
height={media.su_gallery_image.resourceIdObjMeta?.height}
width={media.su_gallery_image.resourceIdObjMeta?.width}
className="max-w-full h-auto m-0 p-0"
/>
</picture>
{media.su_gallery_caption &&
<figcaption
id={captionId}
className="bg-white text-right p-5 m-0 table-caption caption-bottom">
{media.su_gallery_caption}
</figcaption>
}
</figure>
</InterceptionModal>
)
}
export default Page;
42 changes: 25 additions & 17 deletions app/[...slug]/metadata.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {decode} from 'html-entities';
import {
BasicPageNodeType,
EventNodeType,
NewsNodeType,
PersonNodeType,
PolicyNodeType,
StanfordNode,
StanfordParagraph,
WysiwygParagraphType
StanfordParagraph, WysiwygParagraphType
} from "@lib/types";
import {decode} from 'html-entities';
import {buildUrl} from "@lib/drupal/utils";

export const getNodeMetadata = (node: StanfordNode) => {
const defaultData = {
Expand Down Expand Up @@ -41,7 +41,7 @@ export const getNodeMetadata = (node: StanfordNode) => {

case 'node--stanford_policy':
return {
...getPolicyMetaData(node as PolicyNodeType),
...getPolicyMetaData(node),
...defaultData
}
}
Expand All @@ -50,9 +50,12 @@ export const getNodeMetadata = (node: StanfordNode) => {
}

const getBasicPageMetaData = (node: BasicPageNodeType) => {
const imageUrl = node.su_page_image?.field_media_image?.image_style_uri?.card_956x478 || node.su_page_banner?.su_banner_image?.field_media_image?.image_style_uri?.card_956x478;
const imageAlt = node.su_page_image?.field_media_image?.resourceIdObjMeta?.alt || node.su_page_banner?.su_banner_image?.field_media_image?.resourceIdObjMeta?.alt;
const description = node.su_page_description ?? getFirstText(node.su_page_components);
const pageImage = node.su_page_image?.field_media_image;
const bannerImage =node.su_page_banner?.su_banner_image?.field_media_image

const imageUrl = pageImage?.image_style_uri.card_956x478 || bannerImage?.image_style_uri.card_956x478
const imageAlt = pageImage?.resourceIdObjMeta?.alt || bannerImage?.resourceIdObjMeta?.alt || '';
const description = node.su_page_description || getFirstText(node.su_page_components);

return {
description: description,
Expand All @@ -66,9 +69,13 @@ const getBasicPageMetaData = (node: BasicPageNodeType) => {
}

const getNewsMetaData = (node: NewsNodeType) => {
const imageUrl = node.su_news_featured_media?.field_media_image?.image_style_uri?.card_956x478 || node.su_news_banner?.field_media_image?.image_style_uri?.card_956x478;
const imageAlt = node.su_news_featured_media?.field_media_image?.resourceIdObjMeta?.alt || node.su_news_banner?.field_media_image?.resourceIdObjMeta?.alt;
const description = node.su_news_dek ?? getFirstText(node.su_news_components);
const pageImage = node.su_news_featured_media?.field_media_image;
const bannerImage = node.su_news_banner?.field_media_image;

const imageUrl = pageImage?.image_style_uri.card_956x478 || bannerImage?.image_style_uri.card_956x478
const imageAlt = pageImage?.resourceIdObjMeta?.alt || bannerImage?.resourceIdObjMeta?.alt || '';

const description = node.su_news_dek || getFirstText(node.su_news_components);

let publishTime;
if (node.su_news_publishing_date) {
Expand All @@ -89,8 +96,9 @@ const getNewsMetaData = (node: NewsNodeType) => {
}

const getPersonMetaData = (node: PersonNodeType) => {
const imageUrl = node.su_person_photo?.field_media_image?.image_style_uri?.card_956x478;
const imageAlt = node.su_person_photo?.field_media_image?.resourceIdObjMeta?.alt;
const pageImage = node.su_person_photo?.field_media_image;
const imageUrl = pageImage?.image_style_uri.card_956x478;
const imageAlt = pageImage?.resourceIdObjMeta?.alt || '';
const description = node.su_person_full_title ?? getCleanDescription(node.body);

return {
Expand Down Expand Up @@ -120,7 +128,7 @@ const getEventMetaData = (node: EventNodeType) => {
}

const getPolicyMetaData = (node: PolicyNodeType) => {
const description = getCleanDescription(node.body?.processed);
const description = getCleanDescription(node.body?.summary || node.body?.processed);

return {
description: description,
Expand All @@ -132,8 +140,8 @@ const getPolicyMetaData = (node: PolicyNodeType) => {
}
}

const getFirstText = (components: StanfordParagraph[] = []) => {
const firstWysiwyg = components.find(component => component.type === 'paragraph--stanford_wysiwyg') as WysiwygParagraphType | undefined;
const getFirstText = (components?: StanfordParagraph[]) => {
const firstWysiwyg = components?.find(component => component.type === 'paragraph--stanford_wysiwyg') as WysiwygParagraphType;
if (firstWysiwyg) {
return getCleanDescription(firstWysiwyg.su_wysiwyg_text);
}
Expand All @@ -147,11 +155,11 @@ const getCleanDescription = (description: string | undefined): string | undefine
}


const getOpenGraphImage = (imageUrl: string | undefined, imageAlt: string | undefined) => {
const getOpenGraphImage = (imageUrl?: string, imageAlt?: string) => {
if (imageUrl) {
return [
{
url: imageUrl,
url: buildUrl(imageUrl).toString(),
width: 956,
height: 478,
alt: imageAlt,
Expand Down
59 changes: 30 additions & 29 deletions app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
import {getResourceFromContext} from "@lib/drupal/get-resource";
import {translatePathFromContext} from "@lib/drupal/translate-path";
import {notFound, redirect} from "next/navigation";
import NodePage from "@components/nodes/pages/node-page";
import {GetStaticPathsResult, Metadata} from "next";
import {DrupalJsonApiParams} from "drupal-jsonapi-params";
import {getPathsFromContext} from "@lib/drupal/get-paths";
import {getNodeMetadata} from "./metadata";
import {getAccessToken} from "@lib/drupal/get-access-token";
import {isDraftMode} from "@lib/drupal/utils";
import {getPathFromContext, isDraftMode} from "@lib/drupal/utils";
import {PageProps, Params, StanfordNode} from "@lib/types";
import {getResourceByPath, getResourceFromContext} from "@lib/drupal/get-resource";
import {getAccessToken} from "@lib/drupal/get-access-token";
import {translatePathFromContext} from "@lib/drupal/translate-path";
import RedirectError from "@lib/redirect-error";

// https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
export const revalidate = false;

export const generateMetadata = async ({params}: PageProps): Promise<Metadata> => {
let node;
const Page = async ({params}: PageProps) => {
let node = null;
try {
node = await getPageData(params);
if (node) return getNodeMetadata(node);
} catch (e) {}
return {}
} catch (e) {
if (e instanceof RedirectError) redirect(e.message);
}

if (!node) notFound();

return (
<NodePage node={node}/>
)
}

class RedirectError extends Error {
constructor(message?: string) {
super(message);
export const generateMetadata = async ({params}: PageProps): Promise<Metadata> => {
const path = getPathFromContext({params})

try {
const node = await getResourceByPath<StanfordNode>(path)
if (node) return getNodeMetadata(node);
} catch (e) {
}
return {}
}

const getPageData = async(params: Params): Promise<StanfordNode | undefined> => {
Expand Down Expand Up @@ -65,7 +78,8 @@ export const generateStaticParams = async () => {
'node--stanford_course',
]

let paths: GetStaticPathsResult["paths"] = await getPathsFromContext(contentTypes, {params: params.getQueryObject()});
// Use JSON API to fetch the list of all node paths on the site.
let paths: GetStaticPathsResult["paths"] = await getPathsFromContext(contentTypes, {params: params.getQueryObject()});

const completeBuild = process.env.BUILD_COMPLETE === 'true';

Expand All @@ -82,22 +96,9 @@ export const generateStaticParams = async () => {
page++;
}

return paths.map(path => typeof path !== "string" ? path?.params : path).slice(0, (completeBuild ? -1 : 1));
}

const Page = async ({params}: PageProps) => {
let node = null;
try {
node = await getPageData(params);
} catch (e) {
if (e instanceof RedirectError) redirect(e.message);
}

if (!node) notFound();

return (
<NodePage node={node}/>
)
return paths.filter(path => typeof path !== 'object' || path.params?.slug?.[0])
.map(path => typeof path === "object" ? path?.params : path)
.slice(0, (completeBuild ? -1 : 1))
}

export default Page;
4 changes: 0 additions & 4 deletions app/api/app-revalidate/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import {revalidatePath} from "next/cache";

// The app router doesn't correctly revalidate the paths on Vercel. This file is meant for testing and future
// implementation when it actually works.
export const POST = async (request: NextRequest) => {
return GET(request);
}

export const GET = async (request: NextRequest) => {
const secret = request.nextUrl.searchParams.get('secret');
if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) {
Expand Down
7 changes: 3 additions & 4 deletions app/api/draft/route.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// route handler with secret and slug
import {draftMode} from 'next/headers'
import {redirect} from 'next/navigation'
import {getResourceByPath} from "@lib/drupal/get-resource";
import {StanfordNode} from "@lib/types";

export async function GET(request: Request) {
// Parse query string parameters
Expand All @@ -20,7 +18,8 @@ export async function GET(request: Request) {

// Fetch the headless CMS to check if the provided `slug` exists
// getPostBySlug would implement the required fetching logic to the headless CMS
const node = await getResourceByPath<StanfordNode>(slug, {draftMode: true})
const query = await graphqlClient().Route({path: slug});
const node = query.route?.__typename === 'RouteInternal' && query.route.entity as NodeUnion

// If the slug doesn't exist prevent draft mode from being enabled
if (!node) {
Expand All @@ -29,5 +28,5 @@ export async function GET(request: Request) {

// Redirect to the path from the fetched post
// We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
redirect(node.path.alias)
redirect(node.path)
}
Loading

0 comments on commit 0352bc0

Please sign in to comment.