This commit is contained in:
Kristian Duda 2024-06-28 12:23:21 +02:00
parent 82850c1c9e
commit 0f2485a010
3 changed files with 49 additions and 28 deletions

View File

@ -13,7 +13,7 @@ export class AjaxError extends Error {
} }
} }
type AjaxMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type AjaxMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
export const ajax = async <T>(method: AjaxMethod, url: string, data?: object): Promise<T> => { export const ajax = async <T>(method: AjaxMethod, url: string, data?: object): Promise<T> => {
const response = await fetch(url, { const response = await fetch(url, {

View File

@ -1,5 +1,6 @@
import { SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants'; import { SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants';
import { Where, create, find, findByID } from 'lib/shopify/payload'; import { AjaxError } from 'lib/shopify/ajax';
import { Where, create, find, findByID, update } from 'lib/shopify/payload';
import { Cart, 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';
@ -7,7 +8,6 @@ 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 { editCartItemsMutation, removeFromCartMutation } from './mutations/cart'; import { editCartItemsMutation, removeFromCartMutation } from './mutations/cart';
import { getCartQuery } from './queries/cart';
import { getPageQuery } from './queries/page'; import { getPageQuery } from './queries/page';
import { import {
CartItem, CartItem,
@ -22,7 +22,6 @@ import {
ProductOption, ProductOption,
ProductVariant, ProductVariant,
ShopifyCart, ShopifyCart,
ShopifyCartOperation,
ShopifyPageOperation, ShopifyPageOperation,
ShopifyRemoveFromCartOperation, ShopifyRemoveFromCartOperation,
ShopifyUpdateCartOperation ShopifyUpdateCartOperation
@ -116,7 +115,7 @@ const reshapeCartItems = (cartItems: Cart['lines']): CartItem[] => {
const variant = product.variants.find((v) => v.id === item.variant); const variant = product.variants.find((v) => v.id === item.variant);
return { return {
id: item.variant, id: item.id!,
quantity: item.quantity, quantity: item.quantity,
merchandise: { merchandise: {
id: item.variant, id: item.variant,
@ -156,23 +155,35 @@ const reshapeC = (cart: Cart): ExCart => {
export async function createCart(): Promise<ExCart> { export async function createCart(): Promise<ExCart> {
const cart = await create<Cart>('carts', { lines: [] }); const cart = await create<Cart>('carts', { lines: [] });
return reshapeC(cart); return reshapeC(cart.doc);
} }
export async function addToCart( export async function addToCart(
cartId: string, cartId: string,
lines: { merchandiseId: string; quantity: number }[] lines: { merchandiseId: string; quantity: number }[]
): Promise<ExCart> { ): Promise<ExCart> {
console.log('TEST'); const products = await find<Product>('products', {
// const res = await shopifyFetch<ShopifyAddToCartOperation>({ where: {
// query: addToCartMutation, 'variants.id': {
// variables: { in: lines.map((line) => line.merchandiseId)
// cartId, }
// lines }
// }, });
// cache: 'no-store'
// }); const cart = await update<Cart>('carts', cartId, {
// return reshapeCart(res.body.data.cartLinesAdd.cart); lines: lines.map((line) => {
const product = products.docs.find((p) =>
p.variants.some((variant) => variant.id === line.merchandiseId)
);
return {
product: product?.id!,
variant: line.merchandiseId,
quantity: line.quantity
};
})
});
return reshapeC(cart.doc);
} }
export async function removeFromCart(cartId: string, lineIds: string[]): Promise<ExCart> { export async function removeFromCart(cartId: string, lineIds: string[]): Promise<ExCart> {
@ -192,6 +203,7 @@ export async function updateCart(
cartId: string, cartId: string,
lines: { id: string; merchandiseId: string; quantity: number }[] lines: { id: string; merchandiseId: string; quantity: number }[]
): Promise<ExCart> { ): Promise<ExCart> {
console.log('TEST');
const res = await shopifyFetch<ShopifyUpdateCartOperation>({ const res = await shopifyFetch<ShopifyUpdateCartOperation>({
query: editCartItemsMutation, query: editCartItemsMutation,
variables: { variables: {
@ -205,19 +217,18 @@ export async function updateCart(
} }
export async function getCart(cartId: string): Promise<ExCart | undefined> { export async function getCart(cartId: string): Promise<ExCart | undefined> {
const res = await shopifyFetch<ShopifyCartOperation>({ try {
query: getCartQuery, const cart = await findByID<Cart>('carts', cartId);
variables: { cartId }, return reshapeC(cart);
tags: [TAGS.cart], } catch (error: unknown) {
cache: 'no-store' if (error instanceof AjaxError) {
}); if (error.statusCode === 404) {
return undefined;
}
}
// Old carts becomes `null` when you checkout. throw error;
if (!res.body.data.cart) {
return undefined;
} }
return reshapeCart(res.body.data.cart);
} }
export async function getCollection(handle: string): Promise<Collection | undefined> { export async function getCollection(handle: string): Promise<Collection | undefined> {

View File

@ -45,6 +45,11 @@ export type PaginatedDocs<T> = {
totalPages: number; totalPages: number;
}; };
type Doc<T> = {
message: string;
doc: T;
};
type FindParams = { type FindParams = {
where?: Where; where?: Where;
depth?: number; depth?: number;
@ -67,5 +72,10 @@ export const findByID = <T>(collection: string, id: string) => {
export const create = <T extends object>(collection: string, body: Partial<T>) => { export const create = <T extends object>(collection: string, body: Partial<T>) => {
const url = `${process.env.CMS_URL}/api/${collection}`; const url = `${process.env.CMS_URL}/api/${collection}`;
return ajax<T>('POST', url, body); return ajax<Doc<T>>('POST', url, body);
};
export const update = <T extends object>(collection: string, id: string, body: Partial<T>) => {
const url = `${process.env.CMS_URL}/api/${collection}/${id}`;
return ajax<Doc<T>>('PATCH', url, body);
}; };