forked from crowetic/commerce
Add list of products to the returned wishlist
This commit is contained in:
parent
4772878234
commit
95fd730f0a
@ -1,8 +1,13 @@
|
|||||||
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
import { BigcommerceConfig, getConfig } from '..'
|
|
||||||
import { definitions } from '../definitions/wishlist'
|
import { definitions } from '../definitions/wishlist'
|
||||||
|
import { BigcommerceConfig, getConfig } from '..'
|
||||||
|
import getAllProducts, { ProductEdge } from './get-all-products'
|
||||||
|
|
||||||
export type Wishlist = definitions['wishlist_Full']
|
export type Wishlist = Omit<definitions['wishlist_Full'], 'items'> & {
|
||||||
|
items?: (NonNullable<definitions['wishlist_Full']['items']>[0] & {
|
||||||
|
product?: ProductEdge['node']
|
||||||
|
})[]
|
||||||
|
}
|
||||||
|
|
||||||
export type GetCustomerWishlistResult<
|
export type GetCustomerWishlistResult<
|
||||||
T extends { wishlist?: any } = { wishlist?: Wishlist }
|
T extends { wishlist?: any } = { wishlist?: Wishlist }
|
||||||
@ -15,6 +20,7 @@ export type GetCustomerWishlistVariables = {
|
|||||||
async function getCustomerWishlist(opts: {
|
async function getCustomerWishlist(opts: {
|
||||||
variables: GetCustomerWishlistVariables
|
variables: GetCustomerWishlistVariables
|
||||||
config?: BigcommerceConfig
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
}): Promise<GetCustomerWishlistResult>
|
}): Promise<GetCustomerWishlistResult>
|
||||||
|
|
||||||
async function getCustomerWishlist<
|
async function getCustomerWishlist<
|
||||||
@ -24,25 +30,54 @@ async function getCustomerWishlist<
|
|||||||
url: string
|
url: string
|
||||||
variables: V
|
variables: V
|
||||||
config?: BigcommerceConfig
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
}): Promise<GetCustomerWishlistResult<T>>
|
}): Promise<GetCustomerWishlistResult<T>>
|
||||||
|
|
||||||
async function getCustomerWishlist({
|
async function getCustomerWishlist({
|
||||||
config,
|
config,
|
||||||
variables,
|
variables,
|
||||||
|
includeProducts,
|
||||||
}: {
|
}: {
|
||||||
url?: string
|
url?: string
|
||||||
variables: GetCustomerWishlistVariables
|
variables: GetCustomerWishlistVariables
|
||||||
config?: BigcommerceConfig
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
}): Promise<GetCustomerWishlistResult> {
|
}): Promise<GetCustomerWishlistResult> {
|
||||||
config = getConfig(config)
|
config = getConfig(config)
|
||||||
|
|
||||||
const { data } = await config.storeApiFetch<
|
const { data = [] } = await config.storeApiFetch<
|
||||||
RecursivePartial<{ data: Wishlist[] }>
|
RecursivePartial<{ data: Wishlist[] }>
|
||||||
>(`/v3/wishlists?customer_id=${variables.customerId}`)
|
>(`/v3/wishlists?customer_id=${variables.customerId}`)
|
||||||
const wishlists = (data as RecursiveRequired<typeof data>) ?? []
|
const wishlist = data[0]
|
||||||
const wishlist = wishlists[0]
|
|
||||||
|
|
||||||
return { wishlist }
|
if (includeProducts && wishlist?.items?.length) {
|
||||||
|
const entityIds = wishlist.items
|
||||||
|
?.map((item) => item?.product_id)
|
||||||
|
.filter((id): id is number => !!id)
|
||||||
|
|
||||||
|
if (entityIds?.length) {
|
||||||
|
const graphqlData = await getAllProducts({
|
||||||
|
variables: { first: 100, entityIds },
|
||||||
|
config,
|
||||||
|
})
|
||||||
|
// Put the products in an object that we can use to get them by id
|
||||||
|
const productsById = graphqlData.products.reduce<{
|
||||||
|
[k: number]: ProductEdge
|
||||||
|
}>((prods, p) => {
|
||||||
|
prods[p.node.entityId] = p
|
||||||
|
return prods
|
||||||
|
}, {})
|
||||||
|
// Populate the wishlist items with the graphql products
|
||||||
|
wishlist.items.forEach((item) => {
|
||||||
|
const product = item && productsById[item.product_id!]
|
||||||
|
if (item && product) {
|
||||||
|
item.product = product.node
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { wishlist: wishlist as RecursiveRequired<typeof wishlist> }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getCustomerWishlist
|
export default getCustomerWishlist
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import getCustomerId from '../../operations/get-customer-id'
|
import getCustomerId from '../../operations/get-customer-id'
|
||||||
import type { Wishlist, WishlistHandlers } from '..'
|
|
||||||
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
|
import type { Wishlist, WishlistHandlers } from '..'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
const getWishlist: WishlistHandlers['getWishlist'] = async ({
|
const getWishlist: WishlistHandlers['getWishlist'] = async ({
|
||||||
res,
|
res,
|
||||||
body: { customerToken },
|
body: { customerToken, includeProducts },
|
||||||
config,
|
config,
|
||||||
}) => {
|
}) => {
|
||||||
let result: { data?: Wishlist } = {}
|
let result: { data?: Wishlist } = {}
|
||||||
@ -24,8 +24,10 @@ const getWishlist: WishlistHandlers['getWishlist'] = async ({
|
|||||||
|
|
||||||
const { wishlist } = await getCustomerWishlist({
|
const { wishlist } = await getCustomerWishlist({
|
||||||
variables: { customerId },
|
variables: { customerId },
|
||||||
|
includeProducts,
|
||||||
config,
|
config,
|
||||||
})
|
})
|
||||||
|
|
||||||
result = { data: wishlist }
|
result = { data: wishlist }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,12 @@ import createApiHandler, {
|
|||||||
BigcommerceHandler,
|
BigcommerceHandler,
|
||||||
} from '../utils/create-api-handler'
|
} from '../utils/create-api-handler'
|
||||||
import { BigcommerceApiError } from '../utils/errors'
|
import { BigcommerceApiError } from '../utils/errors'
|
||||||
|
import type { Wishlist } from '../operations/get-customer-wishlist'
|
||||||
import getWishlist from './handlers/get-wishlist'
|
import getWishlist from './handlers/get-wishlist'
|
||||||
import addItem from './handlers/add-item'
|
import addItem from './handlers/add-item'
|
||||||
import removeItem from './handlers/remove-item'
|
import removeItem from './handlers/remove-item'
|
||||||
import { definitions } from '../definitions/wishlist'
|
|
||||||
|
export type { Wishlist }
|
||||||
|
|
||||||
export type ItemBody = {
|
export type ItemBody = {
|
||||||
productId: number
|
productId: number
|
||||||
@ -27,10 +29,11 @@ export type WishlistBody = {
|
|||||||
|
|
||||||
export type AddWishlistBody = { wishlist: WishlistBody }
|
export type AddWishlistBody = { wishlist: WishlistBody }
|
||||||
|
|
||||||
export type Wishlist = definitions['wishlist_Full']
|
|
||||||
|
|
||||||
export type WishlistHandlers = {
|
export type WishlistHandlers = {
|
||||||
getWishlist: BigcommerceHandler<Wishlist, { customerToken?: string }>
|
getWishlist: BigcommerceHandler<
|
||||||
|
Wishlist,
|
||||||
|
{ customerToken?: string; includeProducts?: boolean }
|
||||||
|
>
|
||||||
addItem: BigcommerceHandler<
|
addItem: BigcommerceHandler<
|
||||||
Wishlist,
|
Wishlist,
|
||||||
{ customerToken?: string } & Partial<AddItemBody>
|
{ customerToken?: string } & Partial<AddItemBody>
|
||||||
@ -58,7 +61,10 @@ const wishlistApi: BigcommerceApiHandler<Wishlist, WishlistHandlers> = async (
|
|||||||
try {
|
try {
|
||||||
// Return current wishlist info
|
// Return current wishlist info
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
const body = { customerToken }
|
const body = {
|
||||||
|
customerToken,
|
||||||
|
includeProducts: req.query.products === '1',
|
||||||
|
}
|
||||||
return await handlers['getWishlist']({ req, res, config, body })
|
return await handlers['getWishlist']({ req, res, config, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,23 +11,44 @@ const defaultOpts = {
|
|||||||
|
|
||||||
export type { Wishlist }
|
export type { Wishlist }
|
||||||
|
|
||||||
export const fetcher: HookFetcher<Wishlist | null, { customerId?: number }> = (
|
export interface UseWishlistOptions {
|
||||||
|
includeProducts?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseWishlistInput extends UseWishlistOptions {
|
||||||
|
customerId?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetcher: HookFetcher<Wishlist | null, UseWishlistInput> = (
|
||||||
options,
|
options,
|
||||||
{ customerId },
|
{ customerId, includeProducts },
|
||||||
fetch
|
fetch
|
||||||
) => {
|
) => {
|
||||||
return customerId ? fetch({ ...defaultOpts, ...options }) : null
|
if (!customerId) return null
|
||||||
|
|
||||||
|
// Use a dummy base as we only care about the relative path
|
||||||
|
const url = new URL(options?.url ?? defaultOpts.url, 'http://a')
|
||||||
|
|
||||||
|
if (includeProducts) url.searchParams.set('products', '1')
|
||||||
|
|
||||||
|
return fetch({
|
||||||
|
url: url.pathname + url.search,
|
||||||
|
method: options?.method ?? defaultOpts.method,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extendHook(
|
export function extendHook(
|
||||||
customFetcher: typeof fetcher,
|
customFetcher: typeof fetcher,
|
||||||
swrOptions?: SwrOptions<Wishlist | null, { customerId?: number }>
|
swrOptions?: SwrOptions<Wishlist | null, UseWishlistInput>
|
||||||
) {
|
) {
|
||||||
const useWishlists = () => {
|
const useWishlist = ({ includeProducts }: UseWishlistOptions = {}) => {
|
||||||
const { data: customer } = useCustomer()
|
const { data: customer } = useCustomer()
|
||||||
const response = useCommerceWishlist(
|
const response = useCommerceWishlist(
|
||||||
defaultOpts,
|
defaultOpts,
|
||||||
[['customerId', customer?.entityId]],
|
[
|
||||||
|
['customerId', customer?.entityId],
|
||||||
|
['includeProducts', includeProducts],
|
||||||
|
],
|
||||||
customFetcher,
|
customFetcher,
|
||||||
{
|
{
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
@ -47,9 +68,9 @@ export function extendHook(
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
useWishlists.extend = extendHook
|
useWishlist.extend = extendHook
|
||||||
|
|
||||||
return useWishlists
|
return useWishlist
|
||||||
}
|
}
|
||||||
|
|
||||||
export default extendHook(fetcher)
|
export default extendHook(fetcher)
|
||||||
|
@ -21,4 +21,4 @@ export type HookFetcherOptions = {
|
|||||||
method?: string
|
method?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HookInput = [string, string | number | undefined][]
|
export type HookInput = [string, string | number | boolean | undefined][]
|
||||||
|
@ -20,7 +20,8 @@ export default function Home({
|
|||||||
categories,
|
categories,
|
||||||
brands,
|
brands,
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||||
const { data } = useWishlist()
|
const { data } = useWishlist({ includeProducts: true })
|
||||||
|
console.log(data)
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<div className="grid grid-cols-12 gap-8 mt-3 mb-20">
|
<div className="grid grid-cols-12 gap-8 mt-3 mb-20">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user