mirror of
https://github.com/vercel/commerce.git
synced 2025-06-08 09:16:58 +00:00
create use-cart hook
This commit is contained in:
parent
daba93efbe
commit
8adaa98c8d
@ -1,42 +1,43 @@
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||
import useCart, { UseCart } from '@vercel/commerce/cart/use-cart'
|
||||
import { getCartToken } from '../utils/token/cart-token'
|
||||
import { normalizeCart } from '../utils/normalize/normalize-cart'
|
||||
|
||||
export default useCart as UseCart<typeof handler>
|
||||
|
||||
export const handler: SWRHook<any> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
url: `/api/v2/shop/orders`,
|
||||
method: 'GET',
|
||||
},
|
||||
async fetcher() {
|
||||
return {
|
||||
id: '',
|
||||
createdAt: '',
|
||||
currency: { code: '' },
|
||||
taxesIncluded: '',
|
||||
lineItems: [],
|
||||
lineItemsSubtotalPrice: '',
|
||||
subtotalPrice: 0,
|
||||
totalPrice: 0,
|
||||
fetcher: async ({ options, fetch }) => {
|
||||
if (getCartToken()) {
|
||||
const syliusCart = await fetch({
|
||||
url: `${options.url}/${getCartToken()}`,
|
||||
method: options.method,
|
||||
})
|
||||
return normalizeCart(syliusCart)
|
||||
}
|
||||
return null
|
||||
},
|
||||
useHook:
|
||||
({ useData }) =>
|
||||
(input) => {
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(
|
||||
{},
|
||||
{
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return true
|
||||
return (response.data?.lineItems.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}
|
||||
),
|
||||
[]
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -2,3 +2,4 @@ export const API_URL = process.env.NEXT_PUBLIC_SYLIUS_API_URL
|
||||
|
||||
export const SYLIUS_CUSTOMER_TOKEN = 'sylius_customerToken'
|
||||
export const SYLIUS_CUSTOMER_ROUTE = 'sylius_customerRoute'
|
||||
export const SYLIUS_CART_TOKEN = 'sylius_cartToken'
|
||||
|
@ -8,5 +8,6 @@ module.exports = {
|
||||
env: {
|
||||
COMMERCE_SEARCH_ENABLED: process.env.COMMERCE_SEARCH_ENABLED,
|
||||
COMMERCE_CUSTOMERAUTH_ENABLED: process.env.COMMERCE_CUSTOMERAUTH_ENABLED,
|
||||
COMMERCE_CART_ENABLED: process.env.COMMERCE_CART_ENABLED,
|
||||
},
|
||||
}
|
||||
|
25
packages/sylius/src/types/cart.ts
Normal file
25
packages/sylius/src/types/cart.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import {
|
||||
SyliusProduct,
|
||||
SyliusProductOptionValue,
|
||||
SyliusProductVariant,
|
||||
} from './products'
|
||||
|
||||
export interface SyliusOrder {
|
||||
id: number
|
||||
currencyCode: string
|
||||
taxTotal: number
|
||||
itemsTotal: number
|
||||
total: number
|
||||
items: SyliusOrderItem[]
|
||||
}
|
||||
|
||||
export interface SyliusOrderItem {
|
||||
id: number
|
||||
productName: string
|
||||
quantity: number
|
||||
unitPrice: number
|
||||
discountedUnitPrice: number
|
||||
variant: SyliusProductVariant
|
||||
optionValues: SyliusProductOptionValue[]
|
||||
product: SyliusProduct
|
||||
}
|
@ -21,7 +21,7 @@ export interface SyliusProductImage {
|
||||
export interface SyliusProductVariant {
|
||||
id: number
|
||||
code: string
|
||||
optionValues: SyliusProductOptionValues[]
|
||||
optionValues: SyliusProductOptionValue[]
|
||||
name: string
|
||||
price: number
|
||||
originalPrice: number
|
||||
@ -32,13 +32,13 @@ export interface SyliusProductOption {
|
||||
id: number
|
||||
code: string
|
||||
option: string
|
||||
values: SyliusProductOptionValues[]
|
||||
values: SyliusProductOptionValue[]
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface SyliusProductOptionValues {
|
||||
export interface SyliusProductOptionValue {
|
||||
id: number
|
||||
code: string
|
||||
value: string
|
||||
|
82
packages/sylius/src/utils/normalize/normalize-cart.ts
Normal file
82
packages/sylius/src/utils/normalize/normalize-cart.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import {
|
||||
Cart,
|
||||
ProductVariant,
|
||||
SelectedOption,
|
||||
} from '@vercel/commerce/types/cart'
|
||||
import { LineItem } from '@vercel/commerce/types/cart'
|
||||
import { SyliusOrder, SyliusOrderItem } from 'types/cart'
|
||||
import {
|
||||
SyliusProduct,
|
||||
SyliusProductOption,
|
||||
SyliusProductOptionValue,
|
||||
SyliusProductVariant,
|
||||
} from 'types/products'
|
||||
import { normalizeProductImage } from './normalize-product'
|
||||
|
||||
export const normalizeCart = (syliusOrder: SyliusOrder): Cart => {
|
||||
return {
|
||||
id: syliusOrder.id.toString(),
|
||||
createdAt: '',
|
||||
currency: { code: syliusOrder.currencyCode },
|
||||
taxesIncluded: syliusOrder.taxTotal > 0,
|
||||
lineItems: syliusOrder.items.map((item) => normalizeOrderItem(item)),
|
||||
lineItemsSubtotalPrice: syliusOrder.itemsTotal / 100,
|
||||
subtotalPrice: syliusOrder.itemsTotal / 100,
|
||||
totalPrice: syliusOrder.total / 100,
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeOrderItem = (syliusOrderItem: SyliusOrderItem): LineItem => {
|
||||
return {
|
||||
id: syliusOrderItem.id.toString(),
|
||||
variantId: syliusOrderItem.variant.id.toString(),
|
||||
productId: syliusOrderItem.product.id.toString(),
|
||||
name: syliusOrderItem.productName,
|
||||
quantity: syliusOrderItem.quantity,
|
||||
discounts: [],
|
||||
path: syliusOrderItem.product.slug,
|
||||
variant: normalizeOrderItemVariant(
|
||||
syliusOrderItem.variant,
|
||||
syliusOrderItem.product
|
||||
),
|
||||
options: syliusOrderItem.variant.optionValues.map((optionValue) =>
|
||||
normalizeOrderItemOptionValue(
|
||||
optionValue,
|
||||
syliusOrderItem.product.options
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeOrderItemVariant = (
|
||||
syliusVariant: SyliusProductVariant,
|
||||
syliusProduct: SyliusProduct
|
||||
): ProductVariant => {
|
||||
return {
|
||||
id: syliusVariant.id.toString(),
|
||||
sku: '',
|
||||
name: syliusVariant.name,
|
||||
requiresShipping: false,
|
||||
price: syliusVariant.price / 100,
|
||||
listPrice: syliusVariant.originalPrice / 100,
|
||||
isInStock: syliusVariant.inStock,
|
||||
image:
|
||||
syliusProduct.images.length > 0
|
||||
? normalizeProductImage(syliusProduct.images[0])
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeOrderItemOptionValue = (
|
||||
optionValue: SyliusProductOptionValue,
|
||||
options: SyliusProductOption[]
|
||||
): SelectedOption => {
|
||||
const rightOption = options.filter((option) =>
|
||||
option.values.some((value) => value.code === optionValue.code)
|
||||
)[0]
|
||||
return {
|
||||
id: rightOption.id.toString(),
|
||||
name: rightOption.name,
|
||||
value: optionValue.value,
|
||||
}
|
||||
}
|
11
packages/sylius/src/utils/token/cart-token.ts
Normal file
11
packages/sylius/src/utils/token/cart-token.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SYLIUS_CART_TOKEN } from '../../const'
|
||||
|
||||
export const getCartToken = () => localStorage.getItem(SYLIUS_CART_TOKEN)
|
||||
|
||||
export const setCartToken = (token: string | null) => {
|
||||
if (!token) {
|
||||
localStorage.removeItem(SYLIUS_CART_TOKEN)
|
||||
} else {
|
||||
localStorage.setItem(SYLIUS_CART_TOKEN, token)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user