This commit is contained in:
Kristian Duda 2024-06-28 09:41:06 +02:00
parent b8b4e77645
commit 6575311b26
2 changed files with 84 additions and 38 deletions

View File

@ -1,23 +1,19 @@
import { SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants'; import { SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants';
import { Where, find, findByID } from 'lib/shopify/payload'; import { Where, create, find, findByID } from 'lib/shopify/payload';
import { Category, Media, Option, Product } from 'lib/shopify/payload-types'; import { Cart, Category, Media, Option, Product } from 'lib/shopify/payload-types';
import { isShopifyError } from 'lib/type-guards'; import { isShopifyError } from 'lib/type-guards';
import { ensureStartsWith } from 'lib/utils'; import { ensureStartsWith } from 'lib/utils';
import { revalidateTag } from 'next/cache'; import { revalidateTag } from 'next/cache';
import { headers } from 'next/headers'; import { headers } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server'; import { NextRequest, NextResponse } from 'next/server';
import { import { editCartItemsMutation, removeFromCartMutation } from './mutations/cart';
addToCartMutation,
createCartMutation,
editCartItemsMutation,
removeFromCartMutation
} from './mutations/cart';
import { getCartQuery } from './queries/cart'; import { getCartQuery } from './queries/cart';
import { getPageQuery } from './queries/page'; import { getPageQuery } from './queries/page';
import { import {
Cart, CartItem,
Collection, Collection,
Connection, Connection,
Cart as ExCart,
Product as ExProduct, Product as ExProduct,
Image, Image,
Menu, Menu,
@ -25,10 +21,8 @@ import {
Page, Page,
ProductOption, ProductOption,
ProductVariant, ProductVariant,
ShopifyAddToCartOperation,
ShopifyCart, ShopifyCart,
ShopifyCartOperation, ShopifyCartOperation,
ShopifyCreateCartOperation,
ShopifyPageOperation, ShopifyPageOperation,
ShopifyRemoveFromCartOperation, ShopifyRemoveFromCartOperation,
ShopifyUpdateCartOperation ShopifyUpdateCartOperation
@ -102,7 +96,7 @@ const removeEdgesAndNodes = (array: Connection<any>) => {
return array.edges.map((edge) => edge?.node); return array.edges.map((edge) => edge?.node);
}; };
const reshapeCart = (cart: ShopifyCart): Cart => { const reshapeCart = (cart: ShopifyCart): ExCart => {
if (!cart.cost?.totalTaxAmount) { if (!cart.cost?.totalTaxAmount) {
cart.cost.totalTaxAmount = { cart.cost.totalTaxAmount = {
amount: '0.0', amount: '0.0',
@ -116,31 +110,72 @@ const reshapeCart = (cart: ShopifyCart): Cart => {
}; };
}; };
export async function createCart(): Promise<Cart> { const reshapeCartItems = (cartItems: Cart['lines']): CartItem[] => {
const res = await shopifyFetch<ShopifyCreateCartOperation>({ return (cartItems ?? []).map((item) => {
query: createCartMutation, const product = item.product as Product;
cache: 'no-store' const variant = product.variants.find((v) => v.id === item.variant);
});
return reshapeCart(res.body.data.cartCreate.cart); return {
id: product.id,
quantity: item.quantity,
merchandise: {
id: item.variant,
title: product.title,
selectedOptions: [],
product: reshapeProduct(product)
},
cost: {
totalAmount: reshapePrice(variant?.price!)
}
};
});
};
const reshapeC = (cart: Cart): ExCart => {
return {
id: cart.id,
checkoutUrl: '/api/checkout',
cost: {
totalAmount: {
currencyCode: 'EUR',
amount: cart.totalAmount?.toString()!
},
totalTaxAmount: {
currencyCode: 'EUR',
amount: '0.0'
},
subtotalAmount: {
currencyCode: 'EUR',
amount: '0.0'
}
},
lines: reshapeCartItems(cart.lines),
totalQuantity: 0
};
};
export async function createCart(): Promise<ExCart> {
const cart = await create<Cart>('carts', { lines: [] });
return reshapeC(cart);
} }
export async function addToCart( export async function addToCart(
cartId: string, cartId: string,
lines: { merchandiseId: string; quantity: number }[] lines: { merchandiseId: string; quantity: number }[]
): Promise<Cart> { ): Promise<ExCart> {
const res = await shopifyFetch<ShopifyAddToCartOperation>({ console.log('TEST');
query: addToCartMutation, // const res = await shopifyFetch<ShopifyAddToCartOperation>({
variables: { // query: addToCartMutation,
cartId, // variables: {
lines // cartId,
}, // lines
cache: 'no-store' // },
}); // cache: 'no-store'
return reshapeCart(res.body.data.cartLinesAdd.cart); // });
// return reshapeCart(res.body.data.cartLinesAdd.cart);
} }
export async function removeFromCart(cartId: string, lineIds: string[]): Promise<Cart> { export async function removeFromCart(cartId: string, lineIds: string[]): Promise<ExCart> {
const res = await shopifyFetch<ShopifyRemoveFromCartOperation>({ const res = await shopifyFetch<ShopifyRemoveFromCartOperation>({
query: removeFromCartMutation, query: removeFromCartMutation,
variables: { variables: {
@ -156,7 +191,7 @@ export async function removeFromCart(cartId: string, lineIds: string[]): Promise
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 }[]
): Promise<Cart> { ): Promise<ExCart> {
const res = await shopifyFetch<ShopifyUpdateCartOperation>({ const res = await shopifyFetch<ShopifyUpdateCartOperation>({
query: editCartItemsMutation, query: editCartItemsMutation,
variables: { variables: {
@ -169,7 +204,7 @@ export async function updateCart(
return reshapeCart(res.body.data.cartLinesUpdate.cart); return reshapeCart(res.body.data.cartLinesUpdate.cart);
} }
export async function getCart(cartId: string): Promise<Cart | undefined> { export async function getCart(cartId: string): Promise<ExCart | undefined> {
const res = await shopifyFetch<ShopifyCartOperation>({ const res = await shopifyFetch<ShopifyCartOperation>({
query: getCartQuery, query: getCartQuery,
variables: { cartId }, variables: { cartId },
@ -228,18 +263,24 @@ const reshapeOptions = (variants: Product['variants']): ProductOption[] => {
})); }));
}; };
const reshapeSelectedOption = (
selectedOptions: Product['variants'][0]['selectedOptions']
): Array<{ name: string; value: string }> => {
return (selectedOptions ?? []).map((selectedOption) => {
const option = selectedOption.option as Option;
return {
name: option.name,
value: option.values.find(({ value }) => value === selectedOption.value)?.label!
};
});
};
const reshapeVariants = (variants: Product['variants']): ProductVariant[] => { const reshapeVariants = (variants: Product['variants']): ProductVariant[] => {
return variants.map((variant) => ({ return variants.map((variant) => ({
id: variant.id!, id: variant.id!,
title: `${variant.price.amount} ${variant.price.currencyCode}`, title: `${variant.price.amount} ${variant.price.currencyCode}`,
availableForSale: true, availableForSale: true,
selectedOptions: (variant.selectedOptions ?? []).map((selectedOption) => { selectedOptions: reshapeSelectedOption(variant.selectedOptions),
const option = selectedOption.option as Option;
return {
name: option.name,
value: option.values.find(({ value }) => value === selectedOption.value)?.label!
};
}),
price: reshapePrice(variant.price) price: reshapePrice(variant.price)
})); }));
}; };

View File

@ -64,3 +64,8 @@ export const findByID = <T>(collection: string, id: string) => {
const url = `${process.env.CMS_URL}/api/${collection}/${id}`; const url = `${process.env.CMS_URL}/api/${collection}/${id}`;
return ajax<T>('GET', url); return ajax<T>('GET', url);
}; };
export const create = <T extends object>(collection: string, body: Partial<T>) => {
const url = `${process.env.CMS_URL}/api/${collection}`;
return ajax<T>('POST', url, body);
};