From cad57eeca3d9b0304d913a7bbee2a09b09f0707d Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Fri, 2 Jun 2023 10:50:08 -0700 Subject: [PATCH] Create landings subject folder (#37416) --- components/context/TocLandingContext.tsx | 5 +- components/sidebar/SidebarNav.tsx | 4 +- middleware/index.js | 2 +- pages/[versionId]/[productId]/index.tsx | 129 +----------------- pages/index.tsx | 94 +------------ src/landings/README.md | 7 + .../landings/components}/ArticleCard.tsx | 2 +- .../landings/components}/ArticleCards.tsx | 2 +- .../landings/components}/ArticleList.tsx | 2 +- .../components}/CommunityExamples.tsx | 4 +- .../landings/components}/FeaturedArticles.tsx | 4 +- .../landings/components}/GuideCard.tsx | 2 +- .../landings/components}/GuideCards.tsx | 4 +- .../components}/GuidesHero.module.scss | 0 .../landings/components}/GuidesHero.tsx | 2 +- .../landings/components}/HomePageHero.tsx | 2 +- .../landings/components}/LandingHero.tsx | 2 +- .../landings/components}/LandingSection.tsx | 0 .../components}/LearningTrack.module.scss | 0 .../landings/components}/LearningTrack.tsx | 2 +- .../landings/components}/LearningTracks.tsx | 4 +- .../landings/components}/OctocatHeader.tsx | 0 .../components}/ProductArticlesList.tsx | 0 .../landings/components}/ProductGuides.tsx | 10 +- .../components}/ProductGuidesContext.tsx | 0 .../landings/components}/ProductLanding.tsx | 18 +-- .../components}/ProductLandingContext.tsx | 0 .../landings/components}/ProductReleases.tsx | 2 +- .../components}/ProductSelectionCard.tsx | 2 +- .../components}/ProductSelections.tsx | 0 .../landings/components}/RepoCard.tsx | 0 .../landings/components}/SidebarHomepage.tsx | 0 .../landings/components}/SidebarProduct.tsx | 2 +- .../landings/components}/SponsorsExamples.tsx | 4 +- .../landings/components}/TableOfContents.tsx | 2 +- .../landings/components}/TocLanding.tsx | 4 +- .../landings/components}/UserCard.tsx | 0 .../landings/middleware}/featured-links.js | 4 +- src/landings/pages/home.tsx | 93 +++++++++++++ src/landings/pages/product.tsx | 128 +++++++++++++++++ .../landings/tests}/curated-homepage-links.js | 2 +- .../landings/tests}/featured-links.js | 4 +- .../landings/tests}/homepage.js | 0 src/rest/pages/category.tsx | 2 +- 44 files changed, 281 insertions(+), 269 deletions(-) create mode 100644 src/landings/README.md rename {components/guides => src/landings/components}/ArticleCard.tsx (94%) rename {components/guides => src/landings/components}/ArticleCards.tsx (98%) rename {components/landing => src/landings/components}/ArticleList.tsx (97%) rename {components/landing => src/landings/components}/CommunityExamples.tsx (87%) rename {components/landing => src/landings/components}/FeaturedArticles.tsx (90%) rename {components/landing => src/landings/components}/GuideCard.tsx (89%) rename {components/landing => src/landings/components}/GuideCards.tsx (88%) rename {components/guides => src/landings/components}/GuidesHero.module.scss (100%) rename {components/guides => src/landings/components}/GuidesHero.tsx (97%) rename {components/homepage => src/landings/components}/HomePageHero.tsx (90%) rename {components/landing => src/landings/components}/LandingHero.tsx (97%) rename {components/landing => src/landings/components}/LandingSection.tsx (100%) rename {components/guides => src/landings/components}/LearningTrack.module.scss (100%) rename {components/guides => src/landings/components}/LearningTrack.tsx (98%) rename {components/guides => src/landings/components}/LearningTracks.tsx (66%) rename {components/landing => src/landings/components}/OctocatHeader.tsx (100%) rename {components/landing => src/landings/components}/ProductArticlesList.tsx (100%) rename {components/guides => src/landings/components}/ProductGuides.tsx (79%) rename {components/context => src/landings/components}/ProductGuidesContext.tsx (100%) rename {components/landing => src/landings/components}/ProductLanding.tsx (75%) rename {components/context => src/landings/components}/ProductLandingContext.tsx (100%) rename {components/landing => src/landings/components}/ProductReleases.tsx (97%) rename {components/homepage => src/landings/components}/ProductSelectionCard.tsx (96%) rename {components/homepage => src/landings/components}/ProductSelections.tsx (100%) rename {components/landing => src/landings/components}/RepoCard.tsx (100%) rename {components/sidebar => src/landings/components}/SidebarHomepage.tsx (100%) rename {components/sidebar => src/landings/components}/SidebarProduct.tsx (98%) rename {components/landing => src/landings/components}/SponsorsExamples.tsx (86%) rename {components/landing => src/landings/components}/TableOfContents.tsx (97%) rename {components/landing => src/landings/components}/TocLanding.tsx (95%) rename {components/landing => src/landings/components}/UserCard.tsx (100%) rename {middleware => src/landings/middleware}/featured-links.js (92%) create mode 100644 src/landings/pages/home.tsx create mode 100644 src/landings/pages/product.tsx rename {tests/rendering => src/landings/tests}/curated-homepage-links.js (94%) rename {tests/content => src/landings/tests}/featured-links.js (95%) rename {tests/rendering => src/landings/tests}/homepage.js (100%) diff --git a/components/context/TocLandingContext.tsx b/components/context/TocLandingContext.tsx index 054134e03d..349ae5b063 100644 --- a/components/context/TocLandingContext.tsx +++ b/components/context/TocLandingContext.tsx @@ -1,7 +1,10 @@ import pick from 'lodash/pick' import { createContext, useContext } from 'react' import { LearningTrack } from './ArticleContext' -import { FeaturedLink, getFeaturedLinksFromReq } from './ProductLandingContext' +import { + FeaturedLink, + getFeaturedLinksFromReq, +} from 'src/landings/components/ProductLandingContext' export type TocItem = { fullPath: string diff --git a/components/sidebar/SidebarNav.tsx b/components/sidebar/SidebarNav.tsx index dd95a93cd4..1a58ec674c 100644 --- a/components/sidebar/SidebarNav.tsx +++ b/components/sidebar/SidebarNav.tsx @@ -1,8 +1,8 @@ import cx from 'classnames' import { useMainContext } from 'components/context/MainContext' -import { SidebarProduct } from './SidebarProduct' -import { SidebarHomepage } from './SidebarHomepage' +import { SidebarProduct } from 'src/landings/components/SidebarProduct' +import { SidebarHomepage } from '../../src/landings/components/SidebarHomepage' import { AllProductsLink } from './AllProductsLink' import { ApiVersionPicker } from 'src/rest/components/ApiVersionPicker' import { Link } from 'components/Link' diff --git a/middleware/index.js b/middleware/index.js index 114123e6b6..08a27d7b3a 100644 --- a/middleware/index.js +++ b/middleware/index.js @@ -50,7 +50,7 @@ import glossaries from './contextualizers/glossaries.js' import features from './contextualizers/features.js' import productExamples from './contextualizers/product-examples.js' import productGroups from './contextualizers/product-groups.js' -import featuredLinks from './featured-links.js' +import featuredLinks from '../src/landings/middleware/featured-links.js' import learningTrack from './learning-track.js' import next from './next.js' import renderPage from './render-page.js' diff --git a/pages/[versionId]/[productId]/index.tsx b/pages/[versionId]/[productId]/index.tsx index dca2f07eef..0bfccb6df1 100644 --- a/pages/[versionId]/[productId]/index.tsx +++ b/pages/[versionId]/[productId]/index.tsx @@ -1,128 +1 @@ -import { GetServerSideProps } from 'next' -import { useRouter } from 'next/router' - -// "legacy" javascript needed to maintain existing functionality -// typically operating on elements **within** an article. -import copyCode from 'components/lib/copy-code' -import localization from 'components/lib/localization' -import wrapCodeTerms from 'components/lib/wrap-code-terms' - -import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext' - -import { - getProductLandingContextFromRequest, - ProductLandingContextT, - ProductLandingContext, -} from 'components/context/ProductLandingContext' -import { - getProductGuidesContextFromRequest, - ProductGuidesContextT, - ProductGuidesContext, -} from 'components/context/ProductGuidesContext' - -import { - getArticleContextFromRequest, - ArticleContextT, - ArticleContext, -} from 'components/context/ArticleContext' -import { ArticlePage } from 'components/article/ArticlePage' - -import { ProductLanding } from 'components/landing/ProductLanding' -import { ProductGuides } from 'components/guides/ProductGuides' -import { TocLanding } from 'components/landing/TocLanding' -import { - getTocLandingContextFromRequest, - TocLandingContext, - TocLandingContextT, -} from 'components/context/TocLandingContext' -import { useEffect } from 'react' - -function initiateArticleScripts() { - copyCode() - localization() - wrapCodeTerms() -} - -type Props = { - mainContext: MainContextT - productLandingContext?: ProductLandingContextT - productGuidesContext?: ProductGuidesContextT - tocLandingContext?: TocLandingContextT - articleContext?: ArticleContextT -} -const GlobalPage = ({ - mainContext, - productLandingContext, - productGuidesContext, - tocLandingContext, - articleContext, -}: Props) => { - const router = useRouter() - - useEffect(() => { - // https://stackoverflow.com/a/67063998 - initiateArticleScripts() // on initiate page - router.events.on('routeChangeComplete', initiateArticleScripts) // on client side route - return () => { - router.events.off('routeChangeComplete', initiateArticleScripts) - } - }, [router.events]) - - let content - if (productLandingContext) { - content = ( - - - - ) - } else if (productGuidesContext) { - content = ( - - - - ) - } else if (tocLandingContext) { - content = ( - - - - ) - } else if (articleContext) { - content = ( - - - - ) - } else { - throw new Error('No context provided to page') - } - - return {content} -} - -export default GlobalPage - -export const getServerSideProps: GetServerSideProps = async (context) => { - const req = context.req as any - const res = context.res as any - - const props: Props = { - mainContext: await getMainContext(req, res), - } - const { currentLayoutName, relativePath } = props.mainContext - - // This looks a little funky, but it's so we only send one context's data to the client - if (currentLayoutName === 'product-landing') { - props.productLandingContext = await getProductLandingContextFromRequest(req) - } else if (currentLayoutName === 'product-guides') { - props.productGuidesContext = getProductGuidesContextFromRequest(req) - } else if (relativePath?.endsWith('index.md')) { - props.tocLandingContext = getTocLandingContextFromRequest(req) - } else { - props.articleContext = getArticleContextFromRequest(req) - } - - return { - props, - } -} +export { default, getServerSideProps } from 'src/landings/pages/product' diff --git a/pages/index.tsx b/pages/index.tsx index 15c86d3d50..6e92751c3b 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,93 +1 @@ -import React from 'react' -import type { GetServerSideProps } from 'next' - -import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext' - -import { DefaultLayout } from 'components/DefaultLayout' -import { useTranslation } from 'components/hooks/useTranslation' -import { ArticleList } from 'components/landing/ArticleList' -import { HomePageHero } from 'components/homepage/HomePageHero' -import type { ProductGroupT } from 'components/homepage/ProductSelections' -import { ProductSelections } from 'components/homepage/ProductSelections' - -type FeaturedLink = { - href: string - title: string - intro: string -} - -type Props = { - mainContext: MainContextT - popularLinks: Array - gettingStartedLinks: Array - productGroups: Array -} - -export default function MainHomePage({ - mainContext, - gettingStartedLinks, - popularLinks, - productGroups, -}: Props) { - return ( - - - - - - ) -} - -type HomePageProps = { - popularLinks: Array - gettingStartedLinks: Array - productGroups: Array -} -function HomePage(props: HomePageProps) { - const { gettingStartedLinks, popularLinks, productGroups } = props - const { t } = useTranslation(['toc']) - - return ( -
- - -
-
-
-
- -
- -
- -
-
-
-
-
- ) -} - -export const getServerSideProps: GetServerSideProps = async (context) => { - const req = context.req as any - const res = context.res as any - - return { - props: { - mainContext: await getMainContext(req, res), - productGroups: req.context.productGroups, - gettingStartedLinks: req.context.featuredLinks.gettingStarted.map( - ({ title, href, intro }: any) => ({ title, href, intro }) - ), - popularLinks: req.context.featuredLinks.popular.map(({ title, href, intro }: any) => ({ - title, - href, - intro, - })), - }, - } -} +export { default, getServerSideProps } from 'src/landings/pages/home' diff --git a/src/landings/README.md b/src/landings/README.md new file mode 100644 index 0000000000..10dcc60de7 --- /dev/null +++ b/src/landings/README.md @@ -0,0 +1,7 @@ +# Landing pages + +Landing pages include the Docs home page, the product landing pages, and product guides pages. + +## What landing pages are for + +Landing pages provide a hierarchical view of their area, making navigating the Docs easier. diff --git a/components/guides/ArticleCard.tsx b/src/landings/components/ArticleCard.tsx similarity index 94% rename from components/guides/ArticleCard.tsx rename to src/landings/components/ArticleCard.tsx index efc72d25f8..1fa51c64ae 100644 --- a/components/guides/ArticleCard.tsx +++ b/src/landings/components/ArticleCard.tsx @@ -1,6 +1,6 @@ import { Label } from '@primer/react' -import { ArticleGuide } from 'components/context/ProductGuidesContext' +import { ArticleGuide } from 'src/landings/components/ProductGuidesContext' import { Link } from 'components/Link' type Props = { diff --git a/components/guides/ArticleCards.tsx b/src/landings/components/ArticleCards.tsx similarity index 98% rename from components/guides/ArticleCards.tsx rename to src/landings/components/ArticleCards.tsx index 9ade0e8193..a5a0ee9c20 100644 --- a/components/guides/ArticleCards.tsx +++ b/src/landings/components/ArticleCards.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react' -import { ArticleGuide, useProductGuidesContext } from 'components/context/ProductGuidesContext' +import { ArticleGuide, useProductGuidesContext } from 'src/landings/components/ProductGuidesContext' import { useTranslation } from 'components/hooks/useTranslation' import { ArticleCard } from './ArticleCard' import { ActionList, ActionMenu } from '@primer/react' diff --git a/components/landing/ArticleList.tsx b/src/landings/components/ArticleList.tsx similarity index 97% rename from components/landing/ArticleList.tsx rename to src/landings/components/ArticleList.tsx index e5f2cba2ce..89e5c88bbc 100644 --- a/components/landing/ArticleList.tsx +++ b/src/landings/components/ArticleList.tsx @@ -4,7 +4,7 @@ import { ActionList } from '@primer/react' import { useTranslation } from 'components/hooks/useTranslation' import { Link } from 'components/Link' import { ArrowRightIcon } from '@primer/octicons-react' -import { FeaturedLink } from 'components/context/ProductLandingContext' +import { FeaturedLink } from 'src/landings/components/ProductLandingContext' import { useMainContext } from 'components/context/MainContext' import { TruncateLines } from 'components/ui/TruncateLines' import { BumpLink } from 'components/ui/BumpLink' diff --git a/components/landing/CommunityExamples.tsx b/src/landings/components/CommunityExamples.tsx similarity index 87% rename from components/landing/CommunityExamples.tsx rename to src/landings/components/CommunityExamples.tsx index d4f6628cc2..16bb9e870b 100644 --- a/components/landing/CommunityExamples.tsx +++ b/src/landings/components/CommunityExamples.tsx @@ -1,9 +1,9 @@ import { useState } from 'react' import { ArrowRightIcon } from '@primer/octicons-react' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' import { useTranslation } from 'components/hooks/useTranslation' -import { RepoCard } from 'components/landing/RepoCard' +import { RepoCard } from 'src/landings/components/RepoCard' export const CommunityExamples = () => { const { productCommunityExamples } = useProductLandingContext() diff --git a/components/landing/FeaturedArticles.tsx b/src/landings/components/FeaturedArticles.tsx similarity index 90% rename from components/landing/FeaturedArticles.tsx rename to src/landings/components/FeaturedArticles.tsx index 6e040f870f..dc492f7d93 100644 --- a/components/landing/FeaturedArticles.tsx +++ b/src/landings/components/FeaturedArticles.tsx @@ -1,8 +1,8 @@ import cx from 'classnames' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' import { useTranslation } from 'components/hooks/useTranslation' -import { ArticleList } from 'components/landing/ArticleList' +import { ArticleList } from 'src/landings/components/ArticleList' export const FeaturedArticles = () => { const { featuredArticles = [], whatsNewChangelog, changelogUrl } = useProductLandingContext() diff --git a/components/landing/GuideCard.tsx b/src/landings/components/GuideCard.tsx similarity index 89% rename from components/landing/GuideCard.tsx rename to src/landings/components/GuideCard.tsx index 4d050440cb..9b1691547d 100644 --- a/components/landing/GuideCard.tsx +++ b/src/landings/components/GuideCard.tsx @@ -1,4 +1,4 @@ -import type { FeaturedLink } from 'components/context/ProductLandingContext' +import type { FeaturedLink } from 'src/landings/components/ProductLandingContext' type Props = { guide: FeaturedLink diff --git a/components/landing/GuideCards.tsx b/src/landings/components/GuideCards.tsx similarity index 88% rename from components/landing/GuideCards.tsx rename to src/landings/components/GuideCards.tsx index b05135d3bf..f7f56d7d2a 100644 --- a/components/landing/GuideCards.tsx +++ b/src/landings/components/GuideCards.tsx @@ -4,8 +4,8 @@ import { Link } from 'components/Link' import { ArrowRightIcon } from '@primer/octicons-react' import { useMainContext } from 'components/context/MainContext' -import { useProductLandingContext } from 'components/context/ProductLandingContext' -import { GuideCard } from 'components/landing/GuideCard' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' +import { GuideCard } from 'src/landings/components/GuideCard' import { useTranslation } from 'components/hooks/useTranslation' export const GuideCards = () => { diff --git a/components/guides/GuidesHero.module.scss b/src/landings/components/GuidesHero.module.scss similarity index 100% rename from components/guides/GuidesHero.module.scss rename to src/landings/components/GuidesHero.module.scss diff --git a/components/guides/GuidesHero.tsx b/src/landings/components/GuidesHero.tsx similarity index 97% rename from components/guides/GuidesHero.tsx rename to src/landings/components/GuidesHero.tsx index 151a876977..14c657e82b 100644 --- a/components/guides/GuidesHero.tsx +++ b/src/landings/components/GuidesHero.tsx @@ -1,5 +1,5 @@ import cx from 'classnames' -import { useProductGuidesContext } from 'components/context/ProductGuidesContext' +import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext' import { ArrowRightIcon, StarFillIcon } from '@primer/octicons-react' import { useTranslation } from 'components/hooks/useTranslation' import { Link } from 'components/Link' diff --git a/components/homepage/HomePageHero.tsx b/src/landings/components/HomePageHero.tsx similarity index 90% rename from components/homepage/HomePageHero.tsx rename to src/landings/components/HomePageHero.tsx index 0f14227673..2800c7f6cf 100644 --- a/components/homepage/HomePageHero.tsx +++ b/src/landings/components/HomePageHero.tsx @@ -1,4 +1,4 @@ -import { OctocatHeader } from 'components/landing/OctocatHeader' +import { OctocatHeader } from 'src/landings/components/OctocatHeader' import { useTranslation } from 'components/hooks/useTranslation' export const HomePageHero = () => { diff --git a/components/landing/LandingHero.tsx b/src/landings/components/LandingHero.tsx similarity index 97% rename from components/landing/LandingHero.tsx rename to src/landings/components/LandingHero.tsx index 2f74862371..b1fb4fa146 100644 --- a/components/landing/LandingHero.tsx +++ b/src/landings/components/LandingHero.tsx @@ -4,7 +4,7 @@ import { useRouter } from 'next/router' import { LinkExternalIcon, NoteIcon } from '@primer/octicons-react' import { Link } from 'components/Link' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' import { useTranslation } from 'components/hooks/useTranslation' import { useVersion } from 'components/hooks/useVersion' import { Lead } from 'components/ui/Lead' diff --git a/components/landing/LandingSection.tsx b/src/landings/components/LandingSection.tsx similarity index 100% rename from components/landing/LandingSection.tsx rename to src/landings/components/LandingSection.tsx diff --git a/components/guides/LearningTrack.module.scss b/src/landings/components/LearningTrack.module.scss similarity index 100% rename from components/guides/LearningTrack.module.scss rename to src/landings/components/LearningTrack.module.scss diff --git a/components/guides/LearningTrack.tsx b/src/landings/components/LearningTrack.tsx similarity index 98% rename from components/guides/LearningTrack.tsx rename to src/landings/components/LearningTrack.tsx index 2d5f0bbf66..25f588a0cd 100644 --- a/components/guides/LearningTrack.tsx +++ b/src/landings/components/LearningTrack.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'components/hooks/useTranslation' import { ArrowRightIcon } from '@primer/octicons-react' import { ActionList } from '@primer/react' import { useState } from 'react' -import { FeaturedTrack } from 'components/context/ProductGuidesContext' +import { FeaturedTrack } from 'src/landings/components/ProductGuidesContext' import { TruncateLines } from 'components/ui/TruncateLines' import { slug } from 'github-slugger' import styles from './LearningTrack.module.scss' diff --git a/components/guides/LearningTracks.tsx b/src/landings/components/LearningTracks.tsx similarity index 66% rename from components/guides/LearningTracks.tsx rename to src/landings/components/LearningTracks.tsx index 386044d6ae..822e2e6da5 100644 --- a/components/guides/LearningTracks.tsx +++ b/src/landings/components/LearningTracks.tsx @@ -1,5 +1,5 @@ -import { useProductGuidesContext } from 'components/context/ProductGuidesContext' -import { LearningTrack } from 'components/guides/LearningTrack' +import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext' +import { LearningTrack } from 'src/landings/components/LearningTrack' export const LearningTracks = () => { const { learningTracks } = useProductGuidesContext() diff --git a/components/landing/OctocatHeader.tsx b/src/landings/components/OctocatHeader.tsx similarity index 100% rename from components/landing/OctocatHeader.tsx rename to src/landings/components/OctocatHeader.tsx diff --git a/components/landing/ProductArticlesList.tsx b/src/landings/components/ProductArticlesList.tsx similarity index 100% rename from components/landing/ProductArticlesList.tsx rename to src/landings/components/ProductArticlesList.tsx diff --git a/components/guides/ProductGuides.tsx b/src/landings/components/ProductGuides.tsx similarity index 79% rename from components/guides/ProductGuides.tsx rename to src/landings/components/ProductGuides.tsx index 77131b200c..2055b0bc52 100644 --- a/components/guides/ProductGuides.tsx +++ b/src/landings/components/ProductGuides.tsx @@ -1,9 +1,9 @@ import { DefaultLayout } from 'components/DefaultLayout' -import { useProductGuidesContext } from 'components/context/ProductGuidesContext' -import { LandingSection } from 'components/landing/LandingSection' -import { GuidesHero } from 'components/guides/GuidesHero' -import { LearningTracks } from 'components/guides/LearningTracks' -import { ArticleCards } from 'components/guides/ArticleCards' +import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext' +import { LandingSection } from 'src/landings/components/LandingSection' +import { GuidesHero } from 'src/landings/components/GuidesHero' +import { LearningTracks } from 'src/landings/components/LearningTracks' +import { ArticleCards } from 'src/landings/components/ArticleCards' import { useTranslation } from 'components/hooks/useTranslation' import { useMainContext } from 'components/context/MainContext' diff --git a/components/context/ProductGuidesContext.tsx b/src/landings/components/ProductGuidesContext.tsx similarity index 100% rename from components/context/ProductGuidesContext.tsx rename to src/landings/components/ProductGuidesContext.tsx diff --git a/components/landing/ProductLanding.tsx b/src/landings/components/ProductLanding.tsx similarity index 75% rename from components/landing/ProductLanding.tsx rename to src/landings/components/ProductLanding.tsx index 7d4c3b434e..b822fe53e9 100644 --- a/components/landing/ProductLanding.tsx +++ b/src/landings/components/ProductLanding.tsx @@ -1,16 +1,16 @@ import { useRouter } from 'next/router' import { DefaultLayout } from 'components/DefaultLayout' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' -import { LandingHero } from 'components/landing/LandingHero' -import { FeaturedArticles } from 'components/landing/FeaturedArticles' -import { GuideCards } from 'components/landing/GuideCards' -import { SponsorsExamples } from 'components/landing/SponsorsExamples' -import { CommunityExamples } from 'components/landing/CommunityExamples' -import { LandingSection } from 'components/landing/LandingSection' +import { LandingHero } from 'src/landings/components/LandingHero' +import { FeaturedArticles } from 'src/landings/components/FeaturedArticles' +import { GuideCards } from 'src/landings/components/GuideCards' +import { SponsorsExamples } from 'src/landings/components/SponsorsExamples' +import { CommunityExamples } from 'src/landings/components/CommunityExamples' +import { LandingSection } from 'src/landings/components/LandingSection' import { useTranslation } from 'components/hooks/useTranslation' -import { ProductArticlesList } from 'components/landing/ProductArticlesList' -import { ProductReleases } from 'components/landing/ProductReleases' +import { ProductArticlesList } from 'src/landings/components/ProductArticlesList' +import { ProductReleases } from 'src/landings/components/ProductReleases' import { useVersion } from 'components/hooks/useVersion' import { RestRedirect } from 'src/rest/components/RestRedirect' diff --git a/components/context/ProductLandingContext.tsx b/src/landings/components/ProductLandingContext.tsx similarity index 100% rename from components/context/ProductLandingContext.tsx rename to src/landings/components/ProductLandingContext.tsx diff --git a/components/landing/ProductReleases.tsx b/src/landings/components/ProductReleases.tsx similarity index 97% rename from components/landing/ProductReleases.tsx rename to src/landings/components/ProductReleases.tsx index 8b67799b38..2bd74c238e 100644 --- a/components/landing/ProductReleases.tsx +++ b/src/landings/components/ProductReleases.tsx @@ -1,6 +1,6 @@ import { ArrowRightIcon, ArrowUpIcon, FileIcon, ListUnorderedIcon } from '@primer/octicons-react' import { useMainContext } from 'components/context/MainContext' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' import { useTranslation } from 'components/hooks/useTranslation' import { Link } from 'components/Link' import { useRouter } from 'next/router' diff --git a/components/homepage/ProductSelectionCard.tsx b/src/landings/components/ProductSelectionCard.tsx similarity index 96% rename from components/homepage/ProductSelectionCard.tsx rename to src/landings/components/ProductSelectionCard.tsx index 6d9b5065b4..7250e73e24 100644 --- a/components/homepage/ProductSelectionCard.tsx +++ b/src/landings/components/ProductSelectionCard.tsx @@ -1,5 +1,5 @@ import { ProductT, useMainContext } from 'components/context/MainContext' -import type { ProductGroupT } from 'components/homepage/ProductSelections' +import type { ProductGroupT } from 'src/landings/components/ProductSelections' import React from 'react' import { useRouter } from 'next/router' diff --git a/components/homepage/ProductSelections.tsx b/src/landings/components/ProductSelections.tsx similarity index 100% rename from components/homepage/ProductSelections.tsx rename to src/landings/components/ProductSelections.tsx diff --git a/components/landing/RepoCard.tsx b/src/landings/components/RepoCard.tsx similarity index 100% rename from components/landing/RepoCard.tsx rename to src/landings/components/RepoCard.tsx diff --git a/components/sidebar/SidebarHomepage.tsx b/src/landings/components/SidebarHomepage.tsx similarity index 100% rename from components/sidebar/SidebarHomepage.tsx rename to src/landings/components/SidebarHomepage.tsx diff --git a/components/sidebar/SidebarProduct.tsx b/src/landings/components/SidebarProduct.tsx similarity index 98% rename from components/sidebar/SidebarProduct.tsx rename to src/landings/components/SidebarProduct.tsx index 48386cc8c9..65143f4bc7 100644 --- a/components/sidebar/SidebarProduct.tsx +++ b/src/landings/components/SidebarProduct.tsx @@ -7,7 +7,7 @@ import { useMainContext } from 'components/context/MainContext' import { useTranslation } from 'components/hooks/useTranslation' import { Link } from 'components/Link' import { RestCollapsibleSection } from 'src/rest/components/RestCollapsibleSection' -import { ProductCollapsibleSection } from './ProductCollapsibleSection' +import { ProductCollapsibleSection } from 'components/sidebar/ProductCollapsibleSection' export const SidebarProduct = () => { const router = useRouter() diff --git a/components/landing/SponsorsExamples.tsx b/src/landings/components/SponsorsExamples.tsx similarity index 86% rename from components/landing/SponsorsExamples.tsx rename to src/landings/components/SponsorsExamples.tsx index 9ffb4da912..25ce7102b8 100644 --- a/components/landing/SponsorsExamples.tsx +++ b/src/landings/components/SponsorsExamples.tsx @@ -1,9 +1,9 @@ import { ArrowRightIcon } from '@primer/octicons-react' import { Link } from 'components/Link' -import { useProductLandingContext } from 'components/context/ProductLandingContext' +import { useProductLandingContext } from 'src/landings/components/ProductLandingContext' import { useTranslation } from 'components/hooks/useTranslation' -import { UserCard } from 'components/landing/UserCard' +import { UserCard } from 'src/landings/components/UserCard' export const SponsorsExamples = () => { const { productUserExamples } = useProductLandingContext() diff --git a/components/landing/TableOfContents.tsx b/src/landings/components/TableOfContents.tsx similarity index 97% rename from components/landing/TableOfContents.tsx rename to src/landings/components/TableOfContents.tsx index 5c225bb2c2..18d031f3d1 100644 --- a/components/landing/TableOfContents.tsx +++ b/src/landings/components/TableOfContents.tsx @@ -3,7 +3,7 @@ import cx from 'classnames' import { ActionList } from '@primer/react' import { Link } from 'components/Link' -import type { TocItem } from 'components/context/ProductLandingContext' +import type { TocItem } from 'src/landings/components/ProductLandingContext' type Props = { items: Array diff --git a/components/landing/TocLanding.tsx b/src/landings/components/TocLanding.tsx similarity index 95% rename from components/landing/TocLanding.tsx rename to src/landings/components/TocLanding.tsx index 00e0f1f5a6..d7fb8a005d 100644 --- a/components/landing/TocLanding.tsx +++ b/src/landings/components/TocLanding.tsx @@ -4,10 +4,10 @@ import cx from 'classnames' import { useTocLandingContext } from 'components/context/TocLandingContext' import { useTranslation } from 'components/hooks/useTranslation' import { DefaultLayout } from 'components/DefaultLayout' -import { TableOfContents } from 'components/landing/TableOfContents' +import { TableOfContents } from 'src/landings/components/TableOfContents' import { ArticleTitle } from 'components/article/ArticleTitle' import { MarkdownContent } from 'components/ui/MarkdownContent' -import { ArticleList } from 'components/landing/ArticleList' +import { ArticleList } from 'src/landings/components/ArticleList' import { ArticleGridLayout } from 'components/article/ArticleGridLayout' import { Callout } from 'components/ui/Callout' import { Lead } from 'components/ui/Lead' diff --git a/components/landing/UserCard.tsx b/src/landings/components/UserCard.tsx similarity index 100% rename from components/landing/UserCard.tsx rename to src/landings/components/UserCard.tsx diff --git a/middleware/featured-links.js b/src/landings/middleware/featured-links.js similarity index 92% rename from middleware/featured-links.js rename to src/landings/middleware/featured-links.js index a99941f847..5ba67198d7 100644 --- a/middleware/featured-links.js +++ b/src/landings/middleware/featured-links.js @@ -1,5 +1,5 @@ -import getLinkData from '../lib/get-link-data.js' -import renderContent from '../lib/render-content/index.js' +import getLinkData from '../../../lib/get-link-data.js' +import renderContent from '../../../lib/render-content/index.js' // this middleware adds properties to the context object export default async function featuredLinks(req, res, next) { diff --git a/src/landings/pages/home.tsx b/src/landings/pages/home.tsx new file mode 100644 index 0000000000..236d77d0c3 --- /dev/null +++ b/src/landings/pages/home.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import type { GetServerSideProps } from 'next' + +import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext' + +import { DefaultLayout } from 'components/DefaultLayout' +import { useTranslation } from 'components/hooks/useTranslation' +import { ArticleList } from 'src/landings/components/ArticleList' +import { HomePageHero } from 'src/landings/components/HomePageHero' +import type { ProductGroupT } from 'src/landings/components/ProductSelections' +import { ProductSelections } from 'src/landings/components/ProductSelections' + +type FeaturedLink = { + href: string + title: string + intro: string +} + +type Props = { + mainContext: MainContextT + popularLinks: Array + gettingStartedLinks: Array + productGroups: Array +} + +export default function MainHomePage({ + mainContext, + gettingStartedLinks, + popularLinks, + productGroups, +}: Props) { + return ( + + + + + + ) +} + +type HomePageProps = { + popularLinks: Array + gettingStartedLinks: Array + productGroups: Array +} +function HomePage(props: HomePageProps) { + const { gettingStartedLinks, popularLinks, productGroups } = props + const { t } = useTranslation(['toc']) + + return ( +
+ + +
+
+
+
+ +
+ +
+ +
+
+
+
+
+ ) +} + +export const getServerSideProps: GetServerSideProps = async (context) => { + const req = context.req as any + const res = context.res as any + + return { + props: { + mainContext: await getMainContext(req, res), + productGroups: req.context.productGroups, + gettingStartedLinks: req.context.featuredLinks.gettingStarted.map( + ({ title, href, intro }: any) => ({ title, href, intro }) + ), + popularLinks: req.context.featuredLinks.popular.map(({ title, href, intro }: any) => ({ + title, + href, + intro, + })), + }, + } +} diff --git a/src/landings/pages/product.tsx b/src/landings/pages/product.tsx new file mode 100644 index 0000000000..f76efc5e5a --- /dev/null +++ b/src/landings/pages/product.tsx @@ -0,0 +1,128 @@ +import { GetServerSideProps } from 'next' +import { useRouter } from 'next/router' + +// "legacy" javascript needed to maintain existing functionality +// typically operating on elements **within** an article. +import copyCode from 'components/lib/copy-code' +import localization from 'components/lib/localization' +import wrapCodeTerms from 'components/lib/wrap-code-terms' + +import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext' + +import { + getProductLandingContextFromRequest, + ProductLandingContextT, + ProductLandingContext, +} from 'src/landings/components/ProductLandingContext' +import { + getProductGuidesContextFromRequest, + ProductGuidesContextT, + ProductGuidesContext, +} from 'src/landings/components/ProductGuidesContext' + +import { + getArticleContextFromRequest, + ArticleContextT, + ArticleContext, +} from 'components/context/ArticleContext' +import { ArticlePage } from 'components/article/ArticlePage' + +import { ProductLanding } from 'src/landings/components/ProductLanding' +import { ProductGuides } from 'src/landings/components/ProductGuides' +import { TocLanding } from 'src/landings/components/TocLanding' +import { + getTocLandingContextFromRequest, + TocLandingContext, + TocLandingContextT, +} from 'components/context/TocLandingContext' +import { useEffect } from 'react' + +function initiateArticleScripts() { + copyCode() + localization() + wrapCodeTerms() +} + +type Props = { + mainContext: MainContextT + productLandingContext?: ProductLandingContextT + productGuidesContext?: ProductGuidesContextT + tocLandingContext?: TocLandingContextT + articleContext?: ArticleContextT +} +const GlobalPage = ({ + mainContext, + productLandingContext, + productGuidesContext, + tocLandingContext, + articleContext, +}: Props) => { + const router = useRouter() + + useEffect(() => { + // https://stackoverflow.com/a/67063998 + initiateArticleScripts() // on initiate page + router.events.on('routeChangeComplete', initiateArticleScripts) // on client side route + return () => { + router.events.off('routeChangeComplete', initiateArticleScripts) + } + }, [router.events]) + + let content + if (productLandingContext) { + content = ( + + + + ) + } else if (productGuidesContext) { + content = ( + + + + ) + } else if (tocLandingContext) { + content = ( + + + + ) + } else if (articleContext) { + content = ( + + + + ) + } else { + throw new Error('No context provided to page') + } + + return {content} +} + +export default GlobalPage + +export const getServerSideProps: GetServerSideProps = async (context) => { + const req = context.req as any + const res = context.res as any + + const props: Props = { + mainContext: await getMainContext(req, res), + } + const { currentLayoutName, relativePath } = props.mainContext + + // This looks a little funky, but it's so we only send one context's data to the client + if (currentLayoutName === 'product-landing') { + props.productLandingContext = await getProductLandingContextFromRequest(req) + } else if (currentLayoutName === 'product-guides') { + props.productGuidesContext = getProductGuidesContextFromRequest(req) + } else if (relativePath?.endsWith('index.md')) { + props.tocLandingContext = getTocLandingContextFromRequest(req) + } else { + props.articleContext = getArticleContextFromRequest(req) + } + + return { + props, + } +} diff --git a/tests/rendering/curated-homepage-links.js b/src/landings/tests/curated-homepage-links.js similarity index 94% rename from tests/rendering/curated-homepage-links.js rename to src/landings/tests/curated-homepage-links.js index e5a6e5a352..5be1212867 100644 --- a/tests/rendering/curated-homepage-links.js +++ b/src/landings/tests/curated-homepage-links.js @@ -1,4 +1,4 @@ -import { getDOM } from '../helpers/e2etest.js' +import { getDOM } from '../../../tests/helpers/e2etest.js' import { jest } from '@jest/globals' describe('curated homepage links', () => { diff --git a/tests/content/featured-links.js b/src/landings/tests/featured-links.js similarity index 95% rename from tests/content/featured-links.js rename to src/landings/tests/featured-links.js index 92a5ab20bc..d683cb358f 100644 --- a/tests/content/featured-links.js +++ b/src/landings/tests/featured-links.js @@ -1,7 +1,7 @@ import { jest } from '@jest/globals' -import { getDOM } from '../helpers/e2etest.js' -import enterpriseServerReleases from '../../lib/enterprise-server-releases.js' +import { getDOM } from '../../../tests/helpers/e2etest.js' +import enterpriseServerReleases from '../../../lib/enterprise-server-releases.js' describe('featuredLinks', () => { jest.setTimeout(3 * 60 * 1000) diff --git a/tests/rendering/homepage.js b/src/landings/tests/homepage.js similarity index 100% rename from tests/rendering/homepage.js rename to src/landings/tests/homepage.js diff --git a/src/rest/pages/category.tsx b/src/rest/pages/category.tsx index 19116eefd0..7975e7ad06 100644 --- a/src/rest/pages/category.tsx +++ b/src/rest/pages/category.tsx @@ -14,7 +14,7 @@ import { TocLandingContext, TocLandingContextT, } from 'components/context/TocLandingContext' -import { TocLanding } from 'components/landing/TocLanding' +import { TocLanding } from 'src/landings/components/TocLanding' type MinitocItemsT = { restOperationsMiniTocItems: MiniTocItem[]