mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
vendure custom checkout support #619
This commit is contained in:
parent
87134e2990
commit
7b4a617bde
2
packages/vendure/src/checkout/index.ts
Normal file
2
packages/vendure/src/checkout/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { default as useSubmitCheckout } from './use-submit-checkout'
|
||||
export { default as useCheckout } from './use-checkout'
|
@ -1,16 +1,43 @@
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import useCheckout, {
|
||||
UseCheckout,
|
||||
} from '@vercel/commerce/checkout/use-checkout'
|
||||
import type { GetCheckoutHook } from '@vercel/commerce/types/checkout'
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import { useMemo } from 'react'
|
||||
import { getCartQuery } from '../utils/queries/get-cart-query'
|
||||
import useSubmitCheckout from './use-submit-checkout'
|
||||
|
||||
export default useCheckout as UseCheckout<typeof handler>
|
||||
|
||||
export const handler: SWRHook<any> = {
|
||||
export const handler: SWRHook<GetCheckoutHook> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
query: getCartQuery,
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
useHook:
|
||||
({ useData }) =>
|
||||
async (input) => ({}),
|
||||
useHook: ({ useData }) =>
|
||||
function useHook(input) {
|
||||
const submit = useSubmitCheckout()
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return true
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
submit: {
|
||||
get() {
|
||||
return submit
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}),
|
||||
[response, submit]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
93
packages/vendure/src/checkout/use-submit-checkout.tsx
Normal file
93
packages/vendure/src/checkout/use-submit-checkout.tsx
Normal file
@ -0,0 +1,93 @@
|
||||
import useSubmitCheckout, {
|
||||
UseSubmitCheckout,
|
||||
} from '@vercel/commerce/checkout/use-submit-checkout'
|
||||
import type { SubmitCheckoutHook } from '@vercel/commerce/types/checkout'
|
||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||
import { useCallback } from 'react'
|
||||
import {
|
||||
EligiblePaymentMethodsQuery,
|
||||
TransitionOrderToStateResult,
|
||||
AddPaymentToOrderResult,
|
||||
} from '../../schema'
|
||||
import { addPaymentToOrder } from '../utils/mutations/add-payment-to-order'
|
||||
import { transitionOrderToState } from '../utils/mutations/transition-order-to-state'
|
||||
import { eligiblePaymentMethods } from '../utils/queries/eligible-payment-methods'
|
||||
|
||||
export default useSubmitCheckout as UseSubmitCheckout<typeof handler>
|
||||
|
||||
export const handler: MutationHook<SubmitCheckoutHook> = {
|
||||
fetchOptions: {
|
||||
query: addPaymentToOrder,
|
||||
},
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
const transitionResponse = await fetch<TransitionOrderToStateResult>({
|
||||
...options,
|
||||
query: transitionOrderToState,
|
||||
variables: {
|
||||
state: 'ArrangingPayment',
|
||||
},
|
||||
})
|
||||
if (transitionResponse.__typename === 'OrderStateTransitionError') {
|
||||
throw new CommerceError({
|
||||
code: transitionResponse.errorCode,
|
||||
message: transitionResponse.message,
|
||||
})
|
||||
} else {
|
||||
const paymentMethodsResponse = await fetch<EligiblePaymentMethodsQuery>({
|
||||
...options,
|
||||
query: eligiblePaymentMethods,
|
||||
})
|
||||
|
||||
const paymentMethodCode =
|
||||
paymentMethodsResponse?.eligiblePaymentMethods?.[0]?.code
|
||||
|
||||
if (!paymentMethodCode) {
|
||||
throw new CommerceError({
|
||||
message: 'No Eligible payment methods',
|
||||
})
|
||||
}
|
||||
const paymentResponse = await fetch<AddPaymentToOrderResult>({
|
||||
...options,
|
||||
variables: {
|
||||
input: {
|
||||
method: paymentMethodCode,
|
||||
metadata: {
|
||||
// TODO: Payment provider's token should go in here
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if (paymentResponse.__typename === 'Order') {
|
||||
return {
|
||||
hasPayment: true,
|
||||
hasShipping: true,
|
||||
}
|
||||
} else if (
|
||||
paymentResponse.__typename === 'IneligiblePaymentMethodError' ||
|
||||
paymentResponse.__typename === 'NoActiveOrderError' ||
|
||||
paymentResponse.__typename === 'OrderPaymentStateError' ||
|
||||
paymentResponse.__typename === 'OrderStateTransitionError' ||
|
||||
paymentResponse.__typename === 'PaymentDeclinedError' ||
|
||||
paymentResponse.__typename === 'PaymentFailedError'
|
||||
) {
|
||||
throw new CommerceError(paymentResponse)
|
||||
} else {
|
||||
throw new CommerceError({
|
||||
message: 'Something went wrong with Payment request',
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
useHook: ({ fetch }) =>
|
||||
function useHook() {
|
||||
return useCallback(
|
||||
async function onSubmitCheckout(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch]
|
||||
)
|
||||
},
|
||||
}
|
1
packages/vendure/src/const.ts
Normal file
1
packages/vendure/src/const.ts
Normal file
@ -0,0 +1 @@
|
||||
export const VENDURE_TOKEN = 'vendure.Token'
|
@ -1,17 +1,64 @@
|
||||
import useAddItem, {
|
||||
UseAddItem,
|
||||
UseAddItem
|
||||
} from '@vercel/commerce/customer/address/use-add-item'
|
||||
import { MutationHook } from '@vercel/commerce/utils/types'
|
||||
import type { AddItemHook } from '@vercel/commerce/types/customer/address'
|
||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||
import type { MutationHook } from '@vercel/commerce/utils/types'
|
||||
import { useCallback } from 'react'
|
||||
import {
|
||||
ActiveOrderResult,
|
||||
MutationSetOrderShippingAddressArgs
|
||||
} from '../../../schema'
|
||||
import { setOrderShippingAddress } from '../../utils/mutations/set-order-shipping-address'
|
||||
import { normalizeAddress } from '../../utils/normalize'
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<any> = {
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
query: setOrderShippingAddress,
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
() =>
|
||||
async () => ({}),
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
const variables: MutationSetOrderShippingAddressArgs = {
|
||||
input: {
|
||||
fullName: `${item.firstName || ''} ${item.lastName || ''}`,
|
||||
company: item.company,
|
||||
streetLine1: item.streetNumber,
|
||||
streetLine2: item.apartments,
|
||||
postalCode: item.zipCode,
|
||||
city: item.city,
|
||||
// TODO: Since country is statically coming as a HongKong
|
||||
countryCode: 'JP',
|
||||
},
|
||||
}
|
||||
const data = await fetch<ActiveOrderResult>({
|
||||
...options,
|
||||
variables,
|
||||
})
|
||||
if (data.__typename === 'Order') {
|
||||
return normalizeAddress(data)
|
||||
} else if (data.__typename === 'NoActiveOrderError') {
|
||||
throw new CommerceError({
|
||||
code: data.errorCode,
|
||||
message: data.message,
|
||||
})
|
||||
}
|
||||
},
|
||||
useHook: ({ fetch }) =>
|
||||
function useHook() {
|
||||
const { mutate } = useAddresses()
|
||||
|
||||
return useCallback(
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
36
packages/vendure/src/customer/address/use-addresses.tsx
Normal file
36
packages/vendure/src/customer/address/use-addresses.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import type { GetAddressesHook } from '@vercel/commerce/types/customer/address'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import useAddresses, {
|
||||
UseAddresses,
|
||||
} from '@vercel/commerce/customer/address/use-addresses'
|
||||
import { activeCustomerQuery } from '../../utils/queries/active-customer-query'
|
||||
|
||||
export default useAddresses as UseAddresses<typeof handler>
|
||||
|
||||
export const handler: SWRHook<GetAddressesHook> = {
|
||||
fetchOptions: {
|
||||
query: activeCustomerQuery,
|
||||
},
|
||||
useHook: ({ useData }) =>
|
||||
function useHook(input) {
|
||||
console.log(input, 'hello')
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
@ -1,17 +1,88 @@
|
||||
import useAddItem, {
|
||||
UseAddItem,
|
||||
} from '@vercel/commerce/customer/card/use-add-item'
|
||||
import useCards from '@vercel/commerce/customer/card/use-cards'
|
||||
import { AddItemHook } from '@vercel/commerce/types/customer/card'
|
||||
import { CommerceError } from '@vercel/commerce/utils/errors'
|
||||
import { MutationHook } from '@vercel/commerce/utils/types'
|
||||
import { useCallback } from 'react'
|
||||
import { setOrderBillingAddress } from '../../utils/mutations/set-order-billing-address'
|
||||
import {
|
||||
ActiveOrderResult,
|
||||
EligibleShippingMethodsQuery,
|
||||
MutationSetOrderBillingAddressArgs,
|
||||
SetOrderShippingMethodResult,
|
||||
} from '../../../schema'
|
||||
import { eligibleShippingMethods } from '../../utils/queries/eligible-shipping-methods'
|
||||
import { setOrderShippingMethod } from '../../utils/mutations/set-order-shipping-method'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<any> = {
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
query: setOrderBillingAddress,
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
() =>
|
||||
async () => ({}),
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
const variables: MutationSetOrderBillingAddressArgs = {
|
||||
input: {
|
||||
fullName: `${item.firstName || ''} ${item.lastName || ''}`,
|
||||
company: item.company,
|
||||
streetLine1: item.streetNumber,
|
||||
// TODO: Because of TS error apartments
|
||||
// streetLine2: item.apartments,
|
||||
postalCode: item.zipCode,
|
||||
city: item.city,
|
||||
// TODO: Since country is statically coming as a HongKong
|
||||
countryCode: 'JP',
|
||||
},
|
||||
}
|
||||
const data = await fetch<ActiveOrderResult>({
|
||||
...options,
|
||||
variables,
|
||||
})
|
||||
const eligibleMethods = await fetch<EligibleShippingMethodsQuery>({
|
||||
...options,
|
||||
query: eligibleShippingMethods,
|
||||
})
|
||||
const shippingMethodId =
|
||||
eligibleMethods?.['eligibleShippingMethods']?.[0].id
|
||||
if (shippingMethodId) {
|
||||
await fetch<SetOrderShippingMethodResult>({
|
||||
...options,
|
||||
query: setOrderShippingMethod,
|
||||
variables: {
|
||||
shippingMethodId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (data.__typename === 'Order') {
|
||||
// TODO: Not sure what card we should return
|
||||
return {
|
||||
id: '',
|
||||
mask: '',
|
||||
provider: '',
|
||||
}
|
||||
} else if (data.__typename === 'NoActiveOrderError') {
|
||||
throw new CommerceError({
|
||||
code: data.errorCode,
|
||||
message: data.message,
|
||||
})
|
||||
}
|
||||
},
|
||||
useHook: ({ fetch }) =>
|
||||
function useHook() {
|
||||
const { mutate } = useCards()
|
||||
|
||||
return useCallback(
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
33
packages/vendure/src/customer/card/use-cards.tsx
Normal file
33
packages/vendure/src/customer/card/use-cards.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import type { GetCardsHook } from '@vercel/commerce/types/customer/card'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import useCard, { UseCards } from '@vercel/commerce/customer/card/use-cards'
|
||||
|
||||
export default useCard as UseCards<typeof handler>
|
||||
|
||||
export const handler: SWRHook<GetCardsHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/card',
|
||||
method: 'GET',
|
||||
},
|
||||
useHook: ({ useData }) =>
|
||||
function useHook(input) {
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { Fetcher } from '@vercel/commerce/utils/types'
|
||||
import { FetcherError } from '@vercel/commerce/utils/errors'
|
||||
import { getToken, setToken } from './utils/token'
|
||||
|
||||
async function getText(res: Response) {
|
||||
try {
|
||||
@ -35,12 +36,21 @@ export const fetcher: Fetcher = async ({
|
||||
const hasBody = Boolean(variables || query)
|
||||
const body = hasBody ? JSON.stringify({ query, variables }) : undefined
|
||||
const headers = hasBody ? { 'Content-Type': 'application/json' } : undefined
|
||||
const token = getToken()
|
||||
const res = await fetch(shopApiUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
headers: {
|
||||
...headers,
|
||||
authorization: token ? `Bearer ${token}` : '',
|
||||
},
|
||||
credentials: 'include',
|
||||
})
|
||||
// We're using Vendure Bearer token method
|
||||
const authToken = res.headers.get('vendure-auth-token')
|
||||
if (authToken != null) {
|
||||
setToken(authToken)
|
||||
}
|
||||
if (res.ok) {
|
||||
const { data, errors } = await res.json()
|
||||
if (errors) {
|
||||
|
@ -7,6 +7,12 @@ import { handler as useSearch } from './product/use-search'
|
||||
import { handler as useLogin } from './auth/use-login'
|
||||
import { handler as useLogout } from './auth/use-logout'
|
||||
import { handler as useSignup } from './auth/use-signup'
|
||||
import { handler as useCheckout } from './checkout/use-checkout'
|
||||
import { handler as useSubmitCheckout } from './checkout/use-submit-checkout'
|
||||
import { handler as useCards } from './customer/card/use-cards'
|
||||
import { handler as useAddCardItem } from './customer/card/use-add-item'
|
||||
import { handler as useAddresses } from './customer/address/use-addresses'
|
||||
import { handler as useAddAddressItem } from './customer/address/use-add-item'
|
||||
import { fetcher } from './fetcher'
|
||||
|
||||
export const vendureProvider = {
|
||||
@ -14,8 +20,22 @@ export const vendureProvider = {
|
||||
cartCookie: 'session',
|
||||
fetcher,
|
||||
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
||||
customer: { useCustomer },
|
||||
customer: {
|
||||
useCustomer,
|
||||
card: {
|
||||
useCards,
|
||||
useAddItem: useAddCardItem,
|
||||
},
|
||||
address: {
|
||||
useAddresses,
|
||||
useAddItem: useAddAddressItem,
|
||||
},
|
||||
},
|
||||
products: { useSearch },
|
||||
checkout: {
|
||||
useCheckout,
|
||||
useSubmitCheckout,
|
||||
},
|
||||
auth: { useLogin, useLogout, useSignup },
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { orderAddressFragment } from './order-address-fragment'
|
||||
|
||||
export const cartFragment = /* GraphQL */ `
|
||||
fragment Cart on Order {
|
||||
id
|
||||
@ -12,6 +14,12 @@ export const cartFragment = /* GraphQL */ `
|
||||
customer {
|
||||
id
|
||||
}
|
||||
shippingAddress {
|
||||
...OrderAddressFragment
|
||||
}
|
||||
billingAddress {
|
||||
...OrderAddressFragment
|
||||
}
|
||||
lines {
|
||||
id
|
||||
quantity
|
||||
@ -41,4 +49,5 @@ export const cartFragment = /* GraphQL */ `
|
||||
}
|
||||
}
|
||||
}
|
||||
${orderAddressFragment}
|
||||
`
|
||||
|
@ -0,0 +1,14 @@
|
||||
export const orderAddressFragment = /* GraphQL */ `
|
||||
fragment OrderAddressFragment on OrderAddress {
|
||||
fullName
|
||||
company
|
||||
streetLine1
|
||||
streetLine2
|
||||
city
|
||||
province
|
||||
postalCode
|
||||
country
|
||||
countryCode
|
||||
phoneNumber
|
||||
}
|
||||
`
|
34
packages/vendure/src/utils/mutations/add-payment-to-order.ts
Normal file
34
packages/vendure/src/utils/mutations/add-payment-to-order.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { cartFragment } from '../fragments/cart-fragment'
|
||||
|
||||
export const addPaymentToOrder = /* GraphQL */ `
|
||||
mutation addPaymentToOrder($input: PaymentInput!) {
|
||||
addPaymentToOrder(input: $input) {
|
||||
...Cart
|
||||
... on OrderPaymentStateError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on IneligiblePaymentMethodError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on PaymentFailedError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on PaymentDeclinedError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on OrderStateTransitionError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on NoActiveOrderError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -0,0 +1,14 @@
|
||||
import { cartFragment } from '../../utils/fragments/cart-fragment'
|
||||
|
||||
export const setOrderBillingAddress = /* GraphQL */ `
|
||||
mutation setOrderBillingAddress ($input: CreateAddressInput!){
|
||||
setOrderBillingAddress(input: $input) {
|
||||
...Cart
|
||||
... on NoActiveOrderError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -0,0 +1,10 @@
|
||||
import { cartFragment } from '../fragments/cart-fragment'
|
||||
|
||||
export const setCustomerForOrder = /* GraphQL */ `
|
||||
mutation setCustomerForOrder($input: CreateCustomerInput!) {
|
||||
setCustomerForOrder(input: $input) {
|
||||
...Cart
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -0,0 +1,14 @@
|
||||
import { cartFragment } from '../../utils/fragments/cart-fragment'
|
||||
|
||||
export const setOrderShippingAddress = /* GraphQL */ `
|
||||
mutation setOrderShippingAddress($input: CreateAddressInput!) {
|
||||
setOrderShippingAddress(input: $input) {
|
||||
...Cart
|
||||
... on NoActiveOrderError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -0,0 +1,22 @@
|
||||
import { cartFragment } from '../../utils/fragments/cart-fragment'
|
||||
|
||||
export const setOrderShippingMethod = /* GraphQL */ `
|
||||
mutation setOrderShippingMethod($shippingMethodId: ID!) {
|
||||
setOrderShippingMethod(shippingMethodId: $shippingMethodId) {
|
||||
...Cart
|
||||
... on OrderModificationError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on IneligibleShippingMethodError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
... on NoActiveOrderError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -0,0 +1,14 @@
|
||||
import { cartFragment } from '../fragments/cart-fragment'
|
||||
|
||||
export const transitionOrderToState = /* GraphQL */ `
|
||||
mutation transitionOrderToState($state: String!) {
|
||||
transitionOrderToState(state: $state) {
|
||||
...Cart
|
||||
... on OrderStateTransitionError {
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
${cartFragment}
|
||||
`
|
@ -1,6 +1,7 @@
|
||||
import { Product } from '@vercel/commerce/types/product'
|
||||
import { Cart } from '@vercel/commerce/types/cart'
|
||||
import { CartFragment, SearchResultFragment } from '../../schema'
|
||||
import { CustomerAddressTypes } from '@vercel/commerce/types/customer/address'
|
||||
|
||||
export function normalizeSearchResult(item: SearchResultFragment): Product {
|
||||
return {
|
||||
@ -26,7 +27,10 @@ export function normalizeSearchResult(item: SearchResultFragment): Product {
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeCart(order: CartFragment): Cart {
|
||||
export function normalizeCart(order: CartFragment): Cart & {
|
||||
hasShipping: boolean
|
||||
hasPayment: boolean
|
||||
} {
|
||||
return {
|
||||
id: order.id.toString(),
|
||||
createdAt: order.createdAt,
|
||||
@ -58,5 +62,17 @@ export function normalizeCart(order: CartFragment): Cart {
|
||||
requiresShipping: true,
|
||||
},
|
||||
})),
|
||||
hasShipping: !!order.shippingAddress?.fullName,
|
||||
hasPayment: !!order.billingAddress?.fullName,
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeAddress(
|
||||
order: CartFragment
|
||||
): CustomerAddressTypes['address'] {
|
||||
return {
|
||||
// TODO: Not sure what should return.
|
||||
id: '',
|
||||
mask: '',
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
export const eligiblePaymentMethods = /* GraphQL */ `
|
||||
query eligiblePaymentMethods {
|
||||
eligiblePaymentMethods {
|
||||
id
|
||||
code
|
||||
}
|
||||
}
|
||||
`
|
@ -0,0 +1,8 @@
|
||||
export const eligibleShippingMethods = /* GraphQL */ `
|
||||
query eligibleShippingMethods {
|
||||
eligibleShippingMethods {
|
||||
id
|
||||
code
|
||||
}
|
||||
}
|
||||
`
|
9
packages/vendure/src/utils/token.ts
Normal file
9
packages/vendure/src/utils/token.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { VENDURE_TOKEN } from '../const'
|
||||
|
||||
export const getToken = () => {
|
||||
return localStorage.getItem(VENDURE_TOKEN)
|
||||
}
|
||||
|
||||
export const setToken = (token: string) => {
|
||||
localStorage.setItem(VENDURE_TOKEN, token)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user