├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── documentation_issue.yml │ └── feature_request.yml └── workflows │ └── contributor-interaction.yml ├── .gitignore ├── .postcssrc ├── LICENSE ├── README.md ├── coverage ├── clover.xml ├── coverage-final.json ├── lcov-report │ ├── base.css │ ├── block-navigation.js │ ├── favicon.png │ ├── index.html │ ├── prettify.css │ ├── prettify.js │ ├── sort-arrow-sprite.png │ ├── sorter.js │ └── sum.js.html └── lcov.info ├── index.css ├── index.html ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── .babelrc ├── app.js ├── assets │ ├── Cook.jpg │ ├── Empty-fav-tab-img.png │ ├── arrow-icon.png │ ├── avatar.png │ ├── logo.png │ └── ramen-restaurant.jpg ├── components │ ├── About.js │ ├── AppLayout.js │ ├── Body.js │ ├── Cart.js │ ├── CartItem.js │ ├── Contact.js │ ├── Error.js │ ├── Footer.js │ ├── Header.js │ ├── Help.js │ ├── Instamart.js │ ├── Offline.js │ ├── OrdarSummery.js │ ├── ResShimmer.js │ ├── RestaurantMenu.js │ ├── RestaurantMenuAccordion.js │ ├── RestaurantMenuAccordionDetails.js │ ├── RestruarantCards.js │ ├── ScrollToTop.js │ ├── Shimmer.js │ ├── __tests__ │ │ ├── Header.test.js │ │ └── sum.test.js │ └── sum.js ├── mocks │ └── data.js └── utils │ ├── cartSlice.js │ ├── constants.js │ ├── help.json │ ├── helper.js │ ├── index.css │ ├── mockData.js │ ├── store.js │ ├── useFocus.js │ ├── useOnline.js │ ├── useRestaurant.js │ └── userContext.js ├── tailwind.config.js └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug report 2 | description: Create a report to help us improve 3 | labels: ["bug"] 4 | 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Describe the bug 10 | description: A clear and concise description of what the bug is 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | id: expected 16 | attributes: 17 | label: Expected behaviour 18 | description: A clear and concise description of what you expected to happen. 19 | validations: 20 | required: true 21 | 22 | - type: textarea 23 | id: screenshots 24 | attributes: 25 | label: Screenshots 26 | description: Please add screenshots if applicable 27 | validations: 28 | required: false 29 | 30 | - type: textarea 31 | attributes: 32 | label: Additional context 33 | description: Add any other context about the problem here. 34 | validations: 35 | required: false 36 | - type: checkboxes 37 | id: terms 38 | attributes: 39 | label: Code of Conduct 40 | description: By submitting this issue, you agree to follow our Code of Conduct 41 | options: 42 | - label: I agree to follow this project's Code of Conduct 43 | required: true 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation_issue.yml: -------------------------------------------------------------------------------- 1 | name: 📄 Documentation issue 2 | description: Found an issue in the documentation? You can use this one! 3 | title: "[DOCS] " 4 | labels: ["documentation"] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: A brief description of the question or issue, also include what you tried and what didn't work 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: screenshots 15 | attributes: 16 | label: Screenshots 17 | description: Please add screenshots if applicable 18 | validations: 19 | required: false 20 | - type: textarea 21 | id: extrainfo 22 | attributes: 23 | label: Additional information 24 | description: Is there anything else we should know about this issue? 25 | validations: 26 | required: false 27 | - type: checkboxes 28 | id: terms 29 | attributes: 30 | label: Code of Conduct 31 | description: By submitting this issue, you agree to follow our Code of Conduct 32 | options: 33 | - label: I agree to follow this project's Code of Conduct 34 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 💡 Feature request 2 | description: Have a new idea/feature ? Please suggest! 3 | labels: ["enhancement"] 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Is your feature request related to a problem? Please describe. 9 | description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | id: solution 15 | attributes: 16 | label: Describe the solution you'd like 17 | description: A clear and concise description of what you want to happen. 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | id: alternatives 23 | attributes: 24 | label: Describe alternatives you've considered 25 | description: A clear and concise description of any alternative solutions or features you've considered. 26 | validations: 27 | required: false 28 | 29 | - type: textarea 30 | id: extrainfo 31 | attributes: 32 | label: Additional context 33 | description: Add any other context or screenshots about the feature request here. 34 | validations: 35 | required: false 36 | - type: checkboxes 37 | id: terms 38 | attributes: 39 | label: Code of Conduct 40 | description: By submitting this issue, you agree to follow our Code of Conduct 41 | options: 42 | - label: I agree to follow this project's Code of Conduct 43 | required: true 44 | -------------------------------------------------------------------------------- /.github/workflows/contributor-interaction.yml: -------------------------------------------------------------------------------- 1 | name: Contributor Interaction 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | pull_request_target: 7 | types: [opened] 8 | 9 | permissions: 10 | issues: write # Define permissions for issues 11 | pull-requests: write # Define permissions for pull requests 12 | 13 | jobs: 14 | greet_contributors: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: EddieHubCommunity/gh-action-community/src/welcome@main 18 | if: ${{ github.event.sender.login != github.repository_owner }} 19 | with: 20 | github-token: ${{ secrets.GITHUB_TOKEN }} 21 | issue-message: | 22 | ### Hey @${{ github.actor }} 😃, 23 | 24 | Thank you for raising an issue. Soon, the owner/maintainers will review it and offer feedback/suggestions. 25 | Meanwhile if you enjoy contributing to the project, please consider giving it a star ⭐. 26 | pr-message: | 27 | ### Good work @${{ github.actor }} 😃, 28 | 29 | Thank you for raising the PR. Soon, the owner/maintainers will review it and offer feedback/suggestions. 30 | Meanwhile if you enjoy contributing to the project, please consider giving it a star ⭐. 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | dist 3 | .parcel-cache 4 | .cache 5 | 6 | 7 | /coverage -------------------------------------------------------------------------------- /.postcssrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": { 3 | "tailwindcss": {} 4 | } 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Anand Gadagin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 👋 Introducing Hungry-Hero 2 | 3 | The `Hungry Hero` is a modern web application that lets you check out restaurants, see how good they are, look at pictures of delicious food, and find specific types of cuisine. It's easy to use, with a nice design, helping you discover where to eat 4 | 5 | Yes, it's an `open-source` web app! 6 | 7 | Is that all? Nope. You can also create your feature and share them with the world. The best part is that the ReactJS developer will `review` your project code before it gets part of the `Hungry-Hero` app. 8 | 9 | ## Table of Contents 10 | 11 | - [Quick Start](#quick-start-) 12 | - [Want to Contribute](#want-to-contribute-) 13 | - [Guidelines](#guidelines-) 14 | - [Contributors](#contributors-) 15 | 16 | ## Quick start : 17 | Follow these steps to install and set up the project on your local machine. 18 | 19 | First, clone the project repository to your local machine using Git. 20 | Open your terminal or command prompt and run the following command: 21 | ```sh 22 | $ git clone [repository URL] 23 | ``` 24 | 25 | Change your current directory to the newly cloned project folder: 26 | ```sh 27 | $ cd [project folder] 28 | ``` 29 | Install the project dependencies using npm (Node Package Manager) or yarn. 30 | Choose one of the following commands based on your preference: 31 | ```sh 32 | $ npm install (or) yarn install 33 | ``` 34 | 35 | Once the installation is complete, you can start the project. 36 | ```sh 37 | $ npm start (or) yarn run 38 | ``` 39 | ## Want to Contribute 🔥: 40 | 41 | When contributing to this repository, please first discuss the change you wish to make via [issue](https://github.com/Anandsg/Hungry-hero/issues), 42 | [email](mailto:anandgadugin@gmail.com), or any other method with the owners of this repository before making a change. 43 | 44 | - [Pull Request Process](#prp) 45 | - [Code of Conduct](#coc) 46 | 47 | ### Pull Request Process 48 | 49 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. 50 | 51 | ### Code of Conduct 52 | 53 | ##### Our Pledge 54 | 55 | We, as contributors and maintainers, are dedicated to ensuring that everyone can participate in our project and community without facing harassment or discrimination. We welcome individuals of all backgrounds, including but not limited to age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, sexual identity, and orientation. 56 | 57 | ##### Our Duties 58 | 59 | As project maintainers, we have the responsibility to define the guidelines for acceptable conduct within our community. We are also entrusted with the task of taking fair and appropriate actions when any form of unacceptable behavior occurs. 60 | 61 | Project maintainers possess the authority and obligation to: 62 | 63 | - Remove, edit, or decline comments, commits, code, wiki edits, issues, and other contributions that do not adhere to this Code of Conduct. 64 | - Temporarily or permanently ban contributors who engage in behaviors that we consider inappropriate, threatening, offensive, or harmful. 65 | 66 | ##### Summary 67 | 68 | Use the summary field to provide a succinct description of the change: 69 | 70 | - Use the imperative, present tense: "change" not "changed" nor "changes" 71 | - Don't capitalize the first letter 72 | - Don't use dot (.) at the end 73 | 74 | ## Guidelines 🚦: 75 | 76 | Before pushing code please go through our guidelines: 77 | 78 | 1. Use clear and specific titles when pushing your code changes. 79 | 2. Make sure to name your Pull Requests appropriately. 80 | 3. Avoid submitting multiple Pull Requests with the same code; it will be considered spam. 81 | 4. Help everyone understand your code by adding helpful comments. 82 | 83 | Don't forget to follow [@Anandsg](https://github.com/Anandsg) ⭐😊 84 | #### All the best 🙌🏼 85 | 86 | 87 | ## Contributors : 88 | 89 | #### Big Thanks to our amazing contributors 🚀 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /coverage/clover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /coverage/coverage-final.json: -------------------------------------------------------------------------------- 1 | {"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/Header.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/Header.js","statementMap":{"0":{"start":{"line":17,"column":15},"end":{"line":229,"column":1}},"1":{"start":{"line":18,"column":38},"end":{"line":18,"column":52}},"2":{"start":{"line":19,"column":38},"end":{"line":19,"column":53}},"3":{"start":{"line":21,"column":19},"end":{"line":21,"column":30}},"4":{"start":{"line":22,"column":19},"end":{"line":22,"column":42}},"5":{"start":{"line":23,"column":20},"end":{"line":23,"column":60}},"6":{"start":{"line":23,"column":43},"end":{"line":23,"column":59}},"7":{"start":{"line":25,"column":26},"end":{"line":41,"column":6}},"8":{"start":{"line":44,"column":22},"end":{"line":62,"column":3}},"9":{"start":{"line":45,"column":4},"end":{"line":45,"column":46}},"10":{"start":{"line":46,"column":16},"end":{"line":46,"column":63}},"11":{"start":{"line":47,"column":20},"end":{"line":49,"column":5}},"12":{"start":{"line":50,"column":4},"end":{"line":61,"column":5}},"13":{"start":{"line":51,"column":23},"end":{"line":51,"column":52}},"14":{"start":{"line":52,"column":6},"end":{"line":54,"column":7}},"15":{"start":{"line":53,"column":8},"end":{"line":53,"column":66}},"16":{"start":{"line":56,"column":19},"end":{"line":56,"column":40}},"17":{"start":{"line":57,"column":6},"end":{"line":57,"column":24}},"18":{"start":{"line":59,"column":6},"end":{"line":59,"column":56}},"19":{"start":{"line":60,"column":6},"end":{"line":60,"column":18}},"20":{"start":{"line":65,"column":16},"end":{"line":71,"column":4}},"21":{"start":{"line":67,"column":6},"end":{"line":67,"column":46}},"22":{"start":{"line":68,"column":6},"end":{"line":68,"column":27}},"23":{"start":{"line":69,"column":6},"end":{"line":69,"column":70}},"24":{"start":{"line":73,"column":17},"end":{"line":80,"column":3}},"25":{"start":{"line":74,"column":4},"end":{"line":79,"column":5}},"26":{"start":{"line":75,"column":6},"end":{"line":75,"column":45}},"27":{"start":{"line":76,"column":6},"end":{"line":76,"column":26}},"28":{"start":{"line":78,"column":6},"end":{"line":78,"column":26}},"29":{"start":{"line":83,"column":21},"end":{"line":85,"column":3}},"30":{"start":{"line":84,"column":4},"end":{"line":84,"column":31}},"31":{"start":{"line":88,"column":20},"end":{"line":90,"column":3}},"32":{"start":{"line":89,"column":4},"end":{"line":89,"column":25}},"33":{"start":{"line":92,"column":2},"end":{"line":97,"column":9}},"34":{"start":{"line":93,"column":4},"end":{"line":96,"column":5}},"35":{"start":{"line":94,"column":6},"end":{"line":94,"column":55}},"36":{"start":{"line":95,"column":6},"end":{"line":95,"column":27}},"37":{"start":{"line":98,"column":2},"end":{"line":228,"column":4}},"38":{"start":{"line":134,"column":16},"end":{"line":138,"column":23}},"39":{"start":{"line":162,"column":18},"end":{"line":162,"column":26}},"40":{"start":{"line":170,"column":31},"end":{"line":170,"column":39}},"41":{"start":{"line":191,"column":22},"end":{"line":195,"column":29}},"42":{"start":{"line":208,"column":24},"end":{"line":208,"column":32}},"43":{"start":{"line":216,"column":37},"end":{"line":216,"column":45}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":17,"column":15},"end":{"line":17,"column":16}},"loc":{"start":{"line":17,"column":21},"end":{"line":229,"column":1}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":23,"column":32},"end":{"line":23,"column":33}},"loc":{"start":{"line":23,"column":43},"end":{"line":23,"column":59}},"line":23},"2":{"name":"(anonymous_2)","decl":{"start":{"line":44,"column":22},"end":{"line":44,"column":23}},"loc":{"start":{"line":44,"column":46},"end":{"line":62,"column":3}},"line":44},"3":{"name":"(anonymous_3)","decl":{"start":{"line":66,"column":15},"end":{"line":66,"column":16}},"loc":{"start":{"line":66,"column":34},"end":{"line":70,"column":5}},"line":66},"4":{"name":"(anonymous_4)","decl":{"start":{"line":73,"column":17},"end":{"line":73,"column":18}},"loc":{"start":{"line":73,"column":23},"end":{"line":80,"column":3}},"line":73},"5":{"name":"(anonymous_5)","decl":{"start":{"line":83,"column":21},"end":{"line":83,"column":22}},"loc":{"start":{"line":83,"column":27},"end":{"line":85,"column":3}},"line":83},"6":{"name":"(anonymous_6)","decl":{"start":{"line":88,"column":20},"end":{"line":88,"column":21}},"loc":{"start":{"line":88,"column":26},"end":{"line":90,"column":3}},"line":88},"7":{"name":"(anonymous_7)","decl":{"start":{"line":92,"column":12},"end":{"line":92,"column":13}},"loc":{"start":{"line":92,"column":18},"end":{"line":97,"column":3}},"line":92},"8":{"name":"(anonymous_8)","decl":{"start":{"line":133,"column":34},"end":{"line":133,"column":35}},"loc":{"start":{"line":134,"column":16},"end":{"line":138,"column":23}},"line":134},"9":{"name":"(anonymous_9)","decl":{"start":{"line":161,"column":25},"end":{"line":161,"column":26}},"loc":{"start":{"line":161,"column":31},"end":{"line":163,"column":17}},"line":161},"10":{"name":"(anonymous_10)","decl":{"start":{"line":170,"column":25},"end":{"line":170,"column":26}},"loc":{"start":{"line":170,"column":31},"end":{"line":170,"column":39}},"line":170},"11":{"name":"(anonymous_11)","decl":{"start":{"line":190,"column":40},"end":{"line":190,"column":41}},"loc":{"start":{"line":191,"column":22},"end":{"line":195,"column":29}},"line":191},"12":{"name":"(anonymous_12)","decl":{"start":{"line":207,"column":31},"end":{"line":207,"column":32}},"loc":{"start":{"line":207,"column":37},"end":{"line":209,"column":23}},"line":207},"13":{"name":"(anonymous_13)","decl":{"start":{"line":216,"column":31},"end":{"line":216,"column":32}},"loc":{"start":{"line":216,"column":37},"end":{"line":216,"column":45}},"line":216}},"branchMap":{"0":{"loc":{"start":{"line":52,"column":6},"end":{"line":54,"column":7}},"type":"if","locations":[{"start":{"line":52,"column":6},"end":{"line":54,"column":7}},{"start":{},"end":{}}],"line":52},"1":{"loc":{"start":{"line":74,"column":4},"end":{"line":79,"column":5}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":79,"column":5}},{"start":{"line":77,"column":11},"end":{"line":79,"column":5}}],"line":74},"2":{"loc":{"start":{"line":93,"column":4},"end":{"line":96,"column":5}},"type":"if","locations":[{"start":{"line":93,"column":4},"end":{"line":96,"column":5}},{"start":{},"end":{}}],"line":93},"3":{"loc":{"start":{"line":123,"column":17},"end":{"line":125,"column":17}},"type":"binary-expr","locations":[{"start":{"line":123,"column":17},"end":{"line":123,"column":28}},{"start":{"line":124,"column":18},"end":{"line":124,"column":71}}],"line":123},"4":{"loc":{"start":{"line":158,"column":13},"end":{"line":174,"column":13}},"type":"cond-expr","locations":[{"start":{"line":159,"column":14},"end":{"line":166,"column":23}},{"start":{"line":168,"column":14},"end":{"line":173,"column":23}}],"line":158},"5":{"loc":{"start":{"line":178,"column":11},"end":{"line":224,"column":11}},"type":"binary-expr","locations":[{"start":{"line":178,"column":11},"end":{"line":178,"column":21}},{"start":{"line":179,"column":12},"end":{"line":223,"column":18}}],"line":178},"6":{"loc":{"start":{"line":204,"column":19},"end":{"line":220,"column":19}},"type":"cond-expr","locations":[{"start":{"line":205,"column":20},"end":{"line":212,"column":29}},{"start":{"line":214,"column":20},"end":{"line":219,"column":29}}],"line":204}},"s":{"0":1,"1":8,"2":8,"3":8,"4":8,"5":8,"6":8,"7":8,"8":8,"9":2,"10":2,"11":2,"12":2,"13":2,"14":0,"15":0,"16":0,"17":0,"18":2,"19":2,"20":8,"21":0,"22":0,"23":0,"24":8,"25":1,"26":1,"27":1,"28":0,"29":8,"30":0,"31":8,"32":0,"33":8,"34":5,"35":2,"36":2,"37":8,"38":32,"39":1,"40":1,"41":0,"42":0,"43":0},"f":{"0":8,"1":8,"2":2,"3":0,"4":1,"5":0,"6":0,"7":5,"8":32,"9":1,"10":1,"11":0,"12":0,"13":0},"b":{"0":[0,0],"1":[1,0],"2":[2,3],"3":[8,8],"4":[6,2],"5":[8,0],"6":[0,0]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"eaf553535868623aa8b53555d6ec5a2dd5620068"} 2 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/ScrollToTop.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/ScrollToTop.js","statementMap":{"0":{"start":{"line":4,"column":20},"end":{"line":40,"column":1}},"1":{"start":{"line":5,"column":36},"end":{"line":5,"column":51}},"2":{"start":{"line":7,"column":2},"end":{"line":21,"column":9}},"3":{"start":{"line":8,"column":25},"end":{"line":14,"column":5}},"4":{"start":{"line":9,"column":6},"end":{"line":13,"column":7}},"5":{"start":{"line":10,"column":8},"end":{"line":10,"column":27}},"6":{"start":{"line":12,"column":8},"end":{"line":12,"column":28}},"7":{"start":{"line":16,"column":4},"end":{"line":16,"column":52}},"8":{"start":{"line":18,"column":4},"end":{"line":20,"column":6}},"9":{"start":{"line":19,"column":6},"end":{"line":19,"column":57}},"10":{"start":{"line":23,"column":22},"end":{"line":28,"column":3}},"11":{"start":{"line":24,"column":4},"end":{"line":27,"column":7}},"12":{"start":{"line":30,"column":2},"end":{"line":39,"column":4}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":4,"column":20},"end":{"line":4,"column":21}},"loc":{"start":{"line":4,"column":26},"end":{"line":40,"column":1}},"line":4},"1":{"name":"(anonymous_1)","decl":{"start":{"line":7,"column":12},"end":{"line":7,"column":13}},"loc":{"start":{"line":7,"column":18},"end":{"line":21,"column":3}},"line":7},"2":{"name":"(anonymous_2)","decl":{"start":{"line":8,"column":25},"end":{"line":8,"column":26}},"loc":{"start":{"line":8,"column":31},"end":{"line":14,"column":5}},"line":8},"3":{"name":"(anonymous_3)","decl":{"start":{"line":18,"column":11},"end":{"line":18,"column":12}},"loc":{"start":{"line":18,"column":17},"end":{"line":20,"column":5}},"line":18},"4":{"name":"(anonymous_4)","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":23}},"loc":{"start":{"line":23,"column":28},"end":{"line":28,"column":3}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":9,"column":6},"end":{"line":13,"column":7}},"type":"if","locations":[{"start":{"line":9,"column":6},"end":{"line":13,"column":7}},{"start":{"line":11,"column":13},"end":{"line":13,"column":7}}],"line":9},"1":{"loc":{"start":{"line":33,"column":8},"end":{"line":33,"column":40}},"type":"cond-expr","locations":[{"start":{"line":33,"column":20},"end":{"line":33,"column":29}},{"start":{"line":33,"column":32},"end":{"line":33,"column":40}}],"line":33}},"s":{"0":1,"1":8,"2":8,"3":5,"4":0,"5":0,"6":0,"7":5,"8":5,"9":5,"10":8,"11":0,"12":8},"f":{"0":8,"1":5,"2":0,"3":5,"4":0},"b":{"0":[0,0],"1":[0,8]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"9c5946220cfb01c524a8d56e52bbed4e76395d36"} 3 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/sum.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/components/sum.js","statementMap":{"0":{"start":{"line":1,"column":19},"end":{"line":4,"column":3}},"1":{"start":{"line":2,"column":4},"end":{"line":2,"column":23}},"2":{"start":{"line":3,"column":4},"end":{"line":3,"column":17}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":1,"column":19},"end":{"line":1,"column":20}},"loc":{"start":{"line":1,"column":29},"end":{"line":4,"column":3}},"line":1}},"branchMap":{},"s":{"0":1,"1":1,"2":1},"f":{"0":1},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"d4ed5a2dfa8dcaab9b1aea53c5e6829d5112bc8e"} 4 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/cartSlice.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/cartSlice.js","statementMap":{"0":{"start":{"line":3,"column":18},"end":{"line":53,"column":2}},"1":{"start":{"line":12,"column":20},"end":{"line":14,"column":7}},"2":{"start":{"line":13,"column":22},"end":{"line":13,"column":61}},"3":{"start":{"line":15,"column":6},"end":{"line":15,"column":34}},"4":{"start":{"line":16,"column":6},"end":{"line":21,"column":7}},"5":{"start":{"line":17,"column":8},"end":{"line":17,"column":53}},"6":{"start":{"line":18,"column":8},"end":{"line":18,"column":62}},"7":{"start":{"line":20,"column":8},"end":{"line":20,"column":43}},"8":{"start":{"line":23,"column":6},"end":{"line":23,"column":62}},"9":{"start":{"line":26,"column":20},"end":{"line":28,"column":7}},"10":{"start":{"line":27,"column":22},"end":{"line":27,"column":48}},"11":{"start":{"line":29,"column":6},"end":{"line":31,"column":7}},"12":{"start":{"line":30,"column":8},"end":{"line":30,"column":43}},"13":{"start":{"line":34,"column":20},"end":{"line":36,"column":7}},"14":{"start":{"line":35,"column":22},"end":{"line":35,"column":48}},"15":{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},"16":{"start":{"line":38,"column":8},"end":{"line":38,"column":43}},"17":{"start":{"line":42,"column":20},"end":{"line":44,"column":7}},"18":{"start":{"line":43,"column":22},"end":{"line":43,"column":48}},"19":{"start":{"line":45,"column":6},"end":{"line":47,"column":7}},"20":{"start":{"line":46,"column":8},"end":{"line":46,"column":37}},"21":{"start":{"line":50,"column":6},"end":{"line":50,"column":23}},"22":{"start":{"line":61,"column":4},"end":{"line":61,"column":21}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":10,"column":13},"end":{"line":10,"column":14}},"loc":{"start":{"line":10,"column":32},"end":{"line":24,"column":5}},"line":10},"1":{"name":"(anonymous_1)","decl":{"start":{"line":13,"column":8},"end":{"line":13,"column":9}},"loc":{"start":{"line":13,"column":22},"end":{"line":13,"column":61}},"line":13},"2":{"name":"(anonymous_2)","decl":{"start":{"line":25,"column":22},"end":{"line":25,"column":23}},"loc":{"start":{"line":25,"column":41},"end":{"line":32,"column":5}},"line":25},"3":{"name":"(anonymous_3)","decl":{"start":{"line":27,"column":8},"end":{"line":27,"column":9}},"loc":{"start":{"line":27,"column":22},"end":{"line":27,"column":48}},"line":27},"4":{"name":"(anonymous_4)","decl":{"start":{"line":33,"column":22},"end":{"line":33,"column":23}},"loc":{"start":{"line":33,"column":41},"end":{"line":40,"column":5}},"line":33},"5":{"name":"(anonymous_5)","decl":{"start":{"line":35,"column":8},"end":{"line":35,"column":9}},"loc":{"start":{"line":35,"column":22},"end":{"line":35,"column":48}},"line":35},"6":{"name":"(anonymous_6)","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":17}},"loc":{"start":{"line":41,"column":35},"end":{"line":48,"column":5}},"line":41},"7":{"name":"(anonymous_7)","decl":{"start":{"line":43,"column":8},"end":{"line":43,"column":9}},"loc":{"start":{"line":43,"column":22},"end":{"line":43,"column":48}},"line":43},"8":{"name":"(anonymous_8)","decl":{"start":{"line":49,"column":15},"end":{"line":49,"column":16}},"loc":{"start":{"line":49,"column":26},"end":{"line":51,"column":5}},"line":49}},"branchMap":{"0":{"loc":{"start":{"line":16,"column":6},"end":{"line":21,"column":7}},"type":"if","locations":[{"start":{"line":16,"column":6},"end":{"line":21,"column":7}},{"start":{"line":19,"column":13},"end":{"line":21,"column":7}}],"line":16},"1":{"loc":{"start":{"line":29,"column":6},"end":{"line":31,"column":7}},"type":"if","locations":[{"start":{"line":29,"column":6},"end":{"line":31,"column":7}},{"start":{},"end":{}}],"line":29},"2":{"loc":{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":39,"column":7}},{"start":{},"end":{}}],"line":37},"3":{"loc":{"start":{"line":37,"column":10},"end":{"line":37,"column":60}},"type":"binary-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":20}},{"start":{"line":37,"column":24},"end":{"line":37,"column":60}}],"line":37},"4":{"loc":{"start":{"line":45,"column":6},"end":{"line":47,"column":7}},"type":"if","locations":[{"start":{"line":45,"column":6},"end":{"line":47,"column":7}},{"start":{},"end":{}}],"line":45}},"s":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":1},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"bd5fae7b3ea7b17501ea53a0ed0e9230b8a31c7b"} 5 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/constants.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/constants.js","statementMap":{"0":{"start":{"line":2,"column":2},"end":{"line":2,"column":93}},"1":{"start":{"line":5,"column":2},"end":{"line":5,"column":115}},"2":{"start":{"line":8,"column":2},"end":{"line":8,"column":147}},"3":{"start":{"line":11,"column":2},"end":{"line":11,"column":97}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1},"f":{},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"00b46aeb7f22c75f1ad5c59fd67bb26cb79d7338"} 6 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/store.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/store.js","statementMap":{"0":{"start":{"line":16,"column":22},"end":{"line":19,"column":1}},"1":{"start":{"line":21,"column":20},"end":{"line":23,"column":2}},"2":{"start":{"line":25,"column":25},"end":{"line":25,"column":67}},"3":{"start":{"line":27,"column":21},"end":{"line":34,"column":2}},"4":{"start":{"line":29,"column":40},"end":{"line":33,"column":4}},"5":{"start":{"line":36,"column":25},"end":{"line":36,"column":44}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":29,"column":14},"end":{"line":29,"column":15}},"loc":{"start":{"line":29,"column":40},"end":{"line":33,"column":4}},"line":29}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1},"f":{"0":1},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"e9365c27d42cef03e81945b217d2da159b322ad4"} 7 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/useOnline.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/useOnline.js","statementMap":{"0":{"start":{"line":3,"column":18},"end":{"line":17,"column":1}},"1":{"start":{"line":4,"column":34},"end":{"line":4,"column":48}},"2":{"start":{"line":5,"column":2},"end":{"line":14,"column":9}},"3":{"start":{"line":6,"column":25},"end":{"line":8,"column":5}},"4":{"start":{"line":7,"column":6},"end":{"line":7,"column":24}},"5":{"start":{"line":9,"column":26},"end":{"line":11,"column":5}},"6":{"start":{"line":10,"column":6},"end":{"line":10,"column":25}},"7":{"start":{"line":12,"column":4},"end":{"line":12,"column":52}},"8":{"start":{"line":13,"column":4},"end":{"line":13,"column":54}},"9":{"start":{"line":16,"column":2},"end":{"line":16,"column":18}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":3,"column":18},"end":{"line":3,"column":19}},"loc":{"start":{"line":3,"column":24},"end":{"line":17,"column":1}},"line":3},"1":{"name":"(anonymous_1)","decl":{"start":{"line":5,"column":12},"end":{"line":5,"column":13}},"loc":{"start":{"line":5,"column":18},"end":{"line":14,"column":3}},"line":5},"2":{"name":"(anonymous_2)","decl":{"start":{"line":6,"column":25},"end":{"line":6,"column":26}},"loc":{"start":{"line":6,"column":31},"end":{"line":8,"column":5}},"line":6},"3":{"name":"(anonymous_3)","decl":{"start":{"line":9,"column":26},"end":{"line":9,"column":27}},"loc":{"start":{"line":9,"column":32},"end":{"line":11,"column":5}},"line":9}},"branchMap":{},"s":{"0":1,"1":8,"2":8,"3":5,"4":0,"5":5,"6":0,"7":5,"8":5,"9":8},"f":{"0":8,"1":5,"2":0,"3":0},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"ab53d19b700a3a3bec61eed9ac6fd4d3af4997ff"} 8 | ,"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/userContext.js": {"path":"/Users/thennarasur/hacktober/hungry-hero-fork/Hungry-hero/src/utils/userContext.js","statementMap":{"0":{"start":{"line":3,"column":20},"end":{"line":9,"column":2}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"38a16605a834c0f9dfe62becae256acd2a54ef0b"} 9 | } 10 | -------------------------------------------------------------------------------- /coverage/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | height: 100%; 4 | } 5 | body { 6 | font-family: Helvetica Neue, Helvetica, Arial; 7 | font-size: 14px; 8 | color:#333; 9 | } 10 | .small { font-size: 12px; } 11 | *, *:after, *:before { 12 | -webkit-box-sizing:border-box; 13 | -moz-box-sizing:border-box; 14 | box-sizing:border-box; 15 | } 16 | h1 { font-size: 20px; margin: 0;} 17 | h2 { font-size: 14px; } 18 | pre { 19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; 20 | margin: 0; 21 | padding: 0; 22 | -moz-tab-size: 2; 23 | -o-tab-size: 2; 24 | tab-size: 2; 25 | } 26 | a { color:#0074D9; text-decoration:none; } 27 | a:hover { text-decoration:underline; } 28 | .strong { font-weight: bold; } 29 | .space-top1 { padding: 10px 0 0 0; } 30 | .pad2y { padding: 20px 0; } 31 | .pad1y { padding: 10px 0; } 32 | .pad2x { padding: 0 20px; } 33 | .pad2 { padding: 20px; } 34 | .pad1 { padding: 10px; } 35 | .space-left2 { padding-left:55px; } 36 | .space-right2 { padding-right:20px; } 37 | .center { text-align:center; } 38 | .clearfix { display:block; } 39 | .clearfix:after { 40 | content:''; 41 | display:block; 42 | height:0; 43 | clear:both; 44 | visibility:hidden; 45 | } 46 | .fl { float: left; } 47 | @media only screen and (max-width:640px) { 48 | .col3 { width:100%; max-width:100%; } 49 | .hide-mobile { display:none!important; } 50 | } 51 | 52 | .quiet { 53 | color: #7f7f7f; 54 | color: rgba(0,0,0,0.5); 55 | } 56 | .quiet a { opacity: 0.7; } 57 | 58 | .fraction { 59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; 60 | font-size: 10px; 61 | color: #555; 62 | background: #E8E8E8; 63 | padding: 4px 5px; 64 | border-radius: 3px; 65 | vertical-align: middle; 66 | } 67 | 68 | div.path a:link, div.path a:visited { color: #333; } 69 | table.coverage { 70 | border-collapse: collapse; 71 | margin: 10px 0 0 0; 72 | padding: 0; 73 | } 74 | 75 | table.coverage td { 76 | margin: 0; 77 | padding: 0; 78 | vertical-align: top; 79 | } 80 | table.coverage td.line-count { 81 | text-align: right; 82 | padding: 0 5px 0 20px; 83 | } 84 | table.coverage td.line-coverage { 85 | text-align: right; 86 | padding-right: 10px; 87 | min-width:20px; 88 | } 89 | 90 | table.coverage td span.cline-any { 91 | display: inline-block; 92 | padding: 0 5px; 93 | width: 100%; 94 | } 95 | .missing-if-branch { 96 | display: inline-block; 97 | margin-right: 5px; 98 | border-radius: 3px; 99 | position: relative; 100 | padding: 0 4px; 101 | background: #333; 102 | color: yellow; 103 | } 104 | 105 | .skip-if-branch { 106 | display: none; 107 | margin-right: 10px; 108 | position: relative; 109 | padding: 0 4px; 110 | background: #ccc; 111 | color: white; 112 | } 113 | .missing-if-branch .typ, .skip-if-branch .typ { 114 | color: inherit !important; 115 | } 116 | .coverage-summary { 117 | border-collapse: collapse; 118 | width: 100%; 119 | } 120 | .coverage-summary tr { border-bottom: 1px solid #bbb; } 121 | .keyline-all { border: 1px solid #ddd; } 122 | .coverage-summary td, .coverage-summary th { padding: 10px; } 123 | .coverage-summary tbody { border: 1px solid #bbb; } 124 | .coverage-summary td { border-right: 1px solid #bbb; } 125 | .coverage-summary td:last-child { border-right: none; } 126 | .coverage-summary th { 127 | text-align: left; 128 | font-weight: normal; 129 | white-space: nowrap; 130 | } 131 | .coverage-summary th.file { border-right: none !important; } 132 | .coverage-summary th.pct { } 133 | .coverage-summary th.pic, 134 | .coverage-summary th.abs, 135 | .coverage-summary td.pct, 136 | .coverage-summary td.abs { text-align: right; } 137 | .coverage-summary td.file { white-space: nowrap; } 138 | .coverage-summary td.pic { min-width: 120px !important; } 139 | .coverage-summary tfoot td { } 140 | 141 | .coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | .coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | .coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | .status-line { height: 10px; } 155 | /* yellow */ 156 | .cbranch-no { background: yellow !important; color: #111; } 157 | /* dark red */ 158 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } 159 | .low .chart { border:1px solid #C21F39 } 160 | .highlighted, 161 | .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ 162 | background: #C21F39 !important; 163 | } 164 | /* medium red */ 165 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } 166 | /* light red */ 167 | .low, .cline-no { background:#FCE1E5 } 168 | /* light green */ 169 | .high, .cline-yes { background:rgb(230,245,208) } 170 | /* medium green */ 171 | .cstat-yes { background:rgb(161,215,106) } 172 | /* dark green */ 173 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) } 174 | .high .chart { border:1px solid rgb(77,146,33) } 175 | /* dark yellow (gold) */ 176 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; } 177 | .medium .chart { border:1px solid #f9cd0b; } 178 | /* light yellow */ 179 | .medium { background: #fff4c2; } 180 | 181 | .cstat-skip { background: #ddd; color: #111; } 182 | .fstat-skip { background: #ddd; color: #111 !important; } 183 | .cbranch-skip { background: #ddd !important; color: #111; } 184 | 185 | span.cline-neutral { background: #eaeaea; } 186 | 187 | .coverage-summary td.empty { 188 | opacity: .5; 189 | padding-top: 4px; 190 | padding-bottom: 4px; 191 | line-height: 1; 192 | color: #888; 193 | } 194 | 195 | .cover-fill, .cover-empty { 196 | display:inline-block; 197 | height: 12px; 198 | } 199 | .chart { 200 | line-height: 0; 201 | } 202 | .cover-empty { 203 | background: white; 204 | } 205 | .cover-full { 206 | border-right: none !important; 207 | } 208 | pre.prettyprint { 209 | border: none !important; 210 | padding: 0 !important; 211 | margin: 0 !important; 212 | } 213 | .com { color: #999 !important; } 214 | .ignore-none { color: #999; font-weight: normal; } 215 | 216 | .wrapper { 217 | min-height: 100%; 218 | height: auto !important; 219 | height: 100%; 220 | margin: 0 auto -48px; 221 | } 222 | .footer, .push { 223 | height: 48px; 224 | } 225 | -------------------------------------------------------------------------------- /coverage/lcov-report/block-navigation.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var jumpToCode = (function init() { 3 | // Classes of code we would like to highlight in the file view 4 | var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; 5 | 6 | // Elements to highlight in the file listing view 7 | var fileListingElements = ['td.pct.low']; 8 | 9 | // We don't want to select elements that are direct descendants of another match 10 | var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` 11 | 12 | // Selecter that finds elements on the page to which we can jump 13 | var selector = 14 | fileListingElements.join(', ') + 15 | ', ' + 16 | notSelector + 17 | missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` 18 | 19 | // The NodeList of matching elements 20 | var missingCoverageElements = document.querySelectorAll(selector); 21 | 22 | var currentIndex; 23 | 24 | function toggleClass(index) { 25 | missingCoverageElements 26 | .item(currentIndex) 27 | .classList.remove('highlighted'); 28 | missingCoverageElements.item(index).classList.add('highlighted'); 29 | } 30 | 31 | function makeCurrent(index) { 32 | toggleClass(index); 33 | currentIndex = index; 34 | missingCoverageElements.item(index).scrollIntoView({ 35 | behavior: 'smooth', 36 | block: 'center', 37 | inline: 'center' 38 | }); 39 | } 40 | 41 | function goToPrevious() { 42 | var nextIndex = 0; 43 | if (typeof currentIndex !== 'number' || currentIndex === 0) { 44 | nextIndex = missingCoverageElements.length - 1; 45 | } else if (missingCoverageElements.length > 1) { 46 | nextIndex = currentIndex - 1; 47 | } 48 | 49 | makeCurrent(nextIndex); 50 | } 51 | 52 | function goToNext() { 53 | var nextIndex = 0; 54 | 55 | if ( 56 | typeof currentIndex === 'number' && 57 | currentIndex < missingCoverageElements.length - 1 58 | ) { 59 | nextIndex = currentIndex + 1; 60 | } 61 | 62 | makeCurrent(nextIndex); 63 | } 64 | 65 | return function jump(event) { 66 | if ( 67 | document.getElementById('fileSearch') === document.activeElement && 68 | document.activeElement != null 69 | ) { 70 | // if we're currently focused on the search input, we don't want to navigate 71 | return; 72 | } 73 | 74 | switch (event.which) { 75 | case 78: // n 76 | case 74: // j 77 | goToNext(); 78 | break; 79 | case 66: // b 80 | case 75: // k 81 | case 80: // p 82 | goToPrevious(); 83 | break; 84 | } 85 | }; 86 | })(); 87 | window.addEventListener('keydown', jumpToCode); 88 | -------------------------------------------------------------------------------- /coverage/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/coverage/lcov-report/favicon.png -------------------------------------------------------------------------------- /coverage/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for All files 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files

23 |
24 | 25 |
26 | 61.53% 27 | Statements 28 | 64/104 29 |
30 | 31 | 32 |
33 | 32.14% 34 | Branches 35 | 9/28 36 |
37 | 38 | 39 |
40 | 44.11% 41 | Functions 42 | 15/34 43 |
44 | 45 | 46 |
47 | 61.16% 48 | Lines 49 | 63/103 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
FileStatementsBranchesFunctionsLines
components 84 |
85 |
71.66%43/6050%9/1860%12/2071.18%42/59
utils 99 |
100 |
47.72%21/440%0/1021.42%3/1447.72%21/44
113 |
114 |
115 |
116 | 121 | 122 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /coverage/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /coverage/lcov-report/prettify.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /coverage/lcov-report/sorter.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var addSorting = (function() { 3 | 'use strict'; 4 | var cols, 5 | currentSort = { 6 | index: 0, 7 | desc: false 8 | }; 9 | 10 | // returns the summary table element 11 | function getTable() { 12 | return document.querySelector('.coverage-summary'); 13 | } 14 | // returns the thead element of the summary table 15 | function getTableHeader() { 16 | return getTable().querySelector('thead tr'); 17 | } 18 | // returns the tbody element of the summary table 19 | function getTableBody() { 20 | return getTable().querySelector('tbody'); 21 | } 22 | // returns the th element for nth column 23 | function getNthColumn(n) { 24 | return getTableHeader().querySelectorAll('th')[n]; 25 | } 26 | 27 | function onFilterInput() { 28 | const searchValue = document.getElementById('fileSearch').value; 29 | const rows = document.getElementsByTagName('tbody')[0].children; 30 | for (let i = 0; i < rows.length; i++) { 31 | const row = rows[i]; 32 | if ( 33 | row.textContent 34 | .toLowerCase() 35 | .includes(searchValue.toLowerCase()) 36 | ) { 37 | row.style.display = ''; 38 | } else { 39 | row.style.display = 'none'; 40 | } 41 | } 42 | } 43 | 44 | // loads the search box 45 | function addSearchBox() { 46 | var template = document.getElementById('filterTemplate'); 47 | var templateClone = template.content.cloneNode(true); 48 | templateClone.getElementById('fileSearch').oninput = onFilterInput; 49 | template.parentElement.appendChild(templateClone); 50 | } 51 | 52 | // loads all columns 53 | function loadColumns() { 54 | var colNodes = getTableHeader().querySelectorAll('th'), 55 | colNode, 56 | cols = [], 57 | col, 58 | i; 59 | 60 | for (i = 0; i < colNodes.length; i += 1) { 61 | colNode = colNodes[i]; 62 | col = { 63 | key: colNode.getAttribute('data-col'), 64 | sortable: !colNode.getAttribute('data-nosort'), 65 | type: colNode.getAttribute('data-type') || 'string' 66 | }; 67 | cols.push(col); 68 | if (col.sortable) { 69 | col.defaultDescSort = col.type === 'number'; 70 | colNode.innerHTML = 71 | colNode.innerHTML + ''; 72 | } 73 | } 74 | return cols; 75 | } 76 | // attaches a data attribute to every tr element with an object 77 | // of data values keyed by column name 78 | function loadRowData(tableRow) { 79 | var tableCols = tableRow.querySelectorAll('td'), 80 | colNode, 81 | col, 82 | data = {}, 83 | i, 84 | val; 85 | for (i = 0; i < tableCols.length; i += 1) { 86 | colNode = tableCols[i]; 87 | col = cols[i]; 88 | val = colNode.getAttribute('data-value'); 89 | if (col.type === 'number') { 90 | val = Number(val); 91 | } 92 | data[col.key] = val; 93 | } 94 | return data; 95 | } 96 | // loads all row data 97 | function loadData() { 98 | var rows = getTableBody().querySelectorAll('tr'), 99 | i; 100 | 101 | for (i = 0; i < rows.length; i += 1) { 102 | rows[i].data = loadRowData(rows[i]); 103 | } 104 | } 105 | // sorts the table using the data for the ith column 106 | function sortByIndex(index, desc) { 107 | var key = cols[index].key, 108 | sorter = function(a, b) { 109 | a = a.data[key]; 110 | b = b.data[key]; 111 | return a < b ? -1 : a > b ? 1 : 0; 112 | }, 113 | finalSorter = sorter, 114 | tableBody = document.querySelector('.coverage-summary tbody'), 115 | rowNodes = tableBody.querySelectorAll('tr'), 116 | rows = [], 117 | i; 118 | 119 | if (desc) { 120 | finalSorter = function(a, b) { 121 | return -1 * sorter(a, b); 122 | }; 123 | } 124 | 125 | for (i = 0; i < rowNodes.length; i += 1) { 126 | rows.push(rowNodes[i]); 127 | tableBody.removeChild(rowNodes[i]); 128 | } 129 | 130 | rows.sort(finalSorter); 131 | 132 | for (i = 0; i < rows.length; i += 1) { 133 | tableBody.appendChild(rows[i]); 134 | } 135 | } 136 | // removes sort indicators for current column being sorted 137 | function removeSortIndicators() { 138 | var col = getNthColumn(currentSort.index), 139 | cls = col.className; 140 | 141 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 142 | col.className = cls; 143 | } 144 | // adds sort indicators for current column being sorted 145 | function addSortIndicators() { 146 | getNthColumn(currentSort.index).className += currentSort.desc 147 | ? ' sorted-desc' 148 | : ' sorted'; 149 | } 150 | // adds event listeners for all sorter widgets 151 | function enableUI() { 152 | var i, 153 | el, 154 | ithSorter = function ithSorter(i) { 155 | var col = cols[i]; 156 | 157 | return function() { 158 | var desc = col.defaultDescSort; 159 | 160 | if (currentSort.index === i) { 161 | desc = !currentSort.desc; 162 | } 163 | sortByIndex(i, desc); 164 | removeSortIndicators(); 165 | currentSort.index = i; 166 | currentSort.desc = desc; 167 | addSortIndicators(); 168 | }; 169 | }; 170 | for (i = 0; i < cols.length; i += 1) { 171 | if (cols[i].sortable) { 172 | // add the click event handler on the th so users 173 | // dont have to click on those tiny arrows 174 | el = getNthColumn(i).querySelector('.sorter').parentElement; 175 | if (el.addEventListener) { 176 | el.addEventListener('click', ithSorter(i)); 177 | } else { 178 | el.attachEvent('onclick', ithSorter(i)); 179 | } 180 | } 181 | } 182 | } 183 | // adds sorting functionality to the UI 184 | return function() { 185 | if (!getTable()) { 186 | return; 187 | } 188 | cols = loadColumns(); 189 | loadData(); 190 | addSearchBox(); 191 | addSortIndicators(); 192 | enableUI(); 193 | }; 194 | })(); 195 | 196 | window.addEventListener('load', addSorting); 197 | -------------------------------------------------------------------------------- /coverage/lcov-report/sum.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for sum.js 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files sum.js

23 |
24 | 25 |
26 | 100% 27 | Statements 28 | 3/3 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 0/0 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 1/1 43 |
44 | 45 | 46 |
47 | 100% 48 | Lines 49 | 3/3 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 | 63 |
64 |
65 |

66 | 
1 67 | 2 68 | 3 69 | 4 70 | 51x 71 | 1x 72 | 1x 73 |   74 |  
export const sum = (a, b) => {
75 |     console.log(a + b);
76 |     return a + b;
77 |   };
78 |  
79 | 80 |
81 |
82 | 87 | 88 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /coverage/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:src/components/Header.js 3 | FN:17,(anonymous_0) 4 | FN:23,(anonymous_1) 5 | FN:44,(anonymous_2) 6 | FN:66,(anonymous_3) 7 | FN:73,(anonymous_4) 8 | FN:83,(anonymous_5) 9 | FN:88,(anonymous_6) 10 | FN:92,(anonymous_7) 11 | FN:133,(anonymous_8) 12 | FN:161,(anonymous_9) 13 | FN:170,(anonymous_10) 14 | FN:190,(anonymous_11) 15 | FN:207,(anonymous_12) 16 | FN:216,(anonymous_13) 17 | FNF:14 18 | FNH:8 19 | FNDA:8,(anonymous_0) 20 | FNDA:8,(anonymous_1) 21 | FNDA:2,(anonymous_2) 22 | FNDA:0,(anonymous_3) 23 | FNDA:1,(anonymous_4) 24 | FNDA:0,(anonymous_5) 25 | FNDA:0,(anonymous_6) 26 | FNDA:5,(anonymous_7) 27 | FNDA:32,(anonymous_8) 28 | FNDA:1,(anonymous_9) 29 | FNDA:1,(anonymous_10) 30 | FNDA:0,(anonymous_11) 31 | FNDA:0,(anonymous_12) 32 | FNDA:0,(anonymous_13) 33 | DA:17,1 34 | DA:18,8 35 | DA:19,8 36 | DA:21,8 37 | DA:22,8 38 | DA:23,8 39 | DA:25,8 40 | DA:44,8 41 | DA:45,2 42 | DA:46,2 43 | DA:47,2 44 | DA:50,2 45 | DA:51,2 46 | DA:52,0 47 | DA:53,0 48 | DA:56,0 49 | DA:57,0 50 | DA:59,2 51 | DA:60,2 52 | DA:65,8 53 | DA:67,0 54 | DA:68,0 55 | DA:69,0 56 | DA:73,8 57 | DA:74,1 58 | DA:75,1 59 | DA:76,1 60 | DA:78,0 61 | DA:83,8 62 | DA:84,0 63 | DA:88,8 64 | DA:89,0 65 | DA:92,8 66 | DA:93,5 67 | DA:94,2 68 | DA:95,2 69 | DA:98,8 70 | DA:134,32 71 | DA:162,1 72 | DA:170,1 73 | DA:191,0 74 | DA:208,0 75 | DA:216,0 76 | LF:43 77 | LH:30 78 | BRDA:52,0,0,0 79 | BRDA:52,0,1,0 80 | BRDA:74,1,0,1 81 | BRDA:74,1,1,0 82 | BRDA:93,2,0,2 83 | BRDA:93,2,1,3 84 | BRDA:123,3,0,8 85 | BRDA:123,3,1,8 86 | BRDA:158,4,0,6 87 | BRDA:158,4,1,2 88 | BRDA:178,5,0,8 89 | BRDA:178,5,1,0 90 | BRDA:204,6,0,0 91 | BRDA:204,6,1,0 92 | BRF:14 93 | BRH:8 94 | end_of_record 95 | TN: 96 | SF:src/components/ScrollToTop.js 97 | FN:4,(anonymous_0) 98 | FN:7,(anonymous_1) 99 | FN:8,(anonymous_2) 100 | FN:18,(anonymous_3) 101 | FN:23,(anonymous_4) 102 | FNF:5 103 | FNH:3 104 | FNDA:8,(anonymous_0) 105 | FNDA:5,(anonymous_1) 106 | FNDA:0,(anonymous_2) 107 | FNDA:5,(anonymous_3) 108 | FNDA:0,(anonymous_4) 109 | DA:4,1 110 | DA:5,8 111 | DA:7,8 112 | DA:8,5 113 | DA:9,0 114 | DA:10,0 115 | DA:12,0 116 | DA:16,5 117 | DA:18,5 118 | DA:19,5 119 | DA:23,8 120 | DA:24,0 121 | DA:30,8 122 | LF:13 123 | LH:9 124 | BRDA:9,0,0,0 125 | BRDA:9,0,1,0 126 | BRDA:33,1,0,0 127 | BRDA:33,1,1,8 128 | BRF:4 129 | BRH:1 130 | end_of_record 131 | TN: 132 | SF:src/components/sum.js 133 | FN:1,(anonymous_0) 134 | FNF:1 135 | FNH:1 136 | FNDA:1,(anonymous_0) 137 | DA:1,1 138 | DA:2,1 139 | DA:3,1 140 | LF:3 141 | LH:3 142 | BRF:0 143 | BRH:0 144 | end_of_record 145 | TN: 146 | SF:src/utils/cartSlice.js 147 | FN:10,(anonymous_0) 148 | FN:13,(anonymous_1) 149 | FN:25,(anonymous_2) 150 | FN:27,(anonymous_3) 151 | FN:33,(anonymous_4) 152 | FN:35,(anonymous_5) 153 | FN:41,(anonymous_6) 154 | FN:43,(anonymous_7) 155 | FN:49,(anonymous_8) 156 | FNF:9 157 | FNH:0 158 | FNDA:0,(anonymous_0) 159 | FNDA:0,(anonymous_1) 160 | FNDA:0,(anonymous_2) 161 | FNDA:0,(anonymous_3) 162 | FNDA:0,(anonymous_4) 163 | FNDA:0,(anonymous_5) 164 | FNDA:0,(anonymous_6) 165 | FNDA:0,(anonymous_7) 166 | FNDA:0,(anonymous_8) 167 | DA:3,1 168 | DA:12,0 169 | DA:13,0 170 | DA:15,0 171 | DA:16,0 172 | DA:17,0 173 | DA:18,0 174 | DA:20,0 175 | DA:23,0 176 | DA:26,0 177 | DA:27,0 178 | DA:29,0 179 | DA:30,0 180 | DA:34,0 181 | DA:35,0 182 | DA:37,0 183 | DA:38,0 184 | DA:42,0 185 | DA:43,0 186 | DA:45,0 187 | DA:46,0 188 | DA:50,0 189 | DA:61,1 190 | LF:23 191 | LH:2 192 | BRDA:16,0,0,0 193 | BRDA:16,0,1,0 194 | BRDA:29,1,0,0 195 | BRDA:29,1,1,0 196 | BRDA:37,2,0,0 197 | BRDA:37,2,1,0 198 | BRDA:37,3,0,0 199 | BRDA:37,3,1,0 200 | BRDA:45,4,0,0 201 | BRDA:45,4,1,0 202 | BRF:10 203 | BRH:0 204 | end_of_record 205 | TN: 206 | SF:src/utils/constants.js 207 | FNF:0 208 | FNH:0 209 | DA:2,1 210 | DA:5,1 211 | DA:8,1 212 | DA:11,1 213 | LF:4 214 | LH:4 215 | BRF:0 216 | BRH:0 217 | end_of_record 218 | TN: 219 | SF:src/utils/store.js 220 | FN:29,(anonymous_0) 221 | FNF:1 222 | FNH:1 223 | FNDA:1,(anonymous_0) 224 | DA:16,1 225 | DA:21,1 226 | DA:25,1 227 | DA:27,1 228 | DA:29,1 229 | DA:36,1 230 | LF:6 231 | LH:6 232 | BRF:0 233 | BRH:0 234 | end_of_record 235 | TN: 236 | SF:src/utils/useOnline.js 237 | FN:3,(anonymous_0) 238 | FN:5,(anonymous_1) 239 | FN:6,(anonymous_2) 240 | FN:9,(anonymous_3) 241 | FNF:4 242 | FNH:2 243 | FNDA:8,(anonymous_0) 244 | FNDA:5,(anonymous_1) 245 | FNDA:0,(anonymous_2) 246 | FNDA:0,(anonymous_3) 247 | DA:3,1 248 | DA:4,8 249 | DA:5,8 250 | DA:6,5 251 | DA:7,0 252 | DA:9,5 253 | DA:10,0 254 | DA:12,5 255 | DA:13,5 256 | DA:16,8 257 | LF:10 258 | LH:8 259 | BRF:0 260 | BRH:0 261 | end_of_record 262 | TN: 263 | SF:src/utils/userContext.js 264 | FNF:0 265 | FNH:0 266 | DA:3,1 267 | LF:1 268 | LH:1 269 | BRF:0 270 | BRH:0 271 | end_of_record 272 | -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @keyframes wiggle-scale { 6 | 0% { 7 | transform: rotate(-10deg) scale(1); 8 | } 9 | 25% { 10 | transform: scale(1.5); 11 | } 12 | 50% { 13 | transform: rotate(10deg) scale(0.9); 14 | } 15 | 75% { 16 | transform: scale(1.1); 17 | } 18 | 100% { 19 | transform: rotate(-10deg) scale(1); 20 | } 21 | } 22 | 23 | .wiggle-scale { 24 | animation: wiggle-scale 500ms ease-in-out; 25 | } 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | Hungry Hero 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * For a detailed explanation regarding each configuration property, visit: 3 | * https://jestjs.io/docs/configuration 4 | */ 5 | 6 | module.exports = { 7 | // All imported modules in your tests should be mocked automatically 8 | // automock: false, 9 | 10 | // Stop running tests after `n` failures 11 | // bail: 0, 12 | 13 | // The directory where Jest should store its cached dependency information 14 | // cacheDirectory: "/private/var/folders/gt/wftdk9cd69xgmgn_mx8g7_cm0000gn/T/jest_dx", 15 | 16 | // Automatically clear mock calls, instances, contexts and results before every test 17 | clearMocks: true, 18 | 19 | // Indicates whether the coverage information should be collected while executing the test 20 | collectCoverage: true, 21 | 22 | // An array of glob patterns indicating a set of files for which coverage information should be collected 23 | // collectCoverageFrom: undefined, 24 | 25 | // The directory where Jest should output its coverage files 26 | coverageDirectory: "coverage", 27 | 28 | // An array of regexp pattern strings used to skip coverage collection 29 | // coveragePathIgnorePatterns: [ 30 | // "/node_modules/" 31 | // ], 32 | 33 | // Indicates which provider should be used to instrument code for coverage 34 | // coverageProvider: "babel", 35 | 36 | // A list of reporter names that Jest uses when writing coverage reports 37 | // coverageReporters: [ 38 | // "json", 39 | // "text", 40 | // "lcov", 41 | // "clover" 42 | // ], 43 | 44 | // An object that configures minimum threshold enforcement for coverage results 45 | // coverageThreshold: undefined, 46 | 47 | // A path to a custom dependency extractor 48 | // dependencyExtractor: undefined, 49 | 50 | // Make calling deprecated APIs throw helpful error messages 51 | // errorOnDeprecated: false, 52 | 53 | // The default configuration for fake timers 54 | // fakeTimers: { 55 | // "enableGlobally": false 56 | // }, 57 | 58 | // Force coverage collection from ignored files using an array of glob patterns 59 | // forceCoverageMatch: [], 60 | 61 | // A path to a module which exports an async function that is triggered once before all test suites 62 | // globalSetup: undefined, 63 | 64 | // A path to a module which exports an async function that is triggered once after all test suites 65 | // globalTeardown: undefined, 66 | 67 | // A set of global variables that need to be available in all test environments 68 | // globals: {}, 69 | 70 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. 71 | // maxWorkers: "50%", 72 | 73 | // An array of directory names to be searched recursively up from the requiring module's location 74 | // moduleDirectories: [ 75 | // "node_modules" 76 | // ], 77 | 78 | // An array of file extensions your modules use 79 | // moduleFileExtensions: [ 80 | // "js", 81 | // "mjs", 82 | // "cjs", 83 | // "jsx", 84 | // "ts", 85 | // "tsx", 86 | // "json", 87 | // "node" 88 | // ], 89 | 90 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module 91 | // moduleNameMapper: { 92 | // "\\.(css|less)$": "../utils/index.css", 93 | // }, 94 | 95 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 96 | // modulePathIgnorePatterns: [], 97 | 98 | // Activates notifications for test results 99 | // notify: false, 100 | 101 | // An enum that specifies notification mode. Requires { notify: true } 102 | // notifyMode: "failure-change", 103 | 104 | // A preset that is used as a base for Jest's configuration 105 | // preset: undefined, 106 | 107 | // Run tests from one or more projects 108 | // projects: undefined, 109 | 110 | // Use this configuration option to add custom reporters to Jest 111 | // reporters: undefined, 112 | 113 | // Automatically reset mock state before every test 114 | // resetMocks: false, 115 | 116 | // Reset the module registry before running each individual test 117 | // resetModules: false, 118 | 119 | // A path to a custom resolver 120 | // resolver: undefined, 121 | 122 | // Automatically restore mock state and implementation before every test 123 | // restoreMocks: false, 124 | 125 | // The root directory that Jest should scan for tests and modules within 126 | // rootDir: undefined, 127 | 128 | // A list of paths to directories that Jest should use to search for files in 129 | // roots: [ 130 | // "" 131 | // ], 132 | 133 | // Allows you to use a custom runner instead of Jest's default test runner 134 | // runner: "jest-runner", 135 | 136 | // The paths to modules that run some code to configure or set up the testing environment before each test 137 | // setupFiles: [], 138 | 139 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 140 | // setupFilesAfterEnv: [], 141 | 142 | // The number of seconds after which a test is considered as slow and reported as such in the results. 143 | // slowTestThreshold: 5, 144 | 145 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 146 | // snapshotSerializers: [], 147 | 148 | // The test environment that will be used for testing 149 | testEnvironment: "jsdom", 150 | 151 | // Options that will be passed to the testEnvironment 152 | // testEnvironmentOptions: {}, 153 | 154 | // Adds a location field to test results 155 | // testLocationInResults: false, 156 | 157 | // The glob patterns Jest uses to detect test files 158 | // testMatch: [ 159 | // "**/__tests__/**/*.[jt]s?(x)", 160 | // "**/?(*.)+(spec|test).[tj]s?(x)" 161 | // ], 162 | 163 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 164 | // testPathIgnorePatterns: [ 165 | // "/node_modules/" 166 | // ], 167 | 168 | // The regexp pattern or array of patterns that Jest uses to detect test files 169 | // testRegex: [], 170 | 171 | // This option allows the use of a custom results processor 172 | // testResultsProcessor: undefined, 173 | 174 | // This option allows use of a custom test runner 175 | // testRunner: "jest-circus/runner", 176 | 177 | // A map from regular expressions to paths to transformers 178 | // transform: undefined, 179 | 180 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 181 | // transformIgnorePatterns: [ 182 | // "/node_modules/", 183 | // "\\.pnp\\.[^\\/]+$" 184 | // ], 185 | 186 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 187 | // unmockedModulePathPatterns: undefined, 188 | 189 | // Indicates whether each individual test should be reported during the run 190 | // verbose: undefined, 191 | 192 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 193 | // watchPathIgnorePatterns: [], 194 | 195 | // Whether to use watchman for file crawling 196 | // watchman: true, 197 | }; 198 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "namaste-react", 3 | "version": "1.0.0", 4 | "description": "React project ", 5 | "scripts": { 6 | "start": "parcel index.html", 7 | "build": "parcel build index.html", 8 | "test": "jest", 9 | "watch-test": "jest --watch" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/Anandsg/Namaste-react.git" 14 | }, 15 | "author": "Anand", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/Anandsg/Namaste-react/issues" 19 | }, 20 | "homepage": "https://github.com/Anandsg/Namaste-react#readme", 21 | "dependencies": { 22 | "@emotion/react": "^11.11.0", 23 | "@emotion/styled": "^11.11.0", 24 | "@fortawesome/fontawesome-svg-core": "^6.4.0", 25 | "@fortawesome/free-solid-svg-icons": "^6.4.0", 26 | "@fortawesome/react-fontawesome": "^0.2.0", 27 | "@mui/icons-material": "^5.11.16", 28 | "@mui/material": "^5.13.1", 29 | "@react-oauth/google": "^0.11.1", 30 | "@reduxjs/toolkit": "^1.9.5", 31 | "@types/react": "^18.2.6", 32 | "autoprefixer": "^9.8.8", 33 | "lodash": "^4.17.21", 34 | "postcss": "^7.0.39", 35 | "prop-types": "^15.8.1", 36 | "react": "^18.2.0", 37 | "react-bootstrap": "^2.7.4", 38 | "react-collapsible": "^2.10.0", 39 | "react-dom": "^18.2.0", 40 | "react-hot-toast": "^2.4.1", 41 | "react-icons": "^4.8.0", 42 | "react-loading-skeleton": "^3.3.1", 43 | "react-redux": "^8.0.5", 44 | "react-router-dom": "^6.10.0", 45 | "react-type-animation": "^3.0.1", 46 | "redux-persist": "^6.0.0", 47 | "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17" 48 | }, 49 | "devDependencies": { 50 | "@babel/core": "^7.0.0-0", 51 | "@babel/preset-env": "^7.22.20", 52 | "@babel/preset-react": "^7.22.15", 53 | "@testing-library/dom": "^9.3.0", 54 | "@testing-library/react": "^14.0.0", 55 | "babel-jest": "^29.5.0", 56 | "jest": "^29.5.0", 57 | "jest-environment-jsdom": "^29.5.0", 58 | "parcel-bundler": "^1.12.5" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { "targets": { "node": "current" } }], 4 | ["@babel/preset-react", { "runtime": "automatic"}] 5 | ] 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import ReactDOM from "react-dom/client"; 2 | import Body from "./components/Body"; 3 | import About from "./components/About"; 4 | import Error from "./components/Error"; 5 | import { 6 | createBrowserRouter, 7 | RouterProvider, 8 | createRoutesFromElements, 9 | Route, 10 | } from "react-router-dom"; 11 | import Contact from "./components/Contact"; 12 | import RestruarantMenu from "./components/RestaurantMenu"; 13 | import Help from "./components/Help"; 14 | import Cart from "./components/Cart"; 15 | import AppLayout from "./components/AppLayout"; 16 | import { GoogleOAuthProvider } from "@react-oauth/google"; 17 | 18 | const appRouter = createBrowserRouter( 19 | createRoutesFromElements( 20 | 27 | 28 | 29 | } 30 | errorElement={} 31 | > 32 | } /> 33 | } /> 34 | } /> 35 | } /> 36 | } /> 37 | } /> 38 | 39 | ) 40 | ); 41 | 42 | const root = ReactDOM.createRoot(document.getElementById("root")); 43 | 44 | root.render(); 45 | -------------------------------------------------------------------------------- /src/assets/Cook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/Cook.jpg -------------------------------------------------------------------------------- /src/assets/Empty-fav-tab-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/Empty-fav-tab-img.png -------------------------------------------------------------------------------- /src/assets/arrow-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/arrow-icon.png -------------------------------------------------------------------------------- /src/assets/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/avatar.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/ramen-restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anandsg/Hungry-hero/25d0ad653edb72bea4913b32c2dbc82a31a26e31/src/assets/ramen-restaurant.jpg -------------------------------------------------------------------------------- /src/components/About.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FaLinkedin, FaInstagram } from "react-icons/fa"; 3 | 4 | const About = () => { 5 | return ( 6 |
7 |
8 |

9 | About Our Platform 10 |

11 |

12 | Our platform is dedicated to providing the best food delivery 13 | experience. We're passionate about delivering your favorite restaurant 14 | meals right to your doorstep. Our team of Frontend Developers are 15 | committed to creating a top-notch online food delivery platform that 16 | combines artistic creativity with technical excellence. 17 |

18 |

19 | We believe in the power of open-source collaboration. Our app is open 20 | for contributions from developers like you. You can contribute in any 21 | way, whether it's improving code, suggesting features, or helping us 22 | enhance the user experience. Join us in making our platform even 23 | better! 24 |

25 | 43 |
44 |
45 | ); 46 | }; 47 | 48 | export default About; 49 | -------------------------------------------------------------------------------- /src/components/AppLayout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Outlet } from "react-router-dom"; 3 | import Header from "./Header"; 4 | import Footer from "./Footer"; 5 | import { Provider } from "react-redux"; 6 | import { persistor, store } from "../utils/store"; 7 | import { PersistGate } from "redux-persist/integration/react"; 8 | import useOnline from "../utils/useOnline"; 9 | import Offline from "./Offline"; 10 | 11 | const AppLayout = () => { 12 | const isOnline = useOnline(); 13 | return ( 14 |
15 | {isOnline ? ( 16 | 17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 | 26 | 27 | ) : ( 28 | 29 | )} 30 |
31 | ); 32 | }; 33 | 34 | export default AppLayout; 35 | -------------------------------------------------------------------------------- /src/components/Body.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import RestruarantCards from "./RestruarantCards"; 3 | import { useState, useEffect } from "react"; 4 | import Shimmer from "./Shimmer"; 5 | import { filterData } from "../utils/helper"; 6 | import { GrNotification } from "react-icons/gr"; 7 | import { faArrowLeft } from "@fortawesome/free-solid-svg-icons"; 8 | import EmptyFavTab from "../assets/Empty-fav-tab-img.png"; 9 | import RamenRestaurant from "../assets/ramen-restaurant.jpg"; 10 | import ArrowIcon from "../assets/arrow-icon.png"; 11 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 12 | import { useFocus } from "../utils/useFocus"; 13 | 14 | const Body = () => { 15 | const [listOfRestaurants, setListOfRestaurants] = useState([]); 16 | const [filteredListOfRestaurants, setFilteredListOfRestaurants] = useState( 17 | [] 18 | ); 19 | let [favlist, setFavList] = useState([]); 20 | const [showFav, setShowFav] = useState(false); 21 | const [showBackBtn, setShowBackBtn] = useState(false); 22 | const [showFitler, setShowFitler] = useState(false); 23 | const [searchText, setSearchText] = useState(""); 24 | const [message, setMessage] = useState(null); 25 | const [favourites, setFavourites] = useState([]); 26 | 27 | // focus hook 28 | const [focusElement, setFocusElement] = useFocus(); 29 | 30 | useEffect(() => { 31 | // Fetch API 32 | getRestaurants(); 33 | }, []); 34 | 35 | useEffect(() => { 36 | initiateSearch(); 37 | }, [searchText]); 38 | 39 | //Search function 40 | function initiateSearch() { 41 | setShowFav(false); 42 | setShowFitler(false); 43 | let searchList = showFav ? favourites : listOfRestaurants; 44 | if (searchText === "") { 45 | setFilteredListOfRestaurants(searchList); 46 | } else { 47 | const data = filterData(searchText, searchList); 48 | 49 | setFilteredListOfRestaurants(data); 50 | 51 | //Check for toggling Searchbar back button 52 | searchText !== "" ? setShowBackBtn(true) : setShowBackBtn(false); 53 | 54 | if (data.length === 0 && searchText !== "") { 55 | setFilteredListOfRestaurants([]); 56 | } 57 | } 58 | } 59 | 60 | //Reset to default on Back button press 61 | function handleBackBtn() { 62 | setSearchText(""); 63 | setFilteredListOfRestaurants(listOfRestaurants); 64 | setShowFitler(false); 65 | setShowBackBtn(false); 66 | } 67 | 68 | //Listening to Enter key press 69 | const handleKeyUp = (e) => { 70 | //Check if keypressed is enter key (key code 13) 71 | if (e.keyCode === 13) { 72 | initiateSearch(); 73 | } 74 | }; 75 | 76 | async function getRestaurants() { 77 | const data = await fetch( 78 | "https://thingproxy.freeboard.io/fetch/https://www.swiggy.com/dapi/restaurants/list/v5?lat=12.9715987&lng=77.5945627&is-seo-homepage-enabled=true&page_type=DESKTOP_WEB_LISTING" 79 | ); 80 | const json = await data.json(); 81 | // console.log(json); 82 | setListOfRestaurants( 83 | json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants 84 | ); 85 | setFilteredListOfRestaurants( 86 | json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants 87 | ); 88 | // console.log( 89 | // json?.data?.cards[1]?.card?.card?.gridElements?.infoWithStyle?.restaurants 90 | // ); 91 | } 92 | 93 | const handleClick = () => { 94 | getRestaurants(); 95 | setShowFav(false); 96 | }; 97 | 98 | const onClickFav = (id) => { 99 | let idx = favlist.indexOf(id); 100 | if (idx >= 0) { 101 | favlist.splice(idx, 1); 102 | setMessage("Resturant removed from favorite list"); 103 | } else { 104 | favlist.push(id); 105 | setMessage("Resturant added to favorite list"); 106 | } 107 | setFavList(favlist); 108 | setTimeout(() => { 109 | setMessage(null); 110 | }, 2000); 111 | if (showFav) { 112 | setFilteredListOfRestaurants( 113 | filteredListOfRestaurants.filter((it) => it.info.id !== id) 114 | ); 115 | } 116 | }; 117 | // avoid rendering component (Early) 118 | if (!listOfRestaurants) return null; 119 | return listOfRestaurants.length === 0 ? ( 120 | 121 | ) : ( 122 | <> 123 |
124 | {/* searchbar */} 125 | 126 |
127 |
128 |
129 | {searchText.length !== 0 && showBackBtn ? ( 130 | 138 | ) : null} 139 | { 147 | setSearchText(e.target.value); 148 | }} 149 | /> 150 | 151 | 158 |
159 |
160 | { 167 | let filteredList = listOfRestaurants; 168 | if (!showFitler) { 169 | filteredList = listOfRestaurants.filter( 170 | (res) => res.info.avgRating > 4 171 | ); 172 | } 173 | setShowFitler(!showFitler); 174 | setShowFav(false); 175 | setFilteredListOfRestaurants(filteredList); 176 | }} 177 | > 178 | Rating: 4.0+ 179 | 180 | { 187 | let favouriteList = listOfRestaurants; 188 | if (!showFav) { 189 | favouriteList = listOfRestaurants.filter((res) => 190 | favlist.includes(res.info.id) 191 | ); 192 | } 193 | setShowFav(!showFav); 194 | setShowFitler(false); 195 | setFilteredListOfRestaurants(favouriteList); 196 | setFavourites(favouriteList); 197 | }} 198 | > 199 | Favourites 200 | 201 |
202 |
203 |
204 | 205 | {filteredListOfRestaurants?.length === 0 && searchText !== "" && ( 206 |
207 | icon 208 | 209 |

Oops!

210 | 211 |

212 | The restaurant you're searching for doesn't exist. 213 |

214 | 215 | 223 |
224 | )} 225 |
226 |
227 | {filteredListOfRestaurants.length > 0 ? ( 228 |
229 | {filteredListOfRestaurants.map((restaurant) => ( 230 | 237 | ))} 238 |
239 | ) : ( 240 |
241 | {showFav && !searchText && favlist.length === 0 ? ( 242 | <> 243 | icon 244 |
245 | 246 | Find your favourite restaurants now 247 | 248 | 260 |
261 | 262 | ) : null} 263 |
264 | )} 265 |
266 |
267 | {message && ( 268 |
272 | 273 | 274 | 275 | {message} 276 |
277 | )} 278 |
279 | 280 | ); 281 | }; 282 | 283 | export default Body; 284 | -------------------------------------------------------------------------------- /src/components/Cart.js: -------------------------------------------------------------------------------- 1 | import { useDispatch, useSelector } from "react-redux"; 2 | import { clearCart } from "../utils/cartSlice"; 3 | import { Link } from "react-router-dom"; 4 | import cook from "../assets/Cook.jpg"; 5 | import React from "react"; 6 | import CartItem from "./CartItem"; 7 | import OrderSummary from "./OrdarSummery"; 8 | 9 | const Cart = () => { 10 | const cartItems = useSelector((store) => store.cart.items); 11 | const dispatch = useDispatch(); 12 | function HandleClearCart() { 13 | dispatch(clearCart()); 14 | } 15 | 16 | return ( 17 | <> 18 | {cartItems.length > 0 ? ( 19 |
23 |
24 |
25 |
26 |

27 | Cart - {cartItems.length} Items 28 |

29 | 35 |
36 |
37 | {cartItems.map((item) => ( 38 | 39 | ))} 40 |
41 |
42 |
43 | 44 |
45 |
46 |
47 | ) : ( 48 | 49 | )} 50 | 51 | ); 52 | }; 53 | 54 | const EmptyCart = () => { 55 | return ( 56 |
57 | 66 |

67 | Your Cart Is Empty 68 |

69 |

70 | Go to home page for more restaurants 71 |

72 | 73 | {" "} 74 | 77 | 78 |
79 | ); 80 | }; 81 | 82 | export default Cart; 83 | -------------------------------------------------------------------------------- /src/components/CartItem.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { 4 | removeItem, 5 | increaseQuantity, 6 | decreaseQuantity, 7 | } from "../utils/cartSlice"; 8 | import { CDN_URL } from "../utils/constants"; 9 | 10 | const CartItem = ({ 11 | id, 12 | name, 13 | imageId, 14 | defaultPrice, 15 | price, 16 | description, 17 | quantity, 18 | }) => { 19 | const dispatch = useDispatch(); 20 | 21 | function HandleRemoveItem() { 22 | dispatch(removeItem(id)); 23 | } 24 | 25 | function HandleQuantityIncrease() { 26 | dispatch(increaseQuantity(id)); 27 | } 28 | 29 | function HandleQuantityDecrease() { 30 | dispatch(decreaseQuantity(id)); 31 | } 32 | 33 | return ( 34 |
35 |
36 | 46 | 47 |
48 | {name} 49 | 50 | ₹ 51 | {!price 52 | ? Math.round((defaultPrice / 100) * quantity * 100) / 100 53 | : Math.round((price / 100) * quantity * 100) / 100} 54 | 55 | {!price 56 | ? `(${defaultPrice / 100} x ${quantity})` 57 | : `(${price / 100} x ${quantity})`} 58 | 59 | 60 |
61 | {description} 62 |
63 |
64 | 72 | {quantity} 73 | 81 |
82 | 89 |
90 |
91 |
92 |
93 |
94 | ); 95 | }; 96 | 97 | export default CartItem; 98 | -------------------------------------------------------------------------------- /src/components/Contact.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useRef } from "react"; 2 | import React from "react"; 3 | import { useFocus } from "../utils/useFocus"; 4 | 5 | const Contact = () => { 6 | const [name, setName] = useState(""); 7 | const [email, setEmail] = useState(""); 8 | const [msg, setMsg] = useState(""); 9 | const [emailError, setEmailError] = useState(false); 10 | const [nameError, setNameError] = useState(false); 11 | const [msgError, setMsgError] = useState(false); 12 | 13 | // focus hook 14 | const [focusName, setFocusName] = useFocus(); 15 | const [focusEmail, setFocusEmail] = useFocus(); 16 | const [focusMessage, setFocusMessage] = useFocus(); 17 | 18 | //onfocus, onBlur states 19 | const [isFocus, setIsFocus] = useState(false); 20 | const [isBlur, setIsBlur] = useState(false); 21 | 22 | const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/; 23 | const nameRegex = /^[A-Za-z\s'-]+$/; 24 | const allspace = /^\s*$/; 25 | const validateName = (e) => { 26 | setIsFocus(false); 27 | if ( 28 | e.target.value.match(allspace) || 29 | e.target.value.length < 3 || 30 | !e.target.value.match(nameRegex) 31 | ) { 32 | setNameError(true); 33 | } else { 34 | setNameError(false); 35 | } 36 | setName(e.target.value); 37 | }; 38 | 39 | const validateEmail = (e) => { 40 | setIsFocus(false); 41 | if (!e.target.value.match(emailRegex)) { 42 | setEmailError(true); 43 | } else { 44 | setEmailError(false); 45 | } 46 | setEmail(e.target.value); 47 | }; 48 | 49 | const checkMsg = (e) => { 50 | setIsFocus(false); 51 | if (e.target.value == "" || e.target.value.match(allspace)) 52 | setMsgError(true); 53 | else setMsgError(false); 54 | 55 | setMsg(e.target.value); 56 | }; 57 | 58 | const handleSubmitButton = (e) => { 59 | e.preventDefault(); 60 | if (name == "" && email == "" && msg == "") { 61 | setNameError(true); 62 | setEmailError(true); 63 | setMsgError(true); 64 | } 65 | if ( 66 | name != "" && 67 | email != "" && 68 | msg != "" && 69 | !nameError && 70 | !emailError && 71 | !msgError 72 | ) { 73 | alert("Thanks for your submission, we will get back to you soon..."); 74 | setTimeout(() => { 75 | window.location.href = "/"; 76 | }, 1000); 77 | } 78 | }; 79 | const handleClearButton = () => { 80 | setName(""); 81 | setEmail(""); 82 | setMsg(""); 83 | setNameError(false); 84 | setEmailError(false); 85 | setMsgError(false); 86 | }; 87 | 88 | const handleNameKeyUp = (e, targetElem, name, nameError) => { 89 | if (e.key === "Enter" && name != "") { 90 | nameError ? null : targetElem?.current?.focus(); 91 | } 92 | }; 93 | 94 | const handleEmailKeyUp = (e, targetElem, email, emailError) => { 95 | if (e.key === "Enter" && email != "") { 96 | emailError ? null : targetElem?.current?.focus(); 97 | } 98 | }; 99 | 100 | const OnFocusHandler = (e) => { 101 | setIsFocus(true); 102 | setIsBlur(false); 103 | }; 104 | 105 | return ( 106 | <> 107 |
108 |

109 | We're Eager to Receive Your Feedback and Suggestions! 110 |

111 |
115 |
116 | 119 | { 127 | handleNameKeyUp(e, focusEmail, name, nameError); 128 | }} 129 | onChange={(e) => { 130 | const val = e.target.value; 131 | setName(val); 132 | validateName(e); 133 | }} 134 | ref={focusName} 135 | > 136 | {nameError && ( 137 |

138 | Name should not be blank,
must be minimun 3 charcters,{" "} 139 |
integers not allowed 140 |

141 | )} 142 |
143 |
144 | 147 | { 154 | handleEmailKeyUp( 155 | e, 156 | focusMessage, 157 | email, 158 | emailError, 159 | focusEmail 160 | ); 161 | }} 162 | name="userEmail" 163 | onBlur={validateEmail} 164 | onChange={(e) => { 165 | const val = e.target.value; 166 | setEmail(val); 167 | validateEmail(e); 168 | }} 169 | > 170 | {emailError && ( 171 |

172 | Enter a valid email address. 173 |

174 | )} 175 |
176 |
177 | 180 | 190 | {msgError && ( 191 |

192 | Enter a message. 193 |

194 | )} 195 |
196 | 197 |
198 | 205 | 211 |
212 |
213 |
214 | 215 | ); 216 | }; 217 | 218 | export default Contact; 219 | -------------------------------------------------------------------------------- /src/components/Error.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useRouteError } from "react-router-dom"; 3 | 4 | const Error = () => { 5 | const err = useRouteError(); 6 | 7 | return ( 8 |
9 |

Oops!

10 |

there appears to be a glitch.

11 |
12 | ); 13 | }; 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "../utils/index.css"; 3 | 4 | const Footer = () => { 5 | return ( 6 |
7 | Developed with 🧡 and a lot of ☕️ by Anand 8 | 9 | 33 |
34 | ); 35 | }; 36 | 37 | export default Footer; 38 | -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext, useEffect } from "react"; 2 | import { LOGO_URL } from "../utils/constants"; 3 | import { Link, NavLink } from "react-router-dom"; 4 | import useOnline from "../utils/useOnline"; 5 | import UserContext from "../utils/userContext"; 6 | import { useSelector } from "react-redux"; 7 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 8 | import { 9 | faShoppingCart, 10 | faBars, 11 | faTimes, 12 | } from "@fortawesome/free-solid-svg-icons"; 13 | import { HiPhone } from "react-icons/hi"; 14 | import { HiHome, HiBuildingOffice, HiShoppingBag } from "react-icons/hi2"; 15 | import { FaQuestionCircle } from "react-icons/fa"; 16 | 17 | import ScrollToTop from "./ScrollToTop"; 18 | import { useGoogleLogin } from "@react-oauth/google"; 19 | import avatar from "../assets/avatar.png"; 20 | 21 | const Header = () => { 22 | const [isLoggedIn, setisLoggedIn] = useState(true); 23 | const [isMenuOpen, setIsMenuOpen] = useState(false); // Track whether the menu is open 24 | const [isProfileOpen, setisProfileOpen] = useState(false); 25 | const [userInfo, setUserInfo] = useState({ 26 | name: "", 27 | picture: "", 28 | email: "", 29 | }); 30 | 31 | const isOnline = useOnline(); 32 | const { user } = useContext(UserContext); 33 | const cartItems = useSelector((store) => store.cart.items); 34 | 35 | //Function to get userInfo 36 | const getUserInfo = async (access_token) => { 37 | const url = "https://www.googleapis.com/oauth2/v3/userinfo"; 38 | const headers = { 39 | Authorization: `Bearer ${access_token}`, 40 | }; 41 | try { 42 | const response = await fetch(url, { headers }); 43 | if (!response.ok) { 44 | throw new Error(`HTTP error! Status: ${response.status}`); 45 | } 46 | 47 | const data = await response.json(); 48 | const { name, email, picture } = data; 49 | setUserInfo({ 50 | name: name, 51 | email: email, 52 | picture: picture, 53 | }); 54 | } catch (error) { 55 | console.error("Error fetching user info:", error); 56 | throw error; 57 | } 58 | }; 59 | 60 | //Funtion to login with google account 61 | const login = useGoogleLogin({ 62 | onSuccess: (tokenResponse) => { 63 | getUserInfo(tokenResponse.access_token); 64 | setisLoggedIn(false); 65 | localStorage.setItem("accessToken", tokenResponse.access_token); 66 | }, 67 | }); 68 | //Funtion to logOut 69 | const logout = () => { 70 | if (localStorage.getItem("accessToken")) { 71 | localStorage.removeItem("accessToken"); 72 | setisLoggedIn(true); 73 | } else { 74 | setisLoggedIn(true); 75 | } 76 | }; 77 | 78 | // Function to toggle the menu 79 | const toggleMenu = () => { 80 | setIsMenuOpen(!isMenuOpen); 81 | }; 82 | 83 | // Function to close the menu 84 | const closeMenu = () => { 85 | setIsMenuOpen(false); 86 | }; 87 | //For retrieving the accessToken on page referesh 88 | useEffect(() => { 89 | if (localStorage.getItem("accessToken")) { 90 | getUserInfo(localStorage.getItem("accessToken")); 91 | setisLoggedIn(false); 92 | } 93 | }, []); 94 | 95 | return ( 96 | <> 97 | 98 |
99 |
100 |
101 | 102 | Logo 108 | 109 |
110 |
    111 | 114 | isActive ? "text-orange-400 " : "text-black" 115 | } 116 | > 117 |
  • 118 | 119 | 120 | 121 | Home 122 |
  • 123 |
    124 | 127 | isActive ? "text-orange-400 " : "text-black" 128 | } 129 | > 130 |
  • 131 | 132 | 133 | 134 | About 135 |
  • 136 |
    137 | 140 | isActive ? "text-orange-400 " : "text-black" 141 | } 142 | > 143 |
  • 144 | 145 | 146 | 147 | Contact 148 |
  • 149 |
    150 | 153 | isActive ? "text-orange-400 " : "text-black" 154 | } 155 | > 156 |
  • 157 | 158 | 159 | 160 | Help 161 |
  • 162 |
    163 | 166 | isActive ? "text-orange-400 " : "text-black" 167 | } 168 | > 169 |
    170 | 174 | 178 | {cartItems.length} 179 | 180 |
    181 |
    182 | {isLoggedIn ? ( 183 | 191 | ) : ( 192 | <> 193 | 199 | 211 | 212 | )} 213 |
214 |
215 |
216 | {isProfileOpen && !isLoggedIn ? ( 217 |
218 |
219 |
220 | pic 225 |
226 |
227 |
228 | Name: {userInfo.name} 229 |
230 |
231 |
232 | Email: {userInfo.email} 233 |
234 |
{ 237 | logout(); 238 | login(); 239 | }} 240 | > 241 | switch account 242 |
243 |
244 |
245 | ) : ( 246 |
247 | )} 248 | 249 | ); 250 | }; 251 | 252 | export default Header; 253 | -------------------------------------------------------------------------------- /src/components/Help.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { 3 | Accordion, 4 | AccordionSummary, 5 | AccordionDetails, 6 | Typography, 7 | } from "@mui/material"; 8 | import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; 9 | import faqsJsonData from "../utils/help.json"; 10 | 11 | const Section = ({ title, description, isVisible, onClick }) => { 12 | return ( 13 | 23 | } 25 | className="bg-blue-200 transition-all rounded-t-2xl" 26 | > 27 | 32 | {title} 33 | 34 | 35 | 36 | {description} 37 | 38 | 39 | ); 40 | }; 41 | 42 | const Help = () => { 43 | const faqsData = faqsJsonData.faqs; 44 | const [openSectionIndex, setOpenSectionIndex] = useState(-1); 45 | 46 | const toggleSectionVisibility = (index) => { 47 | setOpenSectionIndex((prevIndex) => (prevIndex === index ? -1 : index)); 48 | }; 49 | 50 | return ( 51 |
52 | 61 | FAQs 62 | 63 | {faqsData.map((item, index) => ( 64 |
toggleSectionVisibility(index)} 70 | /> 71 | ))} 72 |
73 | ); 74 | }; 75 | 76 | export default Help; 77 | -------------------------------------------------------------------------------- /src/components/Instamart.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { INSTAMART_URL } from "../utils/constants"; 3 | 4 | const Instamart = () => { 5 | return ( 6 |
7 |
8 |

9 | Get Ready for an Incredible Culinary Experience 10 |

11 | instamart-img 16 |
17 |
18 | ); 19 | }; 20 | 21 | export default Instamart; 22 | -------------------------------------------------------------------------------- /src/components/Offline.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Offline = () => { 4 | return ( 5 |
6 | 15 | 16 | 23 | 24 | {" "} 25 | 26 | {" "} 27 | {" "} 31 | {" "} 32 | {" "} 33 | 34 | 35 |

36 | {" "} 37 | it appears that the user is currently offline 38 |

39 | 45 |
46 | ); 47 | }; 48 | 49 | export default Offline; 50 | -------------------------------------------------------------------------------- /src/components/OrdarSummery.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useSelector } from "react-redux"; 3 | 4 | 5 | const OrderSummary = () => { 6 | const [totalAmount, setTotalAmount] = useState(0); 7 | const [discount, setDiscount] = useState(0); 8 | const [deliveryCharge, setDeliveryCharge] = useState(0); 9 | const cartItems = useSelector((store) => store.cart.items); 10 | 11 | useEffect(() => { 12 | let totalCartAmount = 0; 13 | for (let i = 0; i < cartItems.length; i++) { 14 | totalCartAmount += 15 | Math.round( 16 | (cartItems[i].info.price 17 | ? cartItems[i].info.price / 100 18 | : cartItems[i].info.defaultPrice / 100) * 19 | cartItems[i].info.quantity * 20 | 100 21 | ) / 100; 22 | } 23 | 24 | setTotalAmount(totalCartAmount); 25 | setDeliveryCharge((5 / 100) * totalCartAmount); 26 | setDiscount((10 / 100) * totalCartAmount); 27 | }, [cartItems]); 28 | 29 | return ( 30 |
31 |
34 |
Order Summary
35 |
36 |
37 |
38 | Total Price ({cartItems.length} items) 39 |
40 |
41 | ₹ {totalAmount.toFixed(2)} 42 |
43 |
44 |
45 |
Discount (10%)
46 |
47 | - ₹ {discount.toFixed(2)} 48 |
49 |
50 |
51 |
Delivery Charge (5%)
52 |
53 | + ₹{" "} 54 | {deliveryCharge.toFixed(2)} 55 |
56 |
57 |

58 | You will save {`${discount.toFixed(2)} on this order`} 🎉 59 |

60 |
61 |
62 |
Total Amount
63 |
64 | ₹{" "} 65 | 66 | {(totalAmount + deliveryCharge - discount).toFixed(2)} 67 | 68 |
69 |
70 | 73 |
74 |
75 | ); 76 | }; 77 | 78 | export default OrderSummary; 79 | -------------------------------------------------------------------------------- /src/components/ResShimmer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Skeleton } from "@mui/material"; 3 | import { Box } from "@mui/system"; 4 | 5 | const ResShimmer = () => { 6 | return ( 7 |
{/* Align to center */} 8 |
{/* Full width on small screens and two-thirds of the width on medium and larger screens */} 9 |
10 | 11 | 12 | {/* Increased height */} 13 | 14 | 15 | {/* Increased height */} 16 | 17 | 18 | {/* Increased height */} 19 | 20 | {/* Increased dimensions */} 21 | 22 | {/* Increased height */} 23 | 24 |
25 | {/* Increased height */} 26 | {/* Increased height */} 27 |
28 |
29 | 30 | {/* Increased height */} 31 | 32 | 33 | {/* Increased height */} 34 | 35 |
36 | {[1, 2].map((index) => ( 37 |
41 |
42 | 43 | {/* Increased height */} 44 | 45 |
46 | 47 | {/* Increased height */} 48 | 49 | 50 | {/* Increased height */} 51 | 52 |
53 |

54 | {/* Increased height */} 55 |

56 |
57 |
58 | {/* Further increased dimensions */} 59 | 65 |
66 |
67 | ))} 68 |
69 |
70 |
71 |
72 | ); 73 | }; 74 | 75 | export default ResShimmer; 76 | -------------------------------------------------------------------------------- /src/components/RestaurantMenu.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useParams } from "react-router-dom"; 3 | import { CDN_URL } from "../utils/constants"; 4 | import useRestaurant from "../utils/useRestaurant"; 5 | import ResShimmer from "./ResShimmer"; 6 | import toast, { Toaster } from "react-hot-toast"; 7 | import RestaurantMenuAccordion from "./RestaurantMenuAccordion"; 8 | 9 | const RestruarantMenu = () => { 10 | // Read dynamic URL params 11 | const { resId } = useParams(); 12 | // CUSTOM HOOK 13 | const [restaurant, resmenu, resOffers] = useRestaurant(resId); 14 | 15 | const addFoodItem = (card) => { 16 | // dispatch(addItem(card)); //this is done in children component now 17 | toast.success("Item added to cart"); 18 | }; 19 | 20 | return !restaurant ? ( 21 | 22 | ) : ( 23 |
24 | 25 |
26 | {/*

Res-ID : {resId}

*/} 27 |
28 |
29 |
30 |
31 |
32 | 33 |

{restaurant.name}

34 |
35 | {restaurant.cuisines.join(", ")} 36 | 37 | {restaurant.areaName}, {restaurant.city}{" "} 38 | 39 | 40 | 45 |
46 |
47 | = 4 50 | ? "text-green-500" 51 | : restaurant.avgRating >= 2 52 | ? "text-amber-500" 53 | : "text-red-500" 54 | }`} 55 | > 56 | = 4 59 | ? "text-green-500" 60 | : restaurant.avgRating >= 2 61 | ? "text-amber-500" 62 | : "text-red-500" 63 | }`} 64 | > 65 | ★{" "} 66 | 67 | {restaurant.avgRating} 68 | 69 |
70 | {restaurant.totalRatingsString} 71 |
72 |
73 | {restaurant.feeDetails.message && ( 74 |
75 | 78 | 79 | {restaurant.feeDetails.message} 80 | 81 |
82 | )} 83 |
84 |
85 | {restaurant.sla.slaString && ( 86 |
87 | 95 | 102 | 106 | 107 | 108 | {restaurant.sla.slaString} 109 | 110 |
111 | )} 112 |
113 | 121 | 128 | 132 | 133 | 134 | {restaurant.costForTwoMessage} 135 | 136 |
137 |
138 |
139 | 146 | {resOffers?.card?.card?.gridElements?.infoWithStyle?.offers.map( 147 | (offer, index) => { 148 | return ( 149 |
153 |
154 |
155 | 159 |

160 | {offer.info?.header} 161 |

162 |
163 | 164 | {offer.info?.couponCode} 165 | {" I "} 166 | 167 | {offer.info?.description} 168 | 169 | 170 |
171 |
172 | ); 173 | } 174 | )} 175 |
176 |
177 | {resmenu?.groupedCard?.cardGroupMap?.REGULAR?.cards 178 | .slice(1) 179 | .map((cardInfo, index) => { 180 | return ( 181 | cardInfo?.card?.card?.title && 182 | cardInfo?.card?.card?.itemCards?.map(() => null).length && ( 183 |
184 | addFoodItem()} 187 | /> 188 |
189 |
190 | ) 191 | ); 192 | })} 193 |
194 |
195 |
196 |
197 |
198 | ); 199 | }; 200 | 201 | export default RestruarantMenu; 202 | -------------------------------------------------------------------------------- /src/components/RestaurantMenuAccordion.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | import RestaurantMenuAccordionDetails from "./RestaurantMenuAccordionDetails"; 4 | 5 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 6 | import { faChevronUp, faChevronDown } from "@fortawesome/free-solid-svg-icons"; 7 | import Collapsible from "react-collapsible"; 8 | 9 | const RestaurantMenuAccordion = (props) => { 10 | const { cardInfo, onClickAddFoodItem } = props; 11 | 12 | const [isOpen, setIsOpen] = useState(false); 13 | 14 | const handleOpening = () => { 15 | setIsOpen(true); 16 | }; 17 | 18 | const handleClosing = () => { 19 | setIsOpen(false); 20 | }; 21 | 22 | return ( 23 | 28 |

29 | {cardInfo?.card?.card?.title} ( 30 | {cardInfo?.card?.card?.itemCards?.map(() => null).length}) 31 |

32 | 36 | 37 | } 38 | > 39 | 43 |
44 | ); 45 | }; 46 | 47 | export default RestaurantMenuAccordion; 48 | -------------------------------------------------------------------------------- /src/components/RestaurantMenuAccordionDetails.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FaMinus, FaPlus } from "react-icons/fa"; 3 | import { CDN_URL } from "../utils/constants"; 4 | import { useDispatch, useSelector } from "react-redux"; 5 | import { 6 | addItem, 7 | increaseQuantity, 8 | decreaseQuantity, 9 | } from "../utils/cartSlice"; 10 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 11 | import { 12 | faCircleDot, 13 | faSquareCaretUp, 14 | faStar, 15 | } from "@fortawesome/free-solid-svg-icons"; 16 | 17 | const RestaurantMenuAccordionDetails = (props) => { 18 | const { cardInfo, onClickAddFoodItem } = props; 19 | const cartItems = useSelector((store) => store.cart.items); 20 | 21 | const dispatch = useDispatch(); 22 | const addItemHandler = (card) => { 23 | dispatch(addItem(card)); 24 | onClickAddFoodItem(); 25 | }; 26 | 27 | const increaseItemHandler = (id) => { 28 | dispatch(increaseQuantity(id)); 29 | }; 30 | const decreaseItemHandler = (id) => { 31 | dispatch(decreaseQuantity(id)); 32 | }; 33 | 34 | return cardInfo.card?.card?.itemCards?.map((card) => { 35 | const itemInCart = cartItems.find( 36 | (item) => item.info.id === card.card.info.id 37 | ); 38 | return ( 39 |
43 |
44 |
45 | {card?.card?.info?.itemAttribute?.vegClassifier === "VEG" && ( 46 | 50 | )} 51 | {card?.card?.info?.itemAttribute?.vegClassifier === "NONVEG" && ( 52 | 56 | )} 57 | {card?.card?.info?.isBestseller && ( 58 | 59 | 60 | Bestseller 61 | 62 | )} 63 |
64 | 65 | {card?.card?.info?.name}{" "} 66 | 67 |
68 | 69 | ₹ 70 | {card?.card?.info?.defaultPrice 71 | ? (card?.card?.info?.defaultPrice / 100).toFixed(2) 72 | : 150} 73 | 74 | {card?.card?.info?.offerTags && ( 75 | 76 | {card?.card?.info?.offerTags[0]?.title} |{" "} 77 | {card?.card?.info?.offerTags[0]?.subTitle} 78 | 79 | )} 80 |
81 |

82 | {card?.card?.info?.description} 83 |

84 |
85 |
86 | 95 | {itemInCart ? ( 96 |
97 | decreaseItemHandler(card?.card?.info?.id)} 99 | className="hover:scale-110 cursor-pointer transition-all duration-300 ease-in-out align-middle mt-1" 100 | /> 101 | {itemInCart.info.quantity} 102 | increaseItemHandler(card?.card?.info?.id)} 104 | className="hover:scale-110 cursor-pointer transition-all duration-300 ease-in-out mt-1" 105 | /> 106 |
107 | ) : ( 108 | 114 | )} 115 |
116 |
117 | ); 118 | }); 119 | }; 120 | 121 | export default RestaurantMenuAccordionDetails; 122 | -------------------------------------------------------------------------------- /src/components/RestruarantCards.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { CDN_URL } from "../utils/constants"; 3 | import { AiOutlineHeart, AiFillHeart } from "react-icons/ai"; 4 | import { Link } from "react-router-dom"; 5 | 6 | const RestruarantCards = (props) => { 7 | const { resData, id, favlist, onClickFav } = props; 8 | const [isfav, setfav] = useState(favlist.indexOf(id) > -1); 9 | const [wiggleEffect, setWiggleEffect] = useState(false); 10 | const { 11 | cloudinaryImageId, 12 | name, 13 | avgRating, 14 | cuisines, 15 | slaString, 16 | costForTwo, 17 | aggregatedDiscountInfo, 18 | } = resData; 19 | return ( 20 | 24 |
25 |
26 | 36 | { 41 | setfav(!isfav); 42 | onClickFav(id); 43 | setWiggleEffect(!wiggleEffect); 44 | e.preventDefault(); 45 | }} 46 | > 47 | 52 | 53 | 54 |
55 |
56 |

{name}

57 | {cuisines.join(", ")} 58 |
59 |
= 4 62 | ? "bg-green-500" 63 | : avgRating >= 2 64 | ? "bg-amber-500" 65 | : "bg-red-500" 66 | } font-semibold`} 67 | > 68 | 69 | 70 | {avgRating === "--" ? "4.2" : avgRating} 71 | 72 |
73 | {slaString} 74 |
75 | {costForTwo} 76 |
77 |
78 |
79 | 80 |
81 | 82 | {!aggregatedDiscountInfo?.shortDescriptionList[0]?.meta 83 | ? "30% off | Use NEWFUD" 84 | : aggregatedDiscountInfo?.shortDescriptionList[0]?.meta} 85 | 86 |
87 |
88 |
89 | 90 | ); 91 | }; 92 | 93 | export default RestruarantCards; 94 | -------------------------------------------------------------------------------- /src/components/ScrollToTop.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { FiArrowUp } from "react-icons/fi"; 3 | 4 | const ScrollToTop = () => { 5 | const [isVisible, setIsVisible] = useState(false); 6 | const [scrollProgress, setScrollProgress] = useState(0); 7 | 8 | useEffect(() => { 9 | const handleScroll = () => { 10 | const scrolled = window.scrollY; 11 | const maxScroll = 12 | document.documentElement.scrollHeight - window.innerHeight; 13 | const progress = (scrolled / maxScroll) * 100; 14 | setScrollProgress(progress); 15 | 16 | if (scrolled > 100) { 17 | setIsVisible(true); 18 | } else { 19 | setIsVisible(false); 20 | } 21 | }; 22 | 23 | window.addEventListener("scroll", handleScroll); 24 | 25 | return () => { 26 | window.removeEventListener("scroll", handleScroll); 27 | }; 28 | }, []); 29 | 30 | const scrollToTop = () => { 31 | window.scrollTo({ 32 | top: 0, 33 | behavior: "smooth", 34 | }); 35 | }; 36 | 37 | return ( 38 |
43 |
44 |
50 | 55 |
56 |
57 | ); 58 | }; 59 | 60 | export default ScrollToTop; 61 | -------------------------------------------------------------------------------- /src/components/Shimmer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "react-loading-skeleton/dist/skeleton.css"; 3 | import Skeleton from "react-loading-skeleton"; 4 | 5 | const Shimmer = () => { 6 | return ( 7 |
11 | {Array.from({ length: 20 }).map((_, index) => ( 12 | 13 | ))} 14 |
15 | ); 16 | }; 17 | 18 | const ShimmerCard = () => { 19 | return ( 20 |
21 |
22 | 23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | ); 34 | }; 35 | 36 | export default Shimmer; 37 | -------------------------------------------------------------------------------- /src/components/__tests__/Header.test.js: -------------------------------------------------------------------------------- 1 | import { fireEvent, render } from "@testing-library/react"; 2 | import Header from "../Header"; 3 | import { Provider } from "react-redux"; 4 | import { store } from "../../utils/store"; 5 | import { StaticRouter } from "react-router-dom/server"; 6 | import { GoogleOAuthProvider } from "@react-oauth/google"; 7 | import * as googleOauth from "@react-oauth/google"; 8 | 9 | describe('Header', () => { 10 | jest.spyOn(googleOauth, "useGoogleLogin"); 11 | 12 | test("should load logo on render", () => { 13 | const header = render( 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | ); 22 | 23 | 24 | const logo = header.getAllByTestId("logo"); 25 | expect(logo[0].src).toBe( 26 | "https://www.creativefabrica.com/wp-content/uploads/2018/10/Fast-Delivery-food-logo-by-DEEMKA-STUDIO-580x406.jpg" 27 | ); 28 | }); 29 | 30 | test("should render cart items as 0", () => { 31 | // load header 32 | const header = render( 33 | 34 | 35 | 36 |
37 | 38 | 39 | 40 | ); 41 | 42 | 43 | const cart = header.getByTestId("cart"); 44 | expect(cart.innerHTML).toBe("0"); 45 | }); 46 | 47 | test("should initiate login on click on login button", () => { 48 | const screen = render( 49 | 50 | 51 | 52 |
53 | 54 | 55 | 56 | ); 57 | 58 | const loginButton = screen.getByRole("button", { 59 | name: "Login ⇦" 60 | }); 61 | 62 | expect(loginButton).not.toBeNull(); 63 | 64 | fireEvent.click(loginButton); 65 | expect(googleOauth.useGoogleLogin).toHaveBeenCalledTimes(1); 66 | }); 67 | 68 | test("should initiate logout on click on logout button", () => { 69 | jest.spyOn(Storage.prototype, "getItem").mockReturnValue("accessToken"); 70 | jest.spyOn(Storage.prototype, "removeItem"); 71 | const screen = render( 72 | 73 | 74 | 75 |
76 | 77 | 78 | 79 | ); 80 | 81 | const logoutButton = screen.getByRole("button", { 82 | name: "Logout" 83 | }); 84 | 85 | expect(logoutButton).not.toBeNull(); 86 | 87 | fireEvent.click(logoutButton); 88 | expect(localStorage.removeItem).toHaveBeenCalledWith("accessToken"); 89 | }); 90 | }); -------------------------------------------------------------------------------- /src/components/__tests__/sum.test.js: -------------------------------------------------------------------------------- 1 | import { sum } from "../sum"; 2 | test("check sum of 2 positive number", () => { 3 | expect(sum(2, 5)).toBe(7); 4 | }); 5 | -------------------------------------------------------------------------------- /src/components/sum.js: -------------------------------------------------------------------------------- 1 | export const sum = (a, b) => { 2 | return a + b; 3 | }; 4 | -------------------------------------------------------------------------------- /src/utils/cartSlice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createSlice } from "@reduxjs/toolkit"; 3 | const cartSlice = createSlice({ 4 | name: "cart", 5 | initialState: { 6 | items: [], 7 | }, 8 | 9 | reducers: { 10 | addItem: (state, action) => { 11 | const index = state.items.findIndex( 12 | ({ info }) => info.id === action.payload.card.info.id 13 | ); 14 | if (index < 0) { 15 | let data = { ...action.payload.card, info: { ...action.payload.card.info, quantity: 1 } }; 16 | state.items.push(data) 17 | } else { 18 | state.items[index].info.quantity++; 19 | } 20 | 21 | }, 22 | increaseQuantity: (state, action) => { 23 | const index = state.items.findIndex( 24 | ({ info }) => info.id === action.payload 25 | ); 26 | if (index >= 0) { 27 | state.items[index].info.quantity++; 28 | } 29 | }, 30 | decreaseQuantity: (state, action) => { 31 | const index = state.items.findIndex( 32 | ({ info }) => info.id === action.payload 33 | ); 34 | if (index >= 0 && state.items[index].info.quantity >= 1) { 35 | state.items[index].info.quantity--; 36 | 37 | if (state.items[index].info.quantity == 0) { 38 | // state.items[index].info.quantity--; 39 | state.items.splice(index, 1); 40 | // removeItem(state,action) 41 | } 42 | } 43 | }, 44 | removeItem: (state, action) => { 45 | const index = state.items.findIndex( 46 | ({ info }) => info.id === action.payload 47 | ); 48 | if (index >= 0) { 49 | state.items.splice(index, 1); 50 | } 51 | }, 52 | clearCart: (state) => { 53 | state.items = []; 54 | }, 55 | }, 56 | }); 57 | 58 | export const { 59 | addItem, 60 | removeItem, 61 | clearCart, 62 | increaseQuantity, 63 | decreaseQuantity, 64 | } = cartSlice.actions; 65 | export default cartSlice.reducer; 66 | -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const CDN_URL = 2 | "https://media-assets.swiggy.com/swiggy/image/upload/fl_lossy,f_auto,q_auto,w_660/"; 3 | 4 | export const LOGO_URL = 5 | "https://www.creativefabrica.com/wp-content/uploads/2018/10/Fast-Delivery-food-logo-by-DEEMKA-STUDIO-580x406.jpg"; 6 | 7 | export const FETCH_MENU_URL = 8 | "https://thingproxy.freeboard.io/fetch/https://www.swiggy.com/dapi/menu/pl?page-type=REGULAR_MENU&complete-menu=true&lat=12.9122238&lng=77.5923219&restaurantId="; 9 | 10 | export const INSTAMART_URL = 11 | "https://img.freepik.com/free-vector/flat-coming-soon-background-with-megaphone_1017-33737.jpg"; 12 | -------------------------------------------------------------------------------- /src/utils/help.json: -------------------------------------------------------------------------------- 1 | { 2 | "faqs": [ 3 | { 4 | "id": 1, 5 | "title": "Can I edit my order?", 6 | "description": "Your order can be edited before it reaches the restaurant. You could contact customer support team via chat or call to do so. Once order is placed and restaurant starts preparing your food, you may not edit its contents" 7 | }, 8 | { 9 | "id": 2, 10 | "title": "I want to cancel my order", 11 | "description": "We will do our best to accommodate your request if the order is not placed to the restaurant (Customer service number: 080-67466729). Please note that we will have a right to charge a cancellation fee up to full order value to compensate our restaurant and delivery partners if your order has been confirmed." 12 | }, 13 | { 14 | "id": 3, 15 | "title": "Is single order from many restaurants possible?", 16 | "description": "We currently do not support this functionality. However, you can place orders for individual items from different restaurants." 17 | }, 18 | { 19 | "id": 4, 20 | "title": "How long do you take to deliver?", 21 | "description": "Standard delivery times vary by the location selected and prevailing conditions. Once you select your location, an estimated delivery time is mentioned for each restaurant." 22 | }, 23 | { 24 | "id": 5, 25 | "title": "Can I order from any location?", 26 | "description": "We will deliver from any restaurant listed on the search results for your location. We recommend enabling your GPS location finder and letting the app auto-detect your location." 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/helper.js: -------------------------------------------------------------------------------- 1 | export function filterData(searchText, restaurants) { 2 | const filterData = restaurants.filter((restaurant) => 3 | restaurant?.info?.name.toLowerCase()?.includes(searchText.toLowerCase()) 4 | ); 5 | return filterData; 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/index.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 10px; 3 | width: auto; 4 | text-align: center; 5 | background-color: var(--footer-bg-color); 6 | padding: 20px 10px 20px; 7 | border-radius: 5px; 8 | box-shadow: 3px 3px 10px -1px rgba(193, 180, 180, 0.71); 9 | } 10 | 11 | .footer > i { 12 | padding: 0 5px 0; 13 | font-size: smaller; 14 | } 15 | 16 | .footer > a { 17 | font-weight: 700; 18 | color: var(--dark-blue); 19 | } 20 | 21 | .footer > a:hover { 22 | color: var(--x-dark-orange); 23 | } 24 | 25 | .footer > strong { 26 | padding-left: 5px; 27 | } 28 | 29 | .footer > strong > span { 30 | color: var(--x-dark-orange); 31 | } 32 | .github-logo { 33 | width: 40px; 34 | /* margin-top: -30px; 35 | margin-left: 1280px; */ 36 | height: auto; 37 | } 38 | .peerlist-logo{ 39 | width: 30px; 40 | /* margin-top: -34px; 41 | margin-left: 1330px; */ 42 | height: auto; 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/utils/store.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { combineReducers, configureStore} from "@reduxjs/toolkit"; 3 | import cartSlice from "./cartSlice"; 4 | import storage from 'redux-persist/lib/storage'; 5 | import { 6 | persistReducer, 7 | persistStore, 8 | FLUSH, 9 | REHYDRATE, 10 | PAUSE, 11 | PERSIST, 12 | PURGE, 13 | REGISTER, 14 | } from 'redux-persist'; 15 | 16 | const persistConfig = { 17 | key: 'root', 18 | storage, 19 | } 20 | 21 | const rootReducer = combineReducers({ 22 | cart: cartSlice, 23 | }) 24 | 25 | const persistedReducer = persistReducer(persistConfig, rootReducer) 26 | 27 | export const store = configureStore({ 28 | reducer: persistedReducer, 29 | middleware: (getDefaultMiddleware) => getDefaultMiddleware({ 30 | serializableCheck: { 31 | ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], 32 | }, 33 | }), 34 | }); 35 | 36 | export const persistor = persistStore(store) 37 | -------------------------------------------------------------------------------- /src/utils/useFocus.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | 3 | export const useFocus = () => { 4 | const inputRef = useRef(null); 5 | const setFocus = () => { 6 | inputRef?.current && inputRef?.current?.focus(); 7 | }; 8 | return [inputRef, setFocus]; 9 | }; 10 | -------------------------------------------------------------------------------- /src/utils/useOnline.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | const useOnline = () => { 4 | const [isOnline, setIsOnline] = useState(true); 5 | useEffect(() => { 6 | const handleOnline = () => { 7 | setIsOnline(true); 8 | }; 9 | const handleOffline = () => { 10 | setIsOnline(false); 11 | }; 12 | window.addEventListener("online", handleOnline); 13 | window.addEventListener("offline", handleOffline); 14 | }, []); 15 | 16 | return isOnline; 17 | }; 18 | 19 | export default useOnline; 20 | -------------------------------------------------------------------------------- /src/utils/useRestaurant.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useState, useEffect } from "react"; 3 | import { FETCH_MENU_URL } from "./constants"; 4 | 5 | const useRestaurant = (resId) => { 6 | const [restaurant, setRestaurant] = useState(null); 7 | const [resmenu, setResMenu] = useState([{}]); 8 | const [resOffers, setResOffers] = useState([{}]); 9 | 10 | //get data from API 11 | useEffect(() => { 12 | getRestruarantInfo(); 13 | }, []); 14 | 15 | async function getRestruarantInfo() { 16 | const data = await fetch(FETCH_MENU_URL + resId); 17 | const json = await data.json(); 18 | setRestaurant(json.data?.cards[0]?.card?.card?.info); 19 | if (restaurant) { 20 | const { name, avgRating, cloudinaryImageId, city, costForTwoMessage, sla } = 21 | restaurant; 22 | } 23 | setResOffers(json.data?.cards[1]); 24 | setResMenu(json.data?.cards[2]); 25 | } 26 | // return restuarant data 27 | return [restaurant, resmenu, resOffers]; 28 | }; 29 | 30 | export default useRestaurant; 31 | -------------------------------------------------------------------------------- /src/utils/userContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | const UserContext = createContext({ 4 | user: { 5 | // name: "Developed with ❤️ and a lot of ☕️", 6 | name : "Browse, Order, and Enjoy!", 7 | email: "Dummy@gmail.com", 8 | }, 9 | }); 10 | 11 | export default UserContext; 12 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./src/**/*.{html,js}"], 4 | theme: { 5 | extend: { 6 | keyframes: { 7 | wiggle: { 8 | "0%, 100%": { transform: "rotate(-3deg)" }, 9 | "50%": { transform: "rotate(3deg)" }, 10 | }, 11 | }, 12 | animation: { 13 | wiggle: "wiggle 1s ease-in-out", 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | }; 19 | --------------------------------------------------------------------------------