mirror of
https://github.com/vercel/commerce.git
synced 2025-06-19 05:31:22 +00:00
Add translations, update operations & fixes
This commit is contained in:
parent
61db441df4
commit
9a126164b4
@ -5,7 +5,7 @@ import Link from 'next/link'
|
|||||||
import s from './CartItem.module.css'
|
import s from './CartItem.module.css'
|
||||||
import { Trash, Plus, Minus } from '@components/icons'
|
import { Trash, Plus, Minus } from '@components/icons'
|
||||||
import { useUI } from '@components/ui/context'
|
import { useUI } from '@components/ui/context'
|
||||||
import type { LineItem } from '@framework/types'
|
import type { LineItem } from '@framework/types/cart'
|
||||||
import usePrice from '@framework/product/use-price'
|
import usePrice from '@framework/product/use-price'
|
||||||
import useUpdateItem from '@framework/cart/use-update-item'
|
import useUpdateItem from '@framework/cart/use-update-item'
|
||||||
import useRemoveItem from '@framework/cart/use-remove-item'
|
import useRemoveItem from '@framework/cart/use-remove-item'
|
||||||
|
@ -2,7 +2,7 @@ import { FC } from 'react'
|
|||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import type { Page } from '@framework/common/get-all-pages'
|
import type { Page } from '@framework/types/page'
|
||||||
import getSlug from '@lib/get-slug'
|
import getSlug from '@lib/get-slug'
|
||||||
import { Github, Vercel } from '@components/icons'
|
import { Github, Vercel } from '@components/icons'
|
||||||
import { Logo, Container } from '@components/ui'
|
import { Logo, Container } from '@components/ui'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
import { Grid } from '@components/ui'
|
import { Grid } from '@components/ui'
|
||||||
import { ProductCard } from '@components/product'
|
import { ProductCard } from '@components/product'
|
||||||
import s from './HomeAllProductsGrid.module.css'
|
import s from './HomeAllProductsGrid.module.css'
|
||||||
|
@ -11,7 +11,7 @@ import CartSidebarView from '@components/cart/CartSidebarView'
|
|||||||
|
|
||||||
import LoginView from '@components/auth/LoginView'
|
import LoginView from '@components/auth/LoginView'
|
||||||
import { CommerceProvider } from '@framework'
|
import { CommerceProvider } from '@framework'
|
||||||
import type { Page } from '@framework/common/get-all-pages'
|
import type { Page } from '@framework/types/page'
|
||||||
|
|
||||||
const Loading = () => (
|
const Loading = () => (
|
||||||
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
|
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import type { LineItem } from '@framework/types'
|
import type { LineItem } from '@framework/types/cart'
|
||||||
import useCart from '@framework/cart/use-cart'
|
import useCart from '@framework/cart/use-cart'
|
||||||
import useCustomer from '@framework/customer/use-customer'
|
import useCustomer from '@framework/customer/use-customer'
|
||||||
import { Avatar } from '@components/common'
|
import { Avatar } from '@components/common'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
import s from './ProductCard.module.css'
|
import s from './ProductCard.module.css'
|
||||||
import Image, { ImageProps } from 'next/image'
|
import Image, { ImageProps } from 'next/image'
|
||||||
import WishlistButton from '@components/wishlist/WishlistButton'
|
import WishlistButton from '@components/wishlist/WishlistButton'
|
||||||
|
@ -5,7 +5,7 @@ import { FC, useEffect, useState } from 'react'
|
|||||||
import s from './ProductView.module.css'
|
import s from './ProductView.module.css'
|
||||||
import { Swatch, ProductSlider } from '@components/product'
|
import { Swatch, ProductSlider } from '@components/product'
|
||||||
import { Button, Container, Text, useUI } from '@components/ui'
|
import { Button, Container, Text, useUI } from '@components/ui'
|
||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
import usePrice from '@framework/product/use-price'
|
import usePrice from '@framework/product/use-price'
|
||||||
import { useAddItem } from '@framework/cart'
|
import { useAddItem } from '@framework/cart'
|
||||||
import { getVariant, SelectedOptions } from '../helpers'
|
import { getVariant, SelectedOptions } from '../helpers'
|
||||||
|
@ -47,7 +47,7 @@ const Swatch: FC<Omit<ButtonProps, 'variant'> & Props> = ({
|
|||||||
<Check />
|
<Check />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{variant === 'size' ? label : null}
|
{variant !== 'color' ? label : null}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
export type SelectedOptions = Record<string, string | null>
|
export type SelectedOptions = Record<string, string | null>
|
||||||
|
|
||||||
export function getVariant(product: Product, opts: SelectedOptions) {
|
export function getVariant(product: Product, opts: SelectedOptions) {
|
||||||
|
@ -6,7 +6,7 @@ import useAddItem from '@framework/wishlist/use-add-item'
|
|||||||
import useCustomer from '@framework/customer/use-customer'
|
import useCustomer from '@framework/customer/use-customer'
|
||||||
import useWishlist from '@framework/wishlist/use-wishlist'
|
import useWishlist from '@framework/wishlist/use-wishlist'
|
||||||
import useRemoveItem from '@framework/wishlist/use-remove-item'
|
import useRemoveItem from '@framework/wishlist/use-remove-item'
|
||||||
import type { Product, ProductVariant } from '@commerce/types'
|
import type { Product, ProductVariant } from '@framework/types/product'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
productId: Product['id']
|
productId: Product['id']
|
||||||
|
@ -7,7 +7,7 @@ import { Trash } from '@components/icons'
|
|||||||
import { Button, Text } from '@components/ui'
|
import { Button, Text } from '@components/ui'
|
||||||
|
|
||||||
import { useUI } from '@components/ui/context'
|
import { useUI } from '@components/ui/context'
|
||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
import usePrice from '@framework/product/use-price'
|
import usePrice from '@framework/product/use-price'
|
||||||
import useAddItem from '@framework/cart/use-add-item'
|
import useAddItem from '@framework/cart/use-add-item'
|
||||||
import useRemoveItem from '@framework/wishlist/use-remove-item'
|
import useRemoveItem from '@framework/wishlist/use-remove-item'
|
||||||
@ -18,9 +18,9 @@ interface Props {
|
|||||||
|
|
||||||
const WishlistCard: FC<Props> = ({ product }) => {
|
const WishlistCard: FC<Props> = ({ product }) => {
|
||||||
const { price } = usePrice({
|
const { price } = usePrice({
|
||||||
amount: product.prices?.price?.value,
|
amount: product.price?.value,
|
||||||
baseAmount: product.prices?.retailPrice?.value,
|
baseAmount: product.price?.retailPrice,
|
||||||
currencyCode: product.prices?.price?.currencyCode!,
|
currencyCode: product.price?.currencyCode!,
|
||||||
})
|
})
|
||||||
// @ts-ignore Wishlist is not always enabled
|
// @ts-ignore Wishlist is not always enabled
|
||||||
const removeItem = useRemoveItem({ wishlist: { includeProducts: true } })
|
const removeItem = useRemoveItem({ wishlist: { includeProducts: true } })
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { normalizeCart } from '@framework/lib/normalize'
|
import { normalizeCart } from '../../../lib/normalize'
|
||||||
import { parseCartItem } from '../../utils/parse-item'
|
import { parseCartItem } from '../../utils/parse-item'
|
||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getCartCookie from '../../utils/get-cart-cookie'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { normalizeCart } from '@framework/lib/normalize'
|
import { normalizeCart } from '../../../lib/normalize'
|
||||||
import { BigcommerceApiError } from '../../utils/errors'
|
import { BigcommerceApiError } from '../../utils/errors'
|
||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getCartCookie from '../../utils/get-cart-cookie'
|
||||||
import type { BigcommerceCart } from '../../../types'
|
import type { BigcommerceCart } from '../../../types/cart'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
|
||||||
// Return current cart info
|
// Return current cart info
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { normalizeCart } from '@framework/lib/normalize'
|
import { normalizeCart } from '../../../lib/normalize'
|
||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getCartCookie from '../../utils/get-cart-cookie'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { normalizeCart } from '@framework/lib/normalize'
|
import { normalizeCart } from '../../../lib/normalize'
|
||||||
import { parseCartItem } from '../../utils/parse-item'
|
import { parseCartItem } from '../../utils/parse-item'
|
||||||
import getCartCookie from '../../utils/get-cart-cookie'
|
import getCartCookie from '../../utils/get-cart-cookie'
|
||||||
import type { CartEndpoint } from '.'
|
import type { CartEndpoint } from '.'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { ItemBody as WishlistItemBody } from '../wishlist'
|
import type { WishlistItemBody } from '../../types/wishlist'
|
||||||
import type { CartItemBody, OptionSelections } from '../../types'
|
import type { CartItemBody, OptionSelections } from '../../types/cart'
|
||||||
|
|
||||||
type BCWishlistItemBody = {
|
type BCWishlistItemBody = {
|
||||||
product_id: number
|
product_id: number
|
||||||
|
@ -6,7 +6,7 @@ import type {
|
|||||||
} from '@commerce/utils/types'
|
} from '@commerce/utils/types'
|
||||||
import { ValidationError } from '@commerce/utils/errors'
|
import { ValidationError } from '@commerce/utils/errors'
|
||||||
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
||||||
import type { LineItem, UpdateItemHook } from '../types'
|
import type { LineItem, UpdateItemHook } from '../types/cart'
|
||||||
import { handler as removeItemHandler } from './use-remove-item'
|
import { handler as removeItemHandler } from './use-remove-item'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { Product } from '@commerce/types'
|
import type { Product } from '../types/product'
|
||||||
import type { Cart, BigcommerceCart, LineItem } from '../types'
|
import type { Cart, BigcommerceCart, LineItem } from '../types/cart'
|
||||||
import update from './immutability'
|
import update from './immutability'
|
||||||
|
|
||||||
function normalizeProductOption(productOption: any) {
|
function normalizeProductOption(productOption: any) {
|
||||||
|
@ -9,6 +9,7 @@ export type SearchProductsInput = {
|
|||||||
categoryId?: number
|
categoryId?: number
|
||||||
brandId?: number
|
brandId?: number
|
||||||
sort?: string
|
sort?: string
|
||||||
|
locale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handler: SWRHook<SearchProductsHook> = {
|
export const handler: SWRHook<SearchProductsHook> = {
|
||||||
|
@ -148,6 +148,7 @@ export const createEndpoint = <API extends GetAPISchema<any, any>>(
|
|||||||
|
|
||||||
export interface CommerceAPIConfig {
|
export interface CommerceAPIConfig {
|
||||||
locale?: string
|
locale?: string
|
||||||
|
locales?: string[]
|
||||||
commerceUrl: string
|
commerceUrl: string
|
||||||
apiToken: string
|
apiToken: string
|
||||||
cartCookie: string
|
cartCookie: string
|
||||||
|
@ -6,35 +6,53 @@ import {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
AddItemHook,
|
||||||
|
GetCartHook,
|
||||||
|
RemoveItemHook,
|
||||||
|
UpdateItemHook,
|
||||||
|
} from '@framework/types/cart'
|
||||||
|
|
||||||
|
import {
|
||||||
|
AddItemHook as WishlistAddItemHook,
|
||||||
|
GetWishlistHook,
|
||||||
|
RemoveItemHook as WishlistRemoveItemHook,
|
||||||
|
} from '@framework/types/wishlist'
|
||||||
|
|
||||||
|
import { CustomerHook } from '@framework/types/customer'
|
||||||
|
import { LoginHook } from '@framework/types/login'
|
||||||
|
import { LogoutHook } from '@framework/types/logout'
|
||||||
|
import { SearchProductsHook } from '@framework/types/product'
|
||||||
|
import { SignupHook } from '@framework/types/signup'
|
||||||
|
|
||||||
import { Fetcher, SWRHook, MutationHook } from './utils/types'
|
import { Fetcher, SWRHook, MutationHook } from './utils/types'
|
||||||
import type { FetchCartInput } from './cart/use-cart'
|
|
||||||
import type { Cart, Wishlist, Customer, SearchProductsData } from './types'
|
|
||||||
|
|
||||||
const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
||||||
|
|
||||||
export type Provider = CommerceConfig & {
|
export type Provider = CommerceConfig & {
|
||||||
fetcher: Fetcher
|
fetcher: Fetcher
|
||||||
cart?: {
|
cart?: {
|
||||||
useCart?: SWRHook<Cart | null, any, FetchCartInput>
|
useCart?: SWRHook<GetCartHook>
|
||||||
useAddItem?: MutationHook<any, any, any>
|
useAddItem?: MutationHook<AddItemHook>
|
||||||
useUpdateItem?: MutationHook<any, any, any>
|
useUpdateItem?: MutationHook<UpdateItemHook>
|
||||||
useRemoveItem?: MutationHook<any, any, any>
|
useRemoveItem?: MutationHook<RemoveItemHook>
|
||||||
}
|
}
|
||||||
wishlist?: {
|
wishlist?: {
|
||||||
useWishlist?: SWRHook<Wishlist | null, any, any>
|
useWishlist?: SWRHook<GetWishlistHook>
|
||||||
useAddItem?: MutationHook<any, any, any>
|
useAddItem?: MutationHook<WishlistAddItemHook>
|
||||||
useRemoveItem?: MutationHook<any, any, any>
|
useRemoveItem?: MutationHook<WishlistRemoveItemHook>
|
||||||
}
|
}
|
||||||
customer?: {
|
customer?: {
|
||||||
useCustomer?: SWRHook<Customer | null, any, any>
|
useCustomer?: SWRHook<CustomerHook>
|
||||||
}
|
}
|
||||||
products?: {
|
products?: {
|
||||||
useSearch?: SWRHook<SearchProductsData, any, any>
|
useSearch?: SWRHook<SearchProductsHook>
|
||||||
}
|
}
|
||||||
auth?: {
|
auth?: {
|
||||||
useSignup?: MutationHook<any, any, any>
|
useSignup?: MutationHook<SignupHook>
|
||||||
useLogin?: MutationHook<any, any, any>
|
useLogin?: MutationHook<LoginHook>
|
||||||
useLogout?: MutationHook<any, any, any>
|
useLogout?: MutationHook<LogoutHook>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ export type ProductPrice = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ProductOption = {
|
export type ProductOption = {
|
||||||
|
__typename: 'MultipleChoiceOption'
|
||||||
|
id: string
|
||||||
displayName: string
|
displayName: string
|
||||||
values: ProductOptionValues[]
|
values: ProductOptionValues[]
|
||||||
}
|
}
|
||||||
@ -47,6 +49,7 @@ export type SearchProductsBody = {
|
|||||||
categoryId?: string
|
categoryId?: string
|
||||||
brandId?: string
|
brandId?: string
|
||||||
sort?: string
|
sort?: string
|
||||||
|
locale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductTypes = {
|
export type ProductTypes = {
|
||||||
|
@ -4,7 +4,12 @@ import {
|
|||||||
getCommerceApi as commerceApi,
|
getCommerceApi as commerceApi,
|
||||||
} from '@commerce/api'
|
} from '@commerce/api'
|
||||||
|
|
||||||
import { API_URL, API_TOKEN, SHOPIFY_CUSTOMER_TOKEN_COOKIE } from '../const'
|
import {
|
||||||
|
API_URL,
|
||||||
|
API_TOKEN,
|
||||||
|
SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||||
|
SHOPIFY_CHECKOUT_ID_COOKIE,
|
||||||
|
} from '../const'
|
||||||
|
|
||||||
import fetchGraphqlApi from './utils/fetch-graphql-api'
|
import fetchGraphqlApi from './utils/fetch-graphql-api'
|
||||||
|
|
||||||
@ -29,7 +34,7 @@ const config: ShopifyConfig = {
|
|||||||
commerceUrl: API_URL,
|
commerceUrl: API_URL,
|
||||||
apiToken: API_TOKEN,
|
apiToken: API_TOKEN,
|
||||||
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
customerCookie: SHOPIFY_CUSTOMER_TOKEN_COOKIE,
|
||||||
cartCookie: process.env.SHOPIFY_CART_COOKIE ?? 'shopify_checkoutId',
|
cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
|
||||||
cartCookieMaxAge: ONE_DAY * 30,
|
cartCookieMaxAge: ONE_DAY * 30,
|
||||||
fetch: fetchGraphqlApi,
|
fetch: fetchGraphqlApi,
|
||||||
}
|
}
|
||||||
@ -46,6 +51,5 @@ export type ShopifyAPI<P extends Provider = Provider> = CommerceAPI<P>
|
|||||||
export function getCommerceApi<P extends Provider>(
|
export function getCommerceApi<P extends Provider>(
|
||||||
customProvider: P = provider as any
|
customProvider: P = provider as any
|
||||||
): ShopifyAPI<P> {
|
): ShopifyAPI<P> {
|
||||||
console.log(customProvider)
|
|
||||||
return commerceApi(customProvider)
|
return commerceApi(customProvider)
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,14 @@ import type {
|
|||||||
OperationContext,
|
OperationContext,
|
||||||
OperationOptions,
|
OperationOptions,
|
||||||
} from '@commerce/api/operations'
|
} from '@commerce/api/operations'
|
||||||
import { GetAllPagesQuery, GetAllPagesQueryVariables } from '@framework/schema'
|
import {
|
||||||
|
GetAllPagesQuery,
|
||||||
|
GetAllPagesQueryVariables,
|
||||||
|
PageEdge,
|
||||||
|
} from '@framework/schema'
|
||||||
|
import { normalizePages } from '@framework/utils'
|
||||||
import type { ShopifyConfig, Provider } from '..'
|
import type { ShopifyConfig, Provider } from '..'
|
||||||
import { GetAllPagesOperation } from '../../types/page'
|
import type { GetAllPagesOperation, Page } from '../../types/page'
|
||||||
import getAllPagesQuery from '../../utils/queries/get-all-pages-query'
|
import getAllPagesQuery from '../../utils/queries/get-all-pages-query'
|
||||||
|
|
||||||
export default function getAllPagesOperation({
|
export default function getAllPagesOperation({
|
||||||
@ -25,21 +30,36 @@ export default function getAllPagesOperation({
|
|||||||
async function getAllPages<T extends GetAllPagesOperation>({
|
async function getAllPages<T extends GetAllPagesOperation>({
|
||||||
query = getAllPagesQuery,
|
query = getAllPagesQuery,
|
||||||
config,
|
config,
|
||||||
|
variables,
|
||||||
}: {
|
}: {
|
||||||
url?: string
|
url?: string
|
||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<ShopifyConfig>
|
||||||
|
variables?: GetAllPagesQueryVariables
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
query?: string
|
query?: string
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
const cfg = commerce.getConfig(config)
|
const { fetch, locale, locales = ['en-US'] } = commerce.getConfig(config)
|
||||||
|
|
||||||
const { data } = await cfg.fetch<
|
const { data } = await fetch<GetAllPagesQuery, GetAllPagesQueryVariables>(
|
||||||
GetAllPagesQuery,
|
query,
|
||||||
GetAllPagesQueryVariables
|
{
|
||||||
>(query)
|
variables,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pages: data.pages.edges,
|
pages: locales.reduce<Page[]>(
|
||||||
|
(arr, locale) =>
|
||||||
|
arr.concat(normalizePages(data.pages.edges as PageEdge[], locale)),
|
||||||
|
[]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +39,22 @@ export default function getAllProductsOperation({
|
|||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<ShopifyConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
const cfg = commerce.getConfig(config)
|
const { fetch, locale } = commerce.getConfig(config)
|
||||||
|
|
||||||
const { data } = await cfg.fetch<
|
const { data } = await fetch<
|
||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
GetAllProductsQueryVariables
|
GetAllProductsQueryVariables
|
||||||
>(query, { variables })
|
>(
|
||||||
|
query,
|
||||||
|
{ variables },
|
||||||
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
products: data.products.edges.map(({ node }) =>
|
products: data.products.edges.map(({ node }) =>
|
||||||
|
@ -35,11 +35,23 @@ export default function getPageOperation({
|
|||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<ShopifyConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
}): Promise<T['data']> {
|
}): Promise<T['data']> {
|
||||||
const cfg = commerce.getConfig(config)
|
const { fetch, locale } = commerce.getConfig(config)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: { node: page },
|
data: { node: page },
|
||||||
} = await cfg.fetch<GetPageQuery, GetPageQueryVariables>(query)
|
} = await fetch<GetPageQuery, GetPageQueryVariables>(
|
||||||
|
query,
|
||||||
|
{
|
||||||
|
variables,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return page ? { page } : {}
|
return page ? { page } : {}
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,23 @@ export default function getProductOperation({
|
|||||||
config?: ShopifyConfig
|
config?: ShopifyConfig
|
||||||
variables?: GetProductBySlugQueryVariables
|
variables?: GetProductBySlugQueryVariables
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
config = commerce.getConfig(config)
|
const { fetch, locale } = commerce.getConfig(config)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: { productByHandle },
|
data: { productByHandle },
|
||||||
} = await config.fetch<GetProductBySlugQuery>(query, {
|
} = await fetch<GetProductBySlugQuery>(
|
||||||
variables,
|
query,
|
||||||
})
|
{
|
||||||
|
variables,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...(productByHandle && {
|
...(productByHandle && {
|
||||||
|
@ -26,20 +26,31 @@ export default function getSiteInfoOperation({
|
|||||||
async function getSiteInfo<T extends GetSiteInfoOperation>({
|
async function getSiteInfo<T extends GetSiteInfoOperation>({
|
||||||
query = getSiteInfoQuery,
|
query = getSiteInfoQuery,
|
||||||
config,
|
config,
|
||||||
|
variables,
|
||||||
}: {
|
}: {
|
||||||
query?: string
|
query?: string
|
||||||
config?: Partial<ShopifyConfig>
|
config?: Partial<ShopifyConfig>
|
||||||
preview?: boolean
|
preview?: boolean
|
||||||
|
variables?: GetSiteInfoQueryVariables
|
||||||
} = {}): Promise<T['data']> {
|
} = {}): Promise<T['data']> {
|
||||||
const cfg = commerce.getConfig(config)
|
const cfg = commerce.getConfig(config)
|
||||||
|
|
||||||
const categories = await getCategories(cfg)
|
const categories = await getCategories(cfg)
|
||||||
const brands = await getBrands(cfg)
|
const brands = await getBrands(cfg)
|
||||||
|
/*
|
||||||
const { data } = await cfg.fetch<
|
const { fetch, locale } = cfg
|
||||||
GetSiteInfoQuery,
|
const { data } = await fetch<GetSiteInfoQuery, GetSiteInfoQueryVariables>(
|
||||||
GetSiteInfoQueryVariables
|
query,
|
||||||
>(query)
|
{ variables },
|
||||||
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
return {
|
return {
|
||||||
categories,
|
categories,
|
||||||
|
@ -2,18 +2,19 @@ import { useCallback } from 'react'
|
|||||||
import type { MutationHook } from '@commerce/utils/types'
|
import type { MutationHook } from '@commerce/utils/types'
|
||||||
import { CommerceError } from '@commerce/utils/errors'
|
import { CommerceError } from '@commerce/utils/errors'
|
||||||
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
||||||
|
import type { AddItemHook } from '../types/cart'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
checkoutLineItemAddMutation,
|
checkoutLineItemAddMutation,
|
||||||
getCheckoutId,
|
getCheckoutId,
|
||||||
checkoutToCart,
|
checkoutToCart,
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { Cart, CartItemBody } from '../types'
|
|
||||||
import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema'
|
import { Mutation, MutationCheckoutLineItemsAddArgs } from '../schema'
|
||||||
|
|
||||||
export default useAddItem as UseAddItem<typeof handler>
|
export default useAddItem as UseAddItem<typeof handler>
|
||||||
|
|
||||||
export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
export const handler: MutationHook<AddItemHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: checkoutLineItemAddMutation,
|
query: checkoutLineItemAddMutation,
|
||||||
},
|
},
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import useCommerceCart, {
|
import useCommerceCart, { UseCart } from '@commerce/cart/use-cart'
|
||||||
FetchCartInput,
|
|
||||||
UseCart,
|
|
||||||
} from '@commerce/cart/use-cart'
|
|
||||||
|
|
||||||
import { Cart } from '../types'
|
|
||||||
import { SWRHook } from '@commerce/utils/types'
|
import { SWRHook } from '@commerce/utils/types'
|
||||||
import { checkoutCreate, checkoutToCart } from '../utils'
|
import { checkoutCreate, checkoutToCart } from '../utils'
|
||||||
import getCheckoutQuery from '../utils/queries/get-checkout-query'
|
import getCheckoutQuery from '../utils/queries/get-checkout-query'
|
||||||
|
import { GetCartHook } from '../types/cart'
|
||||||
|
|
||||||
export default useCommerceCart as UseCart<typeof handler>
|
export default useCommerceCart as UseCart<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<
|
export const handler: SWRHook<GetCartHook> = {
|
||||||
Cart | null,
|
|
||||||
{},
|
|
||||||
FetchCartInput,
|
|
||||||
{ isEmpty?: boolean }
|
|
||||||
> = {
|
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: getCheckoutQuery,
|
query: getCheckoutQuery,
|
||||||
},
|
},
|
||||||
|
@ -3,31 +3,29 @@ import type {
|
|||||||
MutationHookContext,
|
MutationHookContext,
|
||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
} from '@commerce/utils/types'
|
} from '@commerce/utils/types'
|
||||||
import { RemoveCartItemBody } from '@commerce/types'
|
|
||||||
import { ValidationError } from '@commerce/utils/errors'
|
import { ValidationError } from '@commerce/utils/errors'
|
||||||
import useRemoveItem, {
|
import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
|
||||||
RemoveItemInput as RemoveItemInputBase,
|
import type { Cart, LineItem, RemoveItemHook } from '../types/cart'
|
||||||
UseRemoveItem,
|
|
||||||
} from '@commerce/cart/use-remove-item'
|
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
|
|
||||||
|
export type RemoveItemFn<T = any> = T extends LineItem
|
||||||
|
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null>
|
||||||
|
: (input: RemoveItemActionInput<T>) => Promise<Cart | null>
|
||||||
|
|
||||||
|
export type RemoveItemActionInput<T = any> = T extends LineItem
|
||||||
|
? Partial<RemoveItemHook['actionInput']>
|
||||||
|
: RemoveItemHook['actionInput']
|
||||||
|
|
||||||
|
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||||
|
|
||||||
import {
|
import {
|
||||||
checkoutLineItemRemoveMutation,
|
checkoutLineItemRemoveMutation,
|
||||||
getCheckoutId,
|
getCheckoutId,
|
||||||
checkoutToCart,
|
checkoutToCart,
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { Cart, LineItem } from '../types'
|
|
||||||
import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema'
|
import { Mutation, MutationCheckoutLineItemsRemoveArgs } from '../schema'
|
||||||
|
|
||||||
export type RemoveItemFn<T = any> = T extends LineItem
|
|
||||||
? (input?: RemoveItemInput<T>) => Promise<Cart | null>
|
|
||||||
: (input: RemoveItemInput<T>) => Promise<Cart | null>
|
|
||||||
|
|
||||||
export type RemoveItemInput<T = any> = T extends LineItem
|
|
||||||
? Partial<RemoveItemInputBase>
|
|
||||||
: RemoveItemInputBase
|
|
||||||
|
|
||||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
|
||||||
|
|
||||||
export const handler = {
|
export const handler = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: checkoutLineItemRemoveMutation,
|
query: checkoutLineItemRemoveMutation,
|
||||||
@ -36,16 +34,14 @@ export const handler = {
|
|||||||
input: { itemId },
|
input: { itemId },
|
||||||
options,
|
options,
|
||||||
fetch,
|
fetch,
|
||||||
}: HookFetcherContext<RemoveCartItemBody>) {
|
}: HookFetcherContext<RemoveItemHook>) {
|
||||||
const data = await fetch<Mutation, MutationCheckoutLineItemsRemoveArgs>({
|
const data = await fetch<Mutation, MutationCheckoutLineItemsRemoveArgs>({
|
||||||
...options,
|
...options,
|
||||||
variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] },
|
variables: { checkoutId: getCheckoutId(), lineItemIds: [itemId] },
|
||||||
})
|
})
|
||||||
return checkoutToCart(data.checkoutLineItemsRemove)
|
return checkoutToCart(data.checkoutLineItemsRemove)
|
||||||
},
|
},
|
||||||
useHook: ({
|
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) => <
|
||||||
fetch,
|
|
||||||
}: MutationHookContext<Cart | null, RemoveCartItemBody>) => <
|
|
||||||
T extends LineItem | undefined = undefined
|
T extends LineItem | undefined = undefined
|
||||||
>(
|
>(
|
||||||
ctx: { item?: T } = {}
|
ctx: { item?: T } = {}
|
||||||
|
@ -5,21 +5,21 @@ import type {
|
|||||||
MutationHookContext,
|
MutationHookContext,
|
||||||
} from '@commerce/utils/types'
|
} from '@commerce/utils/types'
|
||||||
import { ValidationError } from '@commerce/utils/errors'
|
import { ValidationError } from '@commerce/utils/errors'
|
||||||
import useUpdateItem, {
|
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
||||||
UpdateItemInput as UpdateItemInputBase,
|
|
||||||
UseUpdateItem,
|
|
||||||
} from '@commerce/cart/use-update-item'
|
|
||||||
|
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
import { handler as removeItemHandler } from './use-remove-item'
|
import { handler as removeItemHandler } from './use-remove-item'
|
||||||
import type { Cart, LineItem, UpdateCartItemBody } from '../types'
|
import type { UpdateItemHook, LineItem } from '../types/cart'
|
||||||
import { checkoutToCart } from '../utils'
|
import {
|
||||||
import { getCheckoutId, checkoutLineItemUpdateMutation } from '../utils'
|
getCheckoutId,
|
||||||
|
checkoutLineItemUpdateMutation,
|
||||||
|
checkoutToCart,
|
||||||
|
} from '../utils'
|
||||||
import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema'
|
import { Mutation, MutationCheckoutLineItemsUpdateArgs } from '../schema'
|
||||||
|
|
||||||
export type UpdateItemInput<T = any> = T extends LineItem
|
export type UpdateItemActionInput<T = any> = T extends LineItem
|
||||||
? Partial<UpdateItemInputBase<LineItem>>
|
? Partial<UpdateItemHook['actionInput']>
|
||||||
: UpdateItemInputBase<LineItem>
|
: UpdateItemHook['actionInput']
|
||||||
|
|
||||||
export default useUpdateItem as UseUpdateItem<typeof handler>
|
export default useUpdateItem as UseUpdateItem<typeof handler>
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ export const handler = {
|
|||||||
input: { itemId, item },
|
input: { itemId, item },
|
||||||
options,
|
options,
|
||||||
fetch,
|
fetch,
|
||||||
}: HookFetcherContext<UpdateCartItemBody>) {
|
}: HookFetcherContext<UpdateItemHook>) {
|
||||||
if (Number.isInteger(item.quantity)) {
|
if (Number.isInteger(item.quantity)) {
|
||||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||||
if (item.quantity! < 1) {
|
if (item.quantity! < 1) {
|
||||||
@ -64,9 +64,7 @@ export const handler = {
|
|||||||
|
|
||||||
return checkoutToCart(checkoutLineItemsUpdate)
|
return checkoutToCart(checkoutLineItemsUpdate)
|
||||||
},
|
},
|
||||||
useHook: ({
|
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) => <
|
||||||
fetch,
|
|
||||||
}: MutationHookContext<Cart | null, UpdateCartItemBody>) => <
|
|
||||||
T extends LineItem | undefined = undefined
|
T extends LineItem | undefined = undefined
|
||||||
>(
|
>(
|
||||||
ctx: {
|
ctx: {
|
||||||
@ -78,7 +76,7 @@ export const handler = {
|
|||||||
const { mutate } = useCart() as any
|
const { mutate } = useCart() as any
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
debounce(async (input: UpdateItemInput<T>) => {
|
debounce(async (input: UpdateItemActionInput<T>) => {
|
||||||
const itemId = input.id ?? item?.id
|
const itemId = input.id ?? item?.id
|
||||||
const productId = input.productId ?? item?.productId
|
const productId = input.productId ?? item?.productId
|
||||||
const variantId = input.productId ?? item?.variantId
|
const variantId = input.productId ?? item?.variantId
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
||||||
import { Customer } from '@commerce/types'
|
import type { CustomerHook } from '../types/customer'
|
||||||
import { SWRHook } from '@commerce/utils/types'
|
import { SWRHook } from '@commerce/utils/types'
|
||||||
import { getCustomerQuery, getCustomerToken } from '../utils'
|
import { getCustomerQuery, getCustomerToken } from '../utils'
|
||||||
|
import { GetCustomerQuery, GetCustomerQueryVariables } from '../schema'
|
||||||
|
|
||||||
export default useCustomer as UseCustomer<typeof handler>
|
export default useCustomer as UseCustomer<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<Customer | null> = {
|
export const handler: SWRHook<CustomerHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: getCustomerQuery,
|
query: getCustomerQuery,
|
||||||
},
|
},
|
||||||
async fetcher({ options, fetch }) {
|
async fetcher({ options, fetch }) {
|
||||||
const customerAccessToken = getCustomerToken()
|
const customerAccessToken = getCustomerToken()
|
||||||
if (customerAccessToken) {
|
if (customerAccessToken) {
|
||||||
const data = await fetch({
|
const data = await fetch<GetCustomerQuery, GetCustomerQueryVariables>({
|
||||||
...options,
|
...options,
|
||||||
variables: { customerAccessToken: getCustomerToken() },
|
variables: { customerAccessToken: getCustomerToken() },
|
||||||
})
|
})
|
||||||
|
@ -8,13 +8,17 @@ const fetcher: Fetcher = async ({
|
|||||||
variables,
|
variables,
|
||||||
query,
|
query,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { locale, ...vars } = variables
|
||||||
return handleFetchResponse(
|
return handleFetchResponse(
|
||||||
await fetch(url, {
|
await fetch(url, {
|
||||||
method,
|
method,
|
||||||
body: JSON.stringify({ query, variables }),
|
body: JSON.stringify({ query, variables: vars }),
|
||||||
headers: {
|
headers: {
|
||||||
'X-Shopify-Storefront-Access-Token': API_TOKEN!,
|
'X-Shopify-Storefront-Access-Token': API_TOKEN!,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
...(locale && {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -4,9 +4,11 @@ import useSearch, { UseSearch } from '@commerce/product/use-search'
|
|||||||
import {
|
import {
|
||||||
CollectionEdge,
|
CollectionEdge,
|
||||||
GetAllProductsQuery,
|
GetAllProductsQuery,
|
||||||
|
GetProductsFromCollectionQueryVariables,
|
||||||
Product as ShopifyProduct,
|
Product as ShopifyProduct,
|
||||||
ProductEdge,
|
ProductEdge,
|
||||||
} from '../schema'
|
} from '../schema'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getAllProductsQuery,
|
getAllProductsQuery,
|
||||||
getCollectionProductsQuery,
|
getCollectionProductsQuery,
|
||||||
@ -14,27 +16,19 @@ import {
|
|||||||
normalizeProduct,
|
normalizeProduct,
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
|
|
||||||
import { Product } from '@commerce/types'
|
import type { SearchProductsHook } from '../types/product'
|
||||||
|
|
||||||
export default useSearch as UseSearch<typeof handler>
|
|
||||||
|
|
||||||
export type SearchProductsInput = {
|
export type SearchProductsInput = {
|
||||||
search?: string
|
search?: string
|
||||||
categoryId?: string
|
categoryId?: number
|
||||||
brandId?: string
|
brandId?: number
|
||||||
sort?: string
|
sort?: string
|
||||||
|
locale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchProductsData = {
|
export default useSearch as UseSearch<typeof handler>
|
||||||
products: Product[]
|
|
||||||
found: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const handler: SWRHook<
|
export const handler: SWRHook<SearchProductsHook> = {
|
||||||
SearchProductsData,
|
|
||||||
SearchProductsInput,
|
|
||||||
SearchProductsInput
|
|
||||||
> = {
|
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: getAllProductsQuery,
|
query: getAllProductsQuery,
|
||||||
},
|
},
|
||||||
@ -46,7 +40,10 @@ export const handler: SWRHook<
|
|||||||
|
|
||||||
// change the query to getCollectionProductsQuery when categoryId is set
|
// change the query to getCollectionProductsQuery when categoryId is set
|
||||||
if (categoryId) {
|
if (categoryId) {
|
||||||
const data = await fetch<CollectionEdge>({
|
const data = await fetch<
|
||||||
|
CollectionEdge,
|
||||||
|
GetProductsFromCollectionQueryVariables
|
||||||
|
>({
|
||||||
query: getCollectionProductsQuery,
|
query: getCollectionProductsQuery,
|
||||||
method,
|
method,
|
||||||
variables,
|
variables,
|
||||||
@ -81,6 +78,7 @@ export const handler: SWRHook<
|
|||||||
['categoryId', input.categoryId],
|
['categoryId', input.categoryId],
|
||||||
['brandId', input.brandId],
|
['brandId', input.brandId],
|
||||||
['sort', input.sort],
|
['sort', input.sort],
|
||||||
|
['locale', input.locale],
|
||||||
],
|
],
|
||||||
swrOptions: {
|
swrOptions: {
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
|
@ -24,4 +24,4 @@ export const shopifyProvider = {
|
|||||||
auth: { useLogin, useLogout, useSignup },
|
auth: { useLogin, useLogout, useSignup },
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ShopifyProvider = typeof shopifyProvider
|
export type ShopifyProvider = any
|
||||||
|
@ -10,23 +10,10 @@ export type ShopifyCart = {}
|
|||||||
|
|
||||||
export type Cart = Core.Cart & {
|
export type Cart = Core.Cart & {
|
||||||
lineItems: Core.LineItem[]
|
lineItems: Core.LineItem[]
|
||||||
|
url?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OptionSelections = {
|
export type CartTypes = Core.CartTypes
|
||||||
option_id: number
|
|
||||||
option_value: number | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CartItemBody = Core.CartItemBody & {
|
|
||||||
productId: string // The product id is always required for BC
|
|
||||||
optionSelections?: OptionSelections
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CartTypes = {
|
|
||||||
cart: Cart
|
|
||||||
item: Core.LineItem
|
|
||||||
itemBody: CartItemBody
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CartHooks = Core.CartHooks<CartTypes>
|
export type CartHooks = Core.CartHooks<CartTypes>
|
||||||
|
|
||||||
|
1
framework/shopify/types/checkout.ts
Normal file
1
framework/shopify/types/checkout.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/checkout'
|
1
framework/shopify/types/common.ts
Normal file
1
framework/shopify/types/common.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/common'
|
@ -1,2 +1,25 @@
|
|||||||
export * from '@commerce/types'
|
import * as Cart from './cart'
|
||||||
export * from './cart'
|
import * as Checkout from './checkout'
|
||||||
|
import * as Common from './common'
|
||||||
|
import * as Customer from './customer'
|
||||||
|
import * as Login from './login'
|
||||||
|
import * as Logout from './logout'
|
||||||
|
import * as Page from './page'
|
||||||
|
import * as Product from './product'
|
||||||
|
import * as Signup from './signup'
|
||||||
|
import * as Site from './site'
|
||||||
|
import * as Wishlist from './wishlist'
|
||||||
|
|
||||||
|
export type {
|
||||||
|
Cart,
|
||||||
|
Checkout,
|
||||||
|
Common,
|
||||||
|
Customer,
|
||||||
|
Login,
|
||||||
|
Logout,
|
||||||
|
Page,
|
||||||
|
Product,
|
||||||
|
Signup,
|
||||||
|
Site,
|
||||||
|
Wishlist,
|
||||||
|
}
|
||||||
|
1
framework/shopify/types/wishlist.ts
Normal file
1
framework/shopify/types/wishlist.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/wishlist'
|
@ -8,12 +8,25 @@ export type Category = {
|
|||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCategories = async (config: ShopifyConfig): Promise<Category[]> => {
|
const getCategories = async ({
|
||||||
const { data } = await config.fetch(getSiteCollectionsQuery, {
|
fetch,
|
||||||
variables: {
|
locale,
|
||||||
first: 250,
|
}: ShopifyConfig): Promise<Category[]> => {
|
||||||
|
const { data } = await fetch(
|
||||||
|
getSiteCollectionsQuery,
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
first: 250,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
{
|
||||||
|
...(locale && {
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': locale,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
data.collections?.edges?.map(
|
data.collections?.edges?.map(
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import getSortVariables from './get-sort-variables'
|
import getSortVariables from './get-sort-variables'
|
||||||
import type { SearchProductsInput } from '../product/use-search'
|
import { SearchProductsBody } from '../types/product'
|
||||||
|
|
||||||
export const getSearchVariables = ({
|
export const getSearchVariables = ({
|
||||||
brandId,
|
brandId,
|
||||||
search,
|
search,
|
||||||
categoryId,
|
categoryId,
|
||||||
sort,
|
sort,
|
||||||
}: SearchProductsInput) => {
|
locale,
|
||||||
|
}: SearchProductsBody) => {
|
||||||
let query = ''
|
let query = ''
|
||||||
|
|
||||||
if (search) {
|
if (search) {
|
||||||
@ -21,6 +22,9 @@ export const getSearchVariables = ({
|
|||||||
categoryId,
|
categoryId,
|
||||||
query,
|
query,
|
||||||
...getSortVariables(sort, !!categoryId),
|
...getSortVariables(sort, !!categoryId),
|
||||||
|
...(locale && {
|
||||||
|
locale,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Product } from '@commerce/types'
|
import type { Page } from '../types/page'
|
||||||
|
import type { Product } from '../types/product'
|
||||||
|
import type { Cart, LineItem } from '../types/cart'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Product as ShopifyProduct,
|
Product as ShopifyProduct,
|
||||||
@ -9,10 +11,10 @@ import {
|
|||||||
ProductVariantConnection,
|
ProductVariantConnection,
|
||||||
MoneyV2,
|
MoneyV2,
|
||||||
ProductOption,
|
ProductOption,
|
||||||
|
Page as ShopifyPage,
|
||||||
|
PageEdge,
|
||||||
} from '../schema'
|
} from '../schema'
|
||||||
|
|
||||||
import type { Cart, LineItem } from '../types'
|
|
||||||
|
|
||||||
const money = ({ amount, currencyCode }: MoneyV2) => {
|
const money = ({ amount, currencyCode }: MoneyV2) => {
|
||||||
return {
|
return {
|
||||||
value: +amount,
|
value: +amount,
|
||||||
@ -152,12 +154,18 @@ function normalizeLineItem({
|
|||||||
discounts: [],
|
discounts: [],
|
||||||
options:
|
options:
|
||||||
// By default Shopify adds a default variant with default names, we're removing it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095
|
// By default Shopify adds a default variant with default names, we're removing it. https://community.shopify.com/c/Shopify-APIs-SDKs/Adding-new-product-variant-is-automatically-adding-quot-Default/td-p/358095
|
||||||
variant?.title == 'Default Title'
|
variant?.title == 'Default Title' ? [] : variant?.selectedOptions,
|
||||||
? []
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
value: variant?.title,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const normalizePage = (
|
||||||
|
{ title: name, handle, ...page }: ShopifyPage,
|
||||||
|
locale: string
|
||||||
|
): Page => ({
|
||||||
|
...page,
|
||||||
|
url: `/${locale}/${handle}`,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizePages = (edges: PageEdge[], locale: string): Page[] =>
|
||||||
|
edges?.map((edge) => normalizePage(edge.node, locale))
|
||||||
|
@ -14,8 +14,9 @@ export async function getStaticProps({
|
|||||||
preview,
|
preview,
|
||||||
params,
|
params,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext<{ pages: string[] }>) {
|
}: GetStaticPropsContext<{ pages: string[] }>) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ preview, config })
|
const { pages } = await commerce.getAllPages({ preview, config })
|
||||||
const path = params?.pages.join('/')
|
const path = params?.pages.join('/')
|
||||||
const slug = locale ? `${locale}/${path}` : path
|
const slug = locale ? `${locale}/${path}` : path
|
||||||
@ -42,7 +43,8 @@ export async function getStaticProps({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
|
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
|
||||||
const { pages } = await commerce.getAllPages()
|
const config = { locales }
|
||||||
|
const { pages } = await commerce.getAllPages({ config })
|
||||||
const [invalidPaths, log] = missingLocaleInPages()
|
const [invalidPaths, log] = missingLocaleInPages()
|
||||||
const paths = pages
|
const paths = pages
|
||||||
.map((page) => page.url)
|
.map((page) => page.url)
|
||||||
|
@ -6,8 +6,9 @@ import { Container } from '@components/ui'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
return {
|
return {
|
||||||
props: { pages },
|
props: { pages },
|
||||||
|
@ -10,8 +10,9 @@ import { CartItem } from '@components/cart'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
return {
|
return {
|
||||||
props: { pages },
|
props: { pages },
|
||||||
|
@ -8,8 +8,9 @@ import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { products } = await commerce.getAllProducts({
|
const { products } = await commerce.getAllProducts({
|
||||||
variables: { first: 12 },
|
variables: { first: 12 },
|
||||||
config,
|
config,
|
||||||
|
@ -7,8 +7,9 @@ import { Container, Text } from '@components/ui'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
return {
|
return {
|
||||||
props: { pages },
|
props: { pages },
|
||||||
|
@ -11,9 +11,10 @@ import { ProductView } from '@components/product'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
params,
|
params,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
preview,
|
preview,
|
||||||
}: GetStaticPropsContext<{ slug: string }>) {
|
}: GetStaticPropsContext<{ slug: string }>) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
const { product } = await commerce.getProduct({
|
const { product } = await commerce.getProduct({
|
||||||
variables: { slug: params!.slug },
|
variables: { slug: params!.slug },
|
||||||
|
@ -7,8 +7,9 @@ import { Container, Text } from '@components/ui'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
return {
|
return {
|
||||||
props: { pages },
|
props: { pages },
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
getDesignerPath,
|
getDesignerPath,
|
||||||
useSearchMeta,
|
useSearchMeta,
|
||||||
} from '@lib/search'
|
} from '@lib/search'
|
||||||
import { Product } from '@commerce/types'
|
import type { Product } from '@framework/types/product'
|
||||||
|
|
||||||
// TODO(bc) Remove this. This should come from the API
|
// TODO(bc) Remove this. This should come from the API
|
||||||
import getSlug from '@lib/get-slug'
|
import getSlug from '@lib/get-slug'
|
||||||
@ -34,8 +34,9 @@ const SORT = Object.entries({
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
const { categories, brands } = await commerce.getSiteInfo({ config, preview })
|
const { categories, brands } = await commerce.getSiteInfo({ config, preview })
|
||||||
return {
|
return {
|
||||||
@ -55,7 +56,7 @@ export default function Search({
|
|||||||
const [toggleFilter, setToggleFilter] = useState(false)
|
const [toggleFilter, setToggleFilter] = useState(false)
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { asPath } = router
|
const { asPath, locale } = router
|
||||||
const { q, sort } = router.query
|
const { q, sort } = router.query
|
||||||
// `q` can be included but because categories and designers can't be searched
|
// `q` can be included but because categories and designers can't be searched
|
||||||
// in the same way of products, it's better to ignore the search input if one
|
// in the same way of products, it's better to ignore the search input if one
|
||||||
@ -75,6 +76,7 @@ export default function Search({
|
|||||||
categoryId: activeCategory?.entityId,
|
categoryId: activeCategory?.entityId,
|
||||||
brandId: activeBrand?.entityId,
|
brandId: activeBrand?.entityId,
|
||||||
sort: typeof sort === 'string' ? sort : '',
|
sort: typeof sort === 'string' ? sort : '',
|
||||||
|
locale,
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = (event: any, filter: string) => {
|
const handleClick = (event: any, filter: string) => {
|
||||||
|
@ -11,6 +11,7 @@ import useWishlist from '@framework/wishlist/use-wishlist'
|
|||||||
export async function getStaticProps({
|
export async function getStaticProps({
|
||||||
preview,
|
preview,
|
||||||
locale,
|
locale,
|
||||||
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
// Disabling page if Feature is not available
|
// Disabling page if Feature is not available
|
||||||
if (!process.env.COMMERCE_WISHLIST_ENABLED) {
|
if (!process.env.COMMERCE_WISHLIST_ENABLED) {
|
||||||
@ -19,7 +20,7 @@ export async function getStaticProps({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = { locale }
|
const config = { locale, locales }
|
||||||
const { pages } = await commerce.getAllPages({ config, preview })
|
const { pages } = await commerce.getAllPages({ config, preview })
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user