mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 07:26:59 +00:00
feat: Add update and remove item
This commit is contained in:
parent
1f0c79e68a
commit
b3911fe0d1
@ -1,4 +1,4 @@
|
||||
import type { Product } from '@commerce/types/product'
|
||||
import type { Product, ProductVariant } from '@commerce/types/product'
|
||||
export type SelectedOptions = Record<string, string | null>
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
|
||||
@ -30,3 +30,22 @@ export function selectDefaultOptionFromProduct(
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
export function getSelectedOptionsIds(
|
||||
variant: ProductVariant,
|
||||
opts: SelectedOptions
|
||||
) {
|
||||
const [selected] = variant.options.filter((option) => {
|
||||
const type = option.displayName.toLowerCase()
|
||||
const typeSelected = option.values.filter(
|
||||
({ label }) => label.toLowerCase() === opts[type]
|
||||
)
|
||||
if (typeSelected.length > 0) return true
|
||||
return false
|
||||
})
|
||||
return selected
|
||||
? {
|
||||
[`${selected.displayName?.toLowerCase()}Id`]: selected.id,
|
||||
}
|
||||
: {}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import Cookies, { CookieAttributes } from 'js-cookie'
|
||||
|
||||
export const getCookie = (name: string): string | undefined => Cookies.get(name)
|
||||
|
||||
const setCookie = (
|
||||
name: string,
|
||||
token?: string,
|
||||
|
7
framework/commercelayer/api/utils/getCredentials.ts
Normal file
7
framework/commercelayer/api/utils/getCredentials.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { getCookie } from './cookies'
|
||||
|
||||
export default function getCredentials() {
|
||||
const endpoint = process.env.NEXT_PUBLIC_COMMERCELAYER_ENDPOINT as string
|
||||
const accessToken = getCookie('CL_TOKEN') as string
|
||||
return { accessToken, endpoint }
|
||||
}
|
26
framework/commercelayer/api/utils/normalizeLineItems.tsx
Normal file
26
framework/commercelayer/api/utils/normalizeLineItems.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
export default function normalizeLineItems(lineItems: any[]) {
|
||||
return lineItems.map((lineItem) => {
|
||||
const id = lineItem.id
|
||||
const attributes = lineItem.attributes
|
||||
return {
|
||||
id,
|
||||
name: attributes.name,
|
||||
productId: attributes.reference,
|
||||
variantId: attributes.reference,
|
||||
quantity: attributes.quantity,
|
||||
price: attributes.unit_amount_float,
|
||||
variant: {
|
||||
id,
|
||||
name: attributes.name,
|
||||
sku: attributes.sku_code,
|
||||
price: attributes.unit_amount_float,
|
||||
image: {
|
||||
url: `/commercelayer_assets/${attributes.reference}_FLAT.png`,
|
||||
altText: 'Black Women Long Sleeve Shirt',
|
||||
width: 1000,
|
||||
height: 1000,
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
@ -1,17 +1,67 @@
|
||||
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import { LineItem, Order } from '@commercelayer/js-sdk'
|
||||
import setCookie, { getCookie } from '@framework/api/utils/cookies'
|
||||
import getCredentials from '@framework/api/utils/getCredentials'
|
||||
import useCart from '@framework/cart/use-cart'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
export const handler: MutationHook<any> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
async fetcher({ input, options, fetch }) {
|
||||
const localOrderId = localStorage.getItem('CL_ORDER')
|
||||
const credentials = getCredentials()
|
||||
const orderId =
|
||||
localOrderId ||
|
||||
(credentials.accessToken &&
|
||||
(await Order.withCredentials(credentials).create({})).id)
|
||||
if (orderId && input.sizeId) {
|
||||
!localOrderId && localStorage.setItem('CL_ORDER', orderId)
|
||||
const lineItem = await LineItem.withCredentials(credentials).create(
|
||||
{
|
||||
skuCode: input.sizeId,
|
||||
order: Order.build({ id: orderId }),
|
||||
quantity: 1,
|
||||
reference: input.variantId,
|
||||
_update_quantity: 1,
|
||||
},
|
||||
// @ts-ignore
|
||||
{ rawResponse: true }
|
||||
)
|
||||
const attributes = lineItem.data.attributes
|
||||
return {
|
||||
id: lineItem.data.id,
|
||||
name: attributes.name,
|
||||
productId: input.productId,
|
||||
variantId: input.variantId,
|
||||
quantity: attributes.quantity,
|
||||
price: attributes.unit_amount_float,
|
||||
variant: {
|
||||
id: lineItem.data.id,
|
||||
name: attributes.name,
|
||||
sku: input.sizeId,
|
||||
price: attributes.unit_amount_float,
|
||||
image: {
|
||||
url: `/commercelayer_assets/${input.variantId}_FLAT.png`,
|
||||
altText: 'Black Women Long Sleeve Shirt',
|
||||
width: 1000,
|
||||
height: 1000,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
() => {
|
||||
return async function addItem() {
|
||||
return {}
|
||||
}
|
||||
return useCallback(
|
||||
async function addItem(input) {
|
||||
return await fetch({ input })
|
||||
},
|
||||
[fetch]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useCart, { UseCart } from '@commerce/cart/use-cart'
|
||||
import { Order } from '@commercelayer/js-sdk'
|
||||
import getCredentials from '@framework/api/utils/getCredentials'
|
||||
import normalizeLineItems from '../api/utils/normalizeLineItems'
|
||||
|
||||
export default useCart as UseCart<typeof handler>
|
||||
|
||||
@ -9,6 +12,27 @@ export const handler: SWRHook<any> = {
|
||||
query: '',
|
||||
},
|
||||
async fetcher() {
|
||||
const id = localStorage.getItem('CL_ORDER') || ''
|
||||
const credentials = getCredentials()
|
||||
if (id && credentials.accessToken) {
|
||||
const clOrder = await Order.withCredentials(credentials)
|
||||
.includes('lineItems')
|
||||
.find(id, { rawResponse: true })
|
||||
const attributes = clOrder.data.attributes
|
||||
const lineItems = clOrder?.included
|
||||
? normalizeLineItems(clOrder?.included)
|
||||
: []
|
||||
return {
|
||||
id,
|
||||
createdAt: attributes.created_at,
|
||||
currency: { code: attributes.currency_code },
|
||||
taxesIncluded: '',
|
||||
lineItems,
|
||||
lineItemsSubtotalPrice: '',
|
||||
subtotalPrice: attributes.subtotal_amount_float,
|
||||
totalPrice: attributes.total_amount_float,
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: '',
|
||||
createdAt: '',
|
||||
@ -22,21 +46,19 @@ export const handler: SWRHook<any> = {
|
||||
},
|
||||
useHook:
|
||||
({ useData }) =>
|
||||
(input) => {
|
||||
() => {
|
||||
const response = useData()
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(
|
||||
{},
|
||||
{
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return true
|
||||
return response.data.lineItems.length === 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}
|
||||
),
|
||||
[]
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
|
||||
import getCredentials from '@framework/api/utils/getCredentials'
|
||||
import { LineItem } from '@commercelayer/js-sdk'
|
||||
|
||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||
|
||||
@ -7,12 +9,19 @@ export const handler: MutationHook<any> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
async fetcher({ input: { id } }) {
|
||||
const credentials = getCredentials()
|
||||
const orderId = localStorage.getItem('CL_ORDER')
|
||||
if (orderId && id) {
|
||||
await LineItem.build({ id }).withCredentials(credentials).destroy()
|
||||
return {}
|
||||
}
|
||||
},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
() => {
|
||||
return async function removeItem(input) {
|
||||
return {}
|
||||
return await fetch({ input })
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
||||
import useCart from '@commerce/cart/use-cart'
|
||||
import { useCallback } from 'react'
|
||||
import getCredentials from '@framework/api/utils/getCredentials'
|
||||
import { LineItem } from '@commercelayer/js-sdk'
|
||||
|
||||
export default useUpdateItem as UseUpdateItem<any>
|
||||
|
||||
@ -7,12 +11,44 @@ export const handler: MutationHook<any> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
async fetcher({ input: { item, quantity } }) {
|
||||
const credentials = getCredentials()
|
||||
const orderId = localStorage.getItem('CL_ORDER')
|
||||
if (orderId && item.id) {
|
||||
const lineItem = (await LineItem.build({
|
||||
id: item.id,
|
||||
})
|
||||
.withCredentials(credentials)
|
||||
// @ts-ignore
|
||||
.update({ quantity }, null, { rawResponse: true })) as any
|
||||
const attributes = lineItem.data.attributes
|
||||
return {
|
||||
id: lineItem.data.id,
|
||||
name: attributes.name,
|
||||
productId: item.productId,
|
||||
variantId: item.variantId,
|
||||
quantity: attributes.quantity,
|
||||
price: attributes.unit_amount_float,
|
||||
variant: {
|
||||
id: lineItem.data.id,
|
||||
name: attributes.name,
|
||||
sku: lineItem.data.sku_code,
|
||||
price: attributes.unit_amount_float,
|
||||
image: {
|
||||
url: `/commercelayer_assets/${item.variantId}_FLAT.png`,
|
||||
altText: 'Black Women Long Sleeve Shirt',
|
||||
width: 1000,
|
||||
height: 1000,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
useHook:
|
||||
({ fetch }) =>
|
||||
() => {
|
||||
return async function addItem() {
|
||||
return {}
|
||||
({ item }) => {
|
||||
return async function updateItem(input) {
|
||||
return await fetch({ input: { item, ...input } })
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"provider": "commercelayer",
|
||||
"features": {
|
||||
"wishlist": false,
|
||||
"cart": false,
|
||||
"cart": true,
|
||||
"search": false,
|
||||
"customerAuth": true
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user