From 4ae9f3fdd62d690d84aedbf483321de7432b1871 Mon Sep 17 00:00:00 2001 From: builtbysuraj Date: Tue, 6 Feb 2024 14:22:11 +0530 Subject: [PATCH] chore: Add toast notify in cart page --- client/index.html | 2 +- client/package-lock.json | 24 ++++++++++ client/package.json | 1 + .../{public => src/assets/img}/flipkart.png | Bin .../assets/img}/flipkartPlus.png | Bin client/src/context/ServerStatusProvider.tsx | 41 +++++++++++------- client/src/layouts/header/Header.tsx | 2 +- client/src/main.tsx | 2 + client/src/pages/cart/CartPage.tsx | 8 +--- .../components/place-order/PlaceOrder.tsx | 28 +++++++++++- 10 files changed, 81 insertions(+), 27 deletions(-) rename client/{public => src/assets/img}/flipkart.png (100%) rename client/{public => src/assets/img}/flipkartPlus.png (100%) diff --git a/client/index.html b/client/index.html index d8f48db..e132ed2 100644 --- a/client/index.html +++ b/client/index.html @@ -2,7 +2,7 @@ - + Online Shopping Site for Mobiles, Electronics, Furniture, Grocery, diff --git a/client/package-lock.json b/client/package-lock.json index 258a210..e47ce28 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -16,6 +16,7 @@ "lodash.debounce": "^4.0.8", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hot-toast": "^2.4.1", "react-image-gallery": "^1.3.0", "react-redux": "^9.0.4", "react-router-dom": "^6.21.0" @@ -3760,6 +3761,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/goober": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", + "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5151,6 +5160,21 @@ "react": "^18.2.0" } }, + "node_modules/react-hot-toast": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", + "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "dependencies": { + "goober": "^2.1.10" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-image-gallery": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz", diff --git a/client/package.json b/client/package.json index d07f1dd..163d749 100644 --- a/client/package.json +++ b/client/package.json @@ -23,6 +23,7 @@ "lodash.debounce": "^4.0.8", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-hot-toast": "^2.4.1", "react-image-gallery": "^1.3.0", "react-redux": "^9.0.4", "react-router-dom": "^6.21.0" diff --git a/client/public/flipkart.png b/client/src/assets/img/flipkart.png similarity index 100% rename from client/public/flipkart.png rename to client/src/assets/img/flipkart.png diff --git a/client/public/flipkartPlus.png b/client/src/assets/img/flipkartPlus.png similarity index 100% rename from client/public/flipkartPlus.png rename to client/src/assets/img/flipkartPlus.png diff --git a/client/src/context/ServerStatusProvider.tsx b/client/src/context/ServerStatusProvider.tsx index da8f77c..4e45885 100644 --- a/client/src/context/ServerStatusProvider.tsx +++ b/client/src/context/ServerStatusProvider.tsx @@ -1,4 +1,4 @@ -import { ENV } from '@/conf' +import axios from 'axios' import { PropsWithChildren, createContext, @@ -7,29 +7,38 @@ import { useState, } from 'react' -export const ServerStatusContext = createContext<string | null>(null) +import { ENV } from '@/conf' + +type ServerStateType = { + status: boolean + message: string +} + +export const ServerStatusContext = createContext<ServerStateType | null>(null) export default function ServerStatusProvider({ children }: PropsWithChildren) { - const [serverStatus, setServerStatus] = useState<string | null>('') + const [serverStatus, setServerStatus] = useState<ServerStateType>({ + status: false, + message: '', + }) useEffect(() => { - const checkServerStatus = () => { - fetch(`${ENV.SERVER_URL}/api/status`) - .then((response) => response.json()) - .then((data) => { - if (data.status) { - setServerStatus(data.message) - } else { - setServerStatus('Server is not running') - } - }) - .catch(() => setServerStatus('Server is not running')) + const checkServerStatus = async () => { + try { + const { data } = await axios.get(`${ENV.SERVER_URL}/api/status`) + + if (data.status) { + setServerStatus(data) + } else { + setServerStatus({ status: false, message: 'Server is not running' }) + } + } catch (error) { + setServerStatus({ status: false, message: 'Wait for server to start' }) + } } - // Call immediately checkServerStatus() - // Then call every 5 seconds const intervalId = setInterval(checkServerStatus, 10000) // Clear interval on component unmount diff --git a/client/src/layouts/header/Header.tsx b/client/src/layouts/header/Header.tsx index aaf6afc..3206b79 100644 --- a/client/src/layouts/header/Header.tsx +++ b/client/src/layouts/header/Header.tsx @@ -7,8 +7,8 @@ import Input from '@/components/ui/Input' import useGetParams from '@/hooks/useGetParams' import useHandleDispatch from '@/hooks/useHandleDispatch' import { useAppSelector } from '@/state/store' +import flipkart from '../../assets/img/flipkart.png' import styles from './Header.module.css' -import flipkart from '/flipkart.png' function Header() { const cartData = useAppSelector((state) => state.cart) diff --git a/client/src/main.tsx b/client/src/main.tsx index 5546080..d1960da 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,4 +1,5 @@ import { createRoot } from 'react-dom/client' +import { Toaster } from 'react-hot-toast' import { Provider } from 'react-redux' import { RouterProvider } from 'react-router-dom' @@ -25,6 +26,7 @@ if (process.env.NODE_ENV === 'production') { createRoot(document.querySelector('#root')!).render( <Provider store={store}> <ServerStatusProvider> + <Toaster /> <RouterProvider router={router} /> </ServerStatusProvider> </Provider> diff --git a/client/src/pages/cart/CartPage.tsx b/client/src/pages/cart/CartPage.tsx index c3740ad..998531f 100644 --- a/client/src/pages/cart/CartPage.tsx +++ b/client/src/pages/cart/CartPage.tsx @@ -1,4 +1,3 @@ -import { useServerStatus } from '@/context/ServerStatusProvider' import { useAppSelector } from '@/state/store' import type { CartType } from '@/types' import styles from './CartPage.module.css' @@ -6,16 +5,11 @@ import { CartItem, CartPriceDetails, EmptyCart, PlaceOrder } from './components' export default function CartPage() { const cartData = useAppSelector((state) => state.cart) - const serverStatus = useServerStatus() - console.log(serverStatus) - if (!cartData?.length) { - return <EmptyCart /> - } + if (!cartData?.length) return <EmptyCart /> return ( <> - {serverStatus === 'Server is not running' && <h4>{serverStatus}</h4>} <div className={styles.cartContainer}> <div> {cartData?.map((product: CartType) => ( diff --git a/client/src/pages/cart/components/place-order/PlaceOrder.tsx b/client/src/pages/cart/components/place-order/PlaceOrder.tsx index 1347b13..6706c4e 100644 --- a/client/src/pages/cart/components/place-order/PlaceOrder.tsx +++ b/client/src/pages/cart/components/place-order/PlaceOrder.tsx @@ -1,16 +1,27 @@ import axios from 'axios' +import { useServerStatus } from '@/context/ServerStatusProvider' import { totalCartPrice } from '@/utils' +import toast from 'react-hot-toast' import styles from './PlaceOrder.module.css' +declare global { + interface Window { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Razorpay: any + } +} + type Props = { cartData: [] } export default function PlaceOrder({ cartData }: Props) { + const serverStatus = useServerStatus() + const amount = totalCartPrice(cartData) - const handleCheckout = async () => { + const performCheckout = async () => { const { data: { key }, } = await axios.get('http://www.localhost:5000/api/v1/get-key') @@ -34,12 +45,25 @@ export default function PlaceOrder({ cartData }: Props) { address: 'Razorpay Corporate Office', }, } - // @ts-expect-error Custom Razorpay script in index.html + const razor = new window.Razorpay(options) razor.open() } + const handleCheckout = async () => { + if (!serverStatus?.status) { + // @ts-expect-error ... + return toast.error(serverStatus?.message) + } + if (serverStatus?.status) + toast.promise(performCheckout(), { + loading: 'Processing...', + success: <b>Done!</b>, + error: 'Server is not running', + }) + } + return ( <div className={styles.placeOrder}> <button onClick={handleCheckout}>PLACE ORDER</button>