AddToCartButton.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. "use client";
  2. import ShoppingCartIcon from "@components/common/icons/ShoppingCartIcon";
  3. import clsx from "clsx";
  4. import Link from "next/link";
  5. import { useAddProduct } from "@utils/hooks/useAddToCart";
  6. import { useAppSelector } from "@/store/hooks";
  7. import LoadingDots from "@components/common/icons/LoadingDots";
  8. import { useCustomToast } from "@utils/hooks/useToast";
  9. export default function AddToCartButton({
  10. productType,
  11. productUrlKey,
  12. productId,
  13. isSaleable
  14. }: {
  15. productType?: string;
  16. productId: string;
  17. productUrlKey: string;
  18. isSaleable?: string;
  19. }) {
  20. const { isCartLoading, onAddToCart } = useAddProduct();
  21. const { showToast } = useCustomToast();
  22. const { user } = useAppSelector((state) => state.user);
  23. const session = { user };
  24. const handleAddToCart = () => {
  25. if (!isSaleable || isSaleable === "") {
  26. showToast("This product is out of stock", "warning");
  27. return;
  28. }
  29. onAddToCart({
  30. productId: productId.split("/").pop() || "",
  31. quantity: 1,
  32. token: session?.user?.token ?? undefined,
  33. });
  34. };
  35. const buttonClasses =
  36. " flex w-full cursor-pointer items-center justify-center px-4 rounded-full min-h-8 tracking-wide ";
  37. const disabledClasses = "cursor-wait opacity-60 hover:opacity-60";
  38. return productType !== "simple" ? (
  39. <Link
  40. aria-disabled="true"
  41. aria-label={productUrlKey}
  42. rel="prefetch"
  43. prefetch={true}
  44. className={clsx(buttonClasses, {
  45. "hover:opacity-90": true,
  46. })}
  47. href={`/product/${productUrlKey}`}
  48. type="submit"
  49. >
  50. <ShoppingCartIcon className="size-6 -rotate-6 stroke-black stroke-[1.5]" />
  51. </Link>
  52. ) : (
  53. <button
  54. aria-disabled={isCartLoading || !isSaleable || isSaleable === ""}
  55. aria-label={productUrlKey}
  56. className={clsx(buttonClasses, {
  57. "hover:opacity-90": isSaleable && isSaleable !== "",
  58. [disabledClasses]: isCartLoading || !isSaleable || isSaleable === "",
  59. })}
  60. type="button"
  61. onClick={handleAddToCart}
  62. >
  63. {isCartLoading ? (
  64. <LoadingDots className="bg-black" />
  65. ) : (
  66. <ShoppingCartIcon className="size-6 -rotate-6 stroke-black stroke-[1.5]" />
  67. )}
  68. </button>
  69. );
  70. }