feat(MED-100): show toast on delete
This commit is contained in:
48
app/home/(user)/_components/cart/cart-item-delete.tsx
Normal file
48
app/home/(user)/_components/cart/cart-item-delete.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import { Trash } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import { deleteLineItem } from "@lib/data/cart";
|
||||
import { Spinner } from "@medusajs/icons";
|
||||
|
||||
const CartItemDelete = ({
|
||||
id,
|
||||
children,
|
||||
}: {
|
||||
id: string;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleDelete = async () => {
|
||||
setIsDeleting(true);
|
||||
|
||||
const promise = async () => {
|
||||
await deleteLineItem(id);
|
||||
};
|
||||
|
||||
toast.promise(promise, {
|
||||
success: t(`cart:items.delete.success`),
|
||||
loading: t(`cart:items.delete.loading`),
|
||||
error: t(`cart:items.delete.error`),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between text-small-regular">
|
||||
<button
|
||||
className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer"
|
||||
onClick={() => handleDelete()}
|
||||
>
|
||||
{isDeleting ? <Spinner className="animate-spin" /> : <Trash />}
|
||||
<span>{children}</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CartItemDelete;
|
||||
@@ -1,14 +1,13 @@
|
||||
"use client"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import DeleteButton from "@modules/common/components/delete-button"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import {
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from '@kit/ui/table';
|
||||
import { formatCurrency } from "@/packages/shared/src/utils"
|
||||
import { Trash } from "lucide-react"
|
||||
import CartItemDelete from "./cart-item-delete";
|
||||
|
||||
export default function CartItem({ item, currencyCode }: {
|
||||
item: HttpTypes.StoreCartLineItem
|
||||
@@ -49,7 +48,7 @@ export default function CartItem({ item, currencyCode }: {
|
||||
|
||||
<TableCell className="text-right px-6">
|
||||
<span className="flex gap-x-1 justify-end w-[60px]">
|
||||
<DeleteButton id={item.id} data-testid="product-delete-button" Icon={<Trash />} />
|
||||
<CartItemDelete id={item.id} />
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
|
||||
@@ -8,6 +8,7 @@ import { Button } from '@kit/ui/button';
|
||||
import { Trans } from '@kit/ui/trans';
|
||||
import { placeOrder } from "@lib/data/cart"
|
||||
import Link from 'next/link';
|
||||
import Loading from '@/app/home/loading';
|
||||
|
||||
enum Status {
|
||||
LOADING = 'LOADING',
|
||||
@@ -15,12 +16,14 @@ enum Status {
|
||||
}
|
||||
|
||||
export function MontonioCheckoutCallback() {
|
||||
const router = useRouter();
|
||||
const [status, setStatus] = useState<Status>(Status.LOADING);
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const token = searchParams.get('order-token');
|
||||
if (!token) {
|
||||
router.push('/home/cart');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,7 +47,12 @@ export function MontonioCheckoutCallback() {
|
||||
const body = await response.json();
|
||||
const paymentStatus = body.status as string;
|
||||
if (paymentStatus === 'PAID') {
|
||||
await placeOrder();
|
||||
try {
|
||||
await placeOrder();
|
||||
} catch (e) {
|
||||
console.error("Error placing order", e);
|
||||
router.push('/home/cart');
|
||||
}
|
||||
} else {
|
||||
setStatus(Status.ERROR);
|
||||
}
|
||||
@@ -83,5 +91,5 @@ export function MontonioCheckoutCallback() {
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
return (<Loading />);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import {
|
||||
Card,
|
||||
@@ -34,8 +35,9 @@ export default function SelectAnalysisPackage({
|
||||
analysisPackage: StoreProduct
|
||||
countryCode: string,
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const { t, i18n: { language } } = useTranslation();
|
||||
|
||||
|
||||
const [isAddingToCart, setIsAddingToCart] = useState(false);
|
||||
const handleSelect = async (selectedVariant: StoreProductVariant) => {
|
||||
if (!selectedVariant?.id) return null
|
||||
@@ -46,6 +48,7 @@ export default function SelectAnalysisPackage({
|
||||
countryCode,
|
||||
});
|
||||
setIsAddingToCart(false);
|
||||
router.push('/home/cart');
|
||||
}
|
||||
|
||||
const titleKey = analysisPackage.title;
|
||||
|
||||
@@ -44,7 +44,7 @@ export async function retrieveCart(cartId?: string) {
|
||||
},
|
||||
headers,
|
||||
next,
|
||||
cache: "force-cache",
|
||||
//cache: "force-cache",
|
||||
})
|
||||
.then(({ cart }) => cart)
|
||||
.catch(() => null);
|
||||
@@ -396,7 +396,7 @@ export async function placeOrder(cartId?: string) {
|
||||
const id = cartId || (await getCartId());
|
||||
|
||||
if (!id) {
|
||||
return;
|
||||
throw new Error("No existing cart found when placing an order");
|
||||
}
|
||||
|
||||
const headers = {
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
},
|
||||
"services": {
|
||||
"productColumnLabel": "Service name"
|
||||
},
|
||||
"delete": {
|
||||
"success": "Item removed from cart",
|
||||
"loading": "Removing item from cart",
|
||||
"error": "Failed to remove item from cart"
|
||||
}
|
||||
},
|
||||
"orderConfirmed": {
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
},
|
||||
"services": {
|
||||
"productColumnLabel": "Teenuse nimi"
|
||||
},
|
||||
"delete": {
|
||||
"success": "Toode eemaldatud ostukorvist",
|
||||
"loading": "Toote eemaldamine ostukorvist",
|
||||
"error": "Toote eemaldamine ostukorvist ebaõnnestus"
|
||||
}
|
||||
},
|
||||
"orderConfirmed": {
|
||||
|
||||
Reference in New Issue
Block a user