├── .gitignore ├── README.md ├── assets ├── 2022-08-03_094154.png ├── 2022-08-03_094255.png ├── 2022-08-03_094343.png ├── 2022-08-03_094443.png ├── 2022-08-03_094522.png ├── 2022-08-03_094556.png └── 2022-08-03_094720.png ├── client ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── actions │ ├── cartActions.js │ ├── orderActions.js │ ├── productAction.js │ └── userActions.js │ ├── assets │ ├── home.png │ └── logo2.png │ ├── components │ ├── Links │ │ ├── Links.js │ │ └── Links.module.scss │ ├── MetaData.js │ ├── admin │ │ ├── navbar │ │ │ ├── Navbar.js │ │ │ └── Navbar.module.scss │ │ └── sidebar │ │ │ ├── Sidebar.js │ │ │ └── Sidebar.module.scss │ ├── announcement │ │ ├── Announcement.js │ │ └── Announcement.module.scss │ ├── footer │ │ ├── Footer.js │ │ └── Footer.module.scss │ ├── header │ │ ├── Navbar.js │ │ ├── Navbar.scss │ │ └── Search.js │ ├── loader │ │ ├── ButtonLoader.js │ │ ├── ButtonLoader.scss │ │ └── Loader.js │ ├── profileLinks │ │ ├── ProfileLink.js │ │ └── ProfileLink.module.scss │ ├── route │ │ └── ProtectedRoute.js │ └── widget │ │ ├── Widget.js │ │ └── Widget.scss │ ├── config.js │ ├── constants │ ├── cartConstants.js │ ├── orderConstants.js │ ├── productsConstants.js │ └── userConstants.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── pages │ ├── about │ │ ├── About.js │ │ └── About.module.scss │ ├── admin │ │ ├── dashboard │ │ │ ├── Dashboard.js │ │ │ └── Dashboard.module.scss │ │ ├── newProduct │ │ │ ├── NewProduct.js │ │ │ └── NewProduct.module.scss │ │ ├── orders │ │ │ ├── Orders.js │ │ │ ├── Orders.module.scss │ │ │ └── processOrder │ │ │ │ ├── ProcessOrder.js │ │ │ │ └── Processorder.module.scss │ │ ├── productDetails │ │ │ ├── ProductDetails.js │ │ │ └── ProductDetails.module.scss │ │ ├── productReview │ │ │ ├── ProductReview.js │ │ │ └── ProductReview.module.scss │ │ ├── products │ │ │ ├── ProductsList.js │ │ │ └── ProductsList.module.scss │ │ ├── updateProduct │ │ │ ├── UpdateProduct.js │ │ │ └── UpdateProduct.module.scss │ │ └── users │ │ │ ├── Users.js │ │ │ ├── Users.module.scss │ │ │ └── userDetails │ │ │ ├── UserDetails.js │ │ │ └── UserDetails.module.scss │ ├── auth │ │ ├── forgotPassword │ │ │ ├── ForgotPassword.js │ │ │ └── ForgotPassword.module.scss │ │ ├── login │ │ │ ├── Login.js │ │ │ └── Login.module.scss │ │ ├── register │ │ │ ├── Register.js │ │ │ └── Register.module.scss │ │ └── resetPassword │ │ │ ├── ResetPassword.js │ │ │ └── ResetPassword.module.scss │ ├── cart │ │ ├── Cart.js │ │ ├── Cart.module.scss │ │ ├── checkoutSteps │ │ │ ├── CheckoutSteps.js │ │ │ └── CheckoutSteps.module.scss │ │ ├── confirmOrder │ │ │ ├── ConfirmOrder.js │ │ │ └── ConfirmOrder.module.scss │ │ ├── payment │ │ │ ├── Payment.js │ │ │ └── Payment.module.scss │ │ ├── shipping │ │ │ ├── Shipping.js │ │ │ └── Shipping.module.scss │ │ └── success │ │ │ ├── Success.js │ │ │ └── Success.module.scss │ ├── contact │ │ ├── Contact.js │ │ └── Contact.module.scss │ ├── home │ │ ├── Home.js │ │ ├── banner │ │ │ ├── Banner.js │ │ │ └── Banner.module.scss │ │ ├── category │ │ │ ├── Category.js │ │ │ └── Category.module.scss │ │ └── fashion │ │ │ ├── Fashion.js │ │ │ └── Fashion.module.scss │ ├── products │ │ ├── Product.js │ │ ├── Products.js │ │ └── Products.module.scss │ ├── reviews │ │ └── ListReview.js │ ├── singleProduct │ │ ├── SingleProduct.js │ │ └── SingleProduct.module.scss │ └── user │ │ ├── Profile.js │ │ ├── Profile.module.scss │ │ ├── changePassword │ │ ├── ChangePassword.js │ │ └── ChangePassword.module.scss │ │ ├── myOrders │ │ ├── MyOrders.js │ │ └── MyOrders.module.scss │ │ ├── orderDetails │ │ ├── OrderDetails.js │ │ └── OrderDetails.module.scss │ │ └── updateProfile │ │ ├── UpdateProfile.js │ │ └── UpdateProfile.module.scss │ ├── reducers │ ├── cartReducers.js │ ├── orderReducers.js │ ├── productReducers.js │ └── userReducers.js │ ├── reportWebVitals.js │ ├── setupTests.js │ └── store.js ├── config └── database.js ├── controller ├── authController.js ├── orderController.js ├── paymentController.js └── productController.js ├── index.js ├── middleware ├── auth.js ├── catchAsyncErrors.js └── error.js ├── models ├── order.js ├── product.js └── user.js ├── package-lock.json ├── package.json ├── routes ├── auth.js ├── order.js ├── payment.js └── product.js └── utils ├── apiFeatures.js ├── errorHandler.js ├── jwtToken.js └── sendEmail.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MERN Stack Full Ecommerce Site 2 | 3 | Powerful MERN Stack Ecommerce Project using React, Redux, Node.js, Express, MongoDB, Stripe.We are going to using Redux for state management, stipe to handle our payments, Cloudinary to handle our images, and follow the best practices to implement Authentication & Authorization. 4 | 5 | ## Features 6 | 7 | - Build powerful and fully functional E-commerce website using MERN 8 | - Redux (Best state management tool) 9 | - Authentication using cookies 10 | - Complete Admin Dashboard to manage products, orders, reviews, users 11 | - Add third party site like cloudinary to upload images 12 | - Payment Integration using Stripe 13 | - Add filters, search and pagination 14 | - Complete ratings & reviews system 15 | - Complete Cart & Checkout process 16 | 17 | [Live Site](https://shopx-mern-app.herokuapp.com/) 18 | 19 | ## Homepage 20 | 21 | Home Page 22 | 23 | ## Product Page 24 | 25 | Product Page 26 | 27 | ## Product Details Page 28 | 29 | Product Details 30 | 31 | ## Cart Page 32 | 33 | Cart Page 34 | 35 | ## Order Details 36 | 37 | Order Details 38 | -------------------------------------------------------------------------------- /assets/2022-08-03_094154.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094154.png -------------------------------------------------------------------------------- /assets/2022-08-03_094255.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094255.png -------------------------------------------------------------------------------- /assets/2022-08-03_094343.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094343.png -------------------------------------------------------------------------------- /assets/2022-08-03_094443.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094443.png -------------------------------------------------------------------------------- /assets/2022-08-03_094522.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094522.png -------------------------------------------------------------------------------- /assets/2022-08-03_094556.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094556.png -------------------------------------------------------------------------------- /assets/2022-08-03_094720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/assets/2022-08-03_094720.png -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/react": "^11.8.2", 7 | "@emotion/styled": "^11.8.1", 8 | "@mui/material": "^5.5.2", 9 | "@mui/x-data-grid": "^5.7.0", 10 | "@stripe/react-stripe-js": "^1.7.0", 11 | "@stripe/stripe-js": "^1.25.0", 12 | "@testing-library/jest-dom": "^5.16.2", 13 | "@testing-library/react": "^12.1.4", 14 | "@testing-library/user-event": "^13.5.0", 15 | "axios": "^0.26.1", 16 | "bootstrap": "^5.1.3", 17 | "countries-list": "^2.6.1", 18 | "framer-motion": "^6.2.8", 19 | "rc-slider": "^9.6.5", 20 | "react": "^17.0.2", 21 | "react-alert": "^7.0.3", 22 | "react-alert-template-basic": "^1.0.2", 23 | "react-bootstrap": "^2.2.1", 24 | "react-dom": "^17.0.2", 25 | "react-helmet": "^6.1.0", 26 | "react-icons": "^4.3.1", 27 | "react-js-pagination": "^3.0.3", 28 | "react-paginate": "^8.1.2", 29 | "react-redux": "^7.2.6", 30 | "react-router-dom": "^5.3.0", 31 | "react-scripts": "5.0.0", 32 | "redux": "^4.1.2", 33 | "redux-devtools-extension": "^2.13.9", 34 | "redux-thunk": "^2.4.1", 35 | "sass": "^1.49.9", 36 | "swiper": "^8.0.7", 37 | "web-vitals": "^2.1.4" 38 | }, 39 | "scripts": { 40 | "start": "react-scripts start", 41 | "build": "react-scripts build", 42 | "test": "react-scripts test", 43 | "eject": "react-scripts eject" 44 | }, 45 | "eslintConfig": { 46 | "extends": [ 47 | "react-app", 48 | "react-app/jest" 49 | ] 50 | }, 51 | "browserslist": { 52 | "production": [ 53 | ">0.2%", 54 | "not dead", 55 | "not op_mini all" 56 | ], 57 | "development": [ 58 | "last 1 chrome version", 59 | "last 1 firefox version", 60 | "last 1 safari version" 61 | ] 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | React App 22 | 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/client/public/logo512.png -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /client/src/actions/cartActions.js: -------------------------------------------------------------------------------- 1 | import { axiosInstance } from "../config"; 2 | import { 3 | ADD_TO_CART, 4 | REMOVE_ITEM_CART, 5 | SAVE_SHIPPING_INFO, 6 | } from "../constants/cartConstants"; 7 | 8 | export const addItemToCart = (id, quantity) => async (dispatch, getState) => { 9 | const { data } = await axiosInstance.get(`/api/v1/product/${id}`); 10 | 11 | dispatch({ 12 | type: ADD_TO_CART, 13 | payload: { 14 | product: data.product._id, 15 | name: data.product.name, 16 | price: data.product.price, 17 | image: data.product.images[0].url, 18 | stock: data.product.stock, 19 | quantity, 20 | }, 21 | }); 22 | 23 | localStorage.setItem( 24 | "cartItems", 25 | JSON.stringify(getState().cart.cartItems) 26 | ); 27 | }; 28 | 29 | export const removeItemFromCart = (id) => async (dispatch, getState) => { 30 | dispatch({ 31 | type: REMOVE_ITEM_CART, 32 | payload: id, 33 | }); 34 | 35 | localStorage.setItem( 36 | "cartItems", 37 | JSON.stringify(getState().cart.cartItems) 38 | ); 39 | }; 40 | 41 | export const saveShippingInfo = (data) => async (dispatch) => { 42 | dispatch({ 43 | type: SAVE_SHIPPING_INFO, 44 | payload: data, 45 | }); 46 | 47 | localStorage.setItem("shippingInfo", JSON.stringify(data)); 48 | }; 49 | -------------------------------------------------------------------------------- /client/src/actions/orderActions.js: -------------------------------------------------------------------------------- 1 | import { axiosInstance } from "../config"; 2 | import { 3 | CREATE_ORDER_REQUEST, 4 | CREATE_ORDER_SUCCESS, 5 | CREATE_ORDER_FAIL, 6 | CLEAR_ERRORS, 7 | ALL_ORDERS_REQUEST, 8 | ALL_ORDERS_SUCCESS, 9 | ALL_ORDERS_FAIL, 10 | UPDATE_ORDER_REQUEST, 11 | UPDATE_ORDER_SUCCESS, 12 | UPDATE_ORDER_FAIL, 13 | DELETE_ORDER_REQUEST, 14 | DELETE_ORDER_SUCCESS, 15 | DELETE_ORDER_FAIL, 16 | ORDER_DETAILS_REQUEST, 17 | ORDER_DETAILS_SUCCESS, 18 | ORDER_DETAILS_FAIL, 19 | MY_ORDERS_REQUEST, 20 | MY_ORDERS_SUCCESS, 21 | MY_ORDERS_FAIL, 22 | } from "../constants/orderConstants"; 23 | 24 | export const createOrder = (order) => async (dispatch, getState) => { 25 | try { 26 | dispatch({ type: CREATE_ORDER_REQUEST }); 27 | 28 | const config = { 29 | headers: { 30 | "Content-Type": "application/json", 31 | }, 32 | }; 33 | 34 | const { data } = await axiosInstance.post( 35 | "/api/v1/order/new", 36 | order, 37 | config 38 | ); 39 | 40 | dispatch({ 41 | type: CREATE_ORDER_SUCCESS, 42 | payload: data, 43 | }); 44 | } catch (error) { 45 | dispatch({ 46 | type: CREATE_ORDER_FAIL, 47 | payload: error.response.data.message, 48 | }); 49 | } 50 | }; 51 | 52 | // Get curretly logged in user orders 53 | export const myOrders = () => async (dispatch) => { 54 | try { 55 | dispatch({ type: MY_ORDERS_REQUEST }); 56 | 57 | const { data } = await axiosInstance.get("/api/v1/orders/me"); 58 | 59 | dispatch({ 60 | type: MY_ORDERS_SUCCESS, 61 | payload: data.orders, 62 | }); 63 | } catch (error) { 64 | dispatch({ 65 | type: MY_ORDERS_FAIL, 66 | payload: error.response.data.message, 67 | }); 68 | } 69 | }; 70 | 71 | // Get all orders - ADMIN 72 | export const allOrders = () => async (dispatch) => { 73 | try { 74 | dispatch({ type: ALL_ORDERS_REQUEST }); 75 | 76 | const { data } = await axiosInstance.get(`/api/v1/admin/orders`); 77 | 78 | dispatch({ 79 | type: ALL_ORDERS_SUCCESS, 80 | payload: data, 81 | }); 82 | } catch (error) { 83 | dispatch({ 84 | type: ALL_ORDERS_FAIL, 85 | payload: error.response.data.message, 86 | }); 87 | } 88 | }; 89 | 90 | // update order 91 | export const updateOrder = (id, orderData) => async (dispatch) => { 92 | try { 93 | dispatch({ type: UPDATE_ORDER_REQUEST }); 94 | 95 | const config = { 96 | headers: { 97 | "Content-Type": "application/json", 98 | }, 99 | }; 100 | 101 | const { data } = await axiosInstance.put( 102 | `/api/v1/admin/order/${id}`, 103 | orderData, 104 | config 105 | ); 106 | 107 | dispatch({ 108 | type: UPDATE_ORDER_SUCCESS, 109 | payload: data.success, 110 | }); 111 | } catch (error) { 112 | dispatch({ 113 | type: UPDATE_ORDER_FAIL, 114 | payload: error.response.data.message, 115 | }); 116 | } 117 | }; 118 | 119 | // Delete order 120 | export const deleteOrder = (id) => async (dispatch) => { 121 | try { 122 | dispatch({ type: DELETE_ORDER_REQUEST }); 123 | 124 | const { data } = await axiosInstance.delete( 125 | `/api/v1/admin/order/${id}` 126 | ); 127 | 128 | dispatch({ 129 | type: DELETE_ORDER_SUCCESS, 130 | payload: data.success, 131 | }); 132 | } catch (error) { 133 | dispatch({ 134 | type: DELETE_ORDER_FAIL, 135 | payload: error.response.data.message, 136 | }); 137 | } 138 | }; 139 | 140 | // Get order details 141 | export const getOrderDetails = (id) => async (dispatch) => { 142 | try { 143 | dispatch({ type: ORDER_DETAILS_REQUEST }); 144 | 145 | const { data } = await axiosInstance.get(`/api/v1/order/${id}`); 146 | 147 | dispatch({ 148 | type: ORDER_DETAILS_SUCCESS, 149 | payload: data.order, 150 | }); 151 | } catch (error) { 152 | dispatch({ 153 | type: ORDER_DETAILS_FAIL, 154 | payload: error.response.data.message, 155 | }); 156 | } 157 | }; 158 | 159 | // Clear Errors 160 | export const clearErrors = () => async (dispatch) => { 161 | dispatch({ 162 | type: CLEAR_ERRORS, 163 | }); 164 | }; 165 | -------------------------------------------------------------------------------- /client/src/assets/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/client/src/assets/home.png -------------------------------------------------------------------------------- /client/src/assets/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehedi008h/MERN-Stack-Full-Ecommerce-Site/f3d192cd2a6af2e805207f710f1ef5d750fac7cf/client/src/assets/logo2.png -------------------------------------------------------------------------------- /client/src/components/Links/Links.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import styles from "./Links.module.scss"; 4 | 5 | const Links = () => { 6 | return ( 7 |
8 | Home 9 | Products 10 | Contact 11 | About 12 |
13 | ); 14 | }; 15 | 16 | export default Links; 17 | -------------------------------------------------------------------------------- /client/src/components/Links/Links.module.scss: -------------------------------------------------------------------------------- 1 | .links { 2 | height: 50px; 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | border-bottom: 1px solid black; 7 | 8 | a { 9 | margin: 0 1rem; 10 | text-decoration: none; 11 | text-transform: uppercase; 12 | font-weight: 500; 13 | letter-spacing: 0.5px; 14 | color: black; 15 | font-family: var(--font-poppins); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /client/src/components/MetaData.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Helmet } from "react-helmet"; 3 | 4 | const MetaData = ({ title }) => { 5 | return ( 6 | 7 | {`${title} - ShopX`} 8 | 9 | ); 10 | }; 11 | 12 | export default MetaData; 13 | -------------------------------------------------------------------------------- /client/src/components/admin/navbar/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./Navbar.module.scss"; 3 | 4 | const Navbar = () => { 5 | return ( 6 |
7 |

Admin

8 |
9 | ); 10 | }; 11 | 12 | export default Navbar; 13 | -------------------------------------------------------------------------------- /client/src/components/admin/navbar/Navbar.module.scss: -------------------------------------------------------------------------------- 1 | .navbar { 2 | height: 60px; 3 | background: rgba(230, 228, 228, 0.25); 4 | // box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); 5 | // backdrop-filter: blur(4px); 6 | // -webkit-backdrop-filter: blur(4px); 7 | border: 1px solid rgba(255, 255, 255, 0.18); 8 | padding: 0 1rem; 9 | 10 | display: flex; 11 | align-items: center; 12 | font-family: var(--font-poppins); 13 | width: 100%; 14 | } 15 | -------------------------------------------------------------------------------- /client/src/components/admin/sidebar/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { MdOutlineDashboard, MdOutlineFavoriteBorder } from "react-icons/md"; 4 | import { BiUserCircle } from "react-icons/bi"; 5 | import { FiPlusSquare } from "react-icons/fi"; 6 | 7 | import styles from "./Sidebar.module.scss"; 8 | import { HiTemplate } from "react-icons/hi"; 9 | import { AiFillStar, AiOutlineHome } from "react-icons/ai"; 10 | 11 | const Sidebar = () => { 12 | return ( 13 |
14 | 19 |
20 | Main 21 |
22 |
  • 23 | 24 | 25 | Home 26 | 27 |
  • 28 |
  • 29 | 30 | 31 | Dashboard 32 | 33 |
  • 34 |
    35 |
    36 |
    37 | List 38 |
    39 |
  • 40 | 41 | Products 42 | 43 |
  • 44 |
  • 45 | 46 | 50 | Orders 51 | 52 |
  • 53 |
  • 54 | 55 | 56 | Users 57 | 58 |
  • 59 |
  • 60 | 61 | 62 | Reviews 63 | 64 |
  • 65 |
    66 |
    67 |
    68 | Service 69 |
    70 |
  • 71 | 72 | 73 | Add Product 74 | 75 |
  • 76 |
    77 |
    78 |
    79 | ); 80 | }; 81 | 82 | export default Sidebar; 83 | -------------------------------------------------------------------------------- /client/src/components/admin/sidebar/Sidebar.module.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | min-height: 100vh; 3 | background: rgba(230, 228, 228, 0.25); 4 | // box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); 5 | border: 1px solid rgba(255, 255, 255, 0.18); 6 | 7 | font-family: var(--font-roboto); 8 | padding: 1rem; 9 | width: 100%; 10 | div { 11 | margin-top: 30px; 12 | span { 13 | font-weight: 500; 14 | letter-spacing: 1px; 15 | font-size: 16px; 16 | } 17 | div { 18 | display: flex; 19 | flex-direction: column; 20 | gap: 5px; 21 | li { 22 | list-style: none; 23 | padding: 10px 5px; 24 | 25 | &:hover { 26 | border-right: 4px solid #00ccd6; 27 | background-color: #e6ffff; 28 | 29 | border-radius: 5px; 30 | a { 31 | color: #00ccd6; 32 | } 33 | } 34 | a { 35 | text-decoration: none; 36 | font-weight: 500; 37 | letter-spacing: 1px; 38 | padding: 10px 0px; 39 | color: gray; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /client/src/components/announcement/Announcement.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./Announcement.module.scss"; 3 | 4 | const Announcement = () => { 5 | return ( 6 |
    7 | FREE SHIPPING ALL ACROSS THE COUNTRY ! 8 |
    9 | ); 10 | }; 11 | 12 | export default Announcement; 13 | -------------------------------------------------------------------------------- /client/src/components/announcement/Announcement.module.scss: -------------------------------------------------------------------------------- 1 | .announcement { 2 | background-image: linear-gradient(120deg, #f6d365 0%, #fda085 100%); 3 | width: 100%; 4 | height: 40px; 5 | display: flex; 6 | margin: auto; 7 | justify-content: center; 8 | align-items: center; 9 | text-transform: uppercase; 10 | font-weight: 500; 11 | letter-spacing: 0.5px; 12 | color: black; 13 | font-family: var(--font-poppins); 14 | } 15 | -------------------------------------------------------------------------------- /client/src/components/footer/Footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { AiOutlineMail } from "react-icons/ai"; 3 | import styles from "./Footer.module.scss"; 4 | 5 | const Footer = () => { 6 | return ( 7 |
    8 |
    9 |
    10 |
    11 | {/* about us */} 12 |
    13 |
    14 |
    About Us
    15 |
    16 |

    17 | Lorem ipsum dolor sit, amet consectetur 18 | adipisicing elit. Est, et atque ducimus 19 | deserunt asperiores aliquid? 20 |

    21 |
    22 |
    23 |
    24 | {/* information */} 25 |
    26 |
    27 |
    Information
    28 |
    29 |
  • About Us
  • 30 |
  • Contact Us
  • 31 |
  • FAQs
  • 32 |
  • Privacy Policy
  • 33 |
  • Refund policy
  • 34 |
  • Cookie Policy
  • 35 |
    36 |
    37 |
    38 | {/* customer service */} 39 |
    40 |
    41 |
    CUSTTOMER SERVICE
    42 |
    43 |
  • My Account
  • 44 |
  • Support Center
  • 45 |
  • Terms & Conditions
  • 46 |
  • Returns & Exchanges
  • 47 |
  • Shipping & Delivery
  • 48 |
    49 |
    50 |
    51 | {/* the optimal newsletter */} 52 |
    53 |
    54 |
    THE OPTIMAL NEWSLETTER
    55 |
    56 |

    57 | Lorem ipsum dolor sit amet consectetur 58 | adipisicing elit. Omnis, saepe. 59 |

    60 | 61 | 64 |
    65 |
    66 |
    67 |
    68 |
    69 |
    70 |
    71 | © 2022 Optimal. All Rights Reserved. 72 |
    73 |
    74 | ); 75 | }; 76 | 77 | export default Footer; 78 | -------------------------------------------------------------------------------- /client/src/components/footer/Footer.module.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | background-color: #fafafa; 3 | font-family: var(--font-poppins); 4 | margin-top: 25px; 5 | 6 | .footer_info { 7 | padding: 2rem; 8 | 9 | .about_us { 10 | h5 { 11 | font-weight: 500; 12 | text-transform: uppercase; 13 | } 14 | div { 15 | margin-top: 25px; 16 | p { 17 | color: var(--color-gray); 18 | } 19 | } 20 | } 21 | .information { 22 | h5 { 23 | font-weight: 500; 24 | text-transform: uppercase; 25 | } 26 | div { 27 | margin-top: 25px; 28 | li { 29 | color: var(--color-gray); 30 | list-style: none; 31 | margin: 5px 0; 32 | font-size: 16px; 33 | } 34 | } 35 | } 36 | .newsletter { 37 | h5 { 38 | font-weight: 500; 39 | text-transform: uppercase; 40 | } 41 | div { 42 | margin-top: 25px; 43 | p { 44 | color: var(--color-gray); 45 | font-size: 16px; 46 | } 47 | input { 48 | height: 35px; 49 | border: 1px solid black; 50 | outline: none; 51 | background-color: #fff; 52 | padding: 0.5rem 1rem; 53 | } 54 | button { 55 | border: none; 56 | height: 35px; 57 | padding: 0 0.5rem; 58 | background-color: black; 59 | color: white; 60 | } 61 | } 62 | } 63 | } 64 | .copyright { 65 | height: 50px; 66 | background-color: black; 67 | display: flex; 68 | align-items: center; 69 | justify-content: center; 70 | 71 | span { 72 | color: #fff; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /client/src/components/header/Search.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const Search = ({ history }) => { 4 | const [keyword, setKeyword] = useState(""); 5 | 6 | const searchHandler = (e) => { 7 | e.preventDefault(); 8 | 9 | if (keyword.trim()) { 10 | history.push(`/products/search/${keyword}`); 11 | } else { 12 | history.push("/products"); 13 | } 14 | }; 15 | return ( 16 |
    17 |
    18 | setKeyword(e.target.value)} 23 | /> 24 | 27 |
    28 |
    29 | ); 30 | }; 31 | 32 | export default Search; 33 | -------------------------------------------------------------------------------- /client/src/components/loader/ButtonLoader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./ButtonLoader.scss"; 3 | 4 | const ButtonLoader = () => { 5 | return
    ; 6 | }; 7 | 8 | export default ButtonLoader; 9 | -------------------------------------------------------------------------------- /client/src/components/loader/ButtonLoader.scss: -------------------------------------------------------------------------------- 1 | /* Button Loader */ 2 | .lds-dual-ring { 3 | display: inline-block; 4 | width: 16px; 5 | height: 16px; 6 | } 7 | .lds-dual-ring:after { 8 | content: " "; 9 | display: block; 10 | width: 24px; 11 | height: 24px; 12 | border-radius: 50%; 13 | border: 3px solid #fff; 14 | border-color: #fff transparent #fff transparent; 15 | animation: lds-dual-ring 1.2s linear infinite; 16 | } 17 | @keyframes lds-dual-ring { 18 | 0% { 19 | transform: rotate(0deg); 20 | } 21 | 100% { 22 | transform: rotate(360deg); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/src/components/loader/Loader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Spinner } from "react-bootstrap"; 3 | 4 | const Loader = () => { 5 | return ( 6 |
    7 | 8 |
    9 | ); 10 | }; 11 | 12 | export default Loader; 13 | -------------------------------------------------------------------------------- /client/src/components/profileLinks/ProfileLink.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react"; 2 | import { useDispatch, useSelector } from "react-redux"; 3 | import { Link } from "react-router-dom"; 4 | import Loader from "../loader/Loader"; 5 | import styles from "./ProfileLink.module.scss"; 6 | import { AiOutlineEdit, AiOutlineLogout, AiOutlineUser } from "react-icons/ai"; 7 | import { RiLockPasswordLine } from "react-icons/ri"; 8 | import { MdFavoriteBorder } from "react-icons/md"; 9 | import { logout } from "../../actions/userActions"; 10 | import { useAlert } from "react-alert"; 11 | 12 | const ProfileLink = () => { 13 | const { user, loading } = useSelector((state) => state.auth); 14 | 15 | const alert = useAlert(); 16 | const dispatch = useDispatch(); 17 | 18 | const logoutHandler = () => { 19 | dispatch(logout()); 20 | alert.success("Logged out successfully."); 21 | }; 22 | return ( 23 | 24 | {loading ? ( 25 | 26 | ) : ( 27 | 28 |
    29 |
    30 | {user && ( 31 | {user?.name} 32 | )} 33 | 34 |

    {user?.name}

    35 |

    {user?.email}

    36 |
    37 |
    38 | 39 |
    40 | 41 | {" "} 42 | Profile 43 | 44 | 45 | {" "} 46 | Edit Profile 47 | 48 | 49 | 53 | Password 54 | 55 | 56 | 57 | My Order 58 | 59 | 63 |
    64 |
    65 |
    66 | )} 67 |
    68 | ); 69 | }; 70 | 71 | export default ProfileLink; 72 | -------------------------------------------------------------------------------- /client/src/components/profileLinks/ProfileLink.module.scss: -------------------------------------------------------------------------------- 1 | .profile_links { 2 | background-color: #ffffff; 3 | box-shadow: 0 4px 8px 5px rgba(232, 226, 226, 0.2), 4 | 0 6px 20px 0 rgba(0, 0, 0, 0.19); 5 | padding: 1rem; 6 | border-radius: 20px; 7 | font-family: var(--font-poppins); 8 | 9 | div { 10 | img { 11 | height: 150px; 12 | width: 150px; 13 | border-radius: 50%; 14 | border: 3px solid #e8daff; 15 | } 16 | 17 | h4 { 18 | letter-spacing: 1px; 19 | font-weight: 500; 20 | } 21 | 22 | p { 23 | color: var(--color-gray); 24 | } 25 | } 26 | 27 | .links { 28 | display: flex; 29 | flex-direction: column; 30 | 31 | a { 32 | text-decoration: none; 33 | padding: 10px 30px; 34 | color: var(--color-gray); 35 | margin: 5px 0; 36 | border-radius: 5px; 37 | font-weight: 500; 38 | letter-spacing: 0.3px; 39 | font-size: 16px; 40 | transition: all 0.3s ease; 41 | 42 | &:hover { 43 | background-color: #e8daff; 44 | color: black; 45 | } 46 | } 47 | 48 | button { 49 | padding: 10px 30px; 50 | color: var(--color-gray); 51 | margin: 5px 0; 52 | border-radius: 5px; 53 | font-weight: 500; 54 | letter-spacing: 0.3px; 55 | font-size: 16px; 56 | border: none; 57 | background-color: #ffffff; 58 | text-align: start; 59 | transition: all 0.3s ease; 60 | 61 | &:hover { 62 | background-color: #ffd6e8; 63 | color: black; 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /client/src/components/route/ProtectedRoute.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react"; 2 | import { Route, Redirect } from "react-router-dom"; 3 | import { useSelector } from "react-redux"; 4 | 5 | const ProtectedRoute = ({ isAdmin, component: Component, ...rest }) => { 6 | const { isAuthenticated, loading, user } = useSelector( 7 | (state) => state.auth 8 | ); 9 | return ( 10 | 11 | {loading === false && ( 12 | { 15 | if (isAuthenticated === false) { 16 | return ; 17 | } 18 | 19 | if (isAdmin === true && user.role !== "admin") { 20 | return ; 21 | } 22 | 23 | return ; 24 | }} 25 | /> 26 | )} 27 | 28 | ); 29 | }; 30 | 31 | export default ProtectedRoute; 32 | -------------------------------------------------------------------------------- /client/src/components/widget/Widget.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./Widget.scss"; 3 | import { AiOutlineArrowUp } from "react-icons/ai"; 4 | 5 | const Widget = ({ title, icon, link, total }) => { 6 | const diff = 20; 7 | return ( 8 |
    9 |
    10 | {title} 11 | {total} 12 | {link} 13 |
    14 |
    15 |
    16 | 17 | {diff} % 18 |
    19 | {icon} 20 |
    21 |
    22 | ); 23 | }; 24 | 25 | export default Widget; 26 | -------------------------------------------------------------------------------- /client/src/components/widget/Widget.scss: -------------------------------------------------------------------------------- 1 | .widget { 2 | display: flex; 3 | justify-content: space-between; 4 | flex: 1; 5 | padding: 10px; 6 | -webkit-box-shadow: 2px 4px 10px 1px rgba(0, 0, 0, 0.47); 7 | box-shadow: 2px 4px 10px 1px rgba(201, 201, 201, 0.47); 8 | border-radius: 10px; 9 | min-height: 100px; 10 | 11 | .left, 12 | .right { 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: space-between; 16 | 17 | .title { 18 | font-weight: bold; 19 | font-size: 18px; 20 | color: rgb(160, 160, 160); 21 | } 22 | 23 | .counter { 24 | font-size: 32px; 25 | font-weight: 300; 26 | } 27 | 28 | .link { 29 | width: max-content; 30 | font-size: 16px; 31 | border-bottom: 1px solid gray; 32 | } 33 | 34 | .percentage { 35 | display: flex; 36 | align-items: center; 37 | font-size: 14px; 38 | 39 | &.positive { 40 | color: green; 41 | } 42 | &.negative { 43 | color: red; 44 | } 45 | } 46 | 47 | .icon { 48 | font-size: 24px; 49 | padding: 5px; 50 | border-radius: 5px; 51 | align-self: flex-end; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /client/src/config.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const axiosInstance = axios.create({ 4 | baseURL: 5 | "https://e-shop-app.onrender.com", 6 | }); 7 | -------------------------------------------------------------------------------- /client/src/constants/cartConstants.js: -------------------------------------------------------------------------------- 1 | export const ADD_TO_CART = "ADD_TO_CART"; 2 | export const REMOVE_ITEM_CART = "REMOVE_ITEM_CART"; 3 | export const SAVE_SHIPPING_INFO = "SAVE_SHIPPING_INFO"; 4 | -------------------------------------------------------------------------------- /client/src/constants/orderConstants.js: -------------------------------------------------------------------------------- 1 | export const CREATE_ORDER_REQUEST = "CREATE_ORDER_REQUEST"; 2 | export const CREATE_ORDER_SUCCESS = "CREATE_ORDER_SUCCESS"; 3 | export const CREATE_ORDER_FAIL = "CREATE_ORDER_FAIL"; 4 | 5 | export const MY_ORDERS_REQUEST = "MY_ORDERS_REQUEST"; 6 | export const MY_ORDERS_SUCCESS = "MY_ORDERS_SUCCESS"; 7 | export const MY_ORDERS_FAIL = "MY_ORDERS_FAIL"; 8 | 9 | export const ALL_ORDERS_REQUEST = "ALL_ORDERS_REQUEST"; 10 | export const ALL_ORDERS_SUCCESS = "ALL_ORDERS_SUCCESS"; 11 | export const ALL_ORDERS_FAIL = "ALL_ORDERS_FAIL"; 12 | 13 | export const UPDATE_ORDER_REQUEST = "UPDATE_ORDER_REQUEST"; 14 | export const UPDATE_ORDER_SUCCESS = "UPDATE_ORDER_SUCCESS"; 15 | export const UPDATE_ORDER_RESET = "UPDATE_ORDER_RESET"; 16 | export const UPDATE_ORDER_FAIL = "UPDATE_ORDER_FAIL"; 17 | 18 | export const DELETE_ORDER_REQUEST = "DELETE_ORDER_REQUEST"; 19 | export const DELETE_ORDER_SUCCESS = "DELETE_ORDER_SUCCESS"; 20 | export const DELETE_ORDER_RESET = "DELETE_ORDER_RESET"; 21 | export const DELETE_ORDER_FAIL = "DELETE_ORDER_FAIL"; 22 | 23 | export const ORDER_DETAILS_REQUEST = "ORDER_DETAILS_REQUEST"; 24 | export const ORDER_DETAILS_SUCCESS = "ORDER_DETAILS_SUCCESS"; 25 | export const ORDER_DETAILS_FAIL = "ORDER_DETAILS_FAIL"; 26 | 27 | export const CLEAR_ERRORS = "CLEAR_ERRORS"; 28 | -------------------------------------------------------------------------------- /client/src/constants/productsConstants.js: -------------------------------------------------------------------------------- 1 | export const ADMIN_PRODUCTS_REQUEST = "ADMIN_PRODUCTS_REQUEST"; 2 | export const ADMIN_PRODUCTS_SUCCESS = "ADMIN_PRODUCTS_SUCCESS"; 3 | export const ADMIN_PRODUCTS_FAIL = "ADMIN_PRODUCTS_FAIL"; 4 | 5 | export const ALL_PRODUCTS_REQUEST = "ALL_PRODUCTS_REQUEST"; 6 | export const ALL_PRODUCTS_SUCCESS = "ALL_PRODUCTS_SUCCESS"; 7 | export const ALL_PRODUCTS_FAIL = "ALL_PRODUCTS_FAIL"; 8 | 9 | export const NEW_PRODUCT_REQUEST = "NEW_PRODUCT_REQUEST"; 10 | export const NEW_PRODUCT_SUCCESS = "NEW_PRODUCT_SUCCESS"; 11 | export const NEW_PRODUCT_RESET = "NEW_PRODUCT_RESET"; 12 | export const NEW_PRODUCT_FAIL = "NEW_PRODUCT_FAIL"; 13 | 14 | export const DELETE_PRODUCT_REQUEST = "DELETE_PRODUCT_REQUEST"; 15 | export const DELETE_PRODUCT_SUCCESS = "DELETE_PRODUCT_SUCCESS"; 16 | export const DELETE_PRODUCT_RESET = "DELETE_PRODUCT_RESET"; 17 | export const DELETE_PRODUCT_FAIL = "DELETE_PRODUCT_FAIL"; 18 | 19 | export const UPDATE_PRODUCT_REQUEST = "UPDATE_PRODUCT_REQUEST"; 20 | export const UPDATE_PRODUCT_SUCCESS = "UPDATE_PRODUCT_SUCCESS"; 21 | export const UPDATE_PRODUCT_RESET = "UPDATE_PRODUCT_RESET"; 22 | export const UPDATE_PRODUCT_FAIL = "UPDATE_PRODUCT_FAIL"; 23 | 24 | export const PRODUCT_DETAILS_REQUEST = "PRODUCT_DETAILS_REQUEST"; 25 | export const PRODUCT_DETAILS_SUCCESS = "PRODUCT_DETAILS_SUCCESS"; 26 | export const PRODUCT_DETAILS_FAIL = "PRODUCT_DETAILS_FAIL"; 27 | 28 | export const NEW_REVIEW_REQUEST = "NEW_REVIEW_REQUEST"; 29 | export const NEW_REVIEW_SUCCESS = "NEW_REVIEW_SUCCESS"; 30 | export const NEW_REVIEW_RESET = "NEW_REVIEW_RESET"; 31 | export const NEW_REVIEW_FAIL = "NEW_REVIEW_FAIL"; 32 | 33 | export const GET_REVIEWS_REQUEST = "GET_REVIEWS_REQUEST"; 34 | export const GET_REVIEWS_SUCCESS = "GET_REVIEWS_SUCCESS"; 35 | export const GET_REVIEWS_FAIL = "GET_REVIEWS_FAIL"; 36 | 37 | export const DELETE_REVIEW_REQUEST = "DELETE_REVIEW_REQUEST"; 38 | export const DELETE_REVIEW_SUCCESS = "DELETE_REVIEW_SUCCESS"; 39 | export const DELETE_REVIEW_RESET = "DELETE_REVIEW_RESET"; 40 | export const DELETE_REVIEW_FAIL = "DELETE_REVIEW_FAIL"; 41 | 42 | export const CLEAR_ERRORS = "CLEAR_ERRORS"; 43 | -------------------------------------------------------------------------------- /client/src/constants/userConstants.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_REQUEST = "LOGIN_REQUEST"; 2 | export const LOGIN_SUCCESS = "LOGIN_SUCCESS"; 3 | export const LOGIN_FAIL = "LOGIN_FAIL"; 4 | 5 | export const REGISTER_USER_REQUEST = "REGISTER_USER_REQUEST"; 6 | export const REGISTER_USER_SUCCESS = "REGISTER_USER_SUCCESS"; 7 | export const REGISTER_USER_FAIL = "REGISTER_USER_FAIL"; 8 | 9 | export const LOAD_USER_REQUEST = "LOAD_USER_REQUEST"; 10 | export const LOAD_USER_SUCCESS = "LOAD_USER_SUCCESS"; 11 | export const LOAD_USER_FAIL = "LOAD_USER_FAIL"; 12 | 13 | export const UPDATE_PROFILE_REQUEST = "UPDATE_PROFILE_REQUEST"; 14 | export const UPDATE_PROFILE_SUCCESS = "UPDATE_PROFILE_SUCCESS"; 15 | export const UPDATE_PROFILE_RESET = "UPDATE_PROFILE_RESET"; 16 | export const UPDATE_PROFILE_FAIL = "UPDATE_PROFILE_FAIL"; 17 | 18 | export const UPDATE_PASSWORD_REQUEST = "UPDATE_PASSWORD_REQUEST"; 19 | export const UPDATE_PASSWORD_SUCCESS = "UPDATE_PASSWORD_SUCCESS"; 20 | export const UPDATE_PASSWORD_RESET = "UPDATE_PASSWORD_RESET"; 21 | export const UPDATE_PASSWORD_FAIL = "UPDATE_PASSWORD_FAIL"; 22 | 23 | export const FORGOT_PASSWORD_REQUEST = "FORGOT_PASSWORD_REQUEST"; 24 | export const FORGOT_PASSWORD_SUCCESS = "FORGOT_PASSWORD_SUCCESS"; 25 | export const FORGOT_PASSWORD_FAIL = "FORGOT_PASSWORD_FAIL"; 26 | 27 | export const NEW_PASSWORD_REQUEST = "NEW_PASSWORD_REQUEST"; 28 | export const NEW_PASSWORD_SUCCESS = "NEW_PASSWORD_SUCCESS"; 29 | export const NEW_PASSWORD_FAIL = "NEW_PASSWORD_FAIL"; 30 | 31 | export const ALL_USERS_REQUEST = "ALL_USERS_REQUEST"; 32 | export const ALL_USERS_SUCCESS = "ALL_USERS_SUCCESS"; 33 | export const ALL_USERS_FAIL = "ALL_USERS_FAIL"; 34 | 35 | export const USER_DETAILS_REQUEST = "USER_DETAILS_REQUEST"; 36 | export const USER_DETAILS_SUCCESS = "USER_DETAILS_SUCCESS"; 37 | export const USER_DETAILS_FAIL = "USER_DETAILS_FAIL"; 38 | 39 | export const UPDATE_USER_REQUEST = "UPDATE_USER_REQUEST"; 40 | export const UPDATE_USER_SUCCESS = "UPDATE_USER_SUCCESS"; 41 | export const UPDATE_USER_RESET = "UPDATE_USER_RESET"; 42 | export const UPDATE_USER_FAIL = "UPDATE_USER_FAIL"; 43 | 44 | export const DELETE_USER_REQUEST = "DELETE_USER_REQUEST"; 45 | export const DELETE_USER_SUCCESS = "DELETE_USER_SUCCESS"; 46 | export const DELETE_USER_RESET = "DELETE_USER_RESET"; 47 | export const DELETE_USER_FAIL = "DELETE_USER_FAIL"; 48 | 49 | export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS"; 50 | export const LOGOUT_FAIL = "LOGOUT_FAIL"; 51 | 52 | export const CLEAR_ERRORS = "CLEAR_ERRORS"; 53 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Lobster&family=Poppins:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600&family=Roboto:ital,wght@0,400;0,500;0,700;0,900;1,400;1,500;1,700;1,900&display=swap"); 2 | 3 | :root { 4 | --font-lato: "Lato", sans-serif; 5 | --font-lobster: "Lobster", cursive; 6 | --font-poppins: "Poppins", sans-serif; 7 | --font-roboto: "Roboto", sans-serif; 8 | 9 | --color-golden: #dcca87; 10 | --color-black: #0c0c0c; 11 | --color-gray: #545454; 12 | --color-crimson: #f5efdb; 13 | --color-grey: #aaaaaa; 14 | --color-white: #ffffff; 15 | } 16 | 17 | * { 18 | box-sizing: border-box; 19 | padding: 0; 20 | margin: 0; 21 | scroll-behavior: smooth; 22 | } 23 | 24 | body { 25 | width: 100%; 26 | height: 100%; 27 | margin: 0px; 28 | padding: 0px; 29 | overflow-x: hidden; 30 | position: relative; 31 | /* background-color: rgb(0, 30, 60) !important; */ 32 | } 33 | 34 | /* Scroll Bar */ 35 | 36 | ::-webkit-scrollbar-track { 37 | background-color: #f5f5f5; 38 | } 39 | 40 | ::-webkit-scrollbar { 41 | width: 8px; 42 | background-color: #f5f5f5; 43 | } 44 | 45 | ::-webkit-scrollbar-thumb { 46 | background-color: rgba(66, 66, 66, 0.2); 47 | border: 0px; 48 | background-clip: padding-box; 49 | border-radius: 5px; 50 | } 51 | 52 | .ratings { 53 | font-size: 1.2rem; 54 | color: #fdcc0d; 55 | } 56 | 57 | #no_of_reviews { 58 | font-size: 0.85rem; 59 | color: grey; 60 | margin-left: 0.5rem; 61 | } 62 | 63 | /* Ratings */ 64 | 65 | .rating-outer { 66 | display: inline-block; 67 | position: relative; 68 | font-family: FontAwesome; 69 | color: #fdcc0d; 70 | } 71 | 72 | .rating-outer::before { 73 | content: "\f006 \f006 \f006 \f006 \f006"; 74 | } 75 | 76 | .rating-inner { 77 | position: absolute; 78 | top: 0; 79 | left: 0; 80 | white-space: nowrap; 81 | overflow: hidden; 82 | width: 0; 83 | } 84 | 85 | .rating-inner::before { 86 | content: "\f005 \f005 \f005 \f005 \f005"; 87 | color: #f8ce0b; 88 | } 89 | 90 | .greenColor { 91 | color: green; 92 | } 93 | 94 | .redColor { 95 | color: red; 96 | } 97 | 98 | /* Checkout Steps */ 99 | 100 | .checkout-progress div { 101 | box-sizing: border-box; 102 | } 103 | 104 | .checkout-progress { 105 | display: block; 106 | clear: both; 107 | margin: 20px auto; 108 | width: auto; 109 | font-family: sans-serif; 110 | overflow: auto; 111 | } 112 | 113 | .step { 114 | margin: 0; 115 | border: 0; 116 | letter-spacing: 1px; 117 | line-height: 30px; 118 | padding: 5px 10px 5px 15px; 119 | color: grey; 120 | text-decoration: none; 121 | cursor: default; 122 | font-weight: bold; 123 | float: left; 124 | height: auto; 125 | } 126 | 127 | .incomplete { 128 | background: #eeeeee; 129 | } 130 | 131 | .active-step { 132 | background: #fa9c23; 133 | color: #fff; 134 | } 135 | 136 | .triangle-active { 137 | float: left; 138 | width: 0; 139 | border-top: 20px solid transparent; 140 | border-left: 15px solid #fa9c23; 141 | border-bottom: 20px solid transparent; 142 | margin-left: -1px; 143 | } 144 | 145 | .triangle2-active { 146 | width: 0; 147 | float: left; 148 | border-top: 20px solid #fa9c23; 149 | border-left: 15px solid #fff; 150 | border-bottom: 20px solid #fa9c23; 151 | margin-right: -1px; 152 | } 153 | 154 | .triangle-incomplete { 155 | float: left; 156 | width: 0; 157 | border-top: 20px solid transparent; 158 | border-left: 15px solid #eeeeee; 159 | border-bottom: 20px solid transparent; 160 | margin-left: -1px; 161 | } 162 | 163 | .triangle2-incomplete { 164 | width: 0; 165 | float: left; 166 | border-top: 20px solid #eeeeee; 167 | border-left: 15px solid #fff; 168 | border-bottom: 20px solid #eeeeee; 169 | margin-right: -1px; 170 | } 171 | 172 | .image_file { 173 | height: 40px; 174 | width: 300px; 175 | border-radius: 20px; 176 | position: relative; 177 | 178 | display: flex; 179 | justify-content: center; 180 | align-items: center; 181 | 182 | /* border: 4px solid #ffffff; */ 183 | overflow: hidden; 184 | background-image: linear-gradient(to bottom, #2590eb 50%, #ffffff 50%); 185 | background-size: 100% 200%; 186 | transition: all 1s; 187 | color: #ffffff; 188 | font-size: 100px; 189 | } 190 | .image_file input { 191 | height: 300px; 192 | width: 300px; 193 | position: absolute; 194 | top: 0; 195 | left: 0; 196 | opacity: 0; 197 | cursor: pointer; 198 | } 199 | 200 | /* Reviews */ 201 | 202 | .rating { 203 | margin-top: 10rem; 204 | } 205 | 206 | .stars { 207 | height: 100px; 208 | display: flex; 209 | align-items: center; 210 | padding-left: 0; 211 | } 212 | 213 | .star { 214 | display: inline; 215 | list-style: none; 216 | font-size: 3rem; 217 | padding-left: 0.9rem; 218 | color: #e3e3e3; 219 | } 220 | 221 | .star:first-child { 222 | padding-left: 0; 223 | } 224 | 225 | .orange { 226 | color: #fa9c23; 227 | } 228 | 229 | .yellow { 230 | color: #fdcc0d; 231 | } 232 | 233 | .review_user { 234 | font-size: 0.8rem; 235 | color: grey; 236 | } 237 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import { Provider } from "react-redux"; 7 | import store from "./store"; 8 | import "bootstrap/dist/css/bootstrap.min.css"; 9 | 10 | import { positions, transitions, Provider as AlertProvider } from "react-alert"; 11 | import AlertTemplate from "react-alert-template-basic"; 12 | 13 | const options = { 14 | timeout: 5000, 15 | position: positions.BOTTOM_CENTER, 16 | transition: transitions.SCALE, 17 | }; 18 | 19 | ReactDOM.render( 20 | 21 | 22 | 23 | 24 | , 25 | document.getElementById("root") 26 | ); 27 | 28 | reportWebVitals(); 29 | -------------------------------------------------------------------------------- /client/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/src/pages/about/About.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react"; 2 | import { 3 | FcAutomotive, 4 | FcCurrencyExchange, 5 | FcCustomerSupport, 6 | FcRating, 7 | } from "react-icons/fc"; 8 | import Footer from "../../components/footer/Footer"; 9 | import Navbar from "../../components/header/Navbar"; 10 | import MetaData from "../../components/MetaData"; 11 | import styles from "./About.module.scss"; 12 | 13 | const About = () => { 14 | const abouts = [ 15 | { 16 | icon: , 17 | title: "Free Delevery", 18 | description: 19 | "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Beatae, nihil!", 20 | }, 21 | { 22 | icon: , 23 | title: "100% Cash Back", 24 | description: 25 | "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Beatae, nihil!", 26 | }, 27 | { 28 | icon: , 29 | title: "Quality Product", 30 | description: 31 | "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Beatae, nihil!", 32 | }, 33 | { 34 | icon: , 35 | title: "24/7 Support", 36 | description: 37 | "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Beatae, nihil!", 38 | }, 39 | ]; 40 | return ( 41 | 42 | 43 | 44 |
    45 |
    46 |
    47 |

    About Us

    48 |
    49 |
    50 |
    51 |
    52 |
    53 |
    54 |
    55 | About 59 |
    60 |
    61 |
    62 |
    63 |

    64 | Know About Our Ecomerce Business, 65 | History 66 |

    67 |

    68 | Lorem ipsum dolor sit amet consectetur 69 | adipisicing elit. Eaque voluptatibus 70 | est, assumenda cupiditate id nam illo 71 | odio ipsum itaque maxime. 72 |

    73 | 74 |
    75 |
    76 |
    77 | 78 |
    79 |

    Our Features

    80 | 81 |
    82 |
    83 |
    84 | {abouts.map((about, index) => ( 85 |
    89 |
    90 | {about.icon} 91 |
    {about.title}
    92 |

    {about.description}

    93 |
    94 |
    95 | ))} 96 |
    97 |
    98 |
    99 |
    100 |
    101 |
    102 |
    103 |