Skip to content

Commit

Permalink
Feature/icky 176 (vercel#8)
Browse files Browse the repository at this point in the history
* GetProduct Initial Commit

* addItemToCart function implemneted

* Add Item to cart functionality implemented

* ICKY-166-getProducts-and-getProduct (vercel#6)

* GetProduct Initial Commit

* Passed productCode as Slug to get-product

* Moved currencyCode in Config file

* Icky 173 (vercel#9)

* Initial commit related to getAllPages

* Initial Changes

* Making documentListName configurable

* fixing dynamic page rendering and adding typescript code

Co-authored-by: amolnadagonde <amol.nadagonde@kibocommerce.com>
Co-authored-by: kibo-sushant <sushant.jadhav@blueconchtech.com>

* addItemToCart function implemneted

Conflicts resolved

* Add Item to cart functionality implemented

* booleans removed from query

* cart size option enabled

* updated addItem for with and without variants products

Co-authored-by: kibo-sushant <sushant.jadhav@blueconchtech.com>
Co-authored-by: Chandradeepta <43542673+Chandradeepta@users.noreply.github.com>
Co-authored-by: kibo-sushant <89385472+kibo-sushant@users.noreply.github.com>
Co-authored-by: kibo-kevinwatts <85258296+kibo-kevinwatts@users.noreply.github.com>
Co-authored-by: amolnadagonde <amol.nadagonde@kibocommerce.com>
  • Loading branch information
6 people committed Nov 17, 2021
1 parent 072ee0c commit aa8f6b9
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 59 deletions.
104 changes: 104 additions & 0 deletions framework/kibocommerce/api/endpoints/cart/add-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Product } from './../../../schema.d'
import { normalizeCart } from '../../../lib/normalize'
import type { CartEndpoint } from '.'
import addToCurrentCartMutation from '@framework/api/mutations/addToCart-mutation'
import getAnonymousShopperToken from '@framework/api/utils/get-anonymous-shopper-token'
import { getCookieExpirationDate } from '@framework/lib/getCookieExpirationDate'
import { prepareSetCookie } from '@framework/lib/prepareSetCookie'
import { setCookies } from '@framework/lib/setCookie'
import { getProductQuery } from '@framework/api/queries/get-product-query'
import { getCartQuery } from '@framework/api/queries/getCartQuery'

const buildAddToCartVariables = ({
productId,
variantId,
quantity = 1,
productResponse,
}: {
productId: string
variantId: string
quantity: number
productResponse: any
}) => {
const { product } = productResponse.data

const selectedValue = product.variations?.find(
(v: any) => v.productCode === variantId
).options[0].value

const options = product.options?.map((po: any) => ({
attributeFQN: po.attributeFQN,
name: po.attributeDetail.name,
value: po.values.find((v: any) => v.value == selectedValue).value,
}))

return {
productToAdd: {
product: {
productCode: productId,
variationProductCode: variantId ? variantId : null,
options,
},
quantity,
fulfillmentMethod: 'Ship',
},
}
}

const addItem: CartEndpoint['handlers']['addItem'] = async ({
req,
res,
body: { cartId, item },
config,
}) => {
if (!item) {
return res.status(400).json({
data: null,
errors: [{ message: 'Missing item' }],
})
}
if (!item.quantity) item.quantity = 1

const productResponse = await config.fetch(getProductQuery, {
variables: { productCode: item?.productId },
})

const token = req.cookies[config.customerCookie]

let accessToken = token ? JSON.parse(token).accessToken : null

if (!accessToken) {
const response: any = await getAnonymousShopperToken({ config })
accessToken = response?.accessToken
const cookieExpirationDate = getCookieExpirationDate(
config.customerCookieMaxAgeInDays
)

const authCookie = prepareSetCookie(
config.customerCookie,
JSON.stringify(response),
response?.accessTokenExpiration ? { expires: cookieExpirationDate } : {}
)
setCookies(res, [authCookie])
}

const addToCartResponse = await config.fetch(
addToCurrentCartMutation,
{
variables: buildAddToCartVariables({ ...item, productResponse }),
},
{ headers: { 'x-vol-user-claims': accessToken } }
)
let currentCart = null
if (addToCartResponse.data.addItemToCurrentCart) {
let result = await config.fetch(
getCartQuery,
{},
{ headers: { 'x-vol-user-claims': accessToken } }
)
currentCart = result?.data?.currentCart
}
res.status(200).json({ data: normalizeCart(currentCart) })
}

export default addItem
16 changes: 15 additions & 1 deletion framework/kibocommerce/api/endpoints/cart/get-cart.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import getAnonymousShopperToken from '@framework/api/utils/get-anonymous-shopper-token'
import { normalizeCart } from '@framework/lib/normalize'
import { Cart } from '@framework/schema'
import type { CartEndpoint } from '.'
import { getCartQuery } from '../../queries/getCartQuery'

const getCart: CartEndpoint['handlers']['getCart'] = async ({
req,
res,
body: { cartId },
config,
}) => {
let currentCart: Cart = {}
try {
let result = await config.fetch(getCartQuery)
const token = req.cookies[config.customerCookie]
let accessToken = token ? JSON.parse(token).accessToken : null

if (!accessToken) {
const response: any = await getAnonymousShopperToken({config})
accessToken = response?.accessToken
}

let result = await config.fetch(
getCartQuery,
{},
{ headers: { 'x-vol-user-claims': accessToken } }
)
currentCart = result?.data?.currentCart
} catch (error) {
throw error
Expand Down
8 changes: 4 additions & 4 deletions framework/kibocommerce/api/endpoints/cart/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { GetAPISchema, createEndpoint } from '@commerce/api'
import cartEndpoint from '@commerce/api/endpoints/cart'
// import type { CartSchema } from '../../../types/cart'
import type { KiboCommerceAPI } from '../..'
import getCart from './get-cart'
// import addItem from './add-item'
import getCart from './get-cart';
import addItem from './add-item';

// import updateItem from './update-item'
// import removeItem from './remove-item'

Expand All @@ -13,7 +13,7 @@ export type CartEndpoint = CartAPI['endpoint']

export const handlers: CartEndpoint['handlers'] = {
getCart,
// addItem,
addItem,
// updateItem,
// removeItem,
}
Expand Down
32 changes: 32 additions & 0 deletions framework/kibocommerce/api/fragments/cartItemDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export const cartItemDetails = /*GraphQL*/`
fragment cartItemDetails on CartItem {
id
product {
productCode
name
description
imageUrl
options {
attributeFQN
name
value
}
properties {
attributeFQN
name
values {
value
}
}
sku
price {
price
salePrice
}
categories {
id
}
}
quantity
}
`;
12 changes: 12 additions & 0 deletions framework/kibocommerce/api/mutations/addToCart-mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { cartItemDetails } from './../fragments/cartItemDetails'

const addToCurrentCartMutation = /*GraphQL*/ `
${cartItemDetails}
mutation addToCart($productToAdd:CartItemInput!){
addItemToCurrentCart(cartItemInput: $productToAdd) {
...cartItemDetails
}
}`

export default addToCurrentCartMutation
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ export const getAnonymousShopperTokenQuery = /* GraphQL */ `
query {
getAnonymousShopperToken {
accessToken
accessTokenExpiration
refreshToken
refreshTokenExpiration
jwtAccessToken
}
}
`
`
7 changes: 3 additions & 4 deletions framework/kibocommerce/api/utils/fetch-graphql-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { FetcherError } from '@commerce/utils/errors'
import type { GraphQLFetcher } from '@commerce/api'
import type { KiboCommerceConfig } from '../index'
import fetch from './fetch'
import getAnonymousShopperToken from './get-anonymous-shopper-token'

const fetchGraphqlApi: (
getConfig: () => KiboCommerceConfig
Expand All @@ -16,12 +15,12 @@ const fetchGraphqlApi: (
...fetchOptions,
method: 'POST',
headers: {
Authorization: `Bearer ${config.apiToken}`,
...fetchOptions?.headers,
Authorization: `Bearer ${config.apiToken}`,
'Content-Type': 'application/json',
// Need to fetch access token from cookie
'x-vol-user-claims':
'z40ROeWoZYd65SxBHSqnq/j/SRP0tIBHAf/3Sxw2MJLS8lmj1sF9Y+8eWaTObnCbAtFkiNx/BPfojtUFYQj2P9aVPgHsR+IaTpeAdfG1AM0fMLFvIrDbHK6E/BKhupU5NJQAFwYsoImRzIh8jOpXrigBWH9OW/dBjOtuAJaDaDRHdZ3xyDKZQnFa24IZN6b/UZYHf4r6arUU3MjPoVibQdtBObtJPYwe3XtOI/xaInqpehTJPq9nTZlTWR8Tv59UelC4bVWIuGtSAdawmuSS7H8pb5PemmB9MwMeLkGaWZsaRdxMfdOJE8REGqOYr3j89iEj/0a6G1zraVbLzGXyW0hVkz6InxARzA4p96n2n+ZCwWI/olcQKTxJCLsoZ3dVVkWretgUJFMxzAbzDEDtUIda+VuhzhhmlY4SFgOjxtSIudlyAcYs4xwksjDhBtt8RrTyobCUUau1sfht9Zf1pw==',
// 'x-vol-user-claims':
// 'z40ROeWoZYd65SxBHSqnq/j/SRP0tIBHAf/3Sxw2MJLS8lmj1sF9Y+8eWaTObnCbAtFkiNx/BPfojtUFYQj2P9aVPgHsR+IaTpeAdfG1AM0fMLFvIrDbHK6E/BKhupU5NJQAFwYsoImRzIh8jOpXrigBWH9OW/dBjOtuAJaDaDRHdZ3xyDKZQnFa24IZN6b/UZYHf4r6arUU3MjPoVibQdtBObtJPYwe3XtOI/xaInqpehTJPq9nTZlTWR8Tv59UelC4bVWIuGtSAdawmuSS7H8pb5PemmB9MwMeLkGaWZsaRdxMfdOJE8REGqOYr3j89iEj/0a6G1zraVbLzGXyW0hVkz6InxARzA4p96n2n+ZCwWI/olcQKTxJCLsoZ3dVVkWretgUJFMxzAbzDEDtUIda+VuhzhhmlY4SFgOjxtSIudlyAcYs4xwksjDhBtt8RrTyobCUUau1sfht9Zf1pw==',
},
body: JSON.stringify({
query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ async function getAnonymousShopperToken({
config: KiboCommerceConfig
}): Promise<string | undefined> {
const { data } = await config.fetch(getAnonymousShopperTokenQuery)
return String(data?.getAnonymousShopperToken?.accessToken)
return data?.getAnonymousShopperToken
}

export default getAnonymousShopperToken
49 changes: 38 additions & 11 deletions framework/kibocommerce/cart/use-add-item.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
import { useCallback } from 'react'
import type { MutationHook } from '@commerce/utils/types'
import { CommerceError } from '@commerce/utils/errors'
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
import { MutationHook } from '@commerce/utils/types'
import type { AddItemHook } from '@commerce/types/cart'
import useCart from './use-cart'

export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<any> = {

export const handler: MutationHook<AddItemHook> = {
fetchOptions: {
query: '',
url: '/api/cart',
method: 'POST',
},
async fetcher({ input: item, options, fetch }) {
if (
item.quantity &&
(!Number.isInteger(item.quantity) || item.quantity! < 1)
) {
throw new CommerceError({
message: 'The item quantity has to be a valid integer greater than 0',
})
}

const data = await fetch({
...options,
body: { item },
})

return data
},
useHook: ({ fetch }) => () => {
const { mutate } = useCart()

return useCallback(
async function addItem(input) {
const data = await fetch({ input })
await mutate(data, false)
return data
},
[fetch, mutate]
)
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() => {
return async function addItem() {
return {}
}
},
}

0 comments on commit aa8f6b9

Please sign in to comment.