mirror of
https://github.com/vercel/commerce.git
synced 2025-05-22 01:16:58 +00:00
feat: add cart operations
This commit is contained in:
parent
b17652b26b
commit
c2ec7d05b2
@ -10,15 +10,43 @@ function formatErrorMessage(err: Error): string {
|
|||||||
|
|
||||||
export async function POST(req: NextRequest): Promise<Response> {
|
export async function POST(req: NextRequest): Promise<Response> {
|
||||||
const cartId = cookies().get('cartId')?.value;
|
const cartId = cookies().get('cartId')?.value;
|
||||||
const { merchandiseId, isBigCommerceAPI } = await req.json();
|
const { merchandiseId, isBigCommerceAPI, lineId, productId, quantity, variantId } = await req.json();
|
||||||
|
|
||||||
if ((!isBigCommerceAPI && !cartId?.length) || !merchandiseId?.length) {
|
if (!isBigCommerceAPI && (!cartId?.length || !merchandiseId?.length)) {
|
||||||
return NextResponse.json({ error: 'Missing cartId or variantId' }, { status: 400 });
|
return NextResponse.json({ error: 'Missing cartId or variantId' }, { status: 400 });
|
||||||
} else if (isBigCommerceAPI && !merchandiseId?.length) {
|
} else if (!isBigCommerceAPI && !merchandiseId?.length) {
|
||||||
return NextResponse.json({ error: 'Missing variantId' }, { status: 400 });
|
return NextResponse.json({ error: 'Missing variantId' }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cartId && isBigCommerceAPI && lineId && !variantId || quantity === 0) {
|
||||||
|
try {
|
||||||
|
await removeFromCart(cartId!, [lineId]);
|
||||||
|
|
||||||
|
return NextResponse.json({ status: 204 });
|
||||||
|
} catch (e) {
|
||||||
|
if (isVercelCommerceError(e)) {
|
||||||
|
return NextResponse.json({ message: formatErrorMessage(e.message) }, { status: e.status });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await addToCart(cartId || '', [{ merchandiseId, quantity: 1 }]);
|
const { id: cartEntityId } = await addToCart(cartId || '', [{ merchandiseId, quantity: 1, productId }]);
|
||||||
|
|
||||||
|
if ( isBigCommerceAPI && cartEntityId) {
|
||||||
|
const response = NextResponse.json({ status: 204 });
|
||||||
|
|
||||||
|
response.cookies.set('cartId', cartEntityId, {
|
||||||
|
path: '/',
|
||||||
|
sameSite: 'strict',
|
||||||
|
secure: process.env.NODE_ENV === 'production'
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({ status: 204 });
|
return NextResponse.json({ status: 204 });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isVercelCommerceError(e)) {
|
if (isVercelCommerceError(e)) {
|
||||||
@ -31,7 +59,7 @@ export async function POST(req: NextRequest): Promise<Response> {
|
|||||||
|
|
||||||
export async function PUT(req: NextRequest): Promise<Response> {
|
export async function PUT(req: NextRequest): Promise<Response> {
|
||||||
const cartId = cookies().get('cartId')?.value;
|
const cartId = cookies().get('cartId')?.value;
|
||||||
const { variantId, quantity, lineId } = await req.json();
|
const { variantId, quantity, lineId, productId } = await req.json();
|
||||||
|
|
||||||
if (!cartId || !variantId || !quantity || !lineId) {
|
if (!cartId || !variantId || !quantity || !lineId) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@ -44,9 +72,11 @@ export async function PUT(req: NextRequest): Promise<Response> {
|
|||||||
{
|
{
|
||||||
id: lineId,
|
id: lineId,
|
||||||
merchandiseId: variantId,
|
merchandiseId: variantId,
|
||||||
quantity
|
quantity,
|
||||||
|
productId
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return NextResponse.json({ status: 204 });
|
return NextResponse.json({ status: 204 });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isVercelCommerceError(e)) {
|
if (isVercelCommerceError(e)) {
|
||||||
@ -57,6 +87,8 @@ export async function PUT(req: NextRequest): Promise<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: delete route handler fails
|
||||||
|
// https://github.com/vercel/next.js/issues/48096
|
||||||
export async function DELETE(req: NextRequest): Promise<Response> {
|
export async function DELETE(req: NextRequest): Promise<Response> {
|
||||||
const cartId = cookies().get('cartId')?.value;
|
const cartId = cookies().get('cartId')?.value;
|
||||||
const { lineId } = await req.json();
|
const { lineId } = await req.json();
|
||||||
|
@ -14,9 +14,10 @@ export default function DeleteItemButton({ item }: { item: CartItem }) {
|
|||||||
setRemoving(true);
|
setRemoving(true);
|
||||||
|
|
||||||
const response = await fetch(`/api/cart`, {
|
const response = await fetch(`/api/cart`, {
|
||||||
method: 'DELETE',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
lineId: item.id
|
lineId: item.id,
|
||||||
|
isBigCommerceAPI: true,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
@ -21,11 +21,13 @@ export default function EditItemQuantityButton({
|
|||||||
setEditing(true);
|
setEditing(true);
|
||||||
|
|
||||||
const response = await fetch(`/api/cart`, {
|
const response = await fetch(`/api/cart`, {
|
||||||
method: type === 'minus' && item.quantity - 1 === 0 ? 'DELETE' : 'PUT',
|
method: type === 'minus' && item.quantity - 1 === 0 ? 'POST' : 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
lineId: item.id,
|
lineId: item.id,
|
||||||
|
productId: item.merchandise.product.handle,
|
||||||
variantId: item.merchandise.id,
|
variantId: item.merchandise.id,
|
||||||
quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1
|
quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1,
|
||||||
|
isBigCommerceAPI: true
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ import Link from 'next/link';
|
|||||||
import CloseIcon from 'components/icons/close';
|
import CloseIcon from 'components/icons/close';
|
||||||
import ShoppingBagIcon from 'components/icons/shopping-bag';
|
import ShoppingBagIcon from 'components/icons/shopping-bag';
|
||||||
import Price from 'components/price';
|
import Price from 'components/price';
|
||||||
import { DEFAULT_OPTION } from 'lib/constants';
|
|
||||||
import type { VercelCart as Cart } from 'lib/bigcommerce/types';
|
import type { VercelCart as Cart } from 'lib/bigcommerce/types';
|
||||||
|
import { DEFAULT_OPTION } from 'lib/constants';
|
||||||
import { createUrl } from 'lib/utils';
|
import { createUrl } from 'lib/utils';
|
||||||
import DeleteItemButton from './delete-item-button';
|
import DeleteItemButton from './delete-item-button';
|
||||||
import EditItemQuantityButton from './edit-item-quantity-button';
|
import EditItemQuantityButton from './edit-item-quantity-button';
|
||||||
@ -81,8 +81,10 @@ export default function CartModal({
|
|||||||
<ul className="flex-grow overflow-auto p-6">
|
<ul className="flex-grow overflow-auto p-6">
|
||||||
{cart.lines.map((item, i) => {
|
{cart.lines.map((item, i) => {
|
||||||
const merchandiseSearchParams = {} as MerchandiseSearchParams;
|
const merchandiseSearchParams = {} as MerchandiseSearchParams;
|
||||||
|
let subTitleWithSelectedOptions = '';
|
||||||
|
|
||||||
item.merchandise.selectedOptions.forEach(({ name, value }) => {
|
item.merchandise.selectedOptions.forEach(({ name, value }) => {
|
||||||
|
subTitleWithSelectedOptions += `${name}: ${value} `;
|
||||||
if (value !== DEFAULT_OPTION) {
|
if (value !== DEFAULT_OPTION) {
|
||||||
merchandiseSearchParams[name.toLowerCase()] = value;
|
merchandiseSearchParams[name.toLowerCase()] = value;
|
||||||
}
|
}
|
||||||
@ -118,14 +120,14 @@ export default function CartModal({
|
|||||||
</span>
|
</span>
|
||||||
{item.merchandise.title !== DEFAULT_OPTION ? (
|
{item.merchandise.title !== DEFAULT_OPTION ? (
|
||||||
<p className="text-sm" data-testid="cart-product-variant">
|
<p className="text-sm" data-testid="cart-product-variant">
|
||||||
{item.merchandise.title}
|
{item.merchandise.title === item.merchandise.product.title && subTitleWithSelectedOptions ? subTitleWithSelectedOptions : item.merchandise.title}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<Price
|
<Price
|
||||||
className="flex flex-col justify-between space-y-2 text-sm"
|
className="flex flex-col justify-between space-y-2 text-sm"
|
||||||
amount={item.cost.totalAmount.amount}
|
amount={item.cost.totalAmount.amount}
|
||||||
currencyCode={item.cost.totalAmount.currencyCode}
|
currencyCode={item.cost.totalAmount.currencyCode || 'USD'}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex h-9 flex-row">
|
<div className="flex h-9 flex-row">
|
||||||
@ -146,7 +148,7 @@ export default function CartModal({
|
|||||||
<Price
|
<Price
|
||||||
className="text-right"
|
className="text-right"
|
||||||
amount={cart.cost.subtotalAmount.amount}
|
amount={cart.cost.subtotalAmount.amount}
|
||||||
currencyCode={cart.cost.subtotalAmount.currencyCode}
|
currencyCode={cart.cost.subtotalAmount.currencyCode || 'USD'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-2 flex items-center justify-between">
|
<div className="mb-2 flex items-center justify-between">
|
||||||
@ -154,7 +156,7 @@ export default function CartModal({
|
|||||||
<Price
|
<Price
|
||||||
className="text-right"
|
className="text-right"
|
||||||
amount={cart.cost.totalTaxAmount.amount}
|
amount={cart.cost.totalTaxAmount.amount}
|
||||||
currencyCode={cart.cost.totalTaxAmount.currencyCode}
|
currencyCode={cart.cost.totalTaxAmount.currencyCode || 'USD'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-2 flex items-center justify-between border-b border-gray-200 pb-2">
|
<div className="mb-2 flex items-center justify-between border-b border-gray-200 pb-2">
|
||||||
@ -166,7 +168,7 @@ export default function CartModal({
|
|||||||
<Price
|
<Price
|
||||||
className="text-right"
|
className="text-right"
|
||||||
amount={cart.cost.totalAmount.amount}
|
amount={cart.cost.totalAmount.amount}
|
||||||
currencyCode={cart.cost.totalAmount.currencyCode}
|
currencyCode={cart.cost.totalAmount.currencyCode || 'USD'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,8 +14,10 @@ export function AddToCart({
|
|||||||
variants: ProductVariant[];
|
variants: ProductVariant[];
|
||||||
availableForSale: boolean;
|
availableForSale: boolean;
|
||||||
}) {
|
}) {
|
||||||
const productEntityId = variants[0]?.parentId || variants[0]?.id;
|
const productEntityId = variants[0]?.parentId;
|
||||||
const [selectedVariantId, setSelectedVariantId] = useState(productEntityId);
|
const varianEntitytId = variants[0]?.id;
|
||||||
|
const [selectedVariantId, setSelectedVariantId] = useState(varianEntitytId);
|
||||||
|
const [selectedProductId, setSelectedProductId] = useState(productEntityId);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
@ -29,7 +31,8 @@ export function AddToCart({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (variant) {
|
if (variant) {
|
||||||
setSelectedVariantId(variant.parentId || variant.id);
|
setSelectedVariantId(variant.id);
|
||||||
|
setSelectedProductId(variant.parentId);
|
||||||
}
|
}
|
||||||
}, [searchParams, variants, setSelectedVariantId]);
|
}, [searchParams, variants, setSelectedVariantId]);
|
||||||
|
|
||||||
@ -44,6 +47,7 @@ export function AddToCart({
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
merchandiseId: selectedVariantId,
|
merchandiseId: selectedVariantId,
|
||||||
|
productId: selectedProductId,
|
||||||
isBigCommerceAPI: true
|
isBigCommerceAPI: true
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -167,7 +167,7 @@ const getBigCommerceProductsWithCheckout = async (
|
|||||||
) => {
|
) => {
|
||||||
const bigCommerceProducts = await Promise.all(
|
const bigCommerceProducts = await Promise.all(
|
||||||
lines.map(async ({ merchandiseId }) => {
|
lines.map(async ({ merchandiseId }) => {
|
||||||
const productId = Number(merchandiseId);
|
const productId = parseInt(merchandiseId, 10);
|
||||||
|
|
||||||
const resp = await bigcommerceFetch<BigCommerceProductOperation>({
|
const resp = await bigcommerceFetch<BigCommerceProductOperation>({
|
||||||
query: getProductQuery,
|
query: getProductQuery,
|
||||||
@ -191,10 +191,24 @@ const getBigCommerceProductsWithCheckout = async (
|
|||||||
},
|
},
|
||||||
cache: 'no-store'
|
cache: 'no-store'
|
||||||
});
|
});
|
||||||
|
const checkout = resCheckout.body.data.site.checkout ?? {
|
||||||
|
subtotal: {
|
||||||
|
value: 0,
|
||||||
|
currencyCode: '',
|
||||||
|
},
|
||||||
|
grandTotal: {
|
||||||
|
value: 0,
|
||||||
|
currencyCode: '',
|
||||||
|
},
|
||||||
|
taxTotal: {
|
||||||
|
value: 0,
|
||||||
|
currencyCode: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
productsByIdList: bigCommerceProducts,
|
productsByIdList: bigCommerceProducts,
|
||||||
checkout: resCheckout.body.data.site.checkout
|
checkout,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -225,7 +239,7 @@ export async function createCart(): Promise<VercelCart> {
|
|||||||
|
|
||||||
export async function addToCart(
|
export async function addToCart(
|
||||||
cartId: string,
|
cartId: string,
|
||||||
lines: { merchandiseId: string; quantity: number }[]
|
lines: { merchandiseId: string; quantity: number, productId?: string }[]
|
||||||
): Promise<VercelCart> {
|
): Promise<VercelCart> {
|
||||||
let bigCommerceCart: BigCommerceCart;
|
let bigCommerceCart: BigCommerceCart;
|
||||||
|
|
||||||
@ -236,8 +250,9 @@ export async function addToCart(
|
|||||||
addCartLineItemsInput: {
|
addCartLineItemsInput: {
|
||||||
cartEntityId: cartId,
|
cartEntityId: cartId,
|
||||||
data: {
|
data: {
|
||||||
lineItems: lines.map(({ merchandiseId, quantity }) => ({
|
lineItems: lines.map(({ merchandiseId, quantity, productId }) => ({
|
||||||
productEntityId: parseInt(merchandiseId, 10),
|
productEntityId: parseInt(productId!, 10),
|
||||||
|
variantEntityId: parseInt(merchandiseId, 10),
|
||||||
quantity
|
quantity
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -252,8 +267,9 @@ export async function addToCart(
|
|||||||
query: createCartMutation,
|
query: createCartMutation,
|
||||||
variables: {
|
variables: {
|
||||||
createCartInput: {
|
createCartInput: {
|
||||||
lineItems: lines.map(({ merchandiseId, quantity }) => ({
|
lineItems: lines.map(({ merchandiseId, quantity, productId }) => ({
|
||||||
productEntityId: parseInt(merchandiseId, 10),
|
productEntityId: parseInt(productId!, 10),
|
||||||
|
variantEntityId: parseInt(merchandiseId, 10),
|
||||||
quantity
|
quantity
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -303,12 +319,12 @@ export async function removeFromCart(cartId: string, lineIds: string[]): Promise
|
|||||||
// Update on selected options requires variantEntityId, optionEntityId
|
// Update on selected options requires variantEntityId, optionEntityId
|
||||||
export async function updateCart(
|
export async function updateCart(
|
||||||
cartId: string,
|
cartId: string,
|
||||||
lines: { id: string; merchandiseId: string; quantity: number }[]
|
lines: { id: string; merchandiseId: string; quantity: number, productId?: string}[]
|
||||||
): Promise<VercelCart> {
|
): Promise<VercelCart> {
|
||||||
let cartState: { status: number; body: BigCommerceUpdateCartItemOperation } | undefined;
|
let cartState: { status: number; body: BigCommerceUpdateCartItemOperation } | undefined;
|
||||||
|
|
||||||
for (let updates = lines.length; updates > 0; updates--) {
|
for (let updates = lines.length; updates > 0; updates--) {
|
||||||
const { id, merchandiseId, quantity } = lines[updates - 1]!;
|
const { id, merchandiseId, quantity, productId } = lines[updates - 1]!;
|
||||||
const res = await bigcommerceFetch<BigCommerceUpdateCartItemOperation>({
|
const res = await bigcommerceFetch<BigCommerceUpdateCartItemOperation>({
|
||||||
query: updateCartLineItemMutation,
|
query: updateCartLineItemMutation,
|
||||||
variables: {
|
variables: {
|
||||||
@ -317,8 +333,9 @@ export async function updateCart(
|
|||||||
lineItemEntityId: id,
|
lineItemEntityId: id,
|
||||||
data: {
|
data: {
|
||||||
lineItem: {
|
lineItem: {
|
||||||
quantity,
|
productEntityId: parseInt(productId!, 10),
|
||||||
productEntityId: Number(merchandiseId)
|
variantEntityId: parseInt(merchandiseId, 10),
|
||||||
|
quantity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,7 +352,6 @@ export async function updateCart(
|
|||||||
return bigcommerceToVercelCart(updatedCart, productsByIdList, checkout);
|
return bigcommerceToVercelCart(updatedCart, productsByIdList, checkout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: DONE & review if it works
|
|
||||||
export async function getCart(cartId: string): Promise<VercelCart | null> {
|
export async function getCart(cartId: string): Promise<VercelCart | null> {
|
||||||
const res = await bigcommerceFetch<BigCommerceCartOperation>({
|
const res = await bigcommerceFetch<BigCommerceCartOperation>({
|
||||||
query: getCartQuery,
|
query: getCartQuery,
|
||||||
@ -351,11 +367,11 @@ export async function getCart(cartId: string): Promise<VercelCart | null> {
|
|||||||
const lines = vercelFromBigCommerceLineItems(cart.lineItems);
|
const lines = vercelFromBigCommerceLineItems(cart.lineItems);
|
||||||
const { productsByIdList, checkout } = await getBigCommerceProductsWithCheckout(cartId, lines);
|
const { productsByIdList, checkout } = await getBigCommerceProductsWithCheckout(cartId, lines);
|
||||||
|
|
||||||
return bigcommerceToVercelCart(cart, productsByIdList, checkout);
|
return bigcommerceToVercelCart(cart, productsByIdList, checkout);;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollection(handle: string): Promise<VercelCollection> {
|
export async function getCollection(handle: string): Promise<VercelCollection> {
|
||||||
const entityId = await getCategoryEntityIdbyHandle(handle); // NOTE: check if this approach suits us
|
const entityId = await getCategoryEntityIdbyHandle(handle);
|
||||||
const res = await bigcommerceFetch<BigCommerceCollectionOperation>({
|
const res = await bigcommerceFetch<BigCommerceCollectionOperation>({
|
||||||
query: getCategoryQuery,
|
query: getCategoryQuery,
|
||||||
variables: {
|
variables: {
|
||||||
@ -481,7 +497,7 @@ export async function getMenu(handle: string): Promise<VercelMenu[]> {
|
|||||||
title: name,
|
title: name,
|
||||||
path: createVercelCollectionPath(verceLTitle!)
|
path: createVercelCollectionPath(verceLTitle!)
|
||||||
};
|
};
|
||||||
// NOTE: for NavBar we probably should keep it only high level categories
|
// NOTE: keep only high level categories for NavBar
|
||||||
// if (hasChildren && children) {
|
// if (hasChildren && children) {
|
||||||
// return configureVercelMenu(children, hasChildren);
|
// return configureVercelMenu(children, hasChildren);
|
||||||
// }
|
// }
|
||||||
@ -504,7 +520,6 @@ export async function getMenu(handle: string): Promise<VercelMenu[]> {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace with BC API next Page(s) Methods
|
|
||||||
export async function getPage(handle: string): Promise<VercelPage> {
|
export async function getPage(handle: string): Promise<VercelPage> {
|
||||||
const entityId = await getEntityIdByHandle(handle);
|
const entityId = await getEntityIdByHandle(handle);
|
||||||
const res = await bigcommerceFetch<BigCommercePageOperation>({
|
const res = await bigcommerceFetch<BigCommercePageOperation>({
|
||||||
@ -528,7 +543,6 @@ export async function getPages(): Promise<VercelPage[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getProduct(handle: string): Promise<VercelProduct | undefined> {
|
export async function getProduct(handle: string): Promise<VercelProduct | undefined> {
|
||||||
// const productId = await getEntityIdByHandle(handle); // NOTE: check of this approach work
|
|
||||||
const res = await bigcommerceFetch<BigCommerceProductOperation>({
|
const res = await bigcommerceFetch<BigCommerceProductOperation>({
|
||||||
query: getProductQuery,
|
query: getProductQuery,
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -22,8 +22,8 @@ type ProductsList = { productId: number; productData: BigCommerceProduct }[];
|
|||||||
|
|
||||||
const vercelFromBigCommerceLineItems = (lineItems: BigCommerceCart['lineItems']) => {
|
const vercelFromBigCommerceLineItems = (lineItems: BigCommerceCart['lineItems']) => {
|
||||||
const { physicalItems, digitalItems, customItems } = lineItems;
|
const { physicalItems, digitalItems, customItems } = lineItems;
|
||||||
const cartItemMapper = ({ entityId, quantity }: DigitalOrPhysicalItem | CartCustomItem) => ({
|
const cartItemMapper = ({ entityId, quantity, productEntityId }: DigitalOrPhysicalItem | CartCustomItem) => ({
|
||||||
merchandiseId: entityId.toString(),
|
merchandiseId: productEntityId ? productEntityId.toString() : entityId.toString(),
|
||||||
quantity
|
quantity
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -201,17 +201,17 @@ const bigcommerceToVercelCartItems = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item.entityId.toString(),
|
id: item.entityId.toString(), // NOTE: used as lineId || lineItemId
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
cost: {
|
cost: {
|
||||||
totalAmount: {
|
totalAmount: {
|
||||||
amount:
|
amount:
|
||||||
item.extendedListPrice.value.toString() || item.listPrice.value.toString() || '0',
|
item.extendedListPrice.value.toString() || item.listPrice.value.toString() || '0',
|
||||||
currencyCode: item.extendedListPrice.currencyCode || item.listPrice.currencyCode || ''
|
currencyCode: item.extendedListPrice.currencyCode || item.listPrice.currencyCode || ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
merchandise: {
|
merchandise: {
|
||||||
id: item.entityId.toString(),
|
id: isCustomItem ? item.entityId.toString() : (item as DigitalOrPhysicalItem).variantEntityId!.toString(),
|
||||||
title: `${item.name}`,
|
title: `${item.name}`,
|
||||||
selectedOptions,
|
selectedOptions,
|
||||||
product
|
product
|
||||||
@ -238,9 +238,8 @@ const bigcommerceToVercelCart = (
|
|||||||
): VercelCart => {
|
): VercelCart => {
|
||||||
return {
|
return {
|
||||||
id: cart.entityId,
|
id: cart.entityId,
|
||||||
checkoutUrl: '', // NOTE: where to get checkoutUrl??
|
checkoutUrl: '', // TODO: add later
|
||||||
cost: {
|
cost: {
|
||||||
// NOTE: these props lay down in checkout not cart
|
|
||||||
subtotalAmount: {
|
subtotalAmount: {
|
||||||
amount: checkout.subtotal.value.toString(),
|
amount: checkout.subtotal.value.toString(),
|
||||||
currencyCode: checkout.subtotal.currencyCode
|
currencyCode: checkout.subtotal.currencyCode
|
||||||
|
@ -111,7 +111,6 @@ const updateCartLineItemMutation = /* GraphQL */ `
|
|||||||
updatedAt {
|
updatedAt {
|
||||||
utc
|
utc
|
||||||
}
|
}
|
||||||
totalQuantity
|
|
||||||
lineItems {
|
lineItems {
|
||||||
totalQuantity
|
totalQuantity
|
||||||
physicalItems {
|
physicalItems {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user