-
Notifications
You must be signed in to change notification settings - Fork 54
Convert staging to app router [#1067] #1131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
9ec929b
Initial move of `/staging/[[...staging]]` page into App Router style …
genehack f0e8f8f
Port /staging to App Router style [#1067]
genehack 696466a
Update <ListResources> component to take `resourceListingCallback` pa…
genehack 7b13f7d
Update the `/pathogens` page to use the `resourceListingCallback` pro…
genehack ffda8a7
Fix a quoting bug with <ListResources> CSS Module [#1067]
genehack 980d729
Use a fully-specified URL to fetch pathogen resources [#1067]
genehack 047da2c
Initial copy of <ErrorBanner> component into App Router setup [#1067]
genehack b281971
Port <ErrorBanner> component into <ErrorMessage>, App Router style [#…
genehack File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| "use client"; | ||
|
|
||
| import { ResourceListingInfo } from "../../../components/list-resources/types"; | ||
|
|
||
| /** | ||
| * A callback function used by the <ListResources> component (which | ||
| * see) to get the resources to display on the /staging page. | ||
| */ | ||
| export async function stagingResourceListingCallback(): Promise<ResourceListingInfo> { | ||
| const sourceId = "staging"; | ||
| const sourceUrl = `/list-resources/${sourceId}`; | ||
|
|
||
| const response = await fetch(sourceUrl, { | ||
| headers: { accept: "application/json" }, | ||
| }); | ||
| if (response.status !== 200) { | ||
| throw new Error( | ||
| `fetching data from "${sourceUrl}" returned status code ${response.status}`, | ||
| ); | ||
| } | ||
|
|
||
| return (await response.json()).dataset[sourceId]; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import React from "react"; | ||
| import type { Metadata } from "next"; | ||
|
|
||
| import FlexCenter from "../../../components/flex-center"; | ||
| import { FocusParagraphCentered } from "../../../components/focus-paragraph"; | ||
| import ListResources from "../../../components/list-resources"; | ||
| import { SmallSpacer, HugeSpacer } from "../../../components/spacers"; | ||
|
|
||
| import { stagingResourceListingCallback } from "./callback"; | ||
|
|
||
| /** | ||
| * A React Server component that generates the contents of the | ||
| * /staging page. | ||
| * | ||
| * This is abstracted out into a distinct component so that it can | ||
| * also be used in the "./not-found.tsx" component, to render the | ||
| * /staging page content beneath an error banner, when a bad URL is | ||
| * requested. | ||
| */ | ||
| export default function StagingPageContent({ | ||
| metadata, | ||
| }: { | ||
| /** | ||
| * A Metadata object, that is assumed to have a `title` key with a | ||
| * string value | ||
| */ | ||
| metadata: Metadata; | ||
| }): React.ReactElement { | ||
| // the cast is not ideal, but it _is_ going to be a string... | ||
| const title = metadata.title as string; // eslint-disable-line @typescript-eslint/consistent-type-assertions | ||
|
|
||
| return ( | ||
| <> | ||
| <HugeSpacer /> | ||
| <HugeSpacer /> | ||
|
|
||
| <h1>{title}</h1> | ||
|
|
||
| <SmallSpacer /> | ||
|
|
||
| <FlexCenter> | ||
| <FocusParagraphCentered> | ||
| Staging datasets & narratives are intended primarily for internal | ||
| (Nextstrain team) usage. They should be considered unreleased and/or | ||
| out of date; they should not be used to draw scientific conclusions. | ||
| </FocusParagraphCentered> | ||
| </FlexCenter> | ||
|
|
||
| <HugeSpacer /> | ||
|
|
||
| <ListResources | ||
| defaultGroupLinks={false} | ||
| groupDisplayNames={{}} | ||
| quickLinks={[]} | ||
| resourceListingCallback={stagingResourceListingCallback} | ||
| resourceType="dataset" | ||
| tileData={[]} | ||
| versioned={false} | ||
| /> | ||
|
|
||
| <HugeSpacer /> | ||
| </> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| "use client"; | ||
|
|
||
| import React from "react"; | ||
| import { useParams } from "next/navigation"; | ||
|
|
||
| import ErrorMessage from "../../../components/error-message"; | ||
|
|
||
| /** | ||
| * A React Client component that detects if the requested URL | ||
| * contains path elements past `/staging`, and, if so, returns a | ||
| * component that displays an error message banner. If additional | ||
| * path elements are not detected, returns null. | ||
| * | ||
| * N.b., the way this component is used, we only render it when we've | ||
| * already determined that there _is_ a need to display an error | ||
| * message. In other words, it is fully expected that the `else` | ||
| * branch of the conditional will never actually execute. | ||
| */ | ||
| export default function ErrorBanner(): React.ReactElement | null { | ||
| const params = useParams(); | ||
|
|
||
| if (params && params["staging"]) { | ||
| // n.b., I don't think `params["staging"]` is ever going to be | ||
| // anything other than a list, but let's make the type checker | ||
| // happy… | ||
| const path = | ||
| typeof params["staging"] === "string" | ||
| ? params["staging"] | ||
| : params["staging"].join("/"); | ||
|
|
||
| const resourceType = path.startsWith("narratives") | ||
| ? "narrative" | ||
| : "dataset"; | ||
|
|
||
| const title = `The staging ${resourceType} "nextstrain.org/staging/${path}" doesn't exist.`; | ||
| const contents = `Here is the staging page instead.`; | ||
|
|
||
| return <ErrorMessage title={title} contents={contents} />; | ||
| } else { | ||
| // this will never happen | ||
| return null; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import React from "react"; | ||
|
|
||
| import StagingPageContent from "./content"; | ||
| import ErrorBanner from "./error-banner"; | ||
| import { metadata } from "./page"; | ||
|
|
||
| /** | ||
| * A React Server component that renders the usual `/staging` page | ||
| * content, with an error banner up-top explaining that the requested | ||
| * dataset doesn't actually exist. | ||
| */ | ||
| export default function FourOhFour(): React.ReactElement { | ||
| return ( | ||
| <> | ||
| <ErrorBanner /> | ||
| <StagingPageContent metadata={metadata} /> | ||
| </> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import React from "react"; | ||
| import { Metadata } from "next"; | ||
|
|
||
| import StagingPageContent from "./content"; | ||
| import ValidateStagingUrl from "./validateStagingUrl"; | ||
|
|
||
| const title = "Staging Data"; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title, | ||
| }; | ||
|
|
||
| /** | ||
| * A React Server Component for `/staging` | ||
| * | ||
| * A note about how this page works: | ||
| * | ||
| * We expect three different types of requests for resources under | ||
| * `/staging`: | ||
| * | ||
| * 1) Requests for real, existing datasets (e.g., `/staging/ebola`) — | ||
| * these requests are handled by the Express-level router, and this | ||
| * Next.js page never sees them | ||
| * | ||
| * 2) Requests for the plain `/staging` page — that request is handled | ||
| * by this page, and we expect it to return a resource listing of | ||
| * staging datasets, with an HTTP status code of 200 | ||
| * | ||
| * 3) Requests for some longer URL that does NOT correspond to a real, | ||
| * existing dataset (e.g., `/staging/foo`) — in this case, we want | ||
| * to display the same resource listing as the base `/staging` | ||
| * page, but to also include an error banner indicating that the | ||
| * requested resource (`nextstrain.org/staging/foo` in our example) | ||
| * does not exist. We also want the HTTP status code for the | ||
| * response to this request to be a 404 | ||
| * | ||
| * We accomplish this as follows: | ||
| * | ||
| * Requests of type #1 are handled completely at the Express level, | ||
| * and this page never sees them. | ||
| * | ||
| * Requests of type #2 and type #3 _are_ handled by this page. It uses | ||
| * the `<ValidateStagingUrl>` component to detect whether the | ||
| * requested URL was the plain `/staging` or whether there are | ||
| * additional path components beyond that (again, `/staging/foo` in | ||
| * our example). If there _are_ additional path elements, | ||
| * `<ValidateStagingUrl>` detects that and calls Next.js's | ||
| * `notFound()` method, which results in the `./not-found.tsx` page | ||
| * being rendered and returned. If there are not additional path | ||
| * elements (i.e., if the request was for `/staging`), | ||
| * `<ValidateStagingUrl>` returns nothing, and the | ||
| * `<StagingPageContent>` component delivers the desired resource | ||
| * listing. | ||
| * | ||
| * If the `./not-found.tsx` page is rendered, it handles the display | ||
| * of the error banner; it also uses the `<StagingPageContent>` | ||
| * component to render the same resource listing as the default case. | ||
| * However, because it has been invoked via the Next.js `notFound()` | ||
| * method, it will return a 404 status code. | ||
| */ | ||
| export default function StagingPage(): React.ReactElement { | ||
| return ( | ||
| <> | ||
| <ValidateStagingUrl /> | ||
| <StagingPageContent metadata={metadata} /> | ||
| </> | ||
| ); | ||
| } |
23 changes: 23 additions & 0 deletions
23
static-site/app/staging/[[...staging]]/validateStagingUrl.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| "use client"; | ||
|
|
||
| import { notFound, useParams }from "next/navigation"; | ||
|
|
||
| /** | ||
| * A React Client Component to detect when an invalid `/staging/` URL | ||
| * is requested, which calls the `notFound()` method to redirect to | ||
| * the `not-found.tsx` component | ||
| * | ||
| * Note that any actually valid `/staging/<something>` URL will be | ||
| * redirected at the Express router level, before the Next.js router | ||
| * is engaged, so if we are trying to render a `/staging/<something>` | ||
| * URL, it _is_ an error | ||
| */ | ||
| export default function ValidateStagingUrl(): null { | ||
| const params = useParams(); | ||
|
|
||
| if (params && params["staging"]) { | ||
| notFound(); | ||
| } | ||
| else { return null; } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import React from "react"; | ||
|
|
||
| import styles from "./styles.module.css"; | ||
|
|
||
| /** | ||
| * A React Server Component that displays an error message, intended | ||
| * to be used near the top of a page. | ||
| */ | ||
| export default function ErrorMessage({ | ||
| title, | ||
| contents, | ||
| }: { | ||
| title: string; | ||
| contents: string; | ||
| }): React.ReactElement { | ||
| return ( | ||
| <div className={styles.errorMessage}> | ||
| <span className={styles.strongerText}>{title}</span> | ||
| <br /> | ||
| Please <a href="/contact">contact us</a> if you believe this to be an | ||
| error. | ||
| <p>{contents}</p> | ||
| </div> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| .errorMessage { | ||
| background-color: #c2c1be; | ||
| font-size: 18px; | ||
| height: 15%; | ||
| left: 0px; | ||
| margin: 25px 0px 25px 0px; | ||
| padding: 25px 0px 25px 0px; | ||
| text-align: center; | ||
| } | ||
| .errorMessage p { | ||
| margin: 20px 0 0; | ||
| } | ||
|
|
||
| .strongerText { | ||
| font-weight: 500; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,6 +79,6 @@ | |
| } | ||
|
|
||
| .unlinkedGroupName { | ||
| font-size: "2rem"; | ||
| font-weight: "500"; | ||
| font-size: 2rem; | ||
| font-weight: 500; | ||
| } | ||
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.