diff --git a/src/pages/UserCartPaymentSuccess.tsx b/src/pages/UserCartPaymentSuccess.tsx
new file mode 100644
index 00000000..1ac0c846
--- /dev/null
+++ b/src/pages/UserCartPaymentSuccess.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable */
+import React, { useEffect, useState } from 'react';
+import { Meta } from '../components/Meta';
+import { useAppDispatch, useAppSelector } from '../store/store';
+import { PuffLoader, PulseLoader } from 'react-spinners';
+import { toast } from 'react-toastify';
+import { checkout, getUserCarts } from '../store/features/carts/cartSlice';
+import {
+ FaCheckSquare,
+ FaMinus,
+ FaPlus,
+ FaEdit,
+ FaTrash,
+ FaGift,
+ FaShippingFast,
+} from 'react-icons/fa';
+import { useNavigate } from 'react-router-dom';
+import Product from '../components/product/Product';
+import { Box, LinearProgress } from '@mui/material';
+import { useLocation } from 'react-router-dom';
+
+const UserCartPaymentSuccess: React.FC = () => {
+ const dispatch = useAppDispatch();
+ const [isLoading, setIsLoading] = useState(true);
+ const [currentEndpoint, setCurrentEndpoint] = useState('');
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ useEffect(() => {
+ toast.success('Cart payment success');
+ navigate('/shopping-cart');
+ }, [location.search, navigate]);
+
+ return (
+ <>
+
+
)
) : (
- ""
+ ''
)}
@@ -161,11 +165,11 @@ function UserLogin() {
) : null}
@@ -186,4 +190,4 @@ function UserLogin() {
);
}
-export default UserLogin;
\ No newline at end of file
+export default UserLogin;
diff --git a/src/pages/UserViewCart.tsx b/src/pages/UserViewCart.tsx
index 37da0a45..d49826c1 100644
--- a/src/pages/UserViewCart.tsx
+++ b/src/pages/UserViewCart.tsx
@@ -1,10 +1,21 @@
/* eslint-disable */
-import React, { useEffect, useState } from "react";
-import { Meta } from "../components/Meta";
-import { useAppDispatch, useAppSelector } from "../store/store";
-import { PuffLoader, PulseLoader } from "react-spinners";
-import { toast } from "react-toastify";
-import { checkout, getUserCarts , clearCarts,createCart,clearCart,clearCartProduct} from "../store/features/carts/cartSlice";
+import React, { useEffect, useState } from 'react';
+import { Meta } from '../components/Meta';
+import { useAppDispatch, useAppSelector } from '../store/store';
+import { PuffLoader, PulseLoader } from 'react-spinners';
+import { toast } from 'react-toastify';
+import {
+ checkout,
+ getUserCarts,
+ clearCarts,
+ createCart,
+ clearCart,
+ clearCartProduct,
+ createProductStripe,
+ createSessionStripe,
+ updateCartStatus,
+ userSaveOrder,
+} from '../store/features/carts/cartSlice';
import {
FaCheckSquare,
FaMinus,
@@ -13,19 +24,20 @@ import {
FaTrash,
FaGift,
FaShippingFast,
-} from "react-icons/fa";
-import { GiBroom } from "react-icons/gi";
-import { useNavigate } from "react-router-dom";
-import Dialog from "@mui/material/Dialog";
-import DialogActions from "@mui/material/DialogActions";
-import DialogContent from "@mui/material/DialogContent";
-import DialogContentText from "@mui/material/DialogContentText";
-import DialogTitle from "@mui/material/DialogTitle";
-import Product from "../components/product/Product";
-import { Box, LinearProgress } from "@mui/material";
-import Button from "@mui/material/Button";
+} from 'react-icons/fa';
+import { GiBroom } from 'react-icons/gi';
+import { useNavigate } from 'react-router-dom';
+import Dialog from '@mui/material/Dialog';
+import DialogActions from '@mui/material/DialogActions';
+import DialogContent from '@mui/material/DialogContent';
+import DialogContentText from '@mui/material/DialogContentText';
+import DialogTitle from '@mui/material/DialogTitle';
+import Product from '../components/product/Product';
+import { Box, LinearProgress } from '@mui/material';
+import Button from '@mui/material/Button';
import Dispatch from 'react';
-
+import { fetchUserProfile } from '../store/features/user/userSlice';
+import { useLocation } from 'react-router-dom';
const UserViewCart: React.FC = () => {
const dispatch = useAppDispatch();
@@ -34,49 +46,181 @@ const UserViewCart: React.FC = () => {
const [cartData, setCartData] = useState(null);
const [cartResponseData, setCartResponseData] = useState(null);
const [isLoggedOut, setIsLoggedOut] = useState(false);
- const [checkoutData, setcheckoutData] = useState(null);
+ const [checkoutData, setCheckoutData] = useState(null);
const [isCheckoutSuccess, setCheckoutSuccess] = useState(null);
const [isPreloader, setIsPreloader] = useState(false);
const [discount, setDiscount] = useState(0);
const [totalProductPrice, setTotalProductPrice] = useState(0);
- const [arrayOfProduct, setarrayOfProduct] = useState(null);
+ const [arrayOfProduct, setArrayOfProduct] = useState(null);
const [quantities, setQuantities] = useState<{ [key: string]: number }>({});
- const [open,setOpen] = useState(false)
-
+ const [open, setOpen] = useState(false);
+ const [cartToPay, setCartToPay] = useState(null);
+ const [amountToPay, setAmountToPay] = useState(null);
+ const [stripePrice, setStripePrice] = useState('');
+ const [currentEndpoint, setCurrentEndpoint] = useState('');
const navigate = useNavigate();
+ const location = useLocation();
const cartState = useAppSelector((state) => state.cart);
-
-
useEffect(() => {
- const fetchCarts = async () => {
- try {
- setIsLoading(true);
- const response = await dispatch(getUserCarts());
- const response1 = await dispatch(getUserCarts()).unwrap();
- if (response.payload === "Not authorized") {
- setIsLoggedOut(true);
- toast.error("Please login first");
- navigate("/login");
- }
- setCartResponseData(response1.data);
- setIsLoading(false);
- } catch (error: any) {
- if (error === "Not authorized") {
- setIsLoggedOut(true);
- toast.error("Please login first");
- navigate("/login");
- }
- console.error("Error fetching carts:", error);
- setIsLoading(false);
- setIsError(true);
- toast.error(error.message);
- }
- };
fetchCarts();
+ checkPayFailOrSuccess();
}, [dispatch]);
+ const fetchCarts = async () => {
+ try {
+ setIsLoading(true);
+ const response = await dispatch(getUserCarts());
+ const response1 = await dispatch(getUserCarts()).unwrap();
+ if (response.payload === 'Not authorized') {
+ setIsLoggedOut(true);
+ toast.error('Please login first');
+ navigate('/login');
+ }
+ setCartResponseData(response1.data);
+ setIsLoading(false);
+ } catch (error: any) {
+ if (error === 'Not authorized') {
+ setIsLoggedOut(true);
+ toast.error('Please login first');
+ navigate('/login');
+ }
+ console.error('Error fetching carts:', error);
+ setIsLoading(false);
+ setIsError(true);
+ toast.error(error.message);
+ }
+ };
+ const handleCartCheckOut = async (
+ cartId: string,
+ index: number,
+ productsArr: Array<{
+ name: string;
+ description: string;
+ image: string;
+ price: string;
+ shopId: string;
+ }>
+ ) => {
+ setIsPreloader(true);
+ try {
+ const response = await dispatch(checkout(cartId));
+ if (!response.payload) {
+ throw new Error(
+ 'Checkout failed, Check your internet connection or tryagainlater'
+ );
+ }
+ localStorage.setItem('cartToPay', cartId);
+
+ localStorage.setItem('productsToSave', JSON.stringify(productsArr));
+ const totalCartAmount = response.payload.data.totalAmount;
+ const array = cartResponseData.carts[index];
+
+ setArrayOfProduct(array);
+ setCheckoutData(totalCartAmount);
+
+ const totalProductPrice = array.products.reduce(
+ (acc, product) => acc + parseFloat(product.price),
+ 0
+ );
+ setTotalProductPrice(totalProductPrice);
+
+ const names = productsArr.map((product) => product.name).join(', ');
+ const descriptions = productsArr
+ .map((product) => product.description)
+ .join(', ');
+ const image1 = productsArr[0]?.image;
+ const image2 = productsArr[1]?.image;
+ const shopidToSave: any = productsArr[0]?.shopId;
+ localStorage.setItem('shopIdToSave', shopidToSave);
+
+ const unit_amount = Math.round(totalCartAmount * 100);
+
+ setAmountToPay(unit_amount);
+ const stripeProduct = await dispatch(
+ createProductStripe({
+ name: names,
+ description: descriptions,
+ image1,
+ image2,
+ unit_amount: unit_amount,
+ })
+ );
+ localStorage.setItem(
+ 'stripePrice',
+ stripeProduct.payload.data.product.default_price
+ );
+
+ setCheckoutSuccess(true);
+
+ toast.success('Checkout is done Successfully');
+ } catch (error) {
+ console.error('Checkout failed', error);
+ toast.error('Checkout failed');
+ } finally {
+ setIsPreloader(false);
+ }
+ };
+
+ const handlePayCart = async () => {
+ try {
+ setIsPreloader(true);
+ const profile: any = await dispatch(fetchUserProfile());
+ const data = {
+ successUrl: 'https://e-commerce-ninja-fn-staging.netlify.app/shopping-cart?success',
+ cancelUrl: 'https://e-commerce-ninja-fn-staging.netlify.app/shopping-cart?cancel',
+ customerEmail: profile.payload.email,
+ price: localStorage.getItem('stripePrice'),
+ };
+ const response = await dispatch(createSessionStripe(data));
+ const url = response.payload.data.session.url;
+ window.location.href = url;
+ } catch (error) {
+ console.error('Checkout failed', error);
+ toast.error('Payment initialization failed, try again later');
+ } finally {
+ setIsPreloader(false);
+ }
+ };
+
+ const checkPayFailOrSuccess = async () => {
+ const params = window.location.search.slice(1);
+ if (params === 'success') {
+ setIsPreloader(true);
+ const cartId = localStorage.getItem('cartToPay');
+ const products = localStorage.getItem('productsToSave');
+ const shopId = localStorage.getItem('shopIdToSave');
+ if (!cartId || !products || !shopId) {
+ navigate('/shopping-cart');
+ toast.error('Unkonwn error occured saving order');
+ return;
+ }
+ const data = {
+ cartId: cartId,
+ status: 'Paid',
+ };
+ const cartStatus = await dispatch(updateCartStatus(data));
+ const order = await dispatch(
+ userSaveOrder({
+ cartId: cartId,
+ paymentMethodId: 'Stripe',
+ products: products,
+ shopId: shopId,
+ })
+ );
+ toast.success('Cart Payment successful');
+ localStorage.removeItem('cartToPay');
+ localStorage.removeItem('productsToSave');
+ localStorage.removeItem('shopIdToSave');
+ navigate('/shopping-cart');
+ setIsPreloader(false);
+ } else if (params === 'cancel') {
+ toast.error('Payment cancelled successfully');
+ navigate('/shopping-cart');
+ setIsPreloader(false);
+ }
+ };
if (isLoading) {
return (
@@ -89,7 +233,7 @@ const UserViewCart: React.FC = () => {
if (isError) {
return (
-
Failed to load cart products. Please try again later.
+
No cart found.
);
}
@@ -109,31 +253,17 @@ const UserViewCart: React.FC = () => {
);
}
- const handleCartCheckOut = async (cartId, index) => {
- setIsPreloader(true);
- const response = await dispatch(checkout(cartId));
- const array = cartResponseData?.carts[index];
- setarrayOfProduct(array);
- setcheckoutData(response.payload.data.totalAmount);
- const totalProductPrice = array.products.reduce(
- (acc, product) => acc + parseFloat(product.price) * (product.quantity || 1),
- 0
- );
- setTotalProductPrice(totalProductPrice);
- setCheckoutSuccess(true);
- setIsPreloader(false);
- toast.success("Checkout is done Successfully");
- };
-
- const handleAddProductToCart = async (productId: string, quantity:number) => {
+ const handleAddProductToCart = async (
+ productId: string,
+ quantity: number
+ ) => {
try {
- if (quantity < 1) return;
+ if (quantity < 1) return;
const response = await dispatch(
createCart({ productId, quantity })
).unwrap();
if (response.data) {
-
setQuantities((prevQuantities) => ({
...prevQuantities,
[productId]: quantity,
@@ -145,12 +275,12 @@ const UserViewCart: React.FC = () => {
toast.error(response.message);
}
} catch (error: any) {
- if (error === "Not authorized") {
- localStorage.setItem("pendingCartProduct", productId);
- toast.error("Please login first");
- navigate("/login");
+ if (error === 'Not authorized') {
+ localStorage.setItem('pendingCartProduct', productId);
+ toast.error('Please login first');
+ navigate('/login');
} else {
- toast.error("Something went wrong. Please try again later.");
+ toast.error('Something went wrong. Please try again later.');
}
} finally {
setIsLoading(false);
@@ -159,94 +289,97 @@ const UserViewCart: React.FC = () => {
const incrementQuantity = (productId: string) => {
const currentQuantity = quantities[productId] || 1;
- handleAddProductToCart(productId,currentQuantity+1)
+ handleAddProductToCart(productId, currentQuantity + 1);
};
const decrementQuantity = (productId: string) => {
const currentQuantity = quantities[productId] || 1;
if (currentQuantity > 1) {
- handleAddProductToCart(productId,currentQuantity-1)
-
+ handleAddProductToCart(productId, currentQuantity - 1);
}
};
const handleClearCart = async () => {
+ setIsPreloader(true);
+ await dispatch(clearCarts()).unwrap();
+ setIsPreloader(false);
+ await fetchCarts();
+ toast.success('Cart cleared successfully');
+ navigate('/shopping-cart');
+ handleClose();
+ };
+
+ const handleClearSingleCart = async (cartId) => {
try {
- await dispatch(clearCarts()).unwrap();
- const response1 = await dispatch(getUserCarts()).unwrap();
+ setIsPreloader(true);
+ await dispatch(clearCart(cartId));
+ const response1 = await dispatch(getUserCarts()).unwrap();
+ setCheckoutSuccess(false);
setCartResponseData(response1.data);
-
- toast.success("Cart cleared successfully");
- setCartResponseData({ ...cartResponseData, carts: [] });
- setTotalProductPrice(0);
+ const remainingCarts = cartResponseData.carts.filter(
+ (cart) => cart.cartId !== cartId
+ );
+ setCartResponseData({ ...cartResponseData, carts: remainingCarts });
+ setIsPreloader(false);
+ toast.success('Cart cleared successfully');
} catch (error) {
- console.error("Error clearing cart:", error);
- toast.error("Failed to clear the cart");
+ console.error('Error clearing cart:', error);
+ toast.error('Failed to clear the cart');
+ } finally {
+ setIsPreloader(false);
}
};
- const handleClearSingleCart = async (cartId) => {
-
+ const handleClearCartProduct = async (
+ cartId,
+ productId,
+ cartProductsList
+ ) => {
try {
- await dispatch(clearCart(cartId));
- const response1 = await dispatch(getUserCarts()).unwrap();
- setCheckoutSuccess(false);
- setCartResponseData(response1.data);
- const remainingCarts = cartResponseData.carts.filter((cart)=>cart.cartId !== cartId)
- setCartResponseData({...cartResponseData,carts:remainingCarts});
-
-
- toast.success("Cart cleared successfully");
+ setIsPreloader(true);
+ if (cartProductsList.length <= 1) {
+ await handleClearSingleCart(cartId);
+ return;
+ }
+ const response = await dispatch(clearCartProduct({ cartId, productId }));
+ const response1 = await dispatch(getUserCarts()).unwrap();
+ setCartResponseData(response1.data);
+ toast.success('product cleared successfully');
} catch (error) {
- console.error("Error clearing cart:", error);
- toast.error("Failed to clear the cart");
- }
-};
-
-const handleClearCartProduct = async(cartId,productId,cartProductsList)=>{
- try {
- if(cartProductsList.length <=1) {
- await handleClearSingleCart(cartId);
- return;
+ toast.error('Failed to clear the product ');
+ throw error;
+ } finally {
+ setIsPreloader(false);
}
- const response = await dispatch(clearCartProduct({cartId,productId}))
- const response1 = await dispatch(getUserCarts()).unwrap();
- setCartResponseData(response1.data);
- toast.success("product cleared successfully");
- } catch (error) {
- toast.error("Failed to clear the product ");
- throw error
- }
-}
+ };
-let cartProductsList=null;
-const handleClose = () => {
-
- setOpen(false);
-};
+ let cartProductsList = null;
+ const handleClose = () => {
+ setOpen(false);
+ };
return (
<>
{isPreloader && (
-
-
-
-
-
- )}
-
-
-
+
+
+
+
+
+ )}
+
+
+
{cartResponseData?.carts?.map((cart: any, index) => (
@@ -254,13 +387,26 @@ const handleClose = () => {
Shopping Cart
-
+ {cart.status === 'Paid' ? (
+
+ ) : (
+
+ )}
- handleClearSingleCart(cart.cartId)}/>
+ handleClearSingleCart(cart.cartId)}
+ />
{cart.products.map((product: any) => {
@@ -281,25 +427,42 @@ const handleClose = () => {
{product.discount}
${product.price}
-
-
-
-
-
+ {cart.status !== 'Paid' && (
+
+
+
+
+
+
+
+
+
-
-
-
-
+ )}
@@ -344,64 +507,66 @@ const handleClose = () => {
))}