mirror of
https://github.com/vercel/commerce.git
synced 2025-05-14 13:47:49 +00:00
clean reshape get cart
This commit is contained in:
parent
2c6e46b4d9
commit
e2b30b8bb6
@ -2,7 +2,7 @@ import { CartProvider } from 'components/cart/cart-context';
|
|||||||
import { Navbar } from 'components/layout/navbar';
|
import { Navbar } from 'components/layout/navbar';
|
||||||
import { WelcomeToast } from 'components/welcome-toast';
|
import { WelcomeToast } from 'components/welcome-toast';
|
||||||
import { GeistSans } from 'geist/font/sans';
|
import { GeistSans } from 'geist/font/sans';
|
||||||
import { getCart } from 'lib/shopify';
|
import { getCart } from 'lib/fourthwall';
|
||||||
import { ensureStartsWith } from 'lib/utils';
|
import { ensureStartsWith } from 'lib/utils';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import { TAGS } from 'lib/constants';
|
import { TAGS } from 'lib/constants';
|
||||||
import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/shopify';
|
import { getCart } from 'lib/fourthwall';
|
||||||
|
import { addToCart, createCart, removeFromCart, updateCart } from 'lib/shopify';
|
||||||
import { revalidateTag } from 'next/cache';
|
import { revalidateTag } from 'next/cache';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Menu, Product } from "lib/shopify/types";
|
import { Cart, Menu, Product } from "lib/shopify/types";
|
||||||
import { reshapeProducts } from "./reshape";
|
import { reshapeCart, reshapeProducts } from "./reshape";
|
||||||
|
import { FourthwallCart } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers
|
* Helpers
|
||||||
@ -60,9 +61,8 @@ async function fourthwallPost<T>(url: string, data: any, options: RequestInit =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls
|
* Collection operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function getCollectionProducts({
|
export async function getCollectionProducts({
|
||||||
collection,
|
collection,
|
||||||
reverse,
|
reverse,
|
||||||
@ -87,9 +87,24 @@ export async function getCollectionProducts({
|
|||||||
return reshapeProducts(res.body.results);
|
return reshapeProducts(res.body.results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cart operations
|
||||||
|
*/
|
||||||
|
export async function getCart(cartId: string | undefined): Promise<Cart | undefined> {
|
||||||
|
if (!cartId) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fourthwallGet<FourthwallCart>(`${process.env.FW_URL}/api/public/v1.0/carts/${cartId}?secret=${process.env.FW_SECRET}`, {
|
||||||
|
cache: 'no-store'
|
||||||
|
});
|
||||||
|
|
||||||
|
return reshapeCart(res.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stubbed out
|
* TODO: Stubbed out
|
||||||
*/
|
*/
|
||||||
export async function getMenu(handle: string): Promise<Menu[]> {
|
export async function getMenu(handle: string): Promise<Menu[]> {
|
||||||
return [];
|
return [];
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { Image, Money, Product, ProductVariant } from "lib/shopify/types";
|
import { Cart, CartItem, Image, Money, Product, ProductVariant } from "lib/shopify/types";
|
||||||
import { FourthwallMoney, FourthwallProduct, FourthwallProductImage, FourthwallProductVariant } from "./types";
|
import { FourthwallCart, FourthwallCartItem, FourthwallMoney, FourthwallProduct, FourthwallProductImage, FourthwallProductVariant } from "./types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utils
|
||||||
|
*/
|
||||||
const DEFAULT_IMAGE: Image = {
|
const DEFAULT_IMAGE: Image = {
|
||||||
url: '',
|
url: '',
|
||||||
altText: '',
|
altText: '',
|
||||||
@ -8,6 +11,17 @@ const DEFAULT_IMAGE: Image = {
|
|||||||
height: 0
|
height: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const reshapeMoney = (money: FourthwallMoney): Money => {
|
||||||
|
return {
|
||||||
|
amount: money.value.toString(),
|
||||||
|
currencyCode: money.currencyCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Products
|
||||||
|
*/
|
||||||
export const reshapeProducts = (products: FourthwallProduct[]) => {
|
export const reshapeProducts = (products: FourthwallProduct[]) => {
|
||||||
const reshapedProducts = [];
|
const reshapedProducts = [];
|
||||||
|
|
||||||
@ -44,8 +58,6 @@ const reshapeProduct = (product: FourthwallProduct): Product | undefined => {
|
|||||||
description: product.description,
|
description: product.description,
|
||||||
images: reshapeImages(images, product.name),
|
images: reshapeImages(images, product.name),
|
||||||
variants: reshapeVariants(variants),
|
variants: reshapeVariants(variants),
|
||||||
// stubbed out
|
|
||||||
availableForSale: true,
|
|
||||||
priceRange: {
|
priceRange: {
|
||||||
minVariantPrice: {
|
minVariantPrice: {
|
||||||
amount: minPrice.toString(),
|
amount: minPrice.toString(),
|
||||||
@ -56,8 +68,10 @@ const reshapeProduct = (product: FourthwallProduct): Product | undefined => {
|
|||||||
currencyCode,
|
currencyCode,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: [],
|
|
||||||
featuredImage: reshapeImages(images, product.name)[0] || DEFAULT_IMAGE,
|
featuredImage: reshapeImages(images, product.name)[0] || DEFAULT_IMAGE,
|
||||||
|
// TODO: stubbed out
|
||||||
|
availableForSale: true,
|
||||||
|
options: [],
|
||||||
seo: {
|
seo: {
|
||||||
title: product.name,
|
title: product.name,
|
||||||
description: product.description,
|
description: product.description,
|
||||||
@ -87,9 +101,59 @@ const reshapeVariants = (variants: FourthwallProductVariant[]): ProductVariant[]
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const reshapeMoney = (money: FourthwallMoney): Money => {
|
/**
|
||||||
|
* Cart
|
||||||
|
*/
|
||||||
|
const reshapeCartItem = (item: FourthwallCartItem): CartItem => {
|
||||||
return {
|
return {
|
||||||
amount: money.value.toString(),
|
id: item.variant.id,
|
||||||
currencyCode: money.currencyCode
|
quantity: item.quantity,
|
||||||
|
cost: {
|
||||||
|
totalAmount: reshapeMoney(item.variant.unitPrice)
|
||||||
|
},
|
||||||
|
merchandise: {
|
||||||
|
id: item.variant.id,
|
||||||
|
title: item.variant.name,
|
||||||
|
// TODO: Stubbed out
|
||||||
|
selectedOptions: [],
|
||||||
|
product: {
|
||||||
|
id: 'TT',
|
||||||
|
handle: 'TT',
|
||||||
|
title: 'TT',
|
||||||
|
featuredImage: {
|
||||||
|
url: item.variant.images[0]?.url || 'TT',
|
||||||
|
altText: 'TT',
|
||||||
|
width: item.variant.images[0]?.width || 100,
|
||||||
|
height: item.variant.images[0]?.height || 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const reshapeCart = (cart: FourthwallCart): Cart => {
|
||||||
|
const totalValue = cart.items.map((item) => item.quantity * item.variant.unitPrice.value).reduce((a, b) => a + b, 0);
|
||||||
|
const currencyCode = cart.items[0]?.variant.unitPrice.currencyCode || 'USD';
|
||||||
|
|
||||||
|
return {
|
||||||
|
...cart,
|
||||||
|
cost: {
|
||||||
|
totalAmount: {
|
||||||
|
amount: totalValue.toString(),
|
||||||
|
currencyCode,
|
||||||
|
},
|
||||||
|
subtotalAmount: {
|
||||||
|
amount: totalValue.toString(),
|
||||||
|
currencyCode,
|
||||||
|
},
|
||||||
|
totalTaxAmount: {
|
||||||
|
amount: '0.0',
|
||||||
|
currencyCode,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lines: cart.items.map(reshapeCartItem),
|
||||||
|
// TODO: Stubbed out
|
||||||
|
checkoutUrl: 'TT',
|
||||||
|
totalQuantity: cart.items.map((item) => item.quantity).reduce((a, b) => a + b, 0)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -30,3 +30,20 @@ export type FourthwallProductVariant = {
|
|||||||
|
|
||||||
// other attr
|
// other attr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type FourthwallCart = {
|
||||||
|
id: string | undefined;
|
||||||
|
// checkoutUrl: string;
|
||||||
|
// cost: {
|
||||||
|
// subtotalAmount: Money;
|
||||||
|
// totalAmount: Money;
|
||||||
|
// totalTaxAmount: Money;
|
||||||
|
// };
|
||||||
|
items: FourthwallCartItem[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FourthwallCartItem = {
|
||||||
|
variant: FourthwallProductVariant;
|
||||||
|
quantity: number;
|
||||||
|
};
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
editCartItemsMutation,
|
editCartItemsMutation,
|
||||||
removeFromCartMutation
|
removeFromCartMutation
|
||||||
} from './mutations/cart';
|
} from './mutations/cart';
|
||||||
import { getCartQuery } from './queries/cart';
|
|
||||||
import {
|
import {
|
||||||
getCollectionQuery,
|
getCollectionQuery,
|
||||||
getCollectionsQuery
|
getCollectionsQuery
|
||||||
@ -30,7 +29,6 @@ import {
|
|||||||
Product,
|
Product,
|
||||||
ShopifyAddToCartOperation,
|
ShopifyAddToCartOperation,
|
||||||
ShopifyCart,
|
ShopifyCart,
|
||||||
ShopifyCartOperation,
|
|
||||||
ShopifyCollection,
|
ShopifyCollection,
|
||||||
ShopifyCollectionOperation,
|
ShopifyCollectionOperation,
|
||||||
ShopifyCollectionsOperation,
|
ShopifyCollectionsOperation,
|
||||||
@ -249,25 +247,6 @@ export async function updateCart(
|
|||||||
return reshapeCart(res.body.data.cartLinesUpdate.cart);
|
return reshapeCart(res.body.data.cartLinesUpdate.cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCart(cartId: string | undefined): Promise<Cart | undefined> {
|
|
||||||
if (!cartId) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await shopifyFetch<ShopifyCartOperation>({
|
|
||||||
query: getCartQuery,
|
|
||||||
variables: { cartId },
|
|
||||||
tags: [TAGS.cart]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Old carts becomes `null` when you checkout.
|
|
||||||
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> {
|
||||||
const res = await shopifyFetch<ShopifyCollectionOperation>({
|
const res = await shopifyFetch<ShopifyCollectionOperation>({
|
||||||
query: getCollectionQuery,
|
query: getCollectionQuery,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user