Handle null ids

This commit is contained in:
Lee Robinson 2024-07-28 14:49:48 -05:00
parent c131178529
commit 2b2b897cef
4 changed files with 81 additions and 77 deletions

View File

@ -37,7 +37,7 @@ export async function removeItem(prevState: any, merchandiseId: string) {
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
if (lineItem) {
if (lineItem && lineItem.id) {
await removeFromCart(cartId, [lineItem.id]);
revalidateTag(TAGS.cart);
} else {
@ -72,7 +72,7 @@ export async function updateItemQuantity(
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
if (lineItem) {
if (lineItem && lineItem.id) {
if (quantity === 0) {
await removeFromCart(cartId, [lineItem.id]);
} else {
@ -114,5 +114,5 @@ export async function redirectToCheckout() {
export async function createCartAndSetCookie() {
let cart = await createCart();
cookies().set('cartId', cart.id);
cookies().set('cartId', cart.id!);
}

View File

@ -52,7 +52,7 @@ function createOrUpdateCartItem(
const totalAmount = calculateItemCost(quantity, variant.price.amount);
return {
id: existingItem?.id || `${variant.id}_${Date.now()}`,
id: existingItem?.id,
quantity,
cost: {
totalAmount: {
@ -91,7 +91,7 @@ function updateCartTotals(lines: CartItem[]): Pick<Cart, 'totalQuantity' | 'cost
function createEmptyCart(): Cart {
return {
id: `optimistic_${Date.now()}`,
id: undefined,
checkoutUrl: '',
totalQuantity: 0,
lines: [],

View File

@ -90,84 +90,88 @@ export default function CartModal() {
) : (
<div className="flex h-full flex-col justify-between overflow-hidden p-1">
<ul className="flex-grow overflow-auto py-4">
{cart.lines.map((item, i) => {
const merchandiseSearchParams = {} as MerchandiseSearchParams;
{cart.lines
.sort((a, b) =>
a.merchandise.product.title.localeCompare(b.merchandise.product.title)
)
.map((item, i) => {
const merchandiseSearchParams = {} as MerchandiseSearchParams;
item.merchandise.selectedOptions.forEach(({ name, value }) => {
if (value !== DEFAULT_OPTION) {
merchandiseSearchParams[name.toLowerCase()] = value;
}
});
item.merchandise.selectedOptions.forEach(({ name, value }) => {
if (value !== DEFAULT_OPTION) {
merchandiseSearchParams[name.toLowerCase()] = value;
}
});
const merchandiseUrl = createUrl(
`/product/${item.merchandise.product.handle}`,
new URLSearchParams(merchandiseSearchParams)
);
const merchandiseUrl = createUrl(
`/product/${item.merchandise.product.handle}`,
new URLSearchParams(merchandiseSearchParams)
);
return (
<li
key={i}
className="flex w-full flex-col border-b border-neutral-300 dark:border-neutral-700"
>
<div className="relative flex w-full flex-row justify-between px-1 py-4">
<div className="absolute z-40 -mt-2 ml-[55px]">
<DeleteItemButton item={item} optimisticUpdate={updateCartItem} />
</div>
<Link
href={merchandiseUrl}
onClick={closeCart}
className="z-30 flex flex-row space-x-4"
>
<div className="relative h-16 w-16 cursor-pointer overflow-hidden rounded-md border border-neutral-300 bg-neutral-300 dark:border-neutral-700 dark:bg-neutral-900 dark:hover:bg-neutral-800">
<Image
className="h-full w-full object-cover"
width={64}
height={64}
alt={
item.merchandise.product.featuredImage.altText ||
item.merchandise.product.title
}
src={item.merchandise.product.featuredImage.url}
/>
return (
<li
key={i}
className="flex w-full flex-col border-b border-neutral-300 dark:border-neutral-700"
>
<div className="relative flex w-full flex-row justify-between px-1 py-4">
<div className="absolute z-40 -mt-2 ml-[55px]">
<DeleteItemButton item={item} optimisticUpdate={updateCartItem} />
</div>
<Link
href={merchandiseUrl}
onClick={closeCart}
className="z-30 flex flex-row space-x-4"
>
<div className="relative h-16 w-16 cursor-pointer overflow-hidden rounded-md border border-neutral-300 bg-neutral-300 dark:border-neutral-700 dark:bg-neutral-900 dark:hover:bg-neutral-800">
<Image
className="h-full w-full object-cover"
width={64}
height={64}
alt={
item.merchandise.product.featuredImage.altText ||
item.merchandise.product.title
}
src={item.merchandise.product.featuredImage.url}
/>
</div>
<div className="flex flex-1 flex-col text-base">
<span className="leading-tight">
{item.merchandise.product.title}
</span>
{item.merchandise.title !== DEFAULT_OPTION ? (
<p className="text-sm text-neutral-500 dark:text-neutral-400">
{item.merchandise.title}
<div className="flex flex-1 flex-col text-base">
<span className="leading-tight">
{item.merchandise.product.title}
</span>
{item.merchandise.title !== DEFAULT_OPTION ? (
<p className="text-sm text-neutral-500 dark:text-neutral-400">
{item.merchandise.title}
</p>
) : null}
</div>
</Link>
<div className="flex h-16 flex-col justify-between">
<Price
className="flex justify-end space-y-2 text-right text-sm"
amount={item.cost.totalAmount.amount}
currencyCode={item.cost.totalAmount.currencyCode}
/>
<div className="ml-auto flex h-9 flex-row items-center rounded-full border border-neutral-200 dark:border-neutral-700">
<EditItemQuantityButton
item={item}
type="minus"
optimisticUpdate={updateCartItem}
/>
<p className="w-6 text-center">
<span className="w-full text-sm">{item.quantity}</span>
</p>
) : null}
</div>
</Link>
<div className="flex h-16 flex-col justify-between">
<Price
className="flex justify-end space-y-2 text-right text-sm"
amount={item.cost.totalAmount.amount}
currencyCode={item.cost.totalAmount.currencyCode}
/>
<div className="ml-auto flex h-9 flex-row items-center rounded-full border border-neutral-200 dark:border-neutral-700">
<EditItemQuantityButton
item={item}
type="minus"
optimisticUpdate={updateCartItem}
/>
<p className="w-6 text-center">
<span className="w-full text-sm">{item.quantity}</span>
</p>
<EditItemQuantityButton
item={item}
type="plus"
optimisticUpdate={updateCartItem}
/>
<EditItemQuantityButton
item={item}
type="plus"
optimisticUpdate={updateCartItem}
/>
</div>
</div>
</div>
</div>
</li>
);
})}
</li>
);
})}
</ul>
<div className="py-4 text-sm text-neutral-500 dark:text-neutral-400">
<div className="mb-3 flex items-center justify-between border-b border-neutral-200 pb-1 dark:border-neutral-700">

View File

@ -20,7 +20,7 @@ export type CartProduct = {
};
export type CartItem = {
id: string;
id: string | undefined;
quantity: number;
cost: {
totalAmount: Money;
@ -96,7 +96,7 @@ export type SEO = {
};
export type ShopifyCart = {
id: string;
id: string | undefined;
checkoutUrl: string;
cost: {
subtotalAmount: Money;