mirror of
https://github.com/vercel/commerce.git
synced 2025-05-09 03:07:50 +00:00
Handle null ids
This commit is contained in:
parent
c131178529
commit
2b2b897cef
@ -37,7 +37,7 @@ export async function removeItem(prevState: any, merchandiseId: string) {
|
|||||||
|
|
||||||
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
|
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
|
||||||
|
|
||||||
if (lineItem) {
|
if (lineItem && lineItem.id) {
|
||||||
await removeFromCart(cartId, [lineItem.id]);
|
await removeFromCart(cartId, [lineItem.id]);
|
||||||
revalidateTag(TAGS.cart);
|
revalidateTag(TAGS.cart);
|
||||||
} else {
|
} else {
|
||||||
@ -72,7 +72,7 @@ export async function updateItemQuantity(
|
|||||||
|
|
||||||
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
|
const lineItem = cart.lines.find((line) => line.merchandise.id === merchandiseId);
|
||||||
|
|
||||||
if (lineItem) {
|
if (lineItem && lineItem.id) {
|
||||||
if (quantity === 0) {
|
if (quantity === 0) {
|
||||||
await removeFromCart(cartId, [lineItem.id]);
|
await removeFromCart(cartId, [lineItem.id]);
|
||||||
} else {
|
} else {
|
||||||
@ -114,5 +114,5 @@ export async function redirectToCheckout() {
|
|||||||
|
|
||||||
export async function createCartAndSetCookie() {
|
export async function createCartAndSetCookie() {
|
||||||
let cart = await createCart();
|
let cart = await createCart();
|
||||||
cookies().set('cartId', cart.id);
|
cookies().set('cartId', cart.id!);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ function createOrUpdateCartItem(
|
|||||||
const totalAmount = calculateItemCost(quantity, variant.price.amount);
|
const totalAmount = calculateItemCost(quantity, variant.price.amount);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: existingItem?.id || `${variant.id}_${Date.now()}`,
|
id: existingItem?.id,
|
||||||
quantity,
|
quantity,
|
||||||
cost: {
|
cost: {
|
||||||
totalAmount: {
|
totalAmount: {
|
||||||
@ -91,7 +91,7 @@ function updateCartTotals(lines: CartItem[]): Pick<Cart, 'totalQuantity' | 'cost
|
|||||||
|
|
||||||
function createEmptyCart(): Cart {
|
function createEmptyCart(): Cart {
|
||||||
return {
|
return {
|
||||||
id: `optimistic_${Date.now()}`,
|
id: undefined,
|
||||||
checkoutUrl: '',
|
checkoutUrl: '',
|
||||||
totalQuantity: 0,
|
totalQuantity: 0,
|
||||||
lines: [],
|
lines: [],
|
||||||
|
@ -90,84 +90,88 @@ export default function CartModal() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex h-full flex-col justify-between overflow-hidden p-1">
|
<div className="flex h-full flex-col justify-between overflow-hidden p-1">
|
||||||
<ul className="flex-grow overflow-auto py-4">
|
<ul className="flex-grow overflow-auto py-4">
|
||||||
{cart.lines.map((item, i) => {
|
{cart.lines
|
||||||
const merchandiseSearchParams = {} as MerchandiseSearchParams;
|
.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 }) => {
|
item.merchandise.selectedOptions.forEach(({ name, value }) => {
|
||||||
if (value !== DEFAULT_OPTION) {
|
if (value !== DEFAULT_OPTION) {
|
||||||
merchandiseSearchParams[name.toLowerCase()] = value;
|
merchandiseSearchParams[name.toLowerCase()] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const merchandiseUrl = createUrl(
|
const merchandiseUrl = createUrl(
|
||||||
`/product/${item.merchandise.product.handle}`,
|
`/product/${item.merchandise.product.handle}`,
|
||||||
new URLSearchParams(merchandiseSearchParams)
|
new URLSearchParams(merchandiseSearchParams)
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
key={i}
|
key={i}
|
||||||
className="flex w-full flex-col border-b border-neutral-300 dark:border-neutral-700"
|
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="relative flex w-full flex-row justify-between px-1 py-4">
|
||||||
<div className="absolute z-40 -mt-2 ml-[55px]">
|
<div className="absolute z-40 -mt-2 ml-[55px]">
|
||||||
<DeleteItemButton item={item} optimisticUpdate={updateCartItem} />
|
<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>
|
||||||
|
<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">
|
<div className="flex flex-1 flex-col text-base">
|
||||||
<span className="leading-tight">
|
<span className="leading-tight">
|
||||||
{item.merchandise.product.title}
|
{item.merchandise.product.title}
|
||||||
</span>
|
</span>
|
||||||
{item.merchandise.title !== DEFAULT_OPTION ? (
|
{item.merchandise.title !== DEFAULT_OPTION ? (
|
||||||
<p className="text-sm text-neutral-500 dark:text-neutral-400">
|
<p className="text-sm text-neutral-500 dark:text-neutral-400">
|
||||||
{item.merchandise.title}
|
{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>
|
</p>
|
||||||
) : null}
|
<EditItemQuantityButton
|
||||||
</div>
|
item={item}
|
||||||
</Link>
|
type="plus"
|
||||||
<div className="flex h-16 flex-col justify-between">
|
optimisticUpdate={updateCartItem}
|
||||||
<Price
|
/>
|
||||||
className="flex justify-end space-y-2 text-right text-sm"
|
</div>
|
||||||
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}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
);
|
||||||
);
|
})}
|
||||||
})}
|
|
||||||
</ul>
|
</ul>
|
||||||
<div className="py-4 text-sm text-neutral-500 dark:text-neutral-400">
|
<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">
|
<div className="mb-3 flex items-center justify-between border-b border-neutral-200 pb-1 dark:border-neutral-700">
|
||||||
|
@ -20,7 +20,7 @@ export type CartProduct = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type CartItem = {
|
export type CartItem = {
|
||||||
id: string;
|
id: string | undefined;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
cost: {
|
cost: {
|
||||||
totalAmount: Money;
|
totalAmount: Money;
|
||||||
@ -96,7 +96,7 @@ export type SEO = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ShopifyCart = {
|
export type ShopifyCart = {
|
||||||
id: string;
|
id: string | undefined;
|
||||||
checkoutUrl: string;
|
checkoutUrl: string;
|
||||||
cost: {
|
cost: {
|
||||||
subtotalAmount: Money;
|
subtotalAmount: Money;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user