├── .gitignore
├── dist
├── b3909570c94cc41b9906.png
├── index.html
├── runtime.js
└── main.js
├── src
├── images
│ └── VegetarianRestauratLogo.png
├── Modules
│ ├── commentsCounter.js
│ ├── errorHandler.js
│ ├── getItemsDetails.js
│ ├── itemCounter.js
│ ├── newApp.js
│ ├── getComments.js
│ ├── sendComment.js
│ ├── likes.js
│ ├── getItems.js
│ └── commentsPopup.js
├── index.js
├── index.html
└── styles.css
├── .babelrc
├── .hintrc
├── .eslintrc.json
├── .stylelintrc.json
├── tests
├── itemCounter.test.js
└── commentsCounter.test.js
├── webpack.config.js
├── LICENSE
├── package.json
├── .github
└── workflows
│ └── linters.yml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 | .DS_Store
--------------------------------------------------------------------------------
/dist/b3909570c94cc41b9906.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ClaudiaRojasSoto/Api_dishes/HEAD/dist/b3909570c94cc41b9906.png
--------------------------------------------------------------------------------
/src/images/VegetarianRestauratLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ClaudiaRojasSoto/Api_dishes/HEAD/src/images/VegetarianRestauratLogo.png
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "test": {
4 | "plugins": ["@babel/plugin-transform-modules-commonjs"]
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/src/Modules/commentsCounter.js:
--------------------------------------------------------------------------------
1 | const countComments = () => {
2 | const comments = document.querySelectorAll('.comment-text');
3 | return comments.length;
4 | };
5 |
6 | export default countComments;
7 |
--------------------------------------------------------------------------------
/src/Modules/errorHandler.js:
--------------------------------------------------------------------------------
1 | const handleFetchError = (error) => {
2 | const errorMessage = document.getElementById('error-message');
3 | if (errorMessage) {
4 | errorMessage.innerHTML = `${error.message} `;
5 | }
6 | };
7 |
8 | export default handleFetchError;
--------------------------------------------------------------------------------
/src/Modules/getItemsDetails.js:
--------------------------------------------------------------------------------
1 | const getItemDetails = async (id) => {
2 | const request = await fetch(`https://www.themealdb.com/api/json/v1/1/lookup.php?i=${id}`);
3 | const data = await request.json();
4 | return data.meals[0];
5 | };
6 |
7 | export default getItemDetails;
--------------------------------------------------------------------------------
/src/Modules/itemCounter.js:
--------------------------------------------------------------------------------
1 | const homeItemCounter = (containerItems) => {
2 | const hometitle = document.querySelector('#mainTitle');
3 | hometitle.textContent = `${containerItems} Vegetarian Recipes`;
4 | return hometitle.textContent;
5 | };
6 |
7 | export default homeItemCounter;
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles.css';
2 | import mylogo from './images/VegetarianRestauratLogo.png';
3 | import getItems from './Modules/getItems.js';
4 |
5 | document.querySelector('#logo').src = mylogo;
6 |
7 | window.addEventListener('load', () => {
8 | getItems();
9 | });
10 |
--------------------------------------------------------------------------------
/src/Modules/newApp.js:
--------------------------------------------------------------------------------
1 | // Request for the ID in the Involvement API
2 |
3 | const getID = async () => {
4 | const request = await fetch('https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/', {
5 | method: 'POST',
6 | });
7 | const data = await request.text();
8 | return data;
9 | };
10 |
11 | export default getID;
12 |
--------------------------------------------------------------------------------
/src/Modules/getComments.js:
--------------------------------------------------------------------------------
1 | const getComments = async (appId, id) => {
2 | try {
3 | const response = await fetch(`https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/${appId}/comments?item_id=${id}`);
4 | const data = await response.json();
5 | return data;
6 | } catch (error) {
7 | return error;
8 | }
9 | };
10 |
11 | export default getComments;
--------------------------------------------------------------------------------
/.hintrc:
--------------------------------------------------------------------------------
1 | {
2 | "connector": {
3 | "name": "local",
4 | "options": {
5 | "pattern": ["**", "!.git/**", "!node_modules/**"]
6 | }
7 | },
8 | "extends": ["development"],
9 | "formatters": ["stylish"],
10 | "hints": [
11 | "button-type",
12 | "disown-opener",
13 | "html-checker",
14 | "meta-charset-utf-8",
15 | "meta-viewport",
16 | "no-inline-styles:error"
17 | ]
18 | }
--------------------------------------------------------------------------------
/src/Modules/sendComment.js:
--------------------------------------------------------------------------------
1 | const sendComment = async (appId, id, username1, comment1) => {
2 | const response = await fetch(`https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/${appId}/comments`, {
3 | method: 'POST',
4 | headers: {
5 | 'Content-Type': 'application/json',
6 | },
7 | body: JSON.stringify({
8 | item_id: id,
9 | username: username1,
10 | comment: comment1,
11 | }),
12 | });
13 |
14 | if (!response.ok) {
15 | throw new Error('Error sending the comment');
16 | }
17 | };
18 |
19 | export default sendComment;
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jest": true
6 | },
7 | "parser": "babel-eslint",
8 | "parserOptions": {
9 | "ecmaVersion": 2018,
10 | "sourceType": "module"
11 | },
12 | "extends": ["airbnb-base"],
13 | "rules": {
14 | "no-shadow": "off",
15 | "no-param-reassign": "off",
16 | "eol-last": "off",
17 | "import/extensions": [ 1, {
18 | "js": "always", "json": "always"
19 | }]
20 | },
21 | "ignorePatterns": [
22 | "dist/",
23 | "build/"
24 | ]
25 | }
--------------------------------------------------------------------------------
/.stylelintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["stylelint-config-standard"],
3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"],
4 | "rules": {
5 | "at-rule-no-unknown": [
6 | true,
7 | {
8 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"]
9 | }
10 | ],
11 | "scss/at-rule-no-unknown": [
12 | true,
13 | {
14 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"]
15 | }
16 | ],
17 | "csstree/validator": true
18 | },
19 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"]
20 | }
--------------------------------------------------------------------------------
/tests/itemCounter.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @jest-environment jsdom
3 | */
4 |
5 | import homeItemCounter from '../src/Modules/itemCounter.js';
6 |
7 | describe('Return the number of items displayed in the screen', () => {
8 | it('Case 1', () => {
9 | document.body.innerHTML = `
10 |
11 | `;
12 | const items = [1, 2, 3, 4];
13 | const result = homeItemCounter(items.length);
14 | expect(result).toMatch(/4 Vegetarian Recipes/);
15 | });
16 |
17 | it('Case 2', () => {
18 | document.body.innerHTML = `
19 |
20 | `;
21 | const items = [1, 2, 3, 4, 5, 6, 7];
22 | const result = homeItemCounter(items.length);
23 | expect(result).toMatch(/7 Vegetarian Recipes/);
24 | });
25 | });
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const HtmlWebpackPlugin = require('html-webpack-plugin');
3 |
4 | module.exports = {
5 | mode: 'development',
6 | entry: './src/index.js',
7 | devServer: {
8 | static: './dist',
9 | },
10 | plugins: [
11 | new HtmlWebpackPlugin({
12 | template: './src/index.html',
13 | }),
14 | ],
15 | output: {
16 | filename: '[name].js',
17 | path: path.resolve(__dirname, 'dist'),
18 | },
19 | optimization: {
20 | runtimeChunk: 'single',
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.css$/i,
26 | use: ['style-loader', 'css-loader'],
27 | },
28 | {
29 | test: /\.(png|svg|jpg|jpeg|gif)$/i,
30 | type: 'asset/resource',
31 | },
32 | ],
33 | },
34 | };
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
22 |
23 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/commentsCounter.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @jest-environment jsdom
3 | */
4 |
5 | import countComments from '../src/Modules/commentsCounter.js';
6 |
7 | describe('Comments Counter', () => {
8 | document.body.innerHTML = `
9 |
14 | `;
15 |
16 | test('should return the correct number of comments', () => {
17 | expect(countComments()).toBe(3);
18 | });
19 |
20 | test('should return 0 if no comments are present', () => {
21 | document.querySelector('#commentsContainer').innerHTML = '';
22 | expect(countComments()).toBe(0);
23 | });
24 |
25 | test('should not count non-comment elements', () => {
26 | document.querySelector('#commentsContainer').innerHTML += 'Not a comment
';
27 | expect(countComments()).toBe(0);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
22 |
23 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/src/Modules/likes.js:
--------------------------------------------------------------------------------
1 | const postLikes = async (id) => {
2 | const sendData = await fetch('https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/k513WvYOj4wUaRdaeuNF/likes/', {
3 | method: 'POST',
4 | headers: {
5 | 'Content-type': 'application/json; charset=UTF-8',
6 | },
7 | body: JSON.stringify({
8 | item_id: id,
9 | }),
10 | });
11 | const result = await sendData.text();
12 | return result;
13 | };
14 |
15 | export const getLikes = async () => {
16 | const requestLikes = await fetch('https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/k513WvYOj4wUaRdaeuNF/likes/');
17 | const dataLikes = await requestLikes.json();
18 | return dataLikes;
19 | };
20 |
21 | export const updateText = async (idmeal, span) => {
22 | const numberOfLikes = await getLikes();
23 | let likes = 0;
24 | numberOfLikes.forEach((elem) => {
25 | if (elem.item_id === idmeal) {
26 | likes = elem.likes;
27 | }
28 | });
29 | span.textContent = `${likes} likes`;
30 | };
31 |
32 | export default postLikes;
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Andrea Manuel
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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "javascriptcapstone",
3 | "version": "1.0.0",
4 | "description": "The leaderboard website displays scores submitted by different players. It also allows you to submit your score. All data is preserved thanks to the external Leaderboard API service.",
5 | "private": true,
6 | "scripts": {
7 | "test": "jest",
8 | "start": "webpack serve --open",
9 | "build": "webpack",
10 | "predeploy": "npm run build",
11 | "deploy": "gh-pages -d dist"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@babel/plugin-transform-modules-commonjs": "^7.22.5",
18 | "babel-eslint": "^10.1.0",
19 | "css-loader": "^6.8.1",
20 | "eslint": "^7.32.0",
21 | "eslint-config-airbnb-base": "^14.2.1",
22 | "eslint-plugin-import": "^2.27.5",
23 | "gh-pages": "^5.0.0",
24 | "hint": "^7.1.9",
25 | "html-webpack-plugin": "^5.5.3",
26 | "jest": "^29.5.0",
27 | "jest-environment-jsdom": "^29.5.0",
28 | "style-loader": "^3.3.3",
29 | "stylelint": "^13.13.1",
30 | "stylelint-config-standard": "^21.0.0",
31 | "stylelint-csstree-validator": "^1.9.0",
32 | "stylelint-scss": "^3.21.0",
33 | "webpack": "^5.87.0",
34 | "webpack-cli": "^5.1.4",
35 | "webpack-dev-server": "^4.15.1"
36 | },
37 | "dependencies": {
38 | "lodash": "^4.17.21"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Modules/getItems.js:
--------------------------------------------------------------------------------
1 | import showCommentsPopup from './commentsPopup.js';
2 | import handleFetchError from './errorHandler.js';
3 | import postLikes, { getLikes, updateText } from './likes.js';
4 | import homeItemCounter from './itemCounter.js';
5 |
6 | const container = document.querySelector('#itemsContainer');
7 |
8 | const displayItems = (dataMeals) => {
9 | dataMeals.forEach(async (meals) => {
10 | const numberOfLikes = await getLikes();
11 | let likes = 0;
12 | numberOfLikes.forEach((elem) => {
13 | if (elem.item_id === meals.idMeal) {
14 | likes = elem.likes;
15 | }
16 | });
17 | const mainDiv = document.createElement('div');
18 | mainDiv.className = 'dflex container';
19 | mainDiv.innerHTML = `
20 |
21 |
22 |
23 |
${meals.strMeal}
24 |
25 | ${likes} likes
26 | ♡
27 |
28 |
29 |
30 |
31 | `;
32 |
33 | mainDiv.querySelectorAll('#comments').forEach((commentsButton) => {
34 | commentsButton.addEventListener('click', async () => {
35 | await showCommentsPopup(meals.idMeal).catch(handleFetchError);
36 | });
37 | });
38 |
39 | mainDiv.querySelector('#likes').addEventListener('click', async (event) => {
40 | const id = event.target.className;
41 | await postLikes(id);
42 | const updateLikes = mainDiv.querySelector('#likesNumber');
43 | await updateText(meals.idMeal, updateLikes);
44 | });
45 |
46 | container.appendChild(mainDiv);
47 | });
48 | };
49 |
50 | const getItems = async () => {
51 | const request = await fetch('https://themealdb.com/api/json/v1/1/filter.php?c=Vegetarian');
52 | const data = await request.json();
53 | displayItems(data.meals);
54 | homeItemCounter(data.meals.length);
55 | };
56 |
57 | export default getItems;
--------------------------------------------------------------------------------
/.github/workflows/linters.yml:
--------------------------------------------------------------------------------
1 | name: Linters
2 |
3 | on: pull_request
4 |
5 | env:
6 | FORCE_COLOR: 1
7 |
8 | jobs:
9 | lighthouse:
10 | name: Lighthouse
11 | runs-on: ubuntu-22.04
12 | steps:
13 | - uses: actions/checkout@v3
14 | - uses: actions/setup-node@v3
15 | with:
16 | node-version: "18.x"
17 | - name: Setup Lighthouse
18 | run: npm install -g @lhci/cli@0.11.x
19 | - name: Lighthouse Report
20 | run: lhci autorun --upload.target=temporary-public-storage --collect.staticDistDir=.
21 | webhint:
22 | name: Webhint
23 | runs-on: ubuntu-22.04
24 | steps:
25 | - uses: actions/checkout@v3
26 | - uses: actions/setup-node@v3
27 | with:
28 | node-version: "18.x"
29 | - name: Setup Webhint
30 | run: |
31 | npm install --save-dev hint@7.x
32 | [ -f .hintrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.hintrc
33 | - name: Webhint Report
34 | run: npx hint .
35 | stylelint:
36 | name: Stylelint
37 | runs-on: ubuntu-22.04
38 | steps:
39 | - uses: actions/checkout@v3
40 | - uses: actions/setup-node@v3
41 | with:
42 | node-version: "18.x"
43 | - name: Setup Stylelint
44 | run: |
45 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x
46 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.stylelintrc.json
47 | - name: Stylelint Report
48 | run: npx stylelint "**/*.{css,scss}"
49 | eslint:
50 | name: ESLint
51 | runs-on: ubuntu-22.04
52 | steps:
53 | - uses: actions/checkout@v3
54 | - uses: actions/setup-node@v3
55 | with:
56 | node-version: "18.x"
57 | - name: Setup ESLint
58 | run: |
59 | npm install --save-dev eslint@7.x eslint-config-airbnb-base@14.x eslint-plugin-import@2.x babel-eslint@10.x
60 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.eslintrc.json
61 | - name: ESLint Report
62 | run: npx eslint .
63 | nodechecker:
64 | name: node_modules checker
65 | runs-on: ubuntu-22.04
66 | steps:
67 | - uses: actions/checkout@v3
68 | - name: Check node_modules existence
69 | run: |
70 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi
71 |
--------------------------------------------------------------------------------
/src/Modules/commentsPopup.js:
--------------------------------------------------------------------------------
1 | import getItemDetails from './getItemsDetails.js';
2 | import getComments from './getComments.js';
3 | import sendComment from './sendComment.js';
4 | import countComments from './commentsCounter.js';
5 |
6 | const showCommentsPopup = async (id) => {
7 | const details = await getItemDetails(id);
8 | const appId = 'k513WvYOj4wUaRdaeuNF';
9 |
10 | const popup = document.createElement('div');
11 | popup.id = 'commentsPopup';
12 | popup.innerHTML = `
13 | ${details.strMeal}
14 |
15 | ${details.strInstructions}
16 |
17 | Add a comment
18 |
27 | ×
28 | `;
29 |
30 | document.body.appendChild(popup);
31 |
32 | const commentsContainer = popup.querySelector('#commentsContainer');
33 |
34 | // Create a new element to display the comment count
35 | const commentsCountElement = document.createElement('p');
36 | commentsCountElement.id = 'commentsCount';
37 | commentsCountElement.classList.add('comments-count');
38 |
39 | popup.insertBefore(commentsCountElement, commentsContainer);
40 |
41 | const updateComments = async () => {
42 | const comments = await getComments(appId, id);
43 | if (!Array.isArray(comments)) {
44 | // This block it's designed to handle the empty data in comments
45 | } else {
46 | commentsContainer.innerHTML = '';
47 | comments.forEach((comment) => {
48 | const commentElement = document.createElement('p');
49 | commentElement.textContent = `${comment.creation_date} - ${comment.username}: ${comment.comment}`;
50 | commentElement.classList.add('comment-text');
51 | commentsContainer.appendChild(commentElement);
52 | });
53 | // Update the comments count after updating the comments
54 | commentsCountElement.textContent = `Comments: ${countComments()}`;
55 | }
56 | };
57 |
58 | await updateComments();
59 |
60 | const form = popup.querySelector('#commentForm');
61 | form.addEventListener('submit', async (event) => {
62 | const usernameInput = popup.querySelector('#nameInput');
63 | const commentInput = popup.querySelector('#commentInput');
64 |
65 | event.preventDefault();
66 |
67 | const username = usernameInput.value;
68 | const comment = commentInput.value;
69 |
70 | await sendComment(appId, id, username, comment);
71 | await updateComments(); // Update the comments (and the count) after submitting a comment
72 |
73 | // Clear the input fields after the comment has been sent and comments have been updated
74 | usernameInput.value = '';
75 | commentInput.value = '';
76 | });
77 |
78 | popup.querySelector('.closeButton').addEventListener('click', () => {
79 | document.body.removeChild(popup);
80 | });
81 | };
82 |
83 | export default showCommentsPopup;
84 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 0;
3 | margin: 0;
4 | background-color: rgb(161, 230, 230);
5 | }
6 |
7 | .dflex {
8 | display: flex;
9 | justify-content: space-around;
10 | align-items: center;
11 | gap: 15px;
12 | flex-wrap: wrap;
13 | }
14 |
15 | header,
16 | footer {
17 | background-color: rgb(245, 209, 109);
18 | }
19 |
20 | main {
21 | padding: 15px;
22 | }
23 |
24 | #logo {
25 | max-width: 100px;
26 | }
27 |
28 | ul,
29 | li a {
30 | text-decoration: none;
31 | list-style: none;
32 | color: black;
33 | font-size: 15px;
34 | }
35 |
36 | footer {
37 | font-size: 15px;
38 | text-align: center;
39 | justify-content: center;
40 | height: 50px;
41 | }
42 |
43 | .mealimg {
44 | width: 200px;
45 | }
46 |
47 | .mealtitle {
48 | justify-content: center;
49 | flex-direction: column;
50 | text-align: center;
51 | }
52 |
53 | h2 {
54 | color: brown;
55 | }
56 |
57 | .container,
58 | .item {
59 | width: 300px;
60 | height: 460px;
61 | margin-bottom: 40px;
62 | }
63 |
64 | .item {
65 | border: 3px solid brown;
66 | flex-direction: column;
67 | padding: 10px;
68 | background-color: rgba(250, 232, 182, 0.705);
69 | }
70 |
71 | #likes {
72 | background-color: transparent;
73 | border: transparent;
74 | font-size: 30px;
75 | color: brown;
76 | }
77 |
78 | #likes:active {
79 | color: red;
80 | font-weight: 900;
81 | }
82 |
83 | #comments {
84 | background-color: rgb(245, 209, 109);
85 | width: 100px;
86 | height: 34px;
87 | border-radius: 12px;
88 | border: 3px solid brown;
89 | }
90 |
91 | #commentsPopup {
92 | position: fixed;
93 | top: 50%;
94 | left: 50%;
95 | transform: translate(-50%, -50%);
96 | width: 90%;
97 | max-width: 90vw;
98 | height: 90vh;
99 | max-height: 90vh;
100 | overflow-y: auto;
101 | background-color: rgb(250, 232, 182);
102 | padding: 20px;
103 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
104 | text-align: center;
105 | border: 3px solid brown;
106 | }
107 |
108 | #commentsPopup h2 {
109 | margin-bottom: 20px;
110 | }
111 |
112 | #commentsPopup img {
113 | width: 400px;
114 | height: 300px;
115 | object-fit: cover;
116 | }
117 |
118 | #details-instructions {
119 | color: brown;
120 | padding: 30px;
121 | margin-left: 90px;
122 | margin-right: 90px;
123 | }
124 |
125 | #commentsPopup h3 {
126 | color: brown;
127 | margin-bottom: 25px;
128 | }
129 |
130 | #nameInput {
131 | margin-bottom: 10px;
132 | width: 70%;
133 | padding: 5px;
134 | border: 1px solid brown;
135 | }
136 |
137 | #commentInput {
138 | margin-bottom: 20px;
139 | width: 70%;
140 | padding: 5px;
141 | height: 100px;
142 | border: 1px solid brown;
143 | }
144 |
145 | #commentsPopup .closeButton {
146 | position: absolute;
147 | top: 20px;
148 | right: 20px;
149 | background: none;
150 | border: none;
151 | padding: 0;
152 | font-size: 40px;
153 | cursor: pointer;
154 | color: brown;
155 | }
156 |
157 | #submitCommentButton {
158 | background-color: rgb(245, 209, 109);
159 | width: 120px;
160 | height: 40px;
161 | border-radius: 12px;
162 | border: 2px solid brown;
163 | color: brown;
164 | font-size: 16px;
165 | margin-bottom: 20px;
166 | }
167 |
168 | .comment-text {
169 | color: brown;
170 | font-size: 14px;
171 | }
172 |
173 | .comments-count {
174 | color: brown;
175 | font-size: 15px;
176 | font-weight: bold;
177 | }
178 |
179 | #mainTitle {
180 | color: brown;
181 | font-size: 30px;
182 | font-weight: 900;
183 | }
184 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaScriptCapstone
2 |
3 |
4 |
5 | # 📗 Table of Contents
6 |
7 | - [JavaScriptCapstone](#javascriptcapstone)
8 | - [📗 Table of Contents](#-table-of-contents)
9 | - [📖 JavaScriptCapstone ](#-javascriptcapstone-)
10 | - [🛠 Built With ](#-built-with-)
11 | - [Tech Stack ](#tech-stack-)
12 | - [Key Features ](#key-features-)
13 | - [💻 Getting Started ](#-getting-started-)
14 | - [Project Structure](#project-structure)
15 | - [Setup](#setup)
16 | - [Install](#install)
17 | - [Usage](#usage)
18 | - [Run tests](#run-tests)
19 | - [👥 Authors ](#-authors-)
20 | - [🔭 Future Features ](#-future-features-)
21 | - [🤝 Contributing ](#-contributing-)
22 | - [⭐️ Show your support ](#️-show-your-support-)
23 | - [🙏 Acknowledgments ](#-acknowledgments-)
24 | - [📝 License ](#-license-)
25 |
26 | # 📖 JavaScriptCapstone
27 |
28 | > This is the JavaScript Capstone project, where we built a web application based on an external API. The project is a webapp that revolves around a selected API, providing data about a topic of our choice.
29 | > [Here](https://youtu.be/Hi2MclqUOjU) is the link to the video presentation
30 |
31 | ## 🛠 Built With
32 |
33 | ### Tech Stack
34 |
35 |
36 | HTML
37 |
38 | This project use HTML.
39 |
40 |
41 |
42 |
43 | CSS
44 |
45 | The CSS is used to provide the design in the whole page.
46 |
47 |
48 |
49 |
50 | Linters
51 |
52 | The Linters are tools that help us to check and solve the errors in the code
53 | This project count with three linters:
54 |
55 | HTML
56 | CSS
57 | JavaScript
58 |
59 |
60 |
61 |
62 |
63 | Webpack
64 |
65 | HTML Webpack Plugin
66 | Webpack Style/CSS Loader
67 | Local dev Server
68 |
69 |
70 |
71 |
72 | API's
73 |
74 | The Themealdb API is for obtain the food items.
75 | The Innvolvement API is a Microverse API that allows the control of likes and comments.
76 |
77 |
78 |
79 |
80 | ### Key Features
81 |
82 | - **Webpack Configuration**
83 | - **HTML Generation**
84 | - **CSS Styling**
85 | - **Development Server**
86 | - **Code Quality**
87 | - **Modular Structure**
88 | - **ES6 Syntax**
89 | - **JavaScript Functionality**
90 | - **Gitflow**
91 | - **Send and receive data from API**
92 | - **Jest testing**
93 | - **API's**
94 |
95 | (back to top )
96 |
97 |
98 | ## 💻 Getting Started
99 |
100 | > To get a local copy up and running, follow these steps.
101 | > This project requires Node.js and npm installed on your machine.
102 |
103 | -Node.js
104 | -npm
105 |
106 | > -Clone this repository to your local machine using:
107 |
108 | > git clone https://github.com/andream2429/JavaScriptCapstone.git
109 |
110 | > -Navigate to the project folder:
111 |
112 | > cd Leaderboard
113 |
114 | > -Install the project dependencies:
115 |
116 | > npm install
117 |
118 | > o start the development server, run the following command:
119 |
120 | > npm start
121 |
122 | ### Project Structure
123 |
124 | > The project follows the following folder and file structure:
125 |
126 | > /src: Contains the source files of the application.
127 | > /src/index.js: Main entry point of the JavaScript application.
128 | > /src/style.css: CSS file for the application styles.
129 | > /src/index.html: Base HTML file of the application.
130 | > /dist: Contains the generated production files.
131 | > webpack.config.js: Webpack configuration file.
132 |
133 | ### Setup
134 |
135 | > Clone this repository to your desired folder: https://github.com/andream2429/JavaScriptCapstone.git
136 |
137 | ### Install
138 |
139 | > Install this project with: install WebLint and ESLint
140 |
141 | ### Usage
142 |
143 | > To run the project, execute the following command: just need a web Browser
144 |
145 | ### Run tests
146 |
147 | > To run tests, run the following command: you just need a simple web browser to run this project for a test
148 |
149 | ## 👥 Authors
150 |
151 | 👤 **Andrea Manuel**
152 |
153 | - GitHub: [@AndreaM2429](https://github.com/AndreaM2429)
154 | - LinkedIn: [LinkedIn](https://www.linkedin.com/in/andrea-manuel-2b075026a/)
155 |
156 | 👤 **Claudia Rojas**
157 |
158 | - GitHub: [@githubhandle](https://github.com/ClaudiaRojasSoto)
159 | - LinkedIn: [LinkedIn](https://www.linkedin.com/in/claudia-soto-260504208/)
160 |
161 |
162 | (back to top )
163 |
164 | ## 🔭 Future Features
165 |
166 |
167 | - **[User Authentication]**
168 |
169 | (back to top )
170 |
171 | ## 🤝 Contributing
172 |
173 | > Contributions, issues, and feature requests are welcome!
174 |
175 | > Feel free to check the [issues page](https://github.com/AndreaM2429/JavaScriptCapstone/issues).
176 |
177 | (back to top )
178 |
179 | ## ⭐️ Show your support
180 |
181 | > If you like this project show support by following this account
182 |
183 | (back to top )
184 |
185 |
186 |
187 | ## 🙏 Acknowledgments
188 |
189 | > - Microverse for providing the opportunity to learn Git and GitHub in a collaborative environment.
190 |
191 | > - GitHub Docs for providing a wealth of information on Git and GitHub.
192 |
193 | (back to top )
194 |
195 |
196 |
197 | ## 📝 License
198 |
199 | > This project is [MIT](./LICENSE).
200 |
201 | (back to top )
202 |
--------------------------------------------------------------------------------
/dist/runtime.js:
--------------------------------------------------------------------------------
1 | /*
2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3 | * This devtool is neither made for production nor for readable output files.
4 | * It uses "eval()" calls to create a separate source file in the browser devtools.
5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6 | * or disable the default devtool with "devtool: false".
7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8 | */
9 | /******/ (() => { // webpackBootstrap
10 | /******/ "use strict";
11 | /******/ var __webpack_modules__ = ({});
12 | /************************************************************************/
13 | /******/ // The module cache
14 | /******/ var __webpack_module_cache__ = {};
15 | /******/
16 | /******/ // The require function
17 | /******/ function __webpack_require__(moduleId) {
18 | /******/ // Check if module is in cache
19 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
20 | /******/ if (cachedModule !== undefined) {
21 | /******/ return cachedModule.exports;
22 | /******/ }
23 | /******/ // Create a new module (and put it into the cache)
24 | /******/ var module = __webpack_module_cache__[moduleId] = {
25 | /******/ id: moduleId,
26 | /******/ // no module.loaded needed
27 | /******/ exports: {}
28 | /******/ };
29 | /******/
30 | /******/ // Execute the module function
31 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
32 | /******/
33 | /******/ // Return the exports of the module
34 | /******/ return module.exports;
35 | /******/ }
36 | /******/
37 | /******/ // expose the modules object (__webpack_modules__)
38 | /******/ __webpack_require__.m = __webpack_modules__;
39 | /******/
40 | /************************************************************************/
41 | /******/ /* webpack/runtime/chunk loaded */
42 | /******/ (() => {
43 | /******/ var deferred = [];
44 | /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
45 | /******/ if(chunkIds) {
46 | /******/ priority = priority || 0;
47 | /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
48 | /******/ deferred[i] = [chunkIds, fn, priority];
49 | /******/ return;
50 | /******/ }
51 | /******/ var notFulfilled = Infinity;
52 | /******/ for (var i = 0; i < deferred.length; i++) {
53 | /******/ var [chunkIds, fn, priority] = deferred[i];
54 | /******/ var fulfilled = true;
55 | /******/ for (var j = 0; j < chunkIds.length; j++) {
56 | /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
57 | /******/ chunkIds.splice(j--, 1);
58 | /******/ } else {
59 | /******/ fulfilled = false;
60 | /******/ if(priority < notFulfilled) notFulfilled = priority;
61 | /******/ }
62 | /******/ }
63 | /******/ if(fulfilled) {
64 | /******/ deferred.splice(i--, 1)
65 | /******/ var r = fn();
66 | /******/ if (r !== undefined) result = r;
67 | /******/ }
68 | /******/ }
69 | /******/ return result;
70 | /******/ };
71 | /******/ })();
72 | /******/
73 | /******/ /* webpack/runtime/compat get default export */
74 | /******/ (() => {
75 | /******/ // getDefaultExport function for compatibility with non-harmony modules
76 | /******/ __webpack_require__.n = (module) => {
77 | /******/ var getter = module && module.__esModule ?
78 | /******/ () => (module['default']) :
79 | /******/ () => (module);
80 | /******/ __webpack_require__.d(getter, { a: getter });
81 | /******/ return getter;
82 | /******/ };
83 | /******/ })();
84 | /******/
85 | /******/ /* webpack/runtime/define property getters */
86 | /******/ (() => {
87 | /******/ // define getter functions for harmony exports
88 | /******/ __webpack_require__.d = (exports, definition) => {
89 | /******/ for(var key in definition) {
90 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
91 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
92 | /******/ }
93 | /******/ }
94 | /******/ };
95 | /******/ })();
96 | /******/
97 | /******/ /* webpack/runtime/global */
98 | /******/ (() => {
99 | /******/ __webpack_require__.g = (function() {
100 | /******/ if (typeof globalThis === 'object') return globalThis;
101 | /******/ try {
102 | /******/ return this || new Function('return this')();
103 | /******/ } catch (e) {
104 | /******/ if (typeof window === 'object') return window;
105 | /******/ }
106 | /******/ })();
107 | /******/ })();
108 | /******/
109 | /******/ /* webpack/runtime/hasOwnProperty shorthand */
110 | /******/ (() => {
111 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
112 | /******/ })();
113 | /******/
114 | /******/ /* webpack/runtime/make namespace object */
115 | /******/ (() => {
116 | /******/ // define __esModule on exports
117 | /******/ __webpack_require__.r = (exports) => {
118 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
119 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
120 | /******/ }
121 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
122 | /******/ };
123 | /******/ })();
124 | /******/
125 | /******/ /* webpack/runtime/publicPath */
126 | /******/ (() => {
127 | /******/ var scriptUrl;
128 | /******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
129 | /******/ var document = __webpack_require__.g.document;
130 | /******/ if (!scriptUrl && document) {
131 | /******/ if (document.currentScript)
132 | /******/ scriptUrl = document.currentScript.src;
133 | /******/ if (!scriptUrl) {
134 | /******/ var scripts = document.getElementsByTagName("script");
135 | /******/ if(scripts.length) {
136 | /******/ var i = scripts.length - 1;
137 | /******/ while (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;
138 | /******/ }
139 | /******/ }
140 | /******/ }
141 | /******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
142 | /******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
143 | /******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
144 | /******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
145 | /******/ __webpack_require__.p = scriptUrl;
146 | /******/ })();
147 | /******/
148 | /******/ /* webpack/runtime/jsonp chunk loading */
149 | /******/ (() => {
150 | /******/ // no baseURI
151 | /******/
152 | /******/ // object to store loaded and loading chunks
153 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
154 | /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
155 | /******/ var installedChunks = {
156 | /******/ "runtime": 0
157 | /******/ };
158 | /******/
159 | /******/ // no chunk on demand loading
160 | /******/
161 | /******/ // no prefetching
162 | /******/
163 | /******/ // no preloaded
164 | /******/
165 | /******/ // no HMR
166 | /******/
167 | /******/ // no HMR manifest
168 | /******/
169 | /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
170 | /******/
171 | /******/ // install a JSONP callback for chunk loading
172 | /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
173 | /******/ var [chunkIds, moreModules, runtime] = data;
174 | /******/ // add "moreModules" to the modules object,
175 | /******/ // then flag all "chunkIds" as loaded and fire callback
176 | /******/ var moduleId, chunkId, i = 0;
177 | /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
178 | /******/ for(moduleId in moreModules) {
179 | /******/ if(__webpack_require__.o(moreModules, moduleId)) {
180 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
181 | /******/ }
182 | /******/ }
183 | /******/ if(runtime) var result = runtime(__webpack_require__);
184 | /******/ }
185 | /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
186 | /******/ for(;i < chunkIds.length; i++) {
187 | /******/ chunkId = chunkIds[i];
188 | /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
189 | /******/ installedChunks[chunkId][0]();
190 | /******/ }
191 | /******/ installedChunks[chunkId] = 0;
192 | /******/ }
193 | /******/ return __webpack_require__.O(result);
194 | /******/ }
195 | /******/
196 | /******/ var chunkLoadingGlobal = self["webpackChunkjavascriptcapstone"] = self["webpackChunkjavascriptcapstone"] || [];
197 | /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
198 | /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
199 | /******/ })();
200 | /******/
201 | /******/ /* webpack/runtime/nonce */
202 | /******/ (() => {
203 | /******/ __webpack_require__.nc = undefined;
204 | /******/ })();
205 | /******/
206 | /************************************************************************/
207 | /******/
208 | /******/
209 | /******/ })()
210 | ;
--------------------------------------------------------------------------------
/dist/main.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /*
3 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
4 | * This devtool is neither made for production nor for readable output files.
5 | * It uses "eval()" calls to create a separate source file in the browser devtools.
6 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
7 | * or disable the default devtool with "devtool: false".
8 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
9 | */
10 | (self["webpackChunkjavascriptcapstone"] = self["webpackChunkjavascriptcapstone"] || []).push([["main"],{
11 |
12 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/styles.css":
13 | /*!**************************************************************!*\
14 | !*** ./node_modules/css-loader/dist/cjs.js!./src/styles.css ***!
15 | \**************************************************************/
16 | /***/ ((module, __webpack_exports__, __webpack_require__) => {
17 |
18 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body {\n padding: 0;\n margin: 0;\n background-color: rgb(161, 230, 230);\n}\n\n.dflex {\n display: flex;\n justify-content: space-around;\n align-items: center;\n gap: 15px;\n flex-wrap: wrap;\n}\n\nheader,\nfooter {\n background-color: rgb(245, 209, 109);\n}\n\nmain {\n padding: 15px;\n}\n\n#logo {\n max-width: 100px;\n}\n\nul,\nli a {\n text-decoration: none;\n list-style: none;\n color: black;\n font-size: 15px;\n}\n\nfooter {\n font-size: 15px;\n text-align: center;\n justify-content: center;\n height: 50px;\n}\n\n.mealimg {\n width: 200px;\n}\n\n.mealtitle {\n justify-content: center;\n flex-direction: column;\n text-align: center;\n}\n\nh2 {\n color: brown;\n}\n\n.container,\n.item {\n width: 300px;\n height: 460px;\n margin-bottom: 40px;\n}\n\n.item {\n border: 3px solid brown;\n flex-direction: column;\n padding: 10px;\n background-color: rgba(250, 232, 182, 0.705);\n}\n\n#likes {\n background-color: transparent;\n border: transparent;\n font-size: 30px;\n color: brown;\n}\n\n#likes:active {\n color: red;\n font-weight: 900;\n}\n\n#comments {\n background-color: rgb(245, 209, 109);\n width: 100px;\n height: 34px;\n border-radius: 12px;\n border: 3px solid brown;\n}\n\n#commentsPopup {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 90%;\n max-width: 90vw;\n height: 90vh;\n max-height: 90vh;\n overflow-y: auto;\n background-color: rgb(250, 232, 182);\n padding: 20px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n text-align: center;\n border: 3px solid brown;\n}\n\n#commentsPopup h2 {\n margin-bottom: 20px;\n}\n\n#commentsPopup img {\n width: 400px;\n height: 300px;\n object-fit: cover;\n}\n\n#details-instructions {\n color: brown;\n padding: 30px;\n margin-left: 90px;\n margin-right: 90px;\n}\n\n#commentsPopup h3 {\n color: brown;\n margin-bottom: 25px;\n}\n\n#nameInput {\n margin-bottom: 10px;\n width: 70%;\n padding: 5px;\n border: 1px solid brown;\n}\n\n#commentInput {\n margin-bottom: 20px;\n width: 70%;\n padding: 5px;\n height: 100px;\n border: 1px solid brown;\n}\n\n#commentsPopup .closeButton {\n position: absolute;\n top: 20px;\n right: 20px;\n background: none;\n border: none;\n padding: 0;\n font-size: 40px;\n cursor: pointer;\n color: brown;\n}\n\n#submitCommentButton {\n background-color: rgb(245, 209, 109);\n width: 120px;\n height: 40px;\n border-radius: 12px;\n border: 2px solid brown;\n color: brown;\n font-size: 16px;\n margin-bottom: 20px;\n}\n\n.comment-text {\n color: brown;\n font-size: 14px;\n}\n\n.comments-count {\n color: brown;\n font-size: 15px;\n font-weight: bold;\n}\n\n#mainTitle {\n color: brown;\n font-size: 30px;\n font-weight: 900;\n}\n`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://javascriptcapstone/./src/styles.css?./node_modules/css-loader/dist/cjs.js");
19 |
20 | /***/ }),
21 |
22 | /***/ "./node_modules/css-loader/dist/runtime/api.js":
23 | /*!*****************************************************!*\
24 | !*** ./node_modules/css-loader/dist/runtime/api.js ***!
25 | \*****************************************************/
26 | /***/ ((module) => {
27 |
28 | eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/css-loader/dist/runtime/api.js?");
29 |
30 | /***/ }),
31 |
32 | /***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js":
33 | /*!**************************************************************!*\
34 | !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***!
35 | \**************************************************************/
36 | /***/ ((module) => {
37 |
38 | eval("\n\nmodule.exports = function (i) {\n return i[1];\n};\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/css-loader/dist/runtime/noSourceMaps.js?");
39 |
40 | /***/ }),
41 |
42 | /***/ "./src/styles.css":
43 | /*!************************!*\
44 | !*** ./src/styles.css ***!
45 | \************************/
46 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
47 |
48 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ \"./node_modules/style-loader/dist/runtime/styleDomAPI.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ \"./node_modules/style-loader/dist/runtime/insertBySelector.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ \"./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ \"./node_modules/style-loader/dist/runtime/insertStyleElement.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ \"./node_modules/style-loader/dist/runtime/styleTagTransform.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_styles_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./styles.css */ \"./node_modules/css-loader/dist/cjs.js!./src/styles.css\");\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());\noptions.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());\n\n options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, \"head\");\n \noptions.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());\noptions.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_styles_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"], options);\n\n\n\n\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_styles_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"] && _node_modules_css_loader_dist_cjs_js_styles_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals ? _node_modules_css_loader_dist_cjs_js_styles_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals : undefined);\n\n\n//# sourceURL=webpack://javascriptcapstone/./src/styles.css?");
49 |
50 | /***/ }),
51 |
52 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
53 | /*!****************************************************************************!*\
54 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
55 | \****************************************************************************/
56 | /***/ ((module) => {
57 |
58 | eval("\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?");
59 |
60 | /***/ }),
61 |
62 | /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js":
63 | /*!********************************************************************!*\
64 | !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
65 | \********************************************************************/
66 | /***/ ((module) => {
67 |
68 | eval("\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/insertBySelector.js?");
69 |
70 | /***/ }),
71 |
72 | /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js":
73 | /*!**********************************************************************!*\
74 | !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
75 | \**********************************************************************/
76 | /***/ ((module) => {
77 |
78 | eval("\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/insertStyleElement.js?");
79 |
80 | /***/ }),
81 |
82 | /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js":
83 | /*!**********************************************************************************!*\
84 | !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
85 | \**********************************************************************************/
86 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
87 |
88 | eval("\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?");
89 |
90 | /***/ }),
91 |
92 | /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js":
93 | /*!***************************************************************!*\
94 | !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
95 | \***************************************************************/
96 | /***/ ((module) => {
97 |
98 | eval("\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n var needLayer = typeof obj.layer !== \"undefined\";\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n css += obj.css;\n if (needLayer) {\n css += \"}\";\n }\n if (obj.media) {\n css += \"}\";\n }\n if (obj.supports) {\n css += \"}\";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === \"undefined\") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/styleDomAPI.js?");
99 |
100 | /***/ }),
101 |
102 | /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js":
103 | /*!*********************************************************************!*\
104 | !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
105 | \*********************************************************************/
106 | /***/ ((module) => {
107 |
108 | eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;\n\n//# sourceURL=webpack://javascriptcapstone/./node_modules/style-loader/dist/runtime/styleTagTransform.js?");
109 |
110 | /***/ }),
111 |
112 | /***/ "./src/Modules/commentsCounter.js":
113 | /*!****************************************!*\
114 | !*** ./src/Modules/commentsCounter.js ***!
115 | \****************************************/
116 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
117 |
118 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst countComments = () => {\n const comments = document.querySelectorAll('.comment-text');\n return comments.length;\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (countComments);\n\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/commentsCounter.js?");
119 |
120 | /***/ }),
121 |
122 | /***/ "./src/Modules/commentsPopup.js":
123 | /*!**************************************!*\
124 | !*** ./src/Modules/commentsPopup.js ***!
125 | \**************************************/
126 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
127 |
128 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _getItemsDetails_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getItemsDetails.js */ \"./src/Modules/getItemsDetails.js\");\n/* harmony import */ var _getComments_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getComments.js */ \"./src/Modules/getComments.js\");\n/* harmony import */ var _sendComment_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sendComment.js */ \"./src/Modules/sendComment.js\");\n/* harmony import */ var _commentsCounter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./commentsCounter.js */ \"./src/Modules/commentsCounter.js\");\n\n\n\n\n\nconst showCommentsPopup = async (id) => {\n const details = await (0,_getItemsDetails_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(id);\n const appId = 'k513WvYOj4wUaRdaeuNF';\n\n const popup = document.createElement('div');\n popup.id = 'commentsPopup';\n popup.innerHTML = `\n ${details.strMeal} \n \n ${details.strInstructions}
\n \n Add a comment \n \n × \n`;\n\n document.body.appendChild(popup);\n\n const commentsContainer = popup.querySelector('#commentsContainer');\n\n // Create a new element to display the comment count\n const commentsCountElement = document.createElement('p');\n commentsCountElement.id = 'commentsCount';\n commentsCountElement.classList.add('comments-count');\n\n popup.insertBefore(commentsCountElement, commentsContainer);\n\n const updateComments = async () => {\n const comments = await (0,_getComments_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(appId, id);\n if (!Array.isArray(comments)) {\n // This block it's designed to handle the empty data in comments\n } else {\n commentsContainer.innerHTML = '';\n comments.forEach((comment) => {\n const commentElement = document.createElement('p');\n commentElement.textContent = `${comment.creation_date} - ${comment.username}: ${comment.comment}`;\n commentElement.classList.add('comment-text');\n commentsContainer.appendChild(commentElement);\n });\n // Update the comments count after updating the comments\n commentsCountElement.textContent = `Comments: ${(0,_commentsCounter_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()}`;\n }\n };\n\n await updateComments();\n\n const form = popup.querySelector('#commentForm');\n form.addEventListener('submit', async (event) => {\n const usernameInput = popup.querySelector('#nameInput');\n const commentInput = popup.querySelector('#commentInput');\n\n event.preventDefault();\n\n const username = usernameInput.value;\n const comment = commentInput.value;\n\n await (0,_sendComment_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(appId, id, username, comment);\n await updateComments(); // Update the comments (and the count) after submitting a comment\n\n // Clear the input fields after the comment has been sent and comments have been updated\n usernameInput.value = '';\n commentInput.value = '';\n });\n\n popup.querySelector('.closeButton').addEventListener('click', () => {\n document.body.removeChild(popup);\n });\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (showCommentsPopup);\n\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/commentsPopup.js?");
129 |
130 | /***/ }),
131 |
132 | /***/ "./src/Modules/errorHandler.js":
133 | /*!*************************************!*\
134 | !*** ./src/Modules/errorHandler.js ***!
135 | \*************************************/
136 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
137 |
138 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst handleFetchError = (error) => {\n const errorMessage = document.getElementById('error-message');\n if (errorMessage) {\n errorMessage.innerHTML = `${error.message} `;\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (handleFetchError);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/errorHandler.js?");
139 |
140 | /***/ }),
141 |
142 | /***/ "./src/Modules/getComments.js":
143 | /*!************************************!*\
144 | !*** ./src/Modules/getComments.js ***!
145 | \************************************/
146 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
147 |
148 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst getComments = async (appId, id) => {\n try {\n const response = await fetch(`https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/${appId}/comments?item_id=${id}`);\n const data = await response.json();\n return data;\n } catch (error) {\n return error;\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getComments);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/getComments.js?");
149 |
150 | /***/ }),
151 |
152 | /***/ "./src/Modules/getItems.js":
153 | /*!*********************************!*\
154 | !*** ./src/Modules/getItems.js ***!
155 | \*********************************/
156 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
157 |
158 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _commentsPopup_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./commentsPopup.js */ \"./src/Modules/commentsPopup.js\");\n/* harmony import */ var _errorHandler_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./errorHandler.js */ \"./src/Modules/errorHandler.js\");\n/* harmony import */ var _likes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./likes.js */ \"./src/Modules/likes.js\");\n/* harmony import */ var _itemCounter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./itemCounter.js */ \"./src/Modules/itemCounter.js\");\n\n\n\n\n\nconst container = document.querySelector('#itemsContainer');\n\nconst displayItems = (dataMeals) => {\n dataMeals.forEach(async (meals) => {\n const numberOfLikes = await (0,_likes_js__WEBPACK_IMPORTED_MODULE_2__.getLikes)();\n let likes = 0;\n numberOfLikes.forEach((elem) => {\n if (elem.item_id === meals.idMeal) {\n likes = elem.likes;\n }\n });\n const mainDiv = document.createElement('div');\n mainDiv.className = 'dflex container';\n mainDiv.innerHTML = `\n \n
\n
\n
${meals.strMeal} \n
\n ${likes} likes \n ♡ \n
\n
\n \n
\n `;\n\n mainDiv.querySelectorAll('#comments').forEach((commentsButton) => {\n commentsButton.addEventListener('click', async () => {\n await (0,_commentsPopup_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(meals.idMeal).catch(_errorHandler_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"]);\n });\n });\n\n mainDiv.querySelector('#likes').addEventListener('click', async (event) => {\n const id = event.target.className;\n await (0,_likes_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(id);\n const updateLikes = mainDiv.querySelector('#likesNumber');\n await (0,_likes_js__WEBPACK_IMPORTED_MODULE_2__.updateText)(meals.idMeal, updateLikes);\n });\n\n container.appendChild(mainDiv);\n });\n};\n\nconst getItems = async () => {\n const request = await fetch('https://themealdb.com/api/json/v1/1/filter.php?c=Vegetarian');\n const data = await request.json();\n displayItems(data.meals);\n (0,_itemCounter_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(data.meals.length);\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getItems);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/getItems.js?");
159 |
160 | /***/ }),
161 |
162 | /***/ "./src/Modules/getItemsDetails.js":
163 | /*!****************************************!*\
164 | !*** ./src/Modules/getItemsDetails.js ***!
165 | \****************************************/
166 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
167 |
168 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst getItemDetails = async (id) => {\n const request = await fetch(`https://www.themealdb.com/api/json/v1/1/lookup.php?i=${id}`);\n const data = await request.json();\n return data.meals[0];\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getItemDetails);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/getItemsDetails.js?");
169 |
170 | /***/ }),
171 |
172 | /***/ "./src/Modules/itemCounter.js":
173 | /*!************************************!*\
174 | !*** ./src/Modules/itemCounter.js ***!
175 | \************************************/
176 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
177 |
178 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst homeItemCounter = (containerItems) => {\n const hometitle = document.querySelector('#mainTitle');\n hometitle.textContent = `${containerItems} Vegetarian Recipes`;\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (homeItemCounter);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/itemCounter.js?");
179 |
180 | /***/ }),
181 |
182 | /***/ "./src/Modules/likes.js":
183 | /*!******************************!*\
184 | !*** ./src/Modules/likes.js ***!
185 | \******************************/
186 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
187 |
188 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ getLikes: () => (/* binding */ getLikes),\n/* harmony export */ updateText: () => (/* binding */ updateText)\n/* harmony export */ });\nconst postLikes = async (id) => {\n const sendData = await fetch('https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/k513WvYOj4wUaRdaeuNF/likes/', {\n method: 'POST',\n headers: {\n 'Content-type': 'application/json; charset=UTF-8',\n },\n body: JSON.stringify({\n item_id: id,\n }),\n });\n const result = await sendData.text();\n return result;\n};\n\nconst getLikes = async () => {\n const requestLikes = await fetch('https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/k513WvYOj4wUaRdaeuNF/likes/');\n const dataLikes = await requestLikes.json();\n return dataLikes;\n};\n\nconst updateText = async (idmeal, span) => {\n const numberOfLikes = await getLikes();\n let likes = 0;\n numberOfLikes.forEach((elem) => {\n if (elem.item_id === idmeal) {\n likes = elem.likes;\n }\n });\n span.textContent = `${likes} likes`;\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (postLikes);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/likes.js?");
189 |
190 | /***/ }),
191 |
192 | /***/ "./src/Modules/sendComment.js":
193 | /*!************************************!*\
194 | !*** ./src/Modules/sendComment.js ***!
195 | \************************************/
196 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
197 |
198 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst sendComment = async (appId, id, username1, comment1) => {\n const response = await fetch(`https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/${appId}/comments`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n item_id: id,\n username: username1,\n comment: comment1,\n }),\n });\n\n if (!response.ok) {\n throw new Error('Error sending the comment');\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (sendComment);\n\n//# sourceURL=webpack://javascriptcapstone/./src/Modules/sendComment.js?");
199 |
200 | /***/ }),
201 |
202 | /***/ "./src/index.js":
203 | /*!**********************!*\
204 | !*** ./src/index.js ***!
205 | \**********************/
206 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
207 |
208 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _styles_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./styles.css */ \"./src/styles.css\");\n/* harmony import */ var _images_VegetarianRestauratLogo_png__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./images/VegetarianRestauratLogo.png */ \"./src/images/VegetarianRestauratLogo.png\");\n/* harmony import */ var _Modules_getItems_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Modules/getItems.js */ \"./src/Modules/getItems.js\");\n\n\n\n\ndocument.querySelector('#logo').src = _images_VegetarianRestauratLogo_png__WEBPACK_IMPORTED_MODULE_1__;\n\nwindow.addEventListener('load', () => {\n (0,_Modules_getItems_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])();\n});\n\n\n//# sourceURL=webpack://javascriptcapstone/./src/index.js?");
209 |
210 | /***/ }),
211 |
212 | /***/ "./src/images/VegetarianRestauratLogo.png":
213 | /*!************************************************!*\
214 | !*** ./src/images/VegetarianRestauratLogo.png ***!
215 | \************************************************/
216 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
217 |
218 | eval("module.exports = __webpack_require__.p + \"b3909570c94cc41b9906.png\";\n\n//# sourceURL=webpack://javascriptcapstone/./src/images/VegetarianRestauratLogo.png?");
219 |
220 | /***/ })
221 |
222 | },
223 | /******/ __webpack_require__ => { // webpackRuntimeModules
224 | /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
225 | /******/ var __webpack_exports__ = (__webpack_exec__("./src/index.js"));
226 | /******/ }
227 | ]);
--------------------------------------------------------------------------------
Comment 1
11 |Comment 2
12 |Comment 3
13 |