Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions components/cart/CartSidebarView/CartSidebarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Link from 'next/link'
import CartItem from '../CartItem'
import s from './CartSidebarView.module.css'
import { Button } from '@components/ui'
// import { UserNav } from '@components/common'
import { UserNav } from '@components/common'
import { useUI } from '@components/ui/context'
import { Bag, Cross, Check } from '@components/icons'
import useCart from '@framework/cart/use-cart'
Expand Down Expand Up @@ -48,7 +48,10 @@ const CartSidebarView: FC = () => {
<Cross className="h-6 w-6" />
</button>
</div>
<div className="space-y-1">{/* <UserNav /> */}</div>
<div className="space-y-1">
{' '}
<UserNav />{' '}
</div>
</div>
</header>

Expand Down
4 changes: 2 additions & 2 deletions components/common/UserNav/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ const LINKS = [
{
name: 'My Profile',
href: '/profile',
} /*,
},
{
name: 'My Cart',
href: '/cart',
},*/,
},
]

const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => {
Expand Down
8 changes: 4 additions & 4 deletions components/common/UserNav/UserNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ interface Props {
const countItem = (count: number, item: LineItem) => count + item.quantity

const UserNav: FC<Props> = ({ className }) => {
//const { data } = useCart()
const { data } = useCart()
const { data: customer } = useCustomer()
const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI()
//const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0
const itemsCount = data?.lineItems.reduce(countItem, 0) ?? 0

return (
<nav className={cn(s.root, className)}>
<div className={s.mainContainer}>
<ul className={s.list}>
{/*<li className={s.item} onClick={toggleSidebar}>
<li className={s.item} onClick={toggleSidebar}>
<Bag />
{itemsCount > 0 && <span className={s.bagCount}>{itemsCount}</span>}
</li>
process.env.COMMERCE_WISHLIST_ENABLED && (
{/*process.env.COMMERCE_WISHLIST_ENABLED && (
<li className={s.item}>
<Link href="/wishlist">
<a onClick={closeSidebarIfPresent} aria-label="Wishlist">
Expand Down
38 changes: 19 additions & 19 deletions components/product/ProductView/ProductView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Swatch, ProductSlider } from '@components/product'
import { Button, Container, Text, useUI } from '@components/ui'
import type { Product } from '@commerce/types/product'
import usePrice from '@framework/product/use-price'
// import { useAddItem } from '@framework/cart'
import { useAddItem } from '@framework/cart'
import { getVariant, SelectedOptions } from '../helpers'
import WishlistButton from '@components/wishlist/WishlistButton'

Expand All @@ -20,7 +20,7 @@ interface Props {
const ProductView: FC<Props> = ({ product }) => {
// TODO: fix this missing argument issue
/* @ts-ignore */
// const addItem = useAddItem()
const addItem = useAddItem()
const { price } = usePrice({
amount: product.price.value,
baseAmount: product.price.retailPrice,
Expand All @@ -32,28 +32,28 @@ const ProductView: FC<Props> = ({ product }) => {

useEffect(() => {
// Selects the default option
// product.variants[0].options?.forEach((v) => {
// setChoices((choices) => ({
// ...choices,
// [v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(),
// }))
// })
product.variants[0].options?.forEach((v) => {
setChoices((choices) => ({
...choices,
[v.displayName.toLowerCase()]: v.values[0].label.toLowerCase(),
}))
})
}, [])

const variant = getVariant(product, choices)

const addToCart = async () => {
// setLoading(true)
// try {
// await addItem({
// productId: String(product.id),
// variantId: String(variant ? variant.id : product.variants[0].id),
// })
// openSidebar()
// setLoading(false)
// } catch (err) {
// setLoading(false)
// }
setLoading(true)
try {
await addItem({
productId: String(product.id),
variantId: String(variant ? variant.id : product.variants[0].id),
})
openSidebar()
setLoading(false)
} catch (err) {
setLoading(false)
}
}

return (
Expand Down
76 changes: 76 additions & 0 deletions framework/commercetools/api/endpoints/cart/add-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { normalizeCart } from '@framework/lib/normalize'
import getCookie from '@framework/api/utils/get-cookie'
import type { CartEndpoint } from '.'
import { createCartMutation } from '@framework/utils/mutations/create-cart-mutation'
import { updateCartMutation } from '@framework/utils/mutations/update-cart-mutation'
import { getCartQuery } from '@framework/utils/queries/get-cart-query'
import type { CommercetoolsCart } from '@framework/types/cart'

//TODO: Use anonymous session, set customerId on cart and handle currency with locale
const addItem: CartEndpoint['handlers']['addItem'] = async ({
res,
body: { cartId, item },
config,
}) => {
if (!item) {
return res.status(404).json({
data: null,
errors: [{ message: 'Missing item' }],
})
}

if (!item.quantity) item.quantity = 1
const { currency } = config
let result = null
if (!cartId) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you create the cart when no id is there? I mean, is not wrong but just want to know the reasons

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the cartId comes from the cookies, and if it is not saved in the cookies we assume that there is no cart created

const body = {
draft: {
currency: currency,
lineItems: [
{
productId: item.productId,
quantity: item.quantity,
variantId: Number(item.variantId),
},
],
},
}
result = (await config.fetch(createCartMutation, { variables: body }))?.data
?.createCart
} else {
const locale = config.getLocale()
const variables = {
id: cartId,
locale: locale,
}
const activeCart: CommercetoolsCart = (
await config.fetch(getCartQuery, { variables })
)?.data?.cart

const body = {
version: activeCart.version,
id: cartId,
actions: [
{
addLineItem: {
productId: item.productId,
variantId: Number(item.variantId),
quantity: item.quantity,
},
},
],
}

result = (await config.fetch(updateCartMutation, { variables: body }))?.data
?.updateCart
}
if (result) {
res.setHeader(
'Set-Cookie',
getCookie(config.cartCookie, result.id, config.cookieMaxAge)
)
res.status(200).json({ data: result && normalizeCart(result) })
}
}

export default addItem
41 changes: 41 additions & 0 deletions framework/commercetools/api/endpoints/cart/get-cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { normalizeCart } from '@framework/lib/normalize'
import { CommercetoolsGraphQLError } from '@framework/api/utils/errors'
import getCookie from '@framework/api/utils/get-cookie'
import type { CommercetoolsCart } from '@framework/types/cart'
import type { CartEndpoint } from '.'
import { getCartQuery } from '@framework/utils/queries/get-cart-query'

// Return current cart info
const getCart: CartEndpoint['handlers']['getCart'] = async ({
res,
body: { cartId },
config,
}) => {
let result: { data?: { cart: CommercetoolsCart } } = {}
const locale = config.getLocale()
if (cartId) {
try {
const variables = {
id: cartId,
locale: locale,
}
result = await config.fetch(getCartQuery, { variables })
} catch (error) {
if (error instanceof CommercetoolsGraphQLError) {
// Remove the cookie if it exists but the cart wasn't found
res.setHeader('Set-Cookie', getCookie(config.cartCookie))
} else {
throw error
}
}
}
let normalizedCart = null
if (result.data) {
normalizedCart = normalizeCart(result.data.cart)
}

res.status(200).json({
data: normalizedCart,
})
}
export default getCart
26 changes: 26 additions & 0 deletions framework/commercetools/api/endpoints/cart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GetAPISchema, createEndpoint } from '@commerce/api'
import cartEndpoint from '@commerce/api/endpoints/cart'
import type { CartSchema } from '../../../types/cart'
import type { CommercetoolsAPI } from '../..'
import getCart from './get-cart'
import addItem from './add-item'
import updateItem from './update-item'
import removeItem from './remove-item'

export type CartAPI = GetAPISchema<CommercetoolsAPI, CartSchema>

export type CartEndpoint = CartAPI['endpoint']

export const handlers: CartEndpoint['handlers'] = {
getCart,
addItem,
updateItem,
removeItem,
}

const cartApi = createEndpoint<CartAPI>({
handler: cartEndpoint,
handlers,
})

export default cartApi
56 changes: 56 additions & 0 deletions framework/commercetools/api/endpoints/cart/remove-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { normalizeCart } from '@framework/lib/normalize'
import getCookie from '@framework/api/utils/get-cookie'
import type { CartEndpoint } from '.'
import { getCartQuery } from '@framework/utils/queries/get-cart-query'
import { updateCartMutation } from '@framework/utils/mutations/update-cart-mutation'
import type { CommercetoolsCart } from '@framework/types/cart'
import findItemQuantity from '@framework/api/utils/find-item-quantity'

const removeItem: CartEndpoint['handlers']['removeItem'] = async ({
res,
body: { cartId, itemId },
config,
}) => {
if (!cartId || !itemId) {
return res.status(404).json({
data: null,
errors: [{ message: 'Invalid request' }],
})
}
const locale = config.getLocale()
const variables = {
id: cartId,
locale: locale,
}
const activeCart: CommercetoolsCart = (
await config.fetch(getCartQuery, { variables })
)?.data?.cart
const quantity: number = findItemQuantity(activeCart.lineItems, itemId)
const body = {
id: cartId,
version: activeCart?.version,
actions: [
{
removeLineItem: {
lineItemId: itemId,
quantity: quantity,
},
},
],
}
const result: CommercetoolsCart = (
await config.fetch(updateCartMutation, { variables: body })
)?.data?.updateCart

res.setHeader(
'Set-Cookie',
result
? // Update the cart cookie
getCookie(config.cartCookie, cartId, config.cookieMaxAge)
: // Remove the cart cookie if the cart was removed (empty items)
getCookie(config.cartCookie)
)
res.status(200).json({ data: result ? normalizeCart(result) : null })
}

export default removeItem
71 changes: 71 additions & 0 deletions framework/commercetools/api/endpoints/cart/update-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { normalizeCart } from '@framework/lib/normalize'
import getCookie from '@framework/api/utils/get-cookie'
import type { CartEndpoint } from '.'
import type { CommercetoolsCart } from '@framework/types/cart'
import { updateCartMutation } from '@framework/utils/mutations/update-cart-mutation'
import { getCartQuery } from '@framework/utils/queries/get-cart-query'
import { QUANTITY_TO_UPDATE } from '@framework/consts'
const updateItem: CartEndpoint['handlers']['updateItem'] = async ({
res,
body: { cartId, itemId, item },
config,
}) => {
if (!cartId || !itemId || !item) {
return res.status(400).json({
data: null,
errors: [{ message: 'Invalid request' }],
})
}
const locale = config.getLocale()
const variables = {
id: cartId,
locale: locale,
}
const activeCart: CommercetoolsCart = (
await config.fetch(getCartQuery, { variables })
)?.data?.cart
const lineItemToUpdate = activeCart
? activeCart.lineItems.find(
(lineItem) => lineItem.productId === item.productId
)
: null

const actions =
lineItemToUpdate &&
lineItemToUpdate.quantity &&
item.quantity &&
lineItemToUpdate.quantity > item.quantity
? {
removeLineItem: {
lineItemId: itemId,
quantity: QUANTITY_TO_UPDATE,
},
}
: {
addLineItem: {
productId: item.productId,
variantId: item.variantId,
quantity: QUANTITY_TO_UPDATE,
},
}

const body = {
version: activeCart.version,
id: activeCart.id,
actions: [actions],
}
try {
const result: CommercetoolsCart = (
await config.fetch(updateCartMutation, { variables: body })
)?.data?.updateCart
res.setHeader(
'Set-Cookie',
getCookie(config.cartCookie, cartId, config.cookieMaxAge)
)
res.status(200).json({ data: result && normalizeCart(result) })
} catch (error) {
throw Error(`Error updating: ${error}`)
}
}

export default updateItem
Loading