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 { useMemo } from 'react'
|
||||||
import { SWRHook } from '@vercel/commerce/utils/types'
|
import { SWRHook } from '@vercel/commerce/utils/types'
|
||||||
import useCart, { UseCart } from '@vercel/commerce/cart/use-cart'
|
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 default useCart as UseCart<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<any> = {
|
export const handler: SWRHook<any> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: '',
|
url: `/api/v2/shop/orders`,
|
||||||
|
method: 'GET',
|
||||||
},
|
},
|
||||||
async fetcher() {
|
fetcher: async ({ options, fetch }) => {
|
||||||
return {
|
if (getCartToken()) {
|
||||||
id: '',
|
const syliusCart = await fetch({
|
||||||
createdAt: '',
|
url: `${options.url}/${getCartToken()}`,
|
||||||
currency: { code: '' },
|
method: options.method,
|
||||||
taxesIncluded: '',
|
})
|
||||||
lineItems: [],
|
return normalizeCart(syliusCart)
|
||||||
lineItemsSubtotalPrice: '',
|
|
||||||
subtotalPrice: 0,
|
|
||||||
totalPrice: 0,
|
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
},
|
},
|
||||||
useHook:
|
useHook:
|
||||||
({ useData }) =>
|
({ useData }) =>
|
||||||
(input) => {
|
(input) => {
|
||||||
|
const response = useData({
|
||||||
|
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||||
|
})
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() =>
|
() =>
|
||||||
Object.create(
|
Object.create(response, {
|
||||||
{},
|
|
||||||
{
|
|
||||||
isEmpty: {
|
isEmpty: {
|
||||||
get() {
|
get() {
|
||||||
return true
|
return (response.data?.lineItems.length ?? 0) <= 0
|
||||||
},
|
},
|
||||||
enumerable: true,
|
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_TOKEN = 'sylius_customerToken'
|
||||||
export const SYLIUS_CUSTOMER_ROUTE = 'sylius_customerRoute'
|
export const SYLIUS_CUSTOMER_ROUTE = 'sylius_customerRoute'
|
||||||
|
export const SYLIUS_CART_TOKEN = 'sylius_cartToken'
|
||||||
|
@ -8,5 +8,6 @@ module.exports = {
|
|||||||
env: {
|
env: {
|
||||||
COMMERCE_SEARCH_ENABLED: process.env.COMMERCE_SEARCH_ENABLED,
|
COMMERCE_SEARCH_ENABLED: process.env.COMMERCE_SEARCH_ENABLED,
|
||||||
COMMERCE_CUSTOMERAUTH_ENABLED: process.env.COMMERCE_CUSTOMERAUTH_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 {
|
export interface SyliusProductVariant {
|
||||||
id: number
|
id: number
|
||||||
code: string
|
code: string
|
||||||
optionValues: SyliusProductOptionValues[]
|
optionValues: SyliusProductOptionValue[]
|
||||||
name: string
|
name: string
|
||||||
price: number
|
price: number
|
||||||
originalPrice: number
|
originalPrice: number
|
||||||
@ -32,13 +32,13 @@ export interface SyliusProductOption {
|
|||||||
id: number
|
id: number
|
||||||
code: string
|
code: string
|
||||||
option: string
|
option: string
|
||||||
values: SyliusProductOptionValues[]
|
values: SyliusProductOptionValue[]
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SyliusProductOptionValues {
|
export interface SyliusProductOptionValue {
|
||||||
id: number
|
id: number
|
||||||
code: string
|
code: string
|
||||||
value: 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