From d85b05f4ee7a8bb6fe48f1c0bc195c78807bdabd Mon Sep 17 00:00:00 2001 From: Paul Hachmang Date: Thu, 16 Jan 2025 11:37:40 +0100 Subject: [PATCH] =?UTF-8?q?Convert=20home=20to=20render=20the=20home=20Cms?= =?UTF-8?q?Page=20and=20add=20page/[=E2=80=A6url]=20route=20for=20addition?= =?UTF-8?q?al=20pages.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../magento-open-source/pages/[...url].tsx | 29 +----- examples/magento-open-source/pages/index.tsx | 98 +++++-------------- .../pages/page/[...url].tsx | 98 +++++++++++++++++++ .../CmsPageContent/CmsPageContent.tsx | 7 +- packages/magento-cms/graphql/CmsPage.graphql | 12 ++- .../graphql/CmsPageFragment.graphql | 5 + packages/magento-cms/index.ts | 1 + 7 files changed, 141 insertions(+), 109 deletions(-) create mode 100644 examples/magento-open-source/pages/page/[...url].tsx create mode 100644 packages/magento-cms/graphql/CmsPageFragment.graphql diff --git a/examples/magento-open-source/pages/[...url].tsx b/examples/magento-open-source/pages/[...url].tsx index 5cb91e5e3f..b747f654ca 100644 --- a/examples/magento-open-source/pages/[...url].tsx +++ b/examples/magento-open-source/pages/[...url].tsx @@ -9,8 +9,6 @@ import { findParentBreadcrumbItem, getCategoryStaticPaths, } from '@graphcommerce/magento-category' -import type { CmsPageQuery } from '@graphcommerce/magento-cms' -import { CmsPageContent, CmsPageDocument } from '@graphcommerce/magento-cms' import type { FilterTypes, ProductFiltersQuery, @@ -28,12 +26,7 @@ import { productListLink, useProductList, } from '@graphcommerce/magento-product' -import { - PageMeta, - redirectOrNotFound, - redirectTo, - StoreConfigDocument, -} from '@graphcommerce/magento-store' +import { redirectOrNotFound, redirectTo, StoreConfigDocument } from '@graphcommerce/magento-store' import type { GetStaticProps } from '@graphcommerce/next-ui' import { Container, LayoutHeader, LayoutTitle } from '@graphcommerce/next-ui' import { i18n } from '@lingui/core' @@ -50,8 +43,7 @@ import type { CategoryPageQuery } from '../graphql/CategoryPage.gql' import { CategoryPageDocument } from '../graphql/CategoryPage.gql' import { graphqlSharedClient, graphqlSsrClient } from '../lib/graphql/graphqlSsrClient' -export type CategoryProps = CmsPageQuery & - CategoryPageQuery & +export type CategoryProps = CategoryPageQuery & ProductListQuery & ProductFiltersQuery & { filterTypes?: FilterTypes; params?: ProductListParams } export type CategoryRoute = { url: string[] } @@ -60,7 +52,7 @@ type GetPageStaticPaths = GetStaticPaths type GetPageStaticProps = GetStaticProps function CategoryPage(props: CategoryProps) { - const { categories, cmsPage, ...rest } = props + const { categories, ...rest } = props const productList = useProductList({ ...rest, category: categories?.items?.[0], @@ -77,15 +69,6 @@ function CategoryPage(props: CategoryProps) { {category?.name} - {cmsPage && ( - <> - - - - )} {isCategory && isLanding && ( <> @@ -176,7 +159,6 @@ export const getStaticProps: GetPageStaticProps = async (context) => { const staticClient = graphqlSsrClient(context) const categoryPage = staticClient.query({ query: CategoryPageDocument, variables: { url } }) - const cmsPage = staticClient.query({ query: CmsPageDocument, variables: { url } }) const layout = staticClient.query({ query: LayoutDocument, @@ -216,9 +198,7 @@ export const getStaticProps: GetPageStaticProps = async (context) => { }) : undefined - const hasPage = (await cmsPage).data.cmsPage - - if (!hasCategory && !hasPage) return redirectOrNotFound(staticClient, conf, params, locale) + if (!hasCategory) return redirectOrNotFound(staticClient, conf, params, locale) if ((await products)?.errors) { const totalPages = (await filters)?.data.filters?.page_info?.total_pages ?? 0 @@ -244,7 +224,6 @@ export const getStaticProps: GetPageStaticProps = async (context) => { ...(await products)?.data, ...(await filters)?.data, ...(await layout).data, - ...(await cmsPage).data, filterTypes: await filterTypes, params: productListParams, apolloState: await conf.then(() => client.cache.extract()), diff --git a/examples/magento-open-source/pages/index.tsx b/examples/magento-open-source/pages/index.tsx index 7df0bd249f..3a9a85c446 100644 --- a/examples/magento-open-source/pages/index.tsx +++ b/examples/magento-open-source/pages/index.tsx @@ -1,88 +1,33 @@ import type { PageOptions } from '@graphcommerce/framer-next-pages' import { cacheFirst } from '@graphcommerce/graphql' -import { - ProductListDocument, - ProductListQuery, - ProductPageName, -} from '@graphcommerce/magento-product' +import type { CmsPageFragment } from '@graphcommerce/magento-cms' +import { CmsPageContent, CmsPageDocument } from '@graphcommerce/magento-cms' import { StoreConfigDocument } from '@graphcommerce/magento-store' import type { GetStaticProps } from '@graphcommerce/next-ui' -import { - breakpointVal, - HeroBanner, - LayoutHeader, - LayoutTitle, - MetaRobots, - PageMeta, -} from '@graphcommerce/next-ui' -import { Button, Container, Typography } from '@mui/material' +import { Container, isTypename, LayoutHeader, PageMeta } from '@graphcommerce/next-ui' +import { i18n } from '@lingui/core' import type { LayoutNavigationProps } from '../components' import { LayoutDocument, LayoutNavigation } from '../components' import { graphqlSharedClient, graphqlSsrClient } from '../lib/graphql/graphqlSsrClient' -type Props = {} -type RouteProps = { url: string } -type GetPageStaticProps = GetStaticProps +export type CmsPageProps = { cmsPage: CmsPageFragment | null } -function CmsPage(props: Props) { - const {} = props +type GetPageStaticProps = GetStaticProps - return ( - <> - {/* */} +function CmsPage(props: CmsPageProps) { + const { cmsPage } = props - - - Home - - + if (!cmsPage) return Configure cmsPage home - + return ( + <> + + - - Shop Art - - } - videoSrc='https://media.graphassets.com/UNmtIZmWSgmnpUAWcAk0' - sx={(theme) => ({ - '& .HeroBanner-copy': { - minHeight: { xs: 'min(70vh,600px)', md: 'min(70vh,1080px)' }, - [theme.breakpoints.up('sm')]: { - padding: theme.spacings.xl, - justifyItems: 'start', - alignContent: 'center', - textAlign: 'left', - width: '50%', - }, - }, - })} - > - - A journey through creativity - - ({ - textTransform: 'uppercase', - mt: 1, - mb: theme.spacings.sm, - ...breakpointVal('fontSize', 36, 82, theme.breakpoints.values), - '& strong': { - WebkitTextFillColor: 'transparent', - WebkitTextStroke: '1.2px #fff', - }, - })} - > - Discover beauty beyond boundaries. - - + ) } @@ -95,19 +40,24 @@ export default CmsPage export const getStaticProps: GetPageStaticProps = async (context) => { const client = graphqlSharedClient(context) + const conf = client.query({ query: StoreConfigDocument }) const staticClient = graphqlSsrClient(context) - const conf = client.query({ query: StoreConfigDocument }) + const url = (await conf).data.storeConfig?.cms_home_page ?? 'home' + const cmsPageQuery = staticClient.query({ query: CmsPageDocument, variables: { url } }) const layout = staticClient.query({ query: LayoutDocument, fetchPolicy: cacheFirst(staticClient), }) + const cmsPage = (await cmsPageQuery).data.route - return { + const result = { props: { + cmsPage: cmsPage && isTypename(cmsPage, ['CmsPage']) ? cmsPage : null, ...(await layout).data, apolloState: await conf.then(() => client.cache.extract()), }, revalidate: 60 * 20, } + return result } diff --git a/examples/magento-open-source/pages/page/[...url].tsx b/examples/magento-open-source/pages/page/[...url].tsx new file mode 100644 index 0000000000..be47da488f --- /dev/null +++ b/examples/magento-open-source/pages/page/[...url].tsx @@ -0,0 +1,98 @@ +import type { PageOptions } from '@graphcommerce/framer-next-pages' +import { cacheFirst } from '@graphcommerce/graphql' +import { getCategoryStaticPaths } from '@graphcommerce/magento-category' +import type { CmsPageFragment, CmsPageQuery } from '@graphcommerce/magento-cms' +import { CmsPageContent, CmsPageDocument } from '@graphcommerce/magento-cms' +import { PageMeta, redirectOrNotFound, StoreConfigDocument } from '@graphcommerce/magento-store' +import { + Container, + isTypename, + LayoutHeader, + LayoutTitle, + type GetStaticProps, +} from '@graphcommerce/next-ui' +import type { GetStaticPaths } from 'next' +import type { LayoutNavigationProps } from '../../components' +import { LayoutDocument, LayoutNavigation } from '../../components' +import { graphqlSharedClient, graphqlSsrClient } from '../../lib/graphql/graphqlSsrClient' + +export type CmsPageProps = { cmsPage: CmsPageFragment } +export type CmsRoute = { url: string[] } + +type GetPageStaticPaths = GetStaticPaths +type GetPageStaticProps = GetStaticProps + +function CmsPage(props: CmsPageProps) { + const { cmsPage } = props + + return ( + <> + + + + + {cmsPage.content_heading ?? cmsPage.title} + + + + {cmsPage.content_heading && ( + + + {cmsPage.content_heading} + + + )} + + + + ) +} + +const pageOptions: PageOptions = { + Layout: LayoutNavigation, +} +CmsPage.pageOptions = pageOptions + +export default CmsPage + +export const getStaticPaths: GetPageStaticPaths = async ({ locales = [] }) => { + // Disable getStaticPaths while in development mode + if (process.env.NODE_ENV === 'development') return { paths: [], fallback: 'blocking' } + + const path = (locale: string) => getCategoryStaticPaths(graphqlSsrClient({ locale }), locale) + const paths = (await Promise.all(locales.map(path))).flat(1) + return { paths, fallback: 'blocking' } +} + +export const getStaticProps: GetPageStaticProps = async (context) => { + const { params, locale } = context + const url = params?.url?.join('/') ?? '' + if (!url) return { notFound: true } + + const client = graphqlSharedClient(context) + const conf = client.query({ query: StoreConfigDocument }) + const staticClient = graphqlSsrClient(context) + + const cmsPageQuery = staticClient.query({ query: CmsPageDocument, variables: { url } }) + const layout = staticClient.query({ + query: LayoutDocument, + fetchPolicy: cacheFirst(staticClient), + }) + + const cmsPage = (await cmsPageQuery).data.route + if (!cmsPage || !isTypename(cmsPage, ['CmsPage'])) + return redirectOrNotFound(staticClient, conf, params, locale) + + const result = { + props: { + cmsPage, + ...(await layout).data, + apolloState: await conf.then(() => client.cache.extract()), + }, + revalidate: 60 * 20, + } + return result +} diff --git a/packages/magento-cms/components/CmsPageContent/CmsPageContent.tsx b/packages/magento-cms/components/CmsPageContent/CmsPageContent.tsx index cfff46e86b..02e70ab1da 100644 --- a/packages/magento-cms/components/CmsPageContent/CmsPageContent.tsx +++ b/packages/magento-cms/components/CmsPageContent/CmsPageContent.tsx @@ -1,4 +1,4 @@ -import { Container, Typography } from '@mui/material' +import { Container } from '@mui/material' import type { CmsPageContentFragment } from './CmsPageContent.gql' export type CmsPageContentProps = { cmsPage: CmsPageContentFragment } @@ -7,11 +7,6 @@ export function CmsPageContent(props: CmsPageContentProps) { const { cmsPage } = props return ( - {cmsPage.content_heading && ( - - {cmsPage.content_heading} - - )} {/* eslint-disable-next-line react/no-danger */} {cmsPage.content &&
} diff --git a/packages/magento-cms/graphql/CmsPage.graphql b/packages/magento-cms/graphql/CmsPage.graphql index e16c96f1a5..662a7e325c 100644 --- a/packages/magento-cms/graphql/CmsPage.graphql +++ b/packages/magento-cms/graphql/CmsPage.graphql @@ -1,7 +1,11 @@ query CmsPage($url: String!) { - cmsPage(identifier: $url) { - identifier - ...CmsPageMeta - ...CmsPageContent + route(url: $url) { + __typename + relative_url + redirect_code + type + ... on CmsPage { + ...CmsPageFragment + } } } diff --git a/packages/magento-cms/graphql/CmsPageFragment.graphql b/packages/magento-cms/graphql/CmsPageFragment.graphql new file mode 100644 index 0000000000..2f7d4e1ef4 --- /dev/null +++ b/packages/magento-cms/graphql/CmsPageFragment.graphql @@ -0,0 +1,5 @@ +fragment CmsPageFragment on CmsPage { + identifier + ...CmsPageMeta + ...CmsPageContent +} diff --git a/packages/magento-cms/index.ts b/packages/magento-cms/index.ts index 88f6b6f9b3..92b1c6edec 100644 --- a/packages/magento-cms/index.ts +++ b/packages/magento-cms/index.ts @@ -3,3 +3,4 @@ export * from './components/CmsPageContent/CmsPageContent.gql' export * from './components/CmsPageMeta/CmsPageMeta' export * from './components/CmsPageMeta/CmsPageMeta.gql' export * from './graphql/CmsPage.gql' +export * from './graphql/CmsPageFragment.gql'