├── .env.sample ├── .gitignore ├── Dockerfile ├── Readme.md ├── build ├── asset-manifest.json ├── index.html ├── precache-manifest.0920aa6448a966e8c6c3350c7afe0d35.js ├── service-worker.js └── static │ ├── css │ ├── 2.e2dd9b0a.chunk.css │ ├── 2.e2dd9b0a.chunk.css.map │ ├── main.41a31e7c.chunk.css │ └── main.41a31e7c.chunk.css.map │ ├── js │ ├── 2.d388a37e.chunk.js │ ├── 2.d388a37e.chunk.js.LICENSE.txt │ ├── 2.d388a37e.chunk.js.map │ ├── main.2555b188.chunk.js │ ├── main.2555b188.chunk.js.map │ ├── runtime-main.7bb332b4.js │ └── runtime-main.7bb332b4.js.map │ └── media │ ├── 404.bfb9ef34.jpg │ ├── Mihir.96cf34d3.jpeg │ ├── check.41c2a18b.png │ ├── close.4536ae5a.png │ ├── empty.9f3dc705.png │ ├── log.797bb368.svg │ ├── noItem.a8f6abbb.png │ └── register.993f7d29.svg ├── client ├── package-lock.json ├── package.json ├── public │ └── index.html └── src │ ├── App.js │ ├── auth.css │ ├── components │ ├── 404.js │ ├── Alert.js │ ├── Cart.js │ ├── DeleteItem.js │ ├── ErrorList.js │ ├── Forget.js │ ├── Menu.js │ ├── MenuList.js │ ├── Navbar.js │ ├── addProduct.js │ ├── auth.js │ ├── cartList.js │ ├── checkout.js │ ├── contact.js │ ├── deleteItems.js │ ├── fail.js │ ├── order.js │ ├── privateRoutes.js │ ├── resetPassword.js │ ├── sideBar.js │ ├── success.js │ └── verify.js │ ├── context │ ├── alerts │ │ ├── alertContext.js │ │ └── alertState.js │ ├── auth │ │ ├── authContext.js │ │ ├── authReducer.js │ │ ├── authState.js │ │ ├── removeAuthToken.js │ │ └── setAuthToken.js │ ├── cart │ │ ├── cartContext.js │ │ ├── cartReducer.js │ │ └── cartState.js │ ├── loading │ │ ├── loadingContext.js │ │ └── loadingState.js │ ├── products │ │ ├── productReducer.js │ │ ├── productState.js │ │ └── productsContext.js │ └── types.js │ ├── images │ ├── 404.jpg │ ├── 5598.jpg │ ├── Mihir.jpeg │ ├── Spinner.gif │ ├── check.png │ ├── close.png │ ├── empty.png │ ├── log.svg │ ├── noItem.png │ ├── register.svg │ └── tick.png │ ├── index.js │ ├── mobile.css │ └── styles.css ├── config └── db.js ├── controllers └── upload.js ├── default.conf ├── docker-compose.yml ├── images ├── productImage-1598290103896-821019517.jpg ├── productImage-1598290116053-614118570.jpg └── productImage-1598290127103-668259691.jpg ├── middleware └── auth.js ├── models ├── forget.js ├── orders.js ├── product.js └── register.js ├── package-lock.json ├── package.json ├── paytm ├── checksum.js ├── crypt.js └── server.js ├── readme_images ├── add_dish.png ├── cart.png ├── checkout.png ├── contact_us.png ├── delete_items.png ├── login.png ├── menu.png ├── order.png └── verify.png ├── routes ├── admin.js ├── cart.js ├── forget.js ├── image.js ├── items.js ├── login.js ├── order.js ├── orders.js ├── paytm.js ├── register.js ├── resendCode.js ├── reset.js └── verify.js └── server.js /.env.sample: -------------------------------------------------------------------------------- 1 | MERCHANT_ID="Your PayTM Merchant ID here" (https://dashboard.paytm.com/next/apikeys) 2 | MERCHANT_API_KEY="Your PayTM Merchant API key here" (https://dashboard.paytm.com/next/apikeys) 3 | SEND_GRID_KEY="Your Send Grid API key here" (https://sendgrid.com/) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | client/node_modules 3 | build 4 | *.pem 5 | *.zip 6 | .env 7 | config/default.json -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM node:12 3 | WORKDIR /app 4 | COPY package.json /app 5 | RUN npm install 6 | COPY . /app 7 | CMD [ "npm","start" ] -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Welcome to Food Eazy! ✨ 2 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://foodeazy.herokuapp.com/) [![Build passing](https://img.shields.io/badge/Build-Passing-brightgreen.svg?style=flat-square)](https://foodeazy.herokuapp.com/) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://foodeazy.herokuapp.com/) [![License](https://img.shields.io/badge/license-MIT-brightgreen)](https://foodeazy.herokuapp.com/) ![Made with Love in India](https://madewithlove.org.in/badge.svg) 3 | 4 | Food Eazy, is an online platform to order food and avoiding the hassle of going out or paying in cash. The users can opt for home delivery or take away as per thier choice and can pay thorugh cash or online methods (PayTM). In the times of COVID-19 where social distancing is such an important measure we think our website can help restaurants and customers. 5 | 6 | **Project Link** - ***https://foodeazy.herokuapp.com/*** 7 | **Or** - ***http://foodeazy.devforlife07.codes/*** 8 | 9 | 10 | ## Features and Functionalities 😃 11 | **User features** 12 | - User sign up and login 13 | - 2 factor authentication using email 14 | - Password Reset (Forget Password) 15 | - Search for food items 16 | - Sort the food items (By name or price) 17 | - Save Cart 18 | - Delete Cart 19 | - Order Type - Take Away or Delivery 20 | - Payment Methods - Cash or Online (using PayTM wallet, Debit/Credit card, Net Banking) 21 | - View your current and previous orders 22 | 23 | **Admin features** 24 | 25 | - Add new dishes 26 | - Delete dishes 27 | ## Screenshots 28 | ### Login Page![enter image description here](https://raw.githubusercontent.com/Devforlife07/foodeazy/master/readme_images/login.png?token=ALT5AMAOLRKFR423UUHLK6C7KJJ4Y) 29 | ### Email Verify Page![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/verify.png?token=ALT5AMCAUZLVKWU4UFAGZVC7KJKEG) 30 | ### Home Page 31 | ![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/menu.png?token=ALT5AMAG4JWL7EOHY2IT7JC7KJKAQ) 32 | 33 | ### Cart 34 | ![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/cart.png?token=ALT5AMCPL6C2W723CZYJZZK7KJKYY) 35 | ### Checkout 36 | ![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/checkout.png?token=ALT5AMHX44VS5BX2PHTDSY27KJK4K) 37 | ### Contact Us 38 | ![enter image description here](https://raw.githubusercontent.com/Devforlife07/FoodEazy/master/readme_images/contact_us.png) 39 | ### Add Dish (Admin) 40 | ![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/add_dish.png?token=ALT5AMAOEZ2YQ2ECJJMYZCC7KJK6I) 41 | ### Delete Dish (Admin) 42 | ![enter image description here](https://raw.githubusercontent.com/mihir0699/foodeazy/master/readme_images/delete_items.png?token=ALT5AMHLZNKOIMXWOKUKY7K7KJLCE) 43 | ## Tech Stack 💻 44 | 45 | - [React.js](https://reactjs.org/) 46 | - [Node.js](https://nodejs.org/en/) 47 | - [Express.js](https://expressjs.com/) 48 | - [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) 49 | - [Material UI](https://material-ui.com/) 50 | - [React Bootstrap](https://react-bootstrap.github.io/) 51 | 52 | ## API :man_technologist: 53 | 54 | - [PayTM API](https://developer.paytm.com/docs/) 55 | - [Send Grid API](https://sendgrid.com/) 56 | - [Cloudinary API](https://cloudinary.com/) 57 | 58 | ## Installation :zap: 59 | 60 | **1. Clone this repo by running the following command :-** 61 | ```bash 62 | git clone https://github.com/Devforlife07/FoodEazy 63 | cd foodeazy 64 | ``` 65 | 66 | **2. Now install all the required packages by running the following commands :-** 67 | ```bash 68 | npm install 69 | npm run install-client 70 | ``` 71 | **3. Now start the react and node server together by running the following command :-** 72 | ```bash 73 | npm run dev 74 | ``` 75 | **3. Create a `.env` file in the project root folder and copy the format of `.env.sample` file.** 76 | 77 | - `.env.sample` file contains all the environment variables required for running the project. 78 | 79 | 80 | **4.** **🎉 Open your browser and go to `https://localhost:3000`** 81 | 82 | ## Contributors 🤝 83 | - [**Mihir Gupta**](https://github.com/mihir0699) 84 | - [**Devansh Gera**](https://github.com/Devforlife07) 85 | 86 | 87 | ## 🤩 Don't forget to give this repo a ⭐ if you like this repo and want to appreciate our efforts 88 | 89 | 90 | [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com) 91 | [![forthebadge](https://forthebadge.com/images/badges/built-by-developers.svg)](https://forthebadge.com) 92 | 93 | 94 | -------------------------------------------------------------------------------- /build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/static/css/main.41a31e7c.chunk.css", 4 | "main.js": "/static/js/main.2555b188.chunk.js", 5 | "main.js.map": "/static/js/main.2555b188.chunk.js.map", 6 | "runtime-main.js": "/static/js/runtime-main.7bb332b4.js", 7 | "runtime-main.js.map": "/static/js/runtime-main.7bb332b4.js.map", 8 | "static/css/2.e2dd9b0a.chunk.css": "/static/css/2.e2dd9b0a.chunk.css", 9 | "static/js/2.d388a37e.chunk.js": "/static/js/2.d388a37e.chunk.js", 10 | "static/js/2.d388a37e.chunk.js.map": "/static/js/2.d388a37e.chunk.js.map", 11 | "index.html": "/index.html", 12 | "precache-manifest.0920aa6448a966e8c6c3350c7afe0d35.js": "/precache-manifest.0920aa6448a966e8c6c3350c7afe0d35.js", 13 | "service-worker.js": "/service-worker.js", 14 | "static/css/2.e2dd9b0a.chunk.css.map": "/static/css/2.e2dd9b0a.chunk.css.map", 15 | "static/css/main.41a31e7c.chunk.css.map": "/static/css/main.41a31e7c.chunk.css.map", 16 | "static/js/2.d388a37e.chunk.js.LICENSE.txt": "/static/js/2.d388a37e.chunk.js.LICENSE.txt", 17 | "static/media/404.jpg": "/static/media/404.bfb9ef34.jpg", 18 | "static/media/Mihir.jpeg": "/static/media/Mihir.96cf34d3.jpeg", 19 | "static/media/check.png": "/static/media/check.41c2a18b.png", 20 | "static/media/close.png": "/static/media/close.4536ae5a.png", 21 | "static/media/empty.png": "/static/media/empty.9f3dc705.png", 22 | "static/media/log.svg": "/static/media/log.797bb368.svg", 23 | "static/media/noItem.png": "/static/media/noItem.a8f6abbb.png", 24 | "static/media/register.svg": "/static/media/register.993f7d29.svg" 25 | }, 26 | "entrypoints": [ 27 | "static/js/runtime-main.7bb332b4.js", 28 | "static/css/2.e2dd9b0a.chunk.css", 29 | "static/js/2.d388a37e.chunk.js", 30 | "static/css/main.41a31e7c.chunk.css", 31 | "static/js/main.2555b188.chunk.js" 32 | ] 33 | } -------------------------------------------------------------------------------- /build/index.html: -------------------------------------------------------------------------------- 1 | Food Eazy
-------------------------------------------------------------------------------- /build/precache-manifest.0920aa6448a966e8c6c3350c7afe0d35.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "d9626cd7a6284049b24bd5c6fc2d670b", 4 | "url": "/index.html" 5 | }, 6 | { 7 | "revision": "e18d4cf2fdd4ea6d40b5", 8 | "url": "/static/css/2.e2dd9b0a.chunk.css" 9 | }, 10 | { 11 | "revision": "0ce6c63f06b417b57b5a", 12 | "url": "/static/css/main.41a31e7c.chunk.css" 13 | }, 14 | { 15 | "revision": "e18d4cf2fdd4ea6d40b5", 16 | "url": "/static/js/2.d388a37e.chunk.js" 17 | }, 18 | { 19 | "revision": "2a0b20e1d02e77e8b582ff21a215748a", 20 | "url": "/static/js/2.d388a37e.chunk.js.LICENSE.txt" 21 | }, 22 | { 23 | "revision": "0ce6c63f06b417b57b5a", 24 | "url": "/static/js/main.2555b188.chunk.js" 25 | }, 26 | { 27 | "revision": "08f73d5cd9e484c26cef", 28 | "url": "/static/js/runtime-main.7bb332b4.js" 29 | }, 30 | { 31 | "revision": "bfb9ef3477e88b1e97f3312130dad23a", 32 | "url": "/static/media/404.bfb9ef34.jpg" 33 | }, 34 | { 35 | "revision": "96cf34d3ee2addd6e0069957663a8208", 36 | "url": "/static/media/Mihir.96cf34d3.jpeg" 37 | }, 38 | { 39 | "revision": "41c2a18b6a98ec4013bffd052b75a2b1", 40 | "url": "/static/media/check.41c2a18b.png" 41 | }, 42 | { 43 | "revision": "4536ae5afa7a38c1dcd89513dab57d85", 44 | "url": "/static/media/close.4536ae5a.png" 45 | }, 46 | { 47 | "revision": "9f3dc705435876dff82b93a4237b41de", 48 | "url": "/static/media/empty.9f3dc705.png" 49 | }, 50 | { 51 | "revision": "797bb3689f2760bfdd192ee58b815d7d", 52 | "url": "/static/media/log.797bb368.svg" 53 | }, 54 | { 55 | "revision": "a8f6abbb4ea76be277e34cbb17ca9175", 56 | "url": "/static/media/noItem.a8f6abbb.png" 57 | }, 58 | { 59 | "revision": "993f7d292006f5b823f666d3fcb0733b", 60 | "url": "/static/media/register.993f7d29.svg" 61 | } 62 | ]); -------------------------------------------------------------------------------- /build/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to your Workbox-powered service worker! 3 | * 4 | * You'll need to register this file in your web app and you should 5 | * disable HTTP caching for this file too. 6 | * See https://goo.gl/nhQhGp 7 | * 8 | * The rest of the code is auto-generated. Please don't update this file 9 | * directly; instead, make changes to your Workbox build configuration 10 | * and re-run your build process. 11 | * See https://goo.gl/2aRDsh 12 | */ 13 | 14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); 15 | 16 | importScripts( 17 | "/precache-manifest.0920aa6448a966e8c6c3350c7afe0d35.js" 18 | ); 19 | 20 | self.addEventListener('message', (event) => { 21 | if (event.data && event.data.type === 'SKIP_WAITING') { 22 | self.skipWaiting(); 23 | } 24 | }); 25 | 26 | workbox.core.clientsClaim(); 27 | 28 | /** 29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to 30 | * requests for URLs in the manifest. 31 | * See https://goo.gl/S9QRab 32 | */ 33 | self.__precacheManifest = [].concat(self.__precacheManifest || []); 34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); 35 | 36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/index.html"), { 37 | 38 | blacklist: [/^\/_/,/\/[^/?]+\.[^/]+$/], 39 | }); 40 | -------------------------------------------------------------------------------- /build/static/js/2.d388a37e.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | Copyright (c) 2017 Jed Watson. 9 | Licensed under the MIT License (MIT), see 10 | http://jedwatson.github.io/classnames 11 | */ 12 | 13 | /** 14 | * A better abstraction over CSS. 15 | * 16 | * @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present 17 | * @website https://github.com/cssinjs/jss 18 | * @license MIT 19 | */ 20 | 21 | /** @license React v0.18.0 22 | * scheduler.production.min.js 23 | * 24 | * Copyright (c) Facebook, Inc. and its affiliates. 25 | * 26 | * This source code is licensed under the MIT license found in the 27 | * LICENSE file in the root directory of this source tree. 28 | */ 29 | 30 | /** @license React v16.12.0 31 | * react-dom.production.min.js 32 | * 33 | * Copyright (c) Facebook, Inc. and its affiliates. 34 | * 35 | * This source code is licensed under the MIT license found in the 36 | * LICENSE file in the root directory of this source tree. 37 | */ 38 | 39 | /** @license React v16.12.0 40 | * react.production.min.js 41 | * 42 | * Copyright (c) Facebook, Inc. and its affiliates. 43 | * 44 | * This source code is licensed under the MIT license found in the 45 | * LICENSE file in the root directory of this source tree. 46 | */ 47 | 48 | /** @license React v16.13.1 49 | * react-is.production.min.js 50 | * 51 | * Copyright (c) Facebook, Inc. and its affiliates. 52 | * 53 | * This source code is licensed under the MIT license found in the 54 | * LICENSE file in the root directory of this source tree. 55 | */ 56 | -------------------------------------------------------------------------------- /build/static/js/runtime-main.7bb332b4.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,l,a=r[0],f=r[1],i=r[2],p=0,s=[];p0.2%", 35 | "not dead", 36 | "not ie <= 11", 37 | "not op_mini all" 38 | ], 39 | "proxy": "http://localhost:5000" 40 | } 41 | -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 52 | Food Eazy 53 | 54 | 55 | 56 | 73 | 76 |
77 | 78 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useContext } from "react"; 2 | import "./styles.css"; 3 | import "./mobile.css"; 4 | import Navbar from "./components/Navbar"; 5 | import Menu from "./components/Menu"; 6 | import CartState from "./context/cart/cartState"; 7 | import Alert from "./components/Alert"; 8 | import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; 9 | import Cart from "./components/Cart"; 10 | import { Toast } from "react-bootstrap"; 11 | import Auth from "./components/auth"; 12 | import AuthState from "./context/auth/authState"; 13 | import Sidebar from "./components/sideBar"; 14 | import AuthContext from "./context/auth/authContext"; 15 | import PrivateRoutes from "./components/privateRoutes"; 16 | import LoadingContext from "./context/loading/loadingContext"; 17 | import DeleteItems from "./components/deleteItems"; 18 | import setAuthToken from "./context/auth/setAuthToken"; 19 | import CartContext from "./context/cart/cartContext"; 20 | import AddProduct from "./components/addProduct"; 21 | import Fail from "./components/fail"; 22 | import Forget from "./components/Forget"; 23 | import ResetPassword from "./components/resetPassword"; 24 | import Checkout from "./components/checkout"; 25 | import Success from "./components/success"; 26 | import NotFound from "./components/404"; 27 | import Contact from "./components/contact"; 28 | import Order from "./components/order"; 29 | import Verify from "./components/verify"; 30 | export default function App() { 31 | const { userLoaded, isAuthenticated } = useContext(AuthContext); 32 | const [display, setDisplay] = useState(0); 33 | const { loadCart, state } = useContext(CartContext); 34 | const { Loader, loading, setLoading } = useContext(LoadingContext); 35 | const changeDisplay = () => { 36 | setDisplay(display ^ 1); 37 | }; 38 | useEffect(() => { 39 | if (!navigator.onLine) alert("You Are Offline"); 40 | }); 41 | 42 | return ( 43 | <> 44 |
45 | 46 | 47 | 48 | {display === 1 ? ( 49 | 50 | ) : ( 51 | <> 52 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 76 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | )} 88 | 89 | 90 | 91 |
92 | 93 | ); 94 | } 95 | -------------------------------------------------------------------------------- /client/src/auth.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700;800&display=swap"); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body, 10 | input { 11 | font-family: "Poppins", sans-serif; 12 | } 13 | 14 | .container1 { 15 | position: relative; 16 | width: 100%; 17 | background-color: #fff; 18 | min-height: 100vh; 19 | overflow: hidden; 20 | } 21 | 22 | .forms-container { 23 | position: absolute; 24 | width: 100%; 25 | height: 100%; 26 | top: 0; 27 | left: 0; 28 | } 29 | 30 | .signin-signup { 31 | position: absolute; 32 | top: 50%; 33 | transform: translate(-50%, -50%); 34 | left: 75%; 35 | width: 50%; 36 | transition: 1s 0.7s ease-in-out; 37 | display: grid; 38 | grid-template-columns: 1fr; 39 | z-index: 5; 40 | } 41 | 42 | form { 43 | display: flex; 44 | align-items: center; 45 | justify-content: center; 46 | flex-direction: column; 47 | padding: 0rem 5rem; 48 | transition: all 0.2s 0.7s; 49 | overflow: hidden; 50 | grid-column: 1 / 2; 51 | grid-row: 1 / 2; 52 | } 53 | 54 | form.sign-up-form { 55 | opacity: 0; 56 | z-index: 1; 57 | } 58 | 59 | form.sign-in-form { 60 | z-index: 2; 61 | } 62 | 63 | .title { 64 | font-size: 2.2rem; 65 | color: #444; 66 | margin-bottom: 10px; 67 | } 68 | 69 | .input-field { 70 | max-width: 380px; 71 | width: 100%; 72 | background-color: #f0f0f0; 73 | margin: 10px 0; 74 | height: 55px; 75 | border-radius: 55px; 76 | display: grid; 77 | grid-template-columns: 15% 85%; 78 | padding: 0 0.4rem; 79 | position: relative; 80 | } 81 | 82 | .input-field i { 83 | text-align: center; 84 | line-height: 55px; 85 | color: #acacac; 86 | transition: 0.5s; 87 | font-size: 1.1rem; 88 | } 89 | 90 | .input-field input { 91 | background: none; 92 | outline: none; 93 | border: none; 94 | line-height: 1; 95 | font-weight: 600; 96 | font-size: 1.1rem; 97 | color: #333; 98 | } 99 | 100 | .input-field input::placeholder { 101 | color: #aaa; 102 | font-weight: 500; 103 | } 104 | 105 | .social-text { 106 | padding: 0.7rem 0; 107 | font-size: 1rem; 108 | } 109 | 110 | .social-media { 111 | display: flex; 112 | justify-content: center; 113 | } 114 | 115 | .social-icon { 116 | height: 46px; 117 | width: 46px; 118 | display: flex; 119 | justify-content: center; 120 | align-items: center; 121 | margin: 0 0.45rem; 122 | color: #333; 123 | border-radius: 50%; 124 | border: 1px solid #333; 125 | text-decoration: none; 126 | font-size: 1.1rem; 127 | transition: 0.3s; 128 | } 129 | 130 | .social-icon:hover { 131 | color: #4481eb; 132 | border-color: #4481eb; 133 | } 134 | 135 | .btn { 136 | width: 150px; 137 | background-color: #5995fd; 138 | border: none; 139 | outline: none; 140 | height: 49px; 141 | border-radius: 49px; 142 | color: #fff; 143 | text-transform: uppercase; 144 | font-weight: 600; 145 | margin: 10px 0; 146 | cursor: pointer; 147 | transition: 0.5s; 148 | } 149 | 150 | .btn:hover { 151 | background-color: #4d84e2; 152 | } 153 | .panels-container { 154 | position: absolute; 155 | height: 100%; 156 | width: 100%; 157 | top: 0; 158 | left: 0; 159 | display: grid; 160 | grid-template-columns: repeat(2, 1fr); 161 | } 162 | 163 | .container1:before { 164 | content: ""; 165 | position: absolute; 166 | height: 2000px; 167 | width: 2000px; 168 | top: -10%; 169 | right: 48%; 170 | transform: translateY(-50%); 171 | background-image: linear-gradient(-45deg, #4481eb 0%, #04befe 100%); 172 | transition: 1.8s ease-in-out; 173 | border-radius: 50%; 174 | z-index: 6; 175 | } 176 | 177 | .image { 178 | width: 100%; 179 | transition: transform 1.1s ease-in-out; 180 | transition-delay: 0.4s; 181 | } 182 | 183 | .panel { 184 | display: flex; 185 | flex-direction: column; 186 | align-items: flex-end; 187 | justify-content: space-around; 188 | text-align: center; 189 | z-index: 6; 190 | } 191 | 192 | .left-panel { 193 | pointer-events: all; 194 | padding: 3rem 17% 2rem 12%; 195 | } 196 | 197 | .right-panel { 198 | pointer-events: none; 199 | padding: 3rem 12% 2rem 17%; 200 | } 201 | 202 | .panel .content { 203 | color: #fff; 204 | transition: transform 0.9s ease-in-out; 205 | transition-delay: 0.6s; 206 | } 207 | 208 | .panel h3 { 209 | font-weight: 600; 210 | line-height: 1; 211 | font-size: 1.5rem; 212 | } 213 | 214 | .panel p { 215 | font-size: 0.95rem; 216 | padding: 0.7rem 0; 217 | } 218 | 219 | .btn.transparent { 220 | margin: 0; 221 | background: none; 222 | border: 2px solid #fff; 223 | width: 130px; 224 | height: 41px; 225 | font-weight: 600; 226 | font-size: 0.8rem; 227 | } 228 | 229 | .right-panel .image, 230 | .right-panel .content { 231 | transform: translateX(800px); 232 | } 233 | 234 | /* ANIMATION */ 235 | 236 | .container1.sign-up-mode:before { 237 | transform: translate(100%, -50%); 238 | right: 52%; 239 | } 240 | 241 | .container1.sign-up-mode .left-panel .image, 242 | .container1.sign-up-mode .left-panel .content { 243 | transform: translateX(-800px); 244 | } 245 | 246 | .container1.sign-up-mode .signin-signup { 247 | left: 25%; 248 | } 249 | 250 | .container1.sign-up-mode form.sign-up-form { 251 | opacity: 1; 252 | z-index: 2; 253 | } 254 | 255 | .container1.sign-up-mode form.sign-in-form { 256 | opacity: 0; 257 | z-index: 1; 258 | } 259 | 260 | .container1.sign-up-mode .right-panel .image, 261 | .container1.sign-up-mode .right-panel .content { 262 | transform: translateX(0%); 263 | } 264 | 265 | .container1.sign-up-mode .left-panel { 266 | pointer-events: none; 267 | } 268 | 269 | .container1.sign-up-mode .right-panel { 270 | pointer-events: all; 271 | } 272 | 273 | @media (max-width: 870px) { 274 | .container1 { 275 | min-height: 800px; 276 | height: 100vh; 277 | } 278 | .signin-signup { 279 | width: 100%; 280 | top: 95%; 281 | transform: translate(-50%, -100%); 282 | transition: 1s 0.8s ease-in-out; 283 | } 284 | 285 | .signin-signup, 286 | .container1.sign-up-mode .signin-signup { 287 | left: 50%; 288 | } 289 | 290 | .panels-container { 291 | grid-template-columns: 1fr; 292 | grid-template-rows: 1fr 2fr 1fr; 293 | } 294 | 295 | .panel { 296 | flex-direction: row; 297 | justify-content: space-around; 298 | align-items: center; 299 | padding: 2.5rem 8%; 300 | grid-column: 1 / 2; 301 | } 302 | 303 | .right-panel { 304 | grid-row: 3 / 4; 305 | } 306 | 307 | .left-panel { 308 | grid-row: 1 / 2; 309 | } 310 | 311 | .image { 312 | width: 200px; 313 | transition: transform 0.9s ease-in-out; 314 | transition-delay: 0.6s; 315 | } 316 | 317 | .panel .content { 318 | padding-right: 15%; 319 | transition: transform 0.9s ease-in-out; 320 | transition-delay: 0.8s; 321 | } 322 | 323 | .panel h3 { 324 | font-size: 1.2rem; 325 | } 326 | 327 | .panel p { 328 | font-size: 0.7rem; 329 | padding: 0.5rem 0; 330 | } 331 | 332 | .btn.transparent { 333 | width: 110px; 334 | height: 35px; 335 | font-size: 0.7rem; 336 | } 337 | 338 | .container1:before { 339 | width: 1500px; 340 | height: 1500px; 341 | transform: translateX(-50%); 342 | left: 30%; 343 | bottom: 68%; 344 | right: initial; 345 | top: initial; 346 | transition: 2s ease-in-out; 347 | } 348 | 349 | .container1.sign-up-mode:before { 350 | transform: translate(-50%, 100%); 351 | bottom: 32%; 352 | right: initial; 353 | } 354 | 355 | .container1.sign-up-mode .left-panel .image, 356 | .container1.sign-up-mode .left-panel .content { 357 | transform: translateY(-300px); 358 | } 359 | 360 | .container1.sign-up-mode .right-panel .image, 361 | .container1.sign-up-mode .right-panel .content { 362 | transform: translateY(0px); 363 | } 364 | 365 | .right-panel .image, 366 | .right-panel .content { 367 | transform: translateY(300px); 368 | } 369 | 370 | .container1.sign-up-mode .signin-signup { 371 | top: 5%; 372 | transform: translate(-50%, 0); 373 | } 374 | } 375 | 376 | @media (max-width: 570px) { 377 | form { 378 | padding: 0 1.5rem; 379 | } 380 | 381 | .image { 382 | display: none; 383 | } 384 | .panel .content { 385 | padding: 0.5rem 1rem; 386 | } 387 | .container1 { 388 | padding: 1.5rem; 389 | } 390 | 391 | .container1:before { 392 | bottom: 72%; 393 | left: 50%; 394 | } 395 | 396 | .container1.sign-up-mode:before { 397 | bottom: 28%; 398 | left: 50%; 399 | } 400 | } 401 | -------------------------------------------------------------------------------- /client/src/components/404.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | const NotFound = () => { 3 | return ( 4 |
5 | 404 15 |
16 | ); 17 | }; 18 | export default NotFound; 19 | -------------------------------------------------------------------------------- /client/src/components/Alert.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import authContext from "../context/auth/authContext"; 3 | import ErrorList from "./ErrorList"; 4 | import { Toast } from "react-bootstrap"; 5 | import "animate.css"; 6 | 7 | const Alerts = () => { 8 | const { errors, isAuthenticated } = useContext(authContext); 9 | // if (errors.length > 0) return errors.map(err => ); 10 | if (errors.length > 0) 11 | return ( 12 | 13 | ); 14 | 15 | return null; 16 | }; 17 | 18 | export default Alerts; 19 | -------------------------------------------------------------------------------- /client/src/components/Cart.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, useEffect } from "react"; 2 | import MenuList from "./MenuList"; 3 | import ProductContext from "../context/products/productsContext"; 4 | import CartContext from "../context/cart/cartContext"; 5 | import AuthContext from "../context/auth/authContext"; 6 | import CartList from "./cartList"; 7 | import SaveAltIcon from "@material-ui/icons/SaveAlt"; 8 | import { makeStyles } from "@material-ui/core/"; 9 | import { Link } from "react-router-dom"; 10 | import ClearAllIcon from "@material-ui/icons/ClearAll"; 11 | import { Button } from "@material-ui/core"; 12 | import { Container, Toast } from "react-bootstrap"; 13 | import ShoppingCartIcon from "@material-ui/icons/ShoppingCart"; 14 | import zIndex from "@material-ui/core/styles/zIndex"; 15 | import '../styles.css' 16 | import '../mobile.css' 17 | const useStyles = makeStyles((theme) => ({ 18 | button: { 19 | margin: theme.spacing(1) 20 | } 21 | })); 22 | 23 | const SaveCart = (msg) => { 24 | return ( 25 | 26 | 33 | Success 34 | {/* 2 seconds ago */} 35 | 36 | Cart Saved Successfully! 37 | 38 | ); 39 | }; 40 | const Cart = () => { 41 | const classes = useStyles(); 42 | const [save, setSave] = useState(0); 43 | const { 44 | items, 45 | loadCart, 46 | total_price, 47 | total_quantity, 48 | saveCart, 49 | state, 50 | clearCart 51 | } = useContext(CartContext); 52 | // console.log(items); 53 | // useEffect(() => { 54 | // loadCart(); 55 | // }, []); 56 | const { user } = useContext(AuthContext); 57 | const handleClick = async () => { 58 | const bool = await saveCart(user._id, state); 59 | if (bool) setSave(1); 60 | setTimeout(() => { 61 | setSave(0); 62 | }, 3000); 63 | }; 64 | 65 | return ( 66 | <> 67 | {save === 1 ? : ""} 68 | 69 |