mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 04:14:18 +00:00
Merge branch 'main' into spree-framework-poc
This commit is contained in:
commit
1e37ce1ca0
@ -1,4 +1,4 @@
|
|||||||
# Available providers: bigcommerce, shopify, swell
|
# Available providers: local, bigcommerce, shopify, swell, saleor, spree
|
||||||
COMMERCE_PROVIDER=
|
COMMERCE_PROVIDER=
|
||||||
|
|
||||||
BIGCOMMERCE_STOREFRONT_API_URL=
|
BIGCOMMERCE_STOREFRONT_API_URL=
|
||||||
|
@ -7,6 +7,7 @@ import useCustomer from '@framework/customer/use-customer'
|
|||||||
import { Avatar } from '@components/common'
|
import { Avatar } from '@components/common'
|
||||||
import { Heart, Bag } from '@components/icons'
|
import { Heart, Bag } from '@components/icons'
|
||||||
import { useUI } from '@components/ui/context'
|
import { useUI } from '@components/ui/context'
|
||||||
|
import Button from '@components/ui/Button'
|
||||||
import DropdownMenu from './DropdownMenu'
|
import DropdownMenu from './DropdownMenu'
|
||||||
import s from './UserNav.module.css'
|
import s from './UserNav.module.css'
|
||||||
|
|
||||||
@ -26,9 +27,11 @@ const UserNav: FC<Props> = ({ className }) => {
|
|||||||
<nav className={cn(s.root, className)}>
|
<nav className={cn(s.root, className)}>
|
||||||
<ul className={s.list}>
|
<ul className={s.list}>
|
||||||
{process.env.COMMERCE_CART_ENABLED && (
|
{process.env.COMMERCE_CART_ENABLED && (
|
||||||
<li className={s.item} onClick={toggleSidebar}>
|
<li className={s.item}>
|
||||||
<Bag />
|
<Button className={s.item} variant="naked" onClick={toggleSidebar} aria-label="Cart">
|
||||||
{itemsCount > 0 && <span className={s.bagCount}>{itemsCount}</span>}
|
<Bag />
|
||||||
|
{itemsCount > 0 && <span className={s.bagCount}>{itemsCount}</span>}
|
||||||
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
{process.env.COMMERCE_WISHLIST_ENABLED && (
|
||||||
|
@ -35,6 +35,15 @@
|
|||||||
@apply border-accent-9 bg-accent-9 text-accent-0;
|
@apply border-accent-9 bg-accent-9 text-accent-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.naked {
|
||||||
|
@apply bg-transparent font-semibold border-none shadow-none outline-none py-0 px-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.naked:hover,
|
||||||
|
.naked:focus {
|
||||||
|
@apply bg-transparent border-none;
|
||||||
|
}
|
||||||
|
|
||||||
.disabled,
|
.disabled,
|
||||||
.disabled:hover {
|
.disabled:hover {
|
||||||
@apply text-accent-4 border-accent-2 bg-accent-1 cursor-not-allowed;
|
@apply text-accent-4 border-accent-2 bg-accent-1 cursor-not-allowed;
|
||||||
|
@ -12,7 +12,7 @@ import { LoadingDots } from '@components/ui'
|
|||||||
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
href?: string
|
href?: string
|
||||||
className?: string
|
className?: string
|
||||||
variant?: 'flat' | 'slim' | 'ghost'
|
variant?: 'flat' | 'slim' | 'ghost' | 'naked'
|
||||||
active?: boolean
|
active?: boolean
|
||||||
type?: 'submit' | 'reset' | 'button'
|
type?: 'submit' | 'reset' | 'button'
|
||||||
Component?: string | JSXElementConstructor<any>
|
Component?: string | JSXElementConstructor<any>
|
||||||
@ -41,6 +41,7 @@ const Button: React.FC<ButtonProps> = forwardRef((props, buttonRef) => {
|
|||||||
{
|
{
|
||||||
[s.ghost]: variant === 'ghost',
|
[s.ghost]: variant === 'ghost',
|
||||||
[s.slim]: variant === 'slim',
|
[s.slim]: variant === 'slim',
|
||||||
|
[s.naked]: variant === 'naked',
|
||||||
[s.loading]: loading,
|
[s.loading]: loading,
|
||||||
[s.disabled]: disabled,
|
[s.disabled]: disabled,
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.root {
|
.root {
|
||||||
@apply fixed inset-0 h-full z-50 box-border;
|
@apply fixed inset-0 h-full z-50 box-border outline-none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
|
@ -13,28 +13,44 @@ interface SidebarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Sidebar: FC<SidebarProps> = ({ children, onClose }) => {
|
const Sidebar: FC<SidebarProps> = ({ children, onClose }) => {
|
||||||
const ref = useRef() as React.MutableRefObject<HTMLDivElement>
|
const sidebarRef = useRef() as React.MutableRefObject<HTMLDivElement>
|
||||||
|
const contentRef = useRef() as React.MutableRefObject<HTMLDivElement>
|
||||||
|
|
||||||
|
const onKeyDownSidebar = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
|
if (event.code === 'Escape') {
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sidebar = ref.current
|
if (sidebarRef.current) {
|
||||||
|
sidebarRef.current.focus()
|
||||||
|
}
|
||||||
|
|
||||||
if (sidebar) {
|
const contentElement = contentRef.current
|
||||||
disableBodyScroll(sidebar, { reserveScrollBarGap: true })
|
|
||||||
|
if (contentElement) {
|
||||||
|
disableBodyScroll(contentElement, { reserveScrollBarGap: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (sidebar) enableBodyScroll(sidebar)
|
if (contentElement) enableBodyScroll(contentElement)
|
||||||
clearAllBodyScrollLocks()
|
clearAllBodyScrollLocks()
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn(s.root)}>
|
<div
|
||||||
|
className={cn(s.root)}
|
||||||
|
ref={sidebarRef}
|
||||||
|
onKeyDown={onKeyDownSidebar}
|
||||||
|
tabIndex={1}
|
||||||
|
>
|
||||||
<div className="absolute inset-0 overflow-hidden">
|
<div className="absolute inset-0 overflow-hidden">
|
||||||
<div className={s.backdrop} onClick={onClose} />
|
<div className={s.backdrop} onClick={onClose} />
|
||||||
<section className="absolute inset-y-0 right-0 max-w-full flex outline-none pl-10">
|
<section className="absolute inset-y-0 right-0 max-w-full flex outline-none pl-10">
|
||||||
<div className="h-full w-full md:w-screen md:max-w-md">
|
<div className="h-full w-full md:w-screen md:max-w-md">
|
||||||
<div className={s.sidebar} ref={ref}>
|
<div className={s.sidebar} ref={contentRef}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,36 +1,9 @@
|
|||||||
import type { ReactNode } from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import {
|
import { bigcommerceProvider, BigcommerceProvider } from './provider'
|
||||||
CommerceConfig,
|
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
import { bigcommerceProvider } from './provider'
|
|
||||||
import type { BigcommerceProvider } from './provider'
|
|
||||||
|
|
||||||
export { bigcommerceProvider }
|
export { bigcommerceProvider }
|
||||||
export type { BigcommerceProvider }
|
export type { BigcommerceProvider }
|
||||||
|
|
||||||
export const bigcommerceConfig: CommerceConfig = {
|
export const CommerceProvider = getCommerceProvider(bigcommerceProvider)
|
||||||
locale: 'en-us',
|
|
||||||
cartCookie: 'bc_cartId',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BigcommerceConfig = Partial<CommerceConfig>
|
|
||||||
|
|
||||||
export type BigcommerceProps = {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & BigcommerceConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...config }: BigcommerceProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider
|
|
||||||
provider={bigcommerceProvider}
|
|
||||||
config={{ ...bigcommerceConfig, ...config }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce<BigcommerceProvider>()
|
export const useCommerce = () => useCoreCommerce<BigcommerceProvider>()
|
||||||
|
@ -8,13 +8,13 @@ const merge = require('deepmerge')
|
|||||||
const prettier = require('prettier')
|
const prettier = require('prettier')
|
||||||
|
|
||||||
const PROVIDERS = [
|
const PROVIDERS = [
|
||||||
|
'local',
|
||||||
'bigcommerce',
|
'bigcommerce',
|
||||||
'saleor',
|
'saleor',
|
||||||
'shopify',
|
'shopify',
|
||||||
'spree',
|
'spree',
|
||||||
'swell',
|
'swell',
|
||||||
'vendure',
|
'vendure',
|
||||||
'local'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
function getProviderName() {
|
function getProviderName() {
|
||||||
|
@ -47,51 +47,60 @@ export type Provider = CommerceConfig & {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CommerceProps<P extends Provider> = {
|
export type CommerceConfig = {
|
||||||
children?: ReactNode
|
|
||||||
provider: P
|
|
||||||
config: CommerceConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CommerceConfig = Omit<
|
|
||||||
CommerceContextValue<any>,
|
|
||||||
'providerRef' | 'fetcherRef'
|
|
||||||
>
|
|
||||||
|
|
||||||
export type CommerceContextValue<P extends Provider> = {
|
|
||||||
providerRef: MutableRefObject<P>
|
|
||||||
fetcherRef: MutableRefObject<Fetcher>
|
|
||||||
locale: string
|
locale: string
|
||||||
cartCookie: string
|
cartCookie: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CommerceProvider<P extends Provider>({
|
export type CommerceContextValue<P extends Provider> = {
|
||||||
|
providerRef: MutableRefObject<P>
|
||||||
|
fetcherRef: MutableRefObject<Fetcher>
|
||||||
|
} & CommerceConfig
|
||||||
|
|
||||||
|
export type CommerceProps<P extends Provider> = {
|
||||||
|
children?: ReactNode
|
||||||
|
provider: P
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are the properties every provider should allow when implementing
|
||||||
|
* the core commerce provider
|
||||||
|
*/
|
||||||
|
export type CommerceProviderProps = {
|
||||||
|
children?: ReactNode
|
||||||
|
} & Partial<CommerceConfig>
|
||||||
|
|
||||||
|
export function CoreCommerceProvider<P extends Provider>({
|
||||||
provider,
|
provider,
|
||||||
children,
|
children,
|
||||||
config,
|
|
||||||
}: CommerceProps<P>) {
|
}: CommerceProps<P>) {
|
||||||
if (!config) {
|
|
||||||
throw new Error('CommerceProvider requires a valid config object')
|
|
||||||
}
|
|
||||||
|
|
||||||
const providerRef = useRef(provider)
|
const providerRef = useRef(provider)
|
||||||
// TODO: Remove the fetcherRef
|
// TODO: Remove the fetcherRef
|
||||||
const fetcherRef = useRef(provider.fetcher)
|
const fetcherRef = useRef(provider.fetcher)
|
||||||
// Because the config is an object, if the parent re-renders this provider
|
// If the parent re-renders this provider will re-render every
|
||||||
// will re-render every consumer unless we memoize the config
|
// consumer unless we memoize the config
|
||||||
|
const { locale, cartCookie } = providerRef.current
|
||||||
const cfg = useMemo(
|
const cfg = useMemo(
|
||||||
() => ({
|
() => ({ providerRef, fetcherRef, locale, cartCookie }),
|
||||||
providerRef,
|
[locale, cartCookie]
|
||||||
fetcherRef,
|
|
||||||
locale: config.locale,
|
|
||||||
cartCookie: config.cartCookie,
|
|
||||||
}),
|
|
||||||
[config.locale, config.cartCookie]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return <Commerce.Provider value={cfg}>{children}</Commerce.Provider>
|
return <Commerce.Provider value={cfg}>{children}</Commerce.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCommerceProvider<P extends Provider>(provider: P) {
|
||||||
|
return function CommerceProvider({
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: CommerceProviderProps) {
|
||||||
|
return (
|
||||||
|
<CoreCommerceProvider provider={{ ...provider, ...props }}>
|
||||||
|
{children}
|
||||||
|
</CoreCommerceProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function useCommerce<P extends Provider>() {
|
export function useCommerce<P extends Provider>() {
|
||||||
return useContext(Commerce) as CommerceContextValue<P>
|
return useContext(Commerce) as CommerceContextValue<P>
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,9 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import { ReactNode } from 'react'
|
import { localProvider, LocalProvider } from './provider'
|
||||||
import { localProvider } from './provider'
|
|
||||||
import {
|
|
||||||
CommerceConfig,
|
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
|
|
||||||
export const localConfig: CommerceConfig = {
|
export { localProvider }
|
||||||
locale: 'en-us',
|
export type { LocalProvider }
|
||||||
cartCookie: 'session',
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CommerceProvider({
|
export const CommerceProvider = getCommerceProvider(localProvider)
|
||||||
children,
|
|
||||||
...config
|
|
||||||
}: {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & Partial<CommerceConfig>) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider
|
|
||||||
provider={localProvider}
|
|
||||||
config={{ ...localConfig, ...config }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce()
|
export const useCommerce = () => useCoreCommerce<LocalProvider>()
|
||||||
|
@ -9,7 +9,6 @@ import { handler as useLogin } from './auth/use-login'
|
|||||||
import { handler as useLogout } from './auth/use-logout'
|
import { handler as useLogout } from './auth/use-logout'
|
||||||
import { handler as useSignup } from './auth/use-signup'
|
import { handler as useSignup } from './auth/use-signup'
|
||||||
|
|
||||||
export type Provider = typeof localProvider
|
|
||||||
export const localProvider = {
|
export const localProvider = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: 'session',
|
cartCookie: 'session',
|
||||||
@ -19,3 +18,5 @@ export const localProvider = {
|
|||||||
products: { useSearch },
|
products: { useSearch },
|
||||||
auth: { useLogin, useLogout, useSignup },
|
auth: { useLogin, useLogout, useSignup },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LocalProvider = typeof localProvider
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { CommerceAPIConfig } from '@commerce/api'
|
import { CommerceAPI, CommerceAPIConfig, getCommerceApi as commerceApi } from '@commerce/api'
|
||||||
|
import * as operations from './operations'
|
||||||
import * as Const from '../const'
|
import * as Const from '../const'
|
||||||
|
|
||||||
if (!Const.API_URL) {
|
if (!Const.API_URL) {
|
||||||
@ -27,23 +27,12 @@ const config: SaleorConfig = {
|
|||||||
storeChannel: Const.API_CHANNEL,
|
storeChannel: Const.API_CHANNEL,
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
CommerceAPI,
|
|
||||||
getCommerceApi as commerceApi,
|
|
||||||
} from '@commerce/api'
|
|
||||||
|
|
||||||
import * as operations from './operations'
|
|
||||||
|
|
||||||
export interface ShopifyConfig extends CommerceAPIConfig {}
|
|
||||||
|
|
||||||
export const provider = { config, operations }
|
export const provider = { config, operations }
|
||||||
|
|
||||||
export type Provider = typeof provider
|
export type Provider = typeof provider
|
||||||
|
|
||||||
export type SaleorAPI<P extends Provider = Provider> = CommerceAPI<P>
|
export type SaleorAPI<P extends Provider = Provider> = CommerceAPI<P>
|
||||||
|
|
||||||
export function getCommerceApi<P extends Provider>(
|
export function getCommerceApi<P extends Provider>(customProvider: P = provider as any): SaleorAPI<P> {
|
||||||
customProvider: P = provider as any
|
|
||||||
): SaleorAPI<P> {
|
|
||||||
return commerceApi(customProvider)
|
return commerceApi(customProvider)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import type { OperationContext } from '@commerce/api/operations'
|
import type { OperationContext } from '@commerce/api/operations'
|
||||||
import {
|
import { ProductCountableEdge } from '../../schema'
|
||||||
GetAllProductPathsQuery,
|
import type { Provider, SaleorConfig } from '..'
|
||||||
GetAllProductPathsQueryVariables,
|
|
||||||
ProductCountableEdge,
|
|
||||||
} from '../../schema'
|
|
||||||
import type { ShopifyConfig, Provider, SaleorConfig } from '..'
|
|
||||||
|
|
||||||
import { getAllProductsPathsQuery } from '../../utils/queries'
|
import { getAllProductsPathsQuery } from '../../utils/queries'
|
||||||
import fetchAllProducts from '../utils/fetch-all-products'
|
import fetchAllProducts from '../utils/fetch-all-products'
|
||||||
@ -13,10 +9,7 @@ export type GetAllProductPathsResult = {
|
|||||||
products: Array<{ path: string }>
|
products: Array<{ path: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getAllProductPathsOperation({
|
export default function getAllProductPathsOperation({ commerce }: OperationContext<Provider>) {
|
||||||
commerce,
|
|
||||||
}: OperationContext<Provider>) {
|
|
||||||
|
|
||||||
async function getAllProductPaths({
|
async function getAllProductPaths({
|
||||||
query,
|
query,
|
||||||
config,
|
config,
|
||||||
@ -39,7 +32,6 @@ export default function getAllProductPathsOperation({
|
|||||||
path: `/${slug}`,
|
path: `/${slug}`,
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAllProductPaths
|
return getAllProductPaths
|
||||||
|
@ -1,32 +1,9 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import { ReactNode } from 'react'
|
|
||||||
|
|
||||||
import { CommerceConfig, CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
|
||||||
|
|
||||||
import { saleorProvider, SaleorProvider } from './provider'
|
import { saleorProvider, SaleorProvider } from './provider'
|
||||||
import * as Const from './const'
|
|
||||||
|
|
||||||
export { saleorProvider }
|
export { saleorProvider }
|
||||||
export type { SaleorProvider }
|
export type { SaleorProvider }
|
||||||
|
|
||||||
export const saleorConfig: CommerceConfig = {
|
export const CommerceProvider = getCommerceProvider(saleorProvider)
|
||||||
locale: 'en-us',
|
|
||||||
cartCookie: Const.CHECKOUT_ID_COOKIE,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SaleorConfig = Partial<CommerceConfig>
|
export const useCommerce = () => useCoreCommerce<SaleorProvider>()
|
||||||
|
|
||||||
export type SaleorProps = {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & SaleorConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...config }: SaleorProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider provider={saleorProvider} config={{ ...saleorConfig, ...config }}>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce()
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { CHECKOUT_ID_COOKIE } from './const'
|
||||||
import { handler as useCart } from './cart/use-cart'
|
import { handler as useCart } from './cart/use-cart'
|
||||||
import { handler as useAddItem } from './cart/use-add-item'
|
import { handler as useAddItem } from './cart/use-add-item'
|
||||||
import { handler as useUpdateItem } from './cart/use-update-item'
|
import { handler as useUpdateItem } from './cart/use-update-item'
|
||||||
@ -14,8 +15,7 @@ import fetcher from './fetcher'
|
|||||||
|
|
||||||
export const saleorProvider = {
|
export const saleorProvider = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: '',
|
cartCookie: CHECKOUT_ID_COOKIE,
|
||||||
cartCookieToken: '',
|
|
||||||
fetcher,
|
fetcher,
|
||||||
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
||||||
customer: { useCustomer },
|
customer: { useCustomer },
|
||||||
|
@ -1,40 +1,9 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import { ReactNode } from 'react'
|
import { shopifyProvider, ShopifyProvider } from './provider'
|
||||||
|
|
||||||
import {
|
|
||||||
CommerceConfig,
|
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
|
|
||||||
import { shopifyProvider } from './provider'
|
|
||||||
import type { ShopifyProvider } from './provider'
|
|
||||||
import { SHOPIFY_CHECKOUT_ID_COOKIE } from './const'
|
|
||||||
|
|
||||||
export { shopifyProvider }
|
export { shopifyProvider }
|
||||||
export type { ShopifyProvider }
|
export type { ShopifyProvider }
|
||||||
|
|
||||||
export const shopifyConfig: CommerceConfig = {
|
export const CommerceProvider = getCommerceProvider(shopifyProvider)
|
||||||
locale: 'en-us',
|
|
||||||
cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ShopifyConfig = Partial<CommerceConfig>
|
|
||||||
|
|
||||||
export type ShopifyProps = {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & ShopifyConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...config }: ShopifyProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider
|
|
||||||
provider={shopifyProvider}
|
|
||||||
config={{ ...shopifyConfig, ...config }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce<ShopifyProvider>()
|
export const useCommerce = () => useCoreCommerce<ShopifyProvider>()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
COMMERCE_PROVIDER=spree
|
COMMERCE_PROVIDER=spree
|
||||||
|
|
||||||
{# - public (available in the web browser) #}
|
{# - NEXT_PUBLIC_* are exposed to the web browser and the server #}
|
||||||
NEXT_PUBLIC_SPREE_API_HOST=http://localhost:4000
|
NEXT_PUBLIC_SPREE_API_HOST=http://localhost:4000
|
||||||
NEXT_PUBLIC_SPREE_DEFAULT_LOCALE=en-us
|
NEXT_PUBLIC_SPREE_DEFAULT_LOCALE=en-us
|
||||||
NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart_token
|
NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart_token
|
||||||
|
@ -1,37 +1,11 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import { ReactNode } from 'react'
|
import { spreeProvider } from './provider'
|
||||||
|
import type { SpreeProvider } from './provider'
|
||||||
|
|
||||||
import {
|
export { spreeProvider }
|
||||||
CommerceConfig,
|
export type { SpreeProvider }
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
|
|
||||||
import { provider } from './provider'
|
export const CommerceProvider =
|
||||||
import type { Provider } from './provider'
|
getCommerceProvider<SpreeProvider>(spreeProvider)
|
||||||
import { requireConfigValue } from './isomorphic-config'
|
|
||||||
|
|
||||||
export type SpreeProps = {
|
export const useCommerce = () => useCoreCommerce<SpreeProvider>()
|
||||||
children: ReactNode
|
|
||||||
locale: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const spreeCommerceConfigDefaults: CommerceConfig = {
|
|
||||||
locale: requireConfigValue('defaultLocale') as string,
|
|
||||||
cartCookie: requireConfigValue('cartCookieName') as string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SpreeConfig = CommerceConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...restProps }: SpreeProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider<Provider>
|
|
||||||
provider={provider}
|
|
||||||
config={{ ...spreeCommerceConfigDefaults, ...restProps }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce<Provider>()
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import type { Provider } from '@commerce'
|
|
||||||
import fetcher from './fetcher'
|
import fetcher from './fetcher'
|
||||||
|
|
||||||
import { handler as useCart } from './cart/use-cart'
|
import { handler as useCart } from './cart/use-cart'
|
||||||
import { handler as useAddItem } from './cart/use-add-item'
|
import { handler as useAddItem } from './cart/use-add-item'
|
||||||
import { handler as useUpdateItem } from './cart/use-update-item'
|
import { handler as useUpdateItem } from './cart/use-update-item'
|
||||||
@ -10,10 +8,11 @@ import { handler as useSearch } from './product/use-search'
|
|||||||
import { handler as useLogin } from './auth/use-login'
|
import { handler as useLogin } from './auth/use-login'
|
||||||
import { handler as useLogout } from './auth/use-logout'
|
import { handler as useLogout } from './auth/use-logout'
|
||||||
import { handler as useSignup } from './auth/use-signup'
|
import { handler as useSignup } from './auth/use-signup'
|
||||||
|
import { requireConfigValue } from './isomorphic-config'
|
||||||
|
|
||||||
const provider = {
|
const spreeProvider = {
|
||||||
locale: '', // Not an optional key in TypeScript, but already set in config. So, just make it an empty string.
|
locale: requireConfigValue('defaultLocale') as string,
|
||||||
cartCookie: '', // Not an optional key in TypeScript, but already set in config. So, just make it an empty string.
|
cartCookie: requireConfigValue('cartCookieName') as string,
|
||||||
fetcher,
|
fetcher,
|
||||||
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
||||||
customer: { useCustomer },
|
customer: { useCustomer },
|
||||||
@ -21,6 +20,6 @@ const provider = {
|
|||||||
auth: { useLogin, useLogout, useSignup },
|
auth: { useLogin, useLogout, useSignup },
|
||||||
}
|
}
|
||||||
|
|
||||||
export { provider }
|
export { spreeProvider }
|
||||||
|
|
||||||
export type { Provider }
|
export type SpreeProvider = typeof spreeProvider
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { swellConfig } from '../..'
|
import swell from '../../swell'
|
||||||
|
|
||||||
const fetchApi = async (query: string, method: string, variables: [] = []) => {
|
const fetchApi = async (query: string, method: string, variables: [] = []) => {
|
||||||
const { swell } = swellConfig
|
|
||||||
return swell[query][method](...variables)
|
return swell[query][method](...variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default fetchApi
|
export default fetchApi
|
||||||
|
@ -4,8 +4,6 @@ export const SWELL_CHECKOUT_URL_COOKIE = 'swell_checkoutUrl'
|
|||||||
|
|
||||||
export const SWELL_CUSTOMER_TOKEN_COOKIE = 'swell_customerToken'
|
export const SWELL_CUSTOMER_TOKEN_COOKIE = 'swell_customerToken'
|
||||||
|
|
||||||
export const STORE_DOMAIN = process.env.NEXT_PUBLIC_SWELL_STORE_DOMAIN
|
|
||||||
|
|
||||||
export const SWELL_COOKIE_EXPIRE = 30
|
export const SWELL_COOKIE_EXPIRE = 30
|
||||||
|
|
||||||
export const SWELL_STORE_ID = process.env.NEXT_PUBLIC_SWELL_STORE_ID
|
export const SWELL_STORE_ID = process.env.NEXT_PUBLIC_SWELL_STORE_ID
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { Fetcher } from '@commerce/utils/types'
|
import { Fetcher } from '@commerce/utils/types'
|
||||||
import { handleFetchResponse } from './utils'
|
|
||||||
import { swellConfig } from './index'
|
|
||||||
import { CommerceError } from '@commerce/utils/errors'
|
import { CommerceError } from '@commerce/utils/errors'
|
||||||
|
import { handleFetchResponse } from './utils'
|
||||||
|
import swell from './swell'
|
||||||
|
|
||||||
const fetcher: Fetcher = async ({ method = 'get', variables, query }) => {
|
const fetcher: Fetcher = async ({ method = 'get', variables, query }) => {
|
||||||
const { swell } = swellConfig
|
|
||||||
|
|
||||||
async function callSwell() {
|
async function callSwell() {
|
||||||
if (Array.isArray(variables)) {
|
if (Array.isArray(variables)) {
|
||||||
const arg1 = variables[0]
|
const arg1 = variables[0]
|
||||||
|
@ -1,47 +1,9 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import swell from 'swell-js'
|
|
||||||
import { ReactNode } from 'react'
|
|
||||||
|
|
||||||
import {
|
|
||||||
CommerceConfig,
|
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
|
|
||||||
import { swellProvider, SwellProvider } from './provider'
|
import { swellProvider, SwellProvider } from './provider'
|
||||||
import {
|
|
||||||
SWELL_CHECKOUT_ID_COOKIE,
|
|
||||||
SWELL_STORE_ID,
|
|
||||||
SWELL_PUBLIC_KEY,
|
|
||||||
} from './const'
|
|
||||||
swell.init(SWELL_STORE_ID, SWELL_PUBLIC_KEY)
|
|
||||||
|
|
||||||
export { swellProvider }
|
export { swellProvider }
|
||||||
export type { SwellProvider }
|
export type { SwellProvider }
|
||||||
|
|
||||||
export const swellConfig: any = {
|
export const CommerceProvider = getCommerceProvider(swellProvider)
|
||||||
locale: 'en-us',
|
|
||||||
cartCookie: SWELL_CHECKOUT_ID_COOKIE,
|
|
||||||
swell,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SwellConfig = Partial<CommerceConfig>
|
export const useCommerce = () => useCoreCommerce<SwellProvider>()
|
||||||
|
|
||||||
export type SwellProps = {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & SwellConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...config }: SwellProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider
|
|
||||||
// TODO: Fix this type
|
|
||||||
provider={swellProvider as any}
|
|
||||||
config={{ ...swellConfig, ...config }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce()
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Provider } from '@commerce'
|
import { Provider } from '@commerce'
|
||||||
|
import { SWELL_CHECKOUT_ID_COOKIE } from './const'
|
||||||
import { SWELL_CHECKOUT_URL_COOKIE, STORE_DOMAIN } from './const'
|
|
||||||
|
|
||||||
import { handler as useCart } from './cart/use-cart'
|
import { handler as useCart } from './cart/use-cart'
|
||||||
import { handler as useAddItem } from './cart/use-add-item'
|
import { handler as useAddItem } from './cart/use-add-item'
|
||||||
@ -15,11 +14,12 @@ import { handler as useLogout } from './auth/use-logout'
|
|||||||
import { handler as useSignup } from './auth/use-signup'
|
import { handler as useSignup } from './auth/use-signup'
|
||||||
|
|
||||||
import fetcher from './fetcher'
|
import fetcher from './fetcher'
|
||||||
|
import swell from './swell'
|
||||||
|
|
||||||
export const swellProvider: Provider = {
|
export const swellProvider: Provider & { swell: any } = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: SWELL_CHECKOUT_URL_COOKIE,
|
cartCookie: SWELL_CHECKOUT_ID_COOKIE,
|
||||||
// storeDomain: STORE_DOMAIN,
|
swell,
|
||||||
fetcher,
|
fetcher,
|
||||||
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
||||||
customer: { useCustomer },
|
customer: { useCustomer },
|
||||||
|
6
framework/swell/swell.ts
Normal file
6
framework/swell/swell.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import swell from 'swell-js'
|
||||||
|
import { SWELL_STORE_ID, SWELL_PUBLIC_KEY } from './const'
|
||||||
|
|
||||||
|
swell.init(SWELL_STORE_ID, SWELL_PUBLIC_KEY)
|
||||||
|
|
||||||
|
export default swell
|
@ -1,33 +1,9 @@
|
|||||||
import * as React from 'react'
|
import { getCommerceProvider, useCommerce as useCoreCommerce } from '@commerce'
|
||||||
import { ReactNode } from 'react'
|
import { vendureProvider, VendureProvider } from './provider'
|
||||||
import {
|
|
||||||
CommerceConfig,
|
|
||||||
CommerceProvider as CoreCommerceProvider,
|
|
||||||
useCommerce as useCoreCommerce,
|
|
||||||
} from '@commerce'
|
|
||||||
import { vendureProvider } from './provider'
|
|
||||||
|
|
||||||
export const vendureConfig: CommerceConfig = {
|
export { vendureProvider }
|
||||||
locale: 'en-us',
|
export type { VendureProvider }
|
||||||
cartCookie: 'session',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type VendureConfig = Partial<CommerceConfig>
|
export const CommerceProvider = getCommerceProvider(vendureProvider)
|
||||||
|
|
||||||
export type VendureProps = {
|
|
||||||
children?: ReactNode
|
|
||||||
locale: string
|
|
||||||
} & VendureConfig
|
|
||||||
|
|
||||||
export function CommerceProvider({ children, ...config }: VendureProps) {
|
|
||||||
return (
|
|
||||||
<CoreCommerceProvider
|
|
||||||
provider={vendureProvider}
|
|
||||||
config={{ ...vendureConfig, ...config }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</CoreCommerceProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCommerce = () => useCoreCommerce()
|
export const useCommerce = () => useCoreCommerce()
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { Provider } from '@commerce'
|
|
||||||
import { handler as useCart } from './cart/use-cart'
|
import { handler as useCart } from './cart/use-cart'
|
||||||
import { handler as useAddItem } from './cart/use-add-item'
|
import { handler as useAddItem } from './cart/use-add-item'
|
||||||
import { handler as useUpdateItem } from './cart/use-update-item'
|
import { handler as useUpdateItem } from './cart/use-update-item'
|
||||||
@ -10,7 +9,7 @@ import { handler as useLogout } from './auth/use-logout'
|
|||||||
import { handler as useSignup } from './auth/use-signup'
|
import { handler as useSignup } from './auth/use-signup'
|
||||||
import { fetcher } from './fetcher'
|
import { fetcher } from './fetcher'
|
||||||
|
|
||||||
export const vendureProvider: Provider = {
|
export const vendureProvider = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: 'session',
|
cartCookie: 'session',
|
||||||
fetcher,
|
fetcher,
|
||||||
@ -19,3 +18,5 @@ export const vendureProvider: Provider = {
|
|||||||
products: { useSearch },
|
products: { useSearch },
|
||||||
auth: { useLogin, useLogout, useSignup },
|
auth: { useLogin, useLogout, useSignup },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type VendureProvider = typeof vendureProvider
|
||||||
|
Loading…
x
Reference in New Issue
Block a user