Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

Commit

Permalink
sync v2
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-phan committed Nov 6, 2023
1 parent 2d809b7 commit dc2ad3e
Show file tree
Hide file tree
Showing 40 changed files with 228 additions and 189 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div align="center">
<p style="text-align: center;">
<img alt="Version" src="https://img.shields.io/badge/version-2.2.4-blue.svg?cacheSeconds=2592000" />
<img alt="Version" src="https://img.shields.io/badge/version-2.3.0-blue.svg?cacheSeconds=2592000" />
<a href="#" target="_blank">
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?label=license" />
</a>
Expand Down Expand Up @@ -46,7 +46,7 @@ Follow these steps to get started with Pilot and begin crafting your Hydrogen-dr
1. Install [Weaverse Hydrogen Customizer](https://apps.shopify.com/weaverse) from Shopify App Store.
2. Create new Hydrogen storefront inside Weaverse.
3. Initialize the project and start a local dev server with `@weaverse/cli` tool as instructed in the Weaverse editor.
![Init Weaverse Storefront](https://cdn.shopify.com/s/files/1/0693/8201/3220/files/init-project_4882deaa-c661-47cc-a7bf-38b2704e6a0b.png?v=1695816089)
![Init Weaverse Storefront](https://cdn.shopify.com/s/files/1/0838/0052/3057/files/New_storefront.png?v=1699244454)
4. Open the Weaverse editor to start customizing and tailoring your storefront according to your preferences.

## Features overview
Expand Down Expand Up @@ -270,7 +270,7 @@ And then you can use the data in your component with `Component.props.loaderData

Weaverse provides a convenient way to customize your theme inside the **Weaverse editor**. You can add new sections, customize existing ones, and change the theme settings.

![Weaverse Editor](https://cdn.shopify.com/s/files/1/0693/8201/3220/files/Live_demo_-_Weaverse_Hydrogen_2023-09-27_18-58-23.png?v=1695826457)
![Weaverse Editor](https://cdn.shopify.com/s/files/1/0838/0052/3057/files/playground.jpg?v=1699244445)

## References

Expand Down
5 changes: 3 additions & 2 deletions app/components/CountrySelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {CartForm} from '@shopify/hydrogen';
import {Heading, Button, IconCheck} from '~/components';
import type {Localizations, Locale} from '~/lib/type';
import {DEFAULT_LOCALE} from '~/lib/utils';
import {useRootLoaderData} from '~/root';

export function CountrySelector() {
const [root] = useMatches();
const fetcher = useFetcher();
const closeRef = useRef<HTMLDetailsElement>(null);
const selectedLocale = root.data?.selectedLocale ?? DEFAULT_LOCALE;
const rootData = useRootLoaderData();
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const {pathname, search} = useLocation();
const pathWithoutLocale = `${pathname.replace(
selectedLocale.pathPrefix,
Expand Down
8 changes: 4 additions & 4 deletions app/components/FeaturedProducts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ interface FeaturedProductsProps {
* @param query a filtering query
* @param reverse wether to reverse the product results
* @param sortKey Sort the underlying list by the given key.
* @see query https://shopify.dev/api/storefront/2023-07/queries/products
* @see filters https://shopify.dev/api/storefront/2023-07/queries/products#argument-products-query
* @see query https://shopify.dev/api/storefront/current/queries/products
* @see filters https://shopify.dev/api/storefront/current/queries/products#argument-products-query
*/
export function FeaturedProducts({
count = 4,
Expand All @@ -38,7 +38,7 @@ export function FeaturedProducts({
reverse,
sortKey = 'BEST_SELLING',
}: FeaturedProductsProps) {
const {load, data} = useFetcher();
const {load, data} = useFetcher<{products: Product[]}>();
const queryString = useMemo(
() =>
Object.entries({count, sortKey, query, reverse})
Expand Down Expand Up @@ -69,7 +69,7 @@ export function FeaturedProducts({
<FeatureProductsContent
count={count}
onClick={onClose}
products={data?.products as Product[]}
products={data?.products}
/>
</div>
</>
Expand Down
15 changes: 8 additions & 7 deletions app/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useParams, Form, Await, useMatches} from '@remix-run/react';
import {useParams, Form, Await} from '@remix-run/react';
import {useWindowScroll} from 'react-use';
import {Disclosure} from '@headlessui/react';
import {Suspense, useEffect, useMemo} from 'react';
Expand Down Expand Up @@ -32,6 +32,7 @@ import {useIsHydrated} from '~/hooks/useIsHydrated';
import {useCartFetchers} from '~/hooks/useCartFetchers';
import {Logo} from './Logo';
import clsx from 'clsx';
import {useRootLoaderData} from '~/root';

type LayoutProps = {
children: React.ReactNode;
Expand Down Expand Up @@ -107,13 +108,13 @@ function Header({title, menu}: {title: string; menu?: EnhancedMenu}) {
}

function CartDrawer({isOpen, onClose}: {isOpen: boolean; onClose: () => void}) {
const [root] = useMatches();
const rootData = useRootLoaderData();

return (
<Drawer open={isOpen} onClose={onClose} heading="Cart" openFrom="right">
<div className="grid">
<Suspense fallback={<CartLoading />}>
<Await resolve={root.data?.cart}>
<Await resolve={rootData?.cart}>
{(cart) => <Cart layout="drawer" onClose={onClose} cart={cart} />}
</Await>
</Suspense>
Expand Down Expand Up @@ -295,8 +296,8 @@ function DesktopHeader({
}

function AccountLink({className}: {className?: string}) {
const [root] = useMatches();
const isLoggedIn = root.data?.isLoggedIn;
const rootData = useRootLoaderData();
const isLoggedIn = rootData?.isLoggedIn;
return isLoggedIn ? (
<Link to="/account" className={className}>
<IconAccount />
Expand All @@ -315,11 +316,11 @@ function CartCount({
isHome: boolean;
openCart: () => void;
}) {
const [root] = useMatches();
const rootData = useRootLoaderData();

return (
<Suspense fallback={<Badge count={0} dark={isHome} openCart={openCart} />}>
<Await resolve={root.data?.cart}>
<Await resolve={rootData?.cart}>
{(cart) => (
<Badge
dark={isHome}
Expand Down
6 changes: 3 additions & 3 deletions app/components/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
NavLink as RemixNavLink,
type NavLinkProps as RemixNavLinkProps,
type LinkProps as RemixLinkProps,
useMatches,
} from '@remix-run/react';
import {useRootLoaderData} from '~/root';

type LinkProps = Omit<RemixLinkProps, 'className'> & {
className?: RemixNavLinkProps['className'] | RemixLinkProps['className'];
Expand All @@ -27,8 +27,8 @@ type LinkProps = Omit<RemixLinkProps, 'className'> & {
*/
export function Link(props: LinkProps) {
const {to, className, ...resOfProps} = props;
const [root] = useMatches();
const selectedLocale = root.data?.selectedLocale;
const rootData = useRootLoaderData();
const selectedLocale = rootData?.selectedLocale;

let toWithLocale = to;

Expand Down
5 changes: 2 additions & 3 deletions app/data/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export let HOMEPAGE_SEO_QUERY = `#graphql
${COLLECTION_CONTENT_FRAGMENT}
` as const;

// @see: https://shopify.dev/api/storefront/2023-04/queries/products
// @see: https://shopify.dev/api/storefront/current/queries/products
export let HOMEPAGE_FEATURED_PRODUCTS_QUERY = `#graphql
query homepageFeaturedProducts($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
Expand All @@ -42,7 +42,7 @@ export let HOMEPAGE_FEATURED_PRODUCTS_QUERY = `#graphql
${PRODUCT_CARD_FRAGMENT}
`;

// @see: https://shopify.dev/api/storefront/2023-04/queries/collections
// @see: https://shopify.dev/api/storefront/current/queries/collections
export let FEATURED_COLLECTIONS_QUERY = `#graphql
query homepageFeaturedCollections($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
Expand Down Expand Up @@ -235,7 +235,6 @@ export let COLLECTION_QUERY = `#graphql
pageInfo {
hasPreviousPage
hasNextPage
hasNextPage
endCursor
startCursor
}
Expand Down
5 changes: 2 additions & 3 deletions app/hooks/useCartFetchers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ export function useCartFetchers(actionName: string) {
const cartFetchers = [];

for (const fetcher of fetchers) {
const formData = fetcher.submission?.formData;
if (formData) {
const formInputs = CartForm.getFormInput(formData);
if (fetcher.formData) {
const formInputs = CartForm.getFormInput(fetcher.formData);
if (formInputs.action === actionName) {
cartFetchers.push(fetcher);
}
Expand Down
6 changes: 4 additions & 2 deletions app/hooks/usePageAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export function usePageAnalytics({hasUserConsent}: {hasUserConsent: boolean}) {
const data: Record<string, unknown> = {};

matches.forEach((event) => {
const eventData = event?.data;
const eventData = event?.data as Record<string, unknown>;
if (eventData) {
eventData['analytics'] && Object.assign(data, eventData['analytics']);

const selectedLocale = eventData['selectedLocale'] || DEFAULT_LOCALE;
const selectedLocale =
(eventData['selectedLocale'] as typeof DEFAULT_LOCALE) ||
DEFAULT_LOCALE;
Object.assign(data, {
currency: selectedLocale.currency,
acceptedLanguage: selectedLocale.language,
Expand Down
9 changes: 5 additions & 4 deletions app/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
ParentMenuItemFragment,
} from 'storefrontapi.generated';
import {countries} from '~/data/countries';
import {useRootLoaderData} from '~/root';

import type {I18nLocale} from './type';

Expand Down Expand Up @@ -296,8 +297,8 @@ export function getLocaleFromRequest(request: Request): I18nLocale {
}

export function usePrefixPathWithLocale(path: string) {
const [root] = useMatches();
const selectedLocale = root.data?.selectedLocale ?? DEFAULT_LOCALE;
const rootData = useRootLoaderData();
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;

return `${selectedLocale.pathPrefix}${
path.startsWith('/') ? path : '/' + path
Expand All @@ -306,8 +307,8 @@ export function usePrefixPathWithLocale(path: string) {

export function useIsHomePath() {
const {pathname} = useLocation();
const [root] = useMatches();
const selectedLocale = root.data?.selectedLocale ?? DEFAULT_LOCALE;
const rootData = useRootLoaderData();
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const strippedPathname = pathname.replace(selectedLocale.pathPrefix, '');
return strippedPathname === '/';
}
Expand Down
17 changes: 11 additions & 6 deletions app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
defer,
type LinksFunction,
type LoaderArgs,
type LoaderFunctionArgs,
type AppLoadContext,
type SerializeFrom,
} from '@shopify/remix-oxygen';
import {
isRouteErrorResponse,
Expand Down Expand Up @@ -67,7 +67,12 @@ export const links: LinksFunction = () => {
];
};

export async function loader({request, context}: LoaderArgs) {
export const useRootLoaderData = () => {
const [root] = useMatches();
return root?.data as SerializeFrom<typeof loader>;
};

export async function loader({request, context}: LoaderFunctionArgs) {
const {session, storefront, cart} = context;
const [customerAccessToken, layout] = await Promise.all([
session.get('customerAccessToken'),
Expand Down Expand Up @@ -127,9 +132,9 @@ export default withWeaverse(App);

const ErrorBoundaryComponent = ({error}: {error: Error}) => {
const nonce = useNonce();
const [root] = useMatches();
const locale = root?.data?.selectedLocale ?? DEFAULT_LOCALE;
const routeError = useRouteError();
const rootData = useRootLoaderData();
const locale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const isRouteError = isRouteErrorResponse(routeError);

let title = 'Error';
Expand All @@ -151,7 +156,7 @@ const ErrorBoundaryComponent = ({error}: {error: Error}) => {
</head>
<body>
<Layout
layout={root?.data?.layout}
layout={rootData?.layout}
key={`${locale.language}-${locale.country}`}
>
{isRouteError ? (
Expand Down
4 changes: 2 additions & 2 deletions app/routes/($locale).$shopid.orders.$token.authenticate.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import invariant from 'tiny-invariant';

import {Button, PageHeader} from '~/components';
Expand All @@ -10,7 +10,7 @@ import {Button, PageHeader} from '~/components';
that are routing to your Hydrogen storefront. To prevent this, ensure that you redirect
those requests back to Shopify.
*/
export async function loader({request, context: {storefront}}: LoaderArgs) {
export async function loader({request, context: {storefront}}: LoaderFunctionArgs) {
const {origin} = new URL(request.url);
const {shop} = await storefront.query(
`#graphql
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {json, redirect, type ActionFunction} from '@shopify/remix-oxygen';
import {Form, useActionData, type V2_MetaFunction} from '@remix-run/react';
import {Form, useActionData, type MetaFunction} from '@remix-run/react';
import {useRef, useState} from 'react';

import {getInputStyleClasses} from '~/lib/utils';
Expand Down Expand Up @@ -93,7 +93,7 @@ export const action: ActionFunction = async ({
}
};

export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{title: 'Activate Account'}];
};

Expand Down
8 changes: 4 additions & 4 deletions app/routes/($locale).account.login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import {
redirect,
type ActionFunction,
type AppLoadContext,
type LoaderArgs,
type LoaderFunctionArgs,
} from '@shopify/remix-oxygen';
import {
Form,
useActionData,
useLoaderData,
type V2_MetaFunction,
type MetaFunction,
} from '@remix-run/react';
import {MouseEvent, useState} from 'react';

Expand All @@ -20,7 +20,7 @@ export const handle = {
isPublic: true,
};

export async function loader({context, params}: LoaderArgs) {
export async function loader({context, params}: LoaderFunctionArgs) {
const customerAccessToken = await context.session.get('customerAccessToken');

if (customerAccessToken) {
Expand Down Expand Up @@ -89,7 +89,7 @@ export const action: ActionFunction = async ({request, context, params}) => {
}
};

export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{title: 'Login'}];
};

Expand Down
8 changes: 4 additions & 4 deletions app/routes/($locale).account.logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {
redirect,
type ActionFunction,
type AppLoadContext,
type LoaderArgs,
type ActionArgs,
type LoaderFunctionArgs,
type ActionFunctionArgs,
} from '@shopify/remix-oxygen';

export async function doLogout(context: AppLoadContext) {
Expand All @@ -18,10 +18,10 @@ export async function doLogout(context: AppLoadContext) {
});
}

export async function loader({context}: LoaderArgs) {
export async function loader({context}: LoaderFunctionArgs) {
return redirect(context.storefront.i18n.pathPrefix);
}

export const action: ActionFunction = async ({context}: ActionArgs) => {
export const action: ActionFunction = async ({context}: ActionFunctionArgs) => {
return doLogout(context);
};
8 changes: 4 additions & 4 deletions app/routes/($locale).account.orders.$id.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import invariant from 'tiny-invariant';
import clsx from 'clsx';
import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {useLoaderData, type MetaFunction} from '@remix-run/react';
import {Money, Image, flattenConnection} from '@shopify/hydrogen';

import {statusMessage} from '~/lib/utils';
import {Link, Heading, PageHeader, Text} from '~/components';

export const meta: V2_MetaFunction<typeof loader> = ({data}) => {
export const meta: MetaFunction<typeof loader> = ({data}) => {
return [{title: `Order ${data?.order?.name}`}];
};

export async function loader({request, context, params}: LoaderArgs) {
export async function loader({request, context, params}: LoaderFunctionArgs) {
if (!params.id) {
return redirect(params?.locale ? `${params.locale}/account` : '/account');
}
Expand Down
Loading

0 comments on commit dc2ad3e

Please sign in to comment.