Skip to content

Commit

Permalink
Merge branch '1.x' into feature/nojira--slideshow
Browse files Browse the repository at this point in the history
  • Loading branch information
rebeccahongsf committed Apr 4, 2024
2 parents 80d30c3 + 49dd7a6 commit f4d40cb
Show file tree
Hide file tree
Showing 79 changed files with 2,096 additions and 1,059 deletions.
48 changes: 48 additions & 0 deletions .storybook/stories/elements/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type {Meta, StoryObj} from '@storybook/react';
import Accordion from "@components/elements/accordion";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof Accordion> = {
title: 'Design/Elements/Accordion',
component: Accordion,
tags: ['autodocs'],
argTypes: {
button: {
control: "text"
},
onClick: {
table: {
disable: true,
}
},
buttonProps: {
table: {
disable: true,
}
},
panelProps: {
table: {
disable: true,
}
},
isVisible: {
table: {
disable: true,
}
}
}
};

export default meta;
type Story = StoryObj<typeof Accordion>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const AccordionElement: Story = {
render: ({onClick, ...args}) => {
return <Accordion {...args}/>
},
args: {
button: "Id arcu nec vel tempus rutrum.",
children: "Mi amet tempus congue erat fusce euismod eros cursus morbi amet amet diam tristique bibendum hendrerit sed commodo quisque cursus scelerisque morbi placerat tristique magna."
},
};
34 changes: 3 additions & 31 deletions app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
import NodePage from "@components/nodes/pages/node-page";
import UnpublishedBanner from "@components/elements/unpublished-banner";
import {Metadata} from "next";
import {NodeUnion} from "@lib/gql/__generated__/drupal.d";
import {getAllNodePaths, getEntityFromPath} from "@lib/gql/gql-queries";
import {getNodeMetadata} from "./metadata";
import {isDraftMode} from "@lib/drupal/utils";
import {notFound, redirect} from "next/navigation";
import {getPathFromContext, PageProps} from "@lib/drupal/utils";

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

const Page = async ({params}: PageProps) => {
const path = getPathFromContext({params})
const inDraft = isDraftMode();

const {redirect: redirectPath, entity, error} = await getEntityFromPath<NodeUnion>(path, inDraft)
const {redirect: redirectPath, entity, error} = await getEntityFromPath<NodeUnion>(getPathFromContext({params}))

if (error) throw new Error(error);
if (redirectPath?.url) redirect(redirectPath.url)
if (!entity) notFound();

return (
<>
<UnpublishedBanner status={entity.status}>
Unpublished Page
</UnpublishedBanner>
<NodePage node={entity}/>
</>
)
return <NodePage node={entity}/>
}

export const generateMetadata = async ({params}: PageProps): Promise<Metadata> => {
// If the user is in draft mode, there's no need to emit any customized metadata.
if (isDraftMode()) return {};

const path = getPathFromContext({params})
const {entity} = await getEntityFromPath<NodeUnion>(path)
return entity ? getNodeMetadata(entity) : {};
Expand All @@ -46,18 +32,4 @@ export const generateStaticParams = async (): Promise<PageProps["params"][]> =>
return nodePaths.map(path => ({slug: path.split('/').filter(part => !!part)}));
}

const getPathFromContext = (context: PageProps, prefix = ""): string => {
let {slug} = context.params

slug = Array.isArray(slug) ? slug.map((s) => encodeURIComponent(s)).join("/") : slug
slug = slug.replace(/^\//, '');
return prefix ? `${prefix}/${slug}` : `/${slug}`
}

type PageProps = {
params: { slug: string | string[] }
searchParams?: Record<string, string | string[] | undefined>
}


export default Page;
9 changes: 0 additions & 9 deletions app/api/draft/disable/route.tsx

This file was deleted.

13 changes: 9 additions & 4 deletions app/api/draft/route.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {NextRequest, NextResponse} from "next/server";
import {draftMode} from 'next/headers'
import {redirect} from 'next/navigation'
import {cookies} from "next/headers";

export const revalidate = 0;

Expand All @@ -18,10 +18,15 @@ export async function GET(request: NextRequest) {
if (!slug) {
return NextResponse.json({message: 'Invalid slug path'}, {status: 401})
}

draftMode().enable()
cookies().set('preview', secret, {
maxAge: 60 * 60,
httpOnly: true,
sameSite: 'none',
secure: true,
partitioned: true,
});

// Redirect to the path from the fetched post
// We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
redirect(slug)
redirect(`/preview${slug === "/home" ? "" : slug}`)
}
6 changes: 2 additions & 4 deletions app/api/revalidate/route.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {NextRequest, NextResponse} from "next/server";
import {cache as nodeCache} from "@lib/drupal/get-cache";
import {revalidatePath, revalidateTag} from "next/cache";
import {revalidateTag} from "next/cache";

export const revalidate = 0;

Expand All @@ -12,12 +12,10 @@ export const GET = async (request: NextRequest) => {
let path = request.nextUrl.searchParams.get('slug');
if (!path || path.startsWith('/node/')) return NextResponse.json({message: 'Invalid slug'}, {status: 400});

revalidatePath(path);

const tagsInvalidated = ['paths', `paths:${path}`];
if (path.startsWith('/tags/')) path.substring(6).split('/').map(tag => tagsInvalidated.push(tag))

tagsInvalidated.map(tag => revalidateTag(tag));
nodeCache.del(tagsInvalidated)
return NextResponse.json({revalidated: true, path, tags: tagsInvalidated});
return NextResponse.json({revalidated: true, tags: tagsInvalidated});
}
10 changes: 7 additions & 3 deletions app/error.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"use client";

import Button from "@components/elements/button";

const ErrorPage = ({error, reset}: { error: Error; reset: () => void }) => {
console.warn(error.message);
return (
<div className="centered my-50 mt-32">
<h1>Something went wrong!</h1>
Apologies, an error occurred when attempting to preset the page you are attempting to view. Please try a different
path.
<button onClick={() => reset()}>Try again</button>
<p>
Apologies, an error occurred when attempting to preset the page you are attempting to view. Please try a
different path.
</p>
<Button buttonElem onClick={() => reset()}>Try again</Button>
</div>
)
}
Expand Down
34 changes: 9 additions & 25 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import '../src/styles/index.css';
import BackToTop from "@components/elements/back-to-top";
import DrupalWindowSync from "@components/elements/drupal-window-sync";
import Editori11y from "@components/tools/editorially";
import Link from "@components/elements/link";
import PageFooter from "@components/global/page-footer";
import PageHeader from "@components/global/page-header";
import Script from "next/script";
import {GoogleAnalytics} from "@next/third-parties/google";
import {Icon} from "next/dist/lib/metadata/types/metadata-types";
import {StanfordBasicSiteSetting} from "@lib/gql/__generated__/drupal.d";
import {getConfigPage} from "@lib/gql/gql-queries";
import {isDraftMode} from "@lib/drupal/utils";
import {sourceSans3} from "../src/styles/fonts";
import DrupalWindowSync from "@components/elements/drupal-window-sync";
import {isPreviewMode} from "@lib/drupal/utils";
import UserAnalytics from "@components/elements/user-analytics";

const appleIcons: Icon[] = [60, 72, 76, 114, 120, 144, 152, 180].map(size => ({
url: `https://www-media.stanford.edu/assets/favicon/apple-touch-icon-${size}x${size}.png`,
Expand Down Expand Up @@ -46,32 +41,21 @@ export const metadata = {

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

const RootLayout = async ({children, modal}: { children: React.ReactNode, modal: React.ReactNode }) => {
const draftMode = isDraftMode();
const siteSettingsConfig = await getConfigPage<StanfordBasicSiteSetting>('StanfordBasicSiteSetting')
const RootLayout = ({children, modal}: { children: React.ReactNode, modal: React.ReactNode }) => {
const isPreview = isPreviewMode();
return (
<html lang="en" className={sourceSans3.className}>
{draftMode && <><Editori11y/><DrupalWindowSync/></>}

{/* Add Google Analytics and SiteImprove when not in draft mode. */}
{(!draftMode && siteSettingsConfig?.suGoogleAnalytics) &&
<>
<Script async src="//siteimproveanalytics.com/js/siteanalyze_80352.js"/>
<GoogleAnalytics gaId={siteSettingsConfig?.suGoogleAnalytics}/>
</>
{/* Add Google Analytics and SiteImprove when not in preview mode. */}
{!isPreview &&
<UserAnalytics/>
}
<DrupalWindowSync/>
<body>
<nav aria-label="Skip Links">
<a href="#main-content" className="skiplink">Skip to main content</a>
</nav>

{/* Automatically exit "Draft" mode upon the page loading. This prevents unwanted uncached data fetching. */}
{draftMode &&
<Link href="/api/draft/disable" tabIndex={-1} className="sr-only">Disable Draft Mode</Link>
}

<div className="flex flex-col min-h-screen">
<PageHeader/>
<main id="main-content" className="flex-grow mb-32">
Expand Down
4 changes: 2 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Rows from "@components/paragraphs/rows/rows";
import {notFound} from "next/navigation";
import {getEntityFromPath} from "@lib/gql/gql-queries";
import {NodeStanfordPage, NodeUnion} from "@lib/gql/__generated__/drupal.d";
import {isDraftMode} from "@lib/drupal/utils";
import {isPreviewMode} from "@lib/drupal/utils";
import {Metadata} from "next";
import {getNodeMetadata} from "./[...slug]/metadata";
import BannerParagraph from "@components/paragraphs/stanford-banner/banner-paragraph";
Expand All @@ -12,7 +12,7 @@ export const revalidate = false;
export const dynamic = 'force-static';

const Home = async () => {
const {entity, error} = await getEntityFromPath<NodeStanfordPage>('/', isDraftMode());
const {entity, error} = await getEntityFromPath<NodeStanfordPage>('/', isPreviewMode());

if (error) throw new Error(error);
if (!entity) notFound();
Expand Down
25 changes: 25 additions & 0 deletions app/preview/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import NodePage from "@components/nodes/pages/node-page";
import UnpublishedBanner from "@components/elements/unpublished-banner";
import {NodeUnion} from "@lib/gql/__generated__/drupal.d";
import {getEntityFromPath} from "@lib/gql/gql-queries";
import {notFound} from "next/navigation";
import {getPathFromContext, isPreviewMode, PageProps} from "@lib/drupal/utils";

const PreviewPage = async ({params}: PageProps) => {
if (!isPreviewMode()) notFound();
const { entity, error} = await getEntityFromPath<NodeUnion>(getPathFromContext({params}), true)

if (error) throw new Error(error);
if (!entity) notFound();

return (
<>
<UnpublishedBanner status={entity.status}>
Unpublished Page
</UnpublishedBanner>
<NodePage node={entity}/>
</>
)
}

export default PreviewPage;
21 changes: 21 additions & 0 deletions app/preview/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {isPreviewMode} from "@lib/drupal/utils";
import Editori11y from "@components/tools/editorially";
import UnpublishedBanner from "@components/elements/unpublished-banner";

const Layout = ({children}: { children: React.ReactNode }) => {
const inPreview = isPreviewMode();
return (
<>
{inPreview &&
<>
<Editori11y/>
<UnpublishedBanner status={false}>
Preview Mode
</UnpublishedBanner>
</>
}
{children}
</>
)
}
export default Layout;
10 changes: 10 additions & 0 deletions app/preview/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {notFound} from "next/navigation";
import {isPreviewMode} from "@lib/drupal/utils";
import Page from "../page";

const PreviewPage = async () => {
if (!isPreviewMode()) notFound();
return <Page/>
}

export default PreviewPage;
1 change: 0 additions & 1 deletion app/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import AlgoliaSearch from "./algolia-search";

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

export const metadata = {
title: "Search",
Expand Down
Loading

0 comments on commit f4d40cb

Please sign in to comment.