Skip to content

Commit

Permalink
refactor(core): header / footer fragment colocation (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
deini authored Apr 2, 2024
1 parent 8ad9d15 commit a170d05
Show file tree
Hide file tree
Showing 16 changed files with 389 additions and 149 deletions.
42 changes: 34 additions & 8 deletions apps/core/app/[locale]/(default)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { NextIntlClientProvider, useMessages } from 'next-intl';
import { unstable_setRequestLocale } from 'next-intl/server';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages, unstable_setRequestLocale } from 'next-intl/server';
import { PropsWithChildren, Suspense } from 'react';

import { Footer } from '~/components/footer/footer';
import { Header } from '~/components/header';
import { getSessionCustomerId } from '~/auth';
import { client } from '~/client';
import { graphql } from '~/client/graphql';
import { revalidate } from '~/client/revalidate-target';
import { Footer, FooterFragment } from '~/components/footer/footer';
import { Header, HeaderFragment } from '~/components/header';
import { Cart } from '~/components/header/cart';
import { ProductSheet } from '~/components/product-sheet';
import { LocaleType } from '~/i18n';
Expand All @@ -12,23 +16,45 @@ interface Props extends PropsWithChildren {
params: { locale: LocaleType };
}

export default function DefaultLayout({ children, params: { locale } }: Props) {
const LayoutQuery = graphql(
`
query LayoutQuery {
site {
...HeaderFragment
...FooterFragment
}
}
`,
[HeaderFragment, FooterFragment],
);

export default async function DefaultLayout({ children, params: { locale } }: Props) {
const customerId = await getSessionCustomerId();

const { data } = await client.fetch({
document: LayoutQuery,
fetchOptions: customerId ? { cache: 'no-store' } : { next: { revalidate } },
});

unstable_setRequestLocale(locale);

const messages = useMessages();
const messages = await getMessages({ locale });

return (
<>
<Header cart={<Cart />} />
<Header cart={<Cart />} data={data.site} />

<main className="flex-1 px-6 2xl:container sm:px-10 lg:px-12 2xl:mx-auto 2xl:px-0">
{children}
</main>

<Suspense fallback={null}>
<NextIntlClientProvider locale={locale} messages={{ Product: messages.Product ?? {} }}>
<ProductSheet />
</NextIntlClientProvider>
</Suspense>
<Footer />

<Footer data={data.site} />
</>
);
}
22 changes: 19 additions & 3 deletions apps/core/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { PropsWithChildren } from 'react';

import '../globals.css';

import { getStoreSettings } from '~/client/queries/get-store-settings';
import { client } from '~/client';
import { graphql } from '~/client/graphql';
import { revalidate } from '~/client/revalidate-target';

import { Notifications } from '../notifications';
import { Providers } from '../providers';
Expand All @@ -19,9 +21,23 @@ const inter = Inter({
variable: '--font-inter',
});

const RootLayoutMetadataQuery = graphql(`
query RootLayoutMetadataQuery {
site {
settings {
storeName
}
}
}
`);

export async function generateMetadata(): Promise<Metadata> {
const storeSettings = await getStoreSettings();
const title = storeSettings?.storeName ?? 'Catalyst Store';
const { data } = await client.fetch({
document: RootLayoutMetadataQuery,
fetchOptions: { next: { revalidate } },
});

const title = data.site.settings?.storeName ?? 'Catalyst Store';

return {
title: {
Expand Down
30 changes: 26 additions & 4 deletions apps/core/app/[locale]/maintenance/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Phone } from 'lucide-react';
import { ReactNode } from 'react';

import { getStoreSettings } from '~/client/queries/get-store-settings';
import { StoreLogo } from '~/components/store-logo';
import { client } from '~/client';
import { graphql } from '~/client/graphql';
import { StoreLogo, StoreLogoFragment } from '~/components/store-logo';

const Container = ({ children }: { children: ReactNode }) => (
<main className="mx-auto mt-[64px] px-6 md:px-10 lg:mt-[128px]">{children}</main>
Expand All @@ -12,8 +13,29 @@ export const metadata = {
title: 'Maintenance',
};

const MaintenancePageQuery = graphql(
`
query MaintenancePageQuery {
site {
settings {
contact {
phone
}
statusMessage
...StoreLogoFragment
}
}
}
`,
[StoreLogoFragment],
);

export default async function MaintenancePage() {
const storeSettings = await getStoreSettings();
const { data } = await client.fetch({
document: MaintenancePageQuery,
});

const storeSettings = data.site.settings;

if (!storeSettings) {
return (
Expand All @@ -27,7 +49,7 @@ export default async function MaintenancePage() {

return (
<Container>
<StoreLogo />
<StoreLogo data={storeSettings} />

<h1 className="my-8 text-4xl font-black lg:text-5xl">We are down for maintenance</h1>

Expand Down
46 changes: 40 additions & 6 deletions apps/core/app/[locale]/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { removeEdgesAndNodes } from '@bigcommerce/catalyst-client';
import { ShoppingCart } from 'lucide-react';
import { NextIntlClientProvider } from 'next-intl';
import { getLocale, getMessages, getTranslations } from 'next-intl/server';

import { getFeaturedProducts } from '~/client/queries/get-featured-products';
import { Footer } from '~/components/footer/footer';
import { Header } from '~/components/header';
import { client } from '~/client';
import { PRODUCT_DETAILS_FRAGMENT } from '~/client/fragments/product-details';
import { graphql } from '~/client/graphql';
import { revalidate } from '~/client/revalidate-target';
import { Footer, FooterFragment } from '~/components/footer/footer';
import { Header, HeaderFragment } from '~/components/header';
import { CartLink } from '~/components/header/cart';
import { ProductCard } from '~/components/product-card';
import { SearchForm } from '~/components/search-form';
Expand All @@ -13,15 +17,42 @@ export const metadata = {
title: 'Not Found',
};

const NotFoundQuery = graphql(
`
query NotFoundQuery {
site {
...HeaderFragment
...FooterFragment
featuredProducts(first: 4) {
edges {
node {
...ProductDetails
}
}
}
}
}
`,
[HeaderFragment, FooterFragment, PRODUCT_DETAILS_FRAGMENT],
);

export default async function NotFound() {
const locale = await getLocale();
const t = await getTranslations('NotFound');
const messages = await getMessages({ locale });

const featuredProducts = await getFeaturedProducts({
first: 4,
const { data } = await client.fetch({
document: NotFoundQuery,
fetchOptions: { next: { revalidate } },
});

const featuredProducts = removeEdgesAndNodes(data.site.featuredProducts).map(
(featuredProduct) => ({
...featuredProduct,
productOptions: removeEdgesAndNodes(featuredProduct.productOptions),
}),
);

return (
<>
<Header
Expand All @@ -30,7 +61,9 @@ export default async function NotFound() {
<ShoppingCart aria-label="cart" />
</CartLink>
}
data={data.site}
/>

<main className="mx-auto mb-10 max-w-[835px] space-y-8 px-6 sm:px-10 lg:px-0">
<div className="flex flex-col gap-8 px-0 py-16">
<h2 className="text-4xl font-black lg:text-5xl">{t('heading')}</h2>
Expand Down Expand Up @@ -59,7 +92,8 @@ export default async function NotFound() {
</div>
</section>
</main>
<Footer />

<Footer data={data.site} />
</>
);
}
Expand Down
47 changes: 0 additions & 47 deletions apps/core/client/queries/get-store-settings.ts

This file was deleted.

20 changes: 16 additions & 4 deletions apps/core/components/footer/contact-information.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { Fragment } from 'react';

import { getStoreSettings } from '~/client/queries/get-store-settings';
import { FragmentOf, graphql } from '~/client/graphql';

export const ContactInformation = async () => {
const settings = await getStoreSettings();
const contact = settings?.contact;
export const ContactInformationFragment = graphql(`
fragment ContactInformationFragment on Settings {
contact {
address
phone
}
}
`);

interface Props {
data: FragmentOf<typeof ContactInformationFragment>;
}

export const ContactInformation = ({ data }: Props) => {
const { contact } = data;

if (!contact) {
return null;
Expand Down
22 changes: 12 additions & 10 deletions apps/core/components/footer/copyright.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { ComponentPropsWithoutRef } from 'react';
import { FragmentOf, graphql } from '~/client/graphql';

import { getStoreSettings } from '~/client/queries/get-store-settings';

export const Copyright = async (props: ComponentPropsWithoutRef<'p'>) => {
const settings = await getStoreSettings();

if (!settings) {
return null;
export const CopyrightFragment = graphql(`
fragment CopyrightFragment on Settings {
storeName
}
`);

interface Props {
data: FragmentOf<typeof CopyrightFragment>;
}

export const Copyright = ({ data }: Props) => {
return (
<p className="text-gray-500 sm:order-first" {...props}>
© {new Date().getFullYear()} {settings.storeName} – Powered by BigCommerce
<p className="text-gray-500 sm:order-first">
© {new Date().getFullYear()} {data.storeName} – Powered by BigCommerce
</p>
);
};
24 changes: 21 additions & 3 deletions apps/core/components/footer/footer-menus/brand-footer-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import { getBrands } from '~/client/queries/get-brands';
import { removeEdgesAndNodes } from '@bigcommerce/catalyst-client';

import { FragmentOf, graphql } from '~/client/graphql';

import { BaseFooterMenu } from './base-footer-menu';

export const BrandFooterMenu = async () => {
const brands = await getBrands();
export const BrandsFooterMenuFragment = graphql(`
fragment BrandsFooterMenuFragment on BrandConnection {
edges {
node {
entityId
name
path
}
}
}
`);

interface Props {
data: FragmentOf<typeof BrandsFooterMenuFragment>;
}

export const BrandFooterMenu = ({ data }: Props) => {
const brands = removeEdgesAndNodes(data);

if (!brands.length) {
return null;
Expand Down
Loading

0 comments on commit a170d05

Please sign in to comment.