├── app_screenshot.png ├── src ├── function │ ├── itemsCounter.js │ ├── itemLikes.js │ └── request.js ├── assets │ └── images │ │ ├── logo.png │ │ └── nav-logo.gif ├── index.js ├── tests │ ├── commentsCounter.test.js │ └── itemsCount.test.js ├── dom │ ├── likeButton.js │ ├── homePage.js │ └── commentPopUp.js ├── index.html ├── show.html └── style.css ├── .babelrc ├── .stylelintrc.json ├── .hintrc ├── .eslintrc.json ├── MIT.md ├── webpack.config.js ├── package.json ├── .gitignore ├── dist ├── index.html └── main.bundle.js ├── .github └── workflows │ └── linters.yml └── README.md /app_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamzaoutdoors/Serie_Lovers---JS-Capstone-/HEAD/app_screenshot.png -------------------------------------------------------------------------------- /src/function/itemsCounter.js: -------------------------------------------------------------------------------- 1 | const itemsCounter = (items) => items.length; 2 | 3 | export default itemsCounter; 4 | -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamzaoutdoors/Serie_Lovers---JS-Capstone-/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/nav-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hamzaoutdoors/Serie_Lovers---JS-Capstone-/HEAD/src/assets/images/nav-logo.gif -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "plugins": [ 5 | "@babel/plugin-transform-modules-commonjs" 6 | ] 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import homePage from './dom/homePage.js'; 3 | 4 | window.addEventListener('DOMContentLoaded', () => { 5 | homePage(); 6 | }); 7 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": null, 6 | "scss/at-rule-no-unknown": true, 7 | "csstree/validator": true 8 | }, 9 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"] 10 | } -------------------------------------------------------------------------------- /.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 | } 19 | -------------------------------------------------------------------------------- /.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 | } -------------------------------------------------------------------------------- /src/function/itemLikes.js: -------------------------------------------------------------------------------- 1 | const involvementLikesURL = 'https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/Likes/'; 2 | 3 | const postLike = async (itemId) => { 4 | await fetch(involvementLikesURL, { 5 | method: 'POST', 6 | headers: { 7 | 'Content-Type': 'application/json', 8 | }, 9 | body: JSON.stringify({ 10 | item_id: `item${itemId}`, 11 | }), 12 | }); 13 | }; 14 | 15 | const fetchData = async (url) => { 16 | const res = await fetch(url); 17 | const result = await res.json(); 18 | return result; 19 | }; 20 | 21 | export { postLike, fetchData }; -------------------------------------------------------------------------------- /src/tests/commentsCounter.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /* eslint-disable quote-props */ 3 | import itemsCounter from '../function/itemsCounter.js'; 4 | 5 | global.comments = [{ 6 | 'item_id': 'item1', 7 | 'username': 'Jane', 8 | 'comment': 'Hello', 9 | }, 10 | { 11 | 'item_id': 'item1', 12 | 'username': 'Jane', 13 | 'comment': 'Hello', 14 | }, 15 | { 16 | 'item_id': 'item1', 17 | 'username': 'Jane', 18 | 'comment': 'Hello', 19 | }, 20 | { 21 | 'item_id': 'item1', 22 | 'username': 'Jane', 23 | 'comment': 'Hello', 24 | }]; 25 | 26 | describe('shows list counter', () => { 27 | test('this list api had four items', () => { 28 | // Arrange 29 | let count = 0; 30 | // Act 31 | count = itemsCounter(comments); 32 | 33 | // Assert 34 | expect(count).toBe(4); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /MIT.md: -------------------------------------------------------------------------------- 1 | ## Copyright 2021, [YOUR NAME] 2 | 3 | ###### Please delete this line and the next one 4 | ###### APP TYPE can be a webpage/website, a web app, a software and so on 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this [APP TYPE] and associated documentation files, to deal in the [APP TYPE] without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the [APP TYPE], and to permit persons to whom the [APP TYPE] is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the [APP TYPE]. 9 | 10 | THE [APP TYPE] IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE [APP TYPE] OR THE USE OR OTHER DEALINGS IN THE [APP TYPE]. 11 | -------------------------------------------------------------------------------- /src/function/request.js: -------------------------------------------------------------------------------- 1 | const requestURL = 'https://api.tvmaze.com/shows'; 2 | 3 | const getShows = async () => { 4 | const response = await fetch(requestURL); 5 | const list = await response.json(); 6 | if (list) { 7 | document.getElementById('loading').style.display = 'none'; 8 | } 9 | return list; 10 | }; 11 | 12 | const getComments = async (itemId) => { 13 | const involvementUrl = `https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/comments?item_id=item${itemId}`; 14 | const response = await fetch(involvementUrl, { 15 | method: 'GET', 16 | }); 17 | const list = await response.json(); 18 | return list; 19 | }; 20 | 21 | const postComment = async (name, comment, itemId) => { 22 | const postUrl = 'https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/comments'; 23 | const postData = { 24 | item_id: itemId, 25 | username: name, 26 | comment, 27 | }; 28 | await fetch(postUrl, { 29 | method: 'POST', 30 | headers: { 31 | 'Content-type': 'application/json; charset=UTF-8', 32 | }, 33 | body: JSON.stringify(postData), 34 | }); 35 | }; 36 | 37 | export { getShows, getComments, postComment }; 38 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: './src/index.js', 6 | devServer: { 7 | contentBase: './dist', 8 | }, 9 | plugins: [ 10 | 11 | new HtmlWebpackPlugin({ 12 | inject: 'body', 13 | template: './src/index.html', 14 | filename: 'index.html', 15 | minify: { 16 | removeComments: true, 17 | collapseWhitespace: true, 18 | }, 19 | }), 20 | ], 21 | output: { 22 | filename: '[name].bundle.js', 23 | path: path.resolve(__dirname, 'dist'), 24 | clean: true, 25 | }, 26 | mode: 'production', 27 | module: { 28 | rules: [ 29 | { 30 | test: /\.css$/i, 31 | use: ['style-loader', 'css-loader'], 32 | }, 33 | { 34 | test: /\.(gif|png|jpe?g)$/, 35 | use: [ 36 | { 37 | loader: 'file-loader', 38 | options: { 39 | name: '[name].[ext]', 40 | outputPath: 'assets/images/', 41 | }, 42 | }, 43 | ], 44 | }, 45 | { 46 | test: /\.html$/, 47 | use: [ 48 | 'html-loader', 49 | ], 50 | }, 51 | ], 52 | }, 53 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "capstone_js", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "jest --coverage", 9 | "watch": "webpack --watch", 10 | "start": "webpack serve --open", 11 | "deploy": "npm run build && gh-pages -d dist", 12 | "build": "webpack" 13 | }, 14 | "jest": { 15 | "testEnvironment": "jsdom" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/Hamzaoutdoors/Leaderboard-API.git" 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/Hamzaoutdoors/Leaderboard-API/issues" 26 | }, 27 | "homepage": "https://github.com/Hamzaoutdoors/Leaderboard-API#readme", 28 | "devDependencies": { 29 | "@babel/plugin-transform-modules-commonjs": "^7.15.0", 30 | "babel-eslint": "^10.1.0", 31 | "css-loader": "^6.2.0", 32 | "eslint": "^7.32.0", 33 | "eslint-config-airbnb-base": "^14.2.1", 34 | "eslint-plugin-import": "^2.24.0", 35 | "file-loader": "^1.1.6", 36 | "gh-pages": "^3.2.3", 37 | "hint": "^6.1.4", 38 | "html-loader": "^0.5.5", 39 | "html-webpack-plugin": "^5.3.2", 40 | "jest": "^27.1.0", 41 | "style-loader": "^3.2.1", 42 | "stylelint": "^13.13.1", 43 | "stylelint-config-standard": "^21.0.0", 44 | "stylelint-csstree-validator": "^1.9.0", 45 | "stylelint-scss": "^3.20.1", 46 | "url-loader": "^4.1.1", 47 | "webpack": "^5.50.0", 48 | "webpack-cli": "^4.8.0", 49 | "webpack-dev-server": "^3.11.2" 50 | }, 51 | "dependencies": { 52 | "canvas": "^2.8.0", 53 | "lodash": "^4.17.21" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/dom/likeButton.js: -------------------------------------------------------------------------------- 1 | import { postLike, fetchData } from '../function/itemLikes.js'; 2 | 3 | const involvementLikesURL = 'https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/Likes/'; 4 | 5 | const showLikes = (response, span, idItem) => { 6 | const data = response.filter((item) => item.item_id === idItem); 7 | if (data.length !== 0) { 8 | span.innerHTML = `${data[0].likes} likes`; 9 | } 10 | if (data.length === 0) { 11 | span.innerHTML = '0 likes'; 12 | } 13 | }; 14 | 15 | const likeButton = (itemId, div) => { 16 | const heartBtn = document.createElement('div'); 17 | const likeSpan = document.createElement('span'); 18 | const content = document.createElement('div'); 19 | const heartIcon = document.createElement('button'); 20 | 21 | heartBtn.classList.add('heart-btn'); 22 | heartBtn.id = itemId; 23 | content.classList.add('content'); 24 | fetchData(involvementLikesURL) 25 | .then((response) => { 26 | showLikes(response, likeSpan, `item${itemId}`); 27 | }); 28 | likeSpan.id = `numb${itemId}`; 29 | likeSpan.setAttribute('class', 'numb'); 30 | heartIcon.classList.add('heart'); 31 | heartIcon.id = `like${itemId}`; 32 | content.appendChild(likeSpan); 33 | heartIcon.innerHTML = '🤍'; 34 | heartIcon.addEventListener('click', async (ev) => { 35 | const { id } = ev.target; 36 | const likeId = id.slice(4); 37 | ev.preventDefault(); 38 | if (id && id.includes('like')) { 39 | document.getElementById(`${id}`).innerHTML = '❤️'; 40 | content.classList.add('red-bg'); 41 | await postLike(likeId); 42 | } 43 | setTimeout(() => { 44 | document.getElementById(`${id}`).innerHTML = '🤍'; 45 | content.classList.remove('red-bg'); 46 | }, 10); 47 | fetchData(involvementLikesURL) 48 | .then((response) => { 49 | showLikes(response, likeSpan, `item${likeId}`); 50 | }); 51 | }); 52 | heartBtn.appendChild(content); 53 | heartBtn.insertBefore(heartIcon, heartBtn.childNodes[0]); 54 | div.appendChild(heartBtn); 55 | }; 56 | 57 | export default likeButton; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | Series lover

Best shows for the week

Loading...
-------------------------------------------------------------------------------- /.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-18.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: "12.x" 17 | - name: Setup Lighthouse 18 | run: npm install -g @lhci/cli@0.7.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-18.04 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: actions/setup-node@v1 27 | with: 28 | node-version: "12.x" 29 | - name: Setup Webhint 30 | run: | 31 | npm install --save-dev hint@6.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 --telemetry=off . 35 | stylelint: 36 | name: Stylelint 37 | runs-on: ubuntu-18.04 38 | steps: 39 | - uses: actions/checkout@v2 40 | - uses: actions/setup-node@v1 41 | with: 42 | node-version: "12.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-18.04 52 | steps: 53 | - uses: actions/checkout@v2 54 | - uses: actions/setup-node@v1 55 | with: 56 | node-version: "12.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 . -------------------------------------------------------------------------------- /src/tests/itemsCount.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /* eslint-disable quote-props */ 3 | import itemsCounter from '../function/itemsCounter.js'; 4 | 5 | global.fetch = () => Promise.resolve({ 6 | json: () => Promise.resolve([{ 7 | 'id': 1, 8 | 'name': 'Under the Dome', 9 | 'image': { 10 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/81/202627.jpg', 11 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/81/202627.jpg', 12 | }, 13 | }, 14 | { 15 | 'id': 2, 16 | 'name': 'Person of Interest', 17 | 'image': { 18 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/163/407679.jpg', 19 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/163/407679.jpg', 20 | }, 21 | }, 22 | { 23 | 'id': 3, 24 | 'name': 'Bitten', 25 | 'image': { 26 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/0/15.jpg', 27 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/0/15.jpg', 28 | }, 29 | }, 30 | { 31 | 'id': 4, 32 | 'name': 'Arrow', 33 | 'image': { 34 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/213/534017.jpg', 35 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/213/534017.jpg', 36 | }, 37 | }]), 38 | }); 39 | 40 | global.shows = [{ 41 | 'id': 1, 42 | 'name': 'Under the Dome', 43 | 'image': { 44 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/81/202627.jpg', 45 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/81/202627.jpg', 46 | }, 47 | }, 48 | { 49 | 'id': 2, 50 | 'name': 'Person of Interest', 51 | 'image': { 52 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/163/407679.jpg', 53 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/163/407679.jpg', 54 | }, 55 | }, 56 | { 57 | 'id': 3, 58 | 'name': 'Bitten', 59 | 'image': { 60 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/0/15.jpg', 61 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/0/15.jpg', 62 | }, 63 | }, 64 | { 65 | 'id': 4, 66 | 'name': 'Arrow', 67 | 'image': { 68 | 'medium': 'https://static.tvmaze.com/uploads/images/medium_portrait/213/534017.jpg', 69 | 'original': 'https://static.tvmaze.com/uploads/images/original_untouched/213/534017.jpg', 70 | }, 71 | }]; 72 | 73 | describe('shows list counter', () => { 74 | test('this list api had four items', () => { 75 | // Arrange 76 | let count = 0; 77 | // Act 78 | count = itemsCounter(shows); 79 | 80 | // Assert 81 | expect(count).toBe(4); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | Series lover 12 | 13 | 14 |
15 | 33 |
34 |
35 |

Best shows for the week

36 |
37 |
38 |
39 | Loading... 40 |
41 |
42 |
43 | 49 | 50 |
51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/show.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | Series lover 11 | 12 | 13 | 14 |
15 | 34 |
35 |
37 |

Find movie for Today

38 |
39 | Loading... 40 |
41 |
42 |
43 |
44 | show image 45 |
46 |
47 |
48 |
Breaking bad
49 |

It's ABOUT ....

50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 | 63 | 64 |
65 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/dom/homePage.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-cycle */ 2 | import { getShows, getComments, postComment } from '../function/request.js'; 3 | import commentPopUp from './commentPopUp.js'; 4 | import likeButton from './likeButton.js'; 5 | import itemsCounter from '../function/itemsCounter.js'; 6 | 7 | const homePage = async () => { 8 | const container = document.getElementById('homePage'); 9 | const counter = document.getElementById('counter'); 10 | let myShows = await getShows(); 11 | myShows = myShows.slice(160, 169); 12 | counter.innerHTML = `(${itemsCounter(myShows)})`; 13 | myShows.forEach((show) => { 14 | const colDiv = document.createElement('div'); 15 | colDiv.classList.add('col'); 16 | const showDiv = document.createElement('div'); 17 | showDiv.classList.add('card', 'h-100', 'border-warning', 'd-flex', 'flex-column', 'align-items-center', 'showCard', 'mb-3'); 18 | showDiv.classList.add('col-12'); 19 | const myImage = document.createElement('img'); 20 | myImage.classList.add('show-image'); 21 | const imageUrl = show.image.original; 22 | myImage.setAttribute('src', imageUrl); 23 | 24 | const ImagePop = document.createElement('img'); 25 | ImagePop.classList.add('popup-image'); 26 | ImagePop.setAttribute('src', imageUrl); 27 | 28 | const movieTitle = document.createElement('h5'); 29 | movieTitle.classList.add('p-2', 'px-5', 'mt-3', 'title-bg'); 30 | movieTitle.innerHTML = show.name; 31 | 32 | const likeDiv = document.createElement('div'); 33 | likeDiv.classList.add('d-flex', 'flex-column', 'align-items-center', 'justify-content-center'); 34 | likeButton(show.id, likeDiv); 35 | 36 | const movieTitlePop = document.createElement('h5'); 37 | movieTitlePop.classList.add('p-2'); 38 | movieTitlePop.innerHTML = show.name; 39 | 40 | const commentButton = document.createElement('button'); 41 | commentButton.classList.add('btn', 'btn-warning', 'comment-bg', 'h-50', 'font-weight-bold'); 42 | commentButton.innerHTML = 'comment'; 43 | commentButton.id = `item${show.id}`; 44 | const newDiv = document.createElement('div'); 45 | newDiv.classList.add('d-flex', 'justify-content-between'); 46 | 47 | commentButton.addEventListener('click', async (e) => { 48 | e.preventDefault(); 49 | const myComments = await getComments(show.id); 50 | if (myComments.error) { 51 | commentPopUp( 52 | ImagePop, 53 | movieTitlePop, 54 | show.language, 55 | show.runtime, 56 | show.status, 57 | show.rating.average, 58 | ); 59 | } else { 60 | commentPopUp( 61 | ImagePop, 62 | movieTitlePop, 63 | show.language, 64 | show.runtime, 65 | show.status, 66 | show.rating.average, 67 | myComments, 68 | ); 69 | } 70 | const myName = document.getElementById('name'); 71 | const commentInput = document.getElementById('comment'); 72 | const buttonComment = document.getElementById('commentBtn'); 73 | const commentSection = document.getElementById('commentSection'); 74 | const commentClass = document.getElementsByClassName('commentClass'); 75 | buttonComment.addEventListener('click', (e) => { 76 | e.preventDefault(); 77 | postComment(myName.value, commentInput.value, `item${show.id}`); 78 | const newComment = document.createElement('p'); 79 | newComment.innerHTML = `${myName.value}: ${commentInput.value}`; 80 | commentSection.appendChild(newComment); 81 | if (commentClass[0].innerHTML === 'No: comments') { 82 | commentClass[0].innerHTML = ''; 83 | } 84 | myName.value = ''; 85 | commentInput.value = ''; 86 | }); 87 | }); 88 | 89 | showDiv.appendChild(myImage); 90 | showDiv.appendChild(movieTitle); 91 | newDiv.appendChild(commentButton); 92 | newDiv.appendChild(likeDiv); 93 | showDiv.appendChild(newDiv); 94 | colDiv.appendChild(showDiv); 95 | container.appendChild(colDiv); 96 | }); 97 | }; 98 | 99 | export default homePage; 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Microverse 4 | 5 | 6 | MIT Licensed 7 | 8 | 9 | GitHub last commit (branch) 10 | 11 | 12 | GitHub Repo stars 13 | 14 | 15 | GitHub followers 16 | 17 |

18 | 19 |
20 |
21 | 22 |
23 |
24 | " Programming is the breaking of one big impossible task into several very small possible tasks .." - Good programmer 25 |
26 | 27 | # JS-Capstone: Series lover 28 | 29 | > The Series lover website displays scores submitted by different series. It also allows users to submit their comments in every serie show. All data is preserved thanks to the external [TVmaze API](https://www.tvmaze.com/api), the user can like his favourite serie thanks to [Involvement API](https://www.notion.so/Involvement-API-869e60b5ad104603aa6db59e08150270) 30 | 31 |

32 | 33 | logo 34 | 35 |

36 | 37 |

38 | Screenshot 39 |

40 |

41 | Popup 42 |

screen shot of our project

43 |

44 | 45 | # Capstone Live Demo 46 | [Live Demo Link](https://hamzaoutdoors.github.io/Serie_Lovers---JS-Capstone-/) 47 | 48 | # Built with 🔨 49 | - HTML5, CSS3 50 | - JavaScript-ES6 51 | - Bootstrap 5 52 | - Git & Github 53 | - Unit testing with Jest 54 | - github pages 55 | - Visual Studio 56 | - API (async & await) 57 | - fix errors with Linters 58 | - Features of webpack and plugins already included 59 | - style-loader 60 | - css loader 61 | - HtmlWebpackPlugin 62 | - WebPack Dev Server 63 | 64 | # Usage 65 | 66 | - Navigate to your desired directory in your local machine using the terminal. 67 | 68 | - Clone repository by running git clone 69 | 70 | ```sh 71 | $ git clone https://github.com/Hamzaoutdoors/js_capstone.git 72 | ``` 73 | in your local terminal 74 | 75 | - After, run the following commands in your terminal: 76 | ```sh 77 | $ cd JS-Capstone 78 | $ npm install 79 | $ npm run build 80 | $ cd dist 81 | ``` 82 | 83 | - OR Use the following commands to npm run start to start the Webpack Dev server and serve the files from the dist directory npm run build to complile build all source files into the dist directory ```npm run watch``` to set webpack into watch mode so that the build is automatically run whenever changes are made to any of the source files. 84 | 85 | # Authors 86 | 87 | 👤 **Ellaouzi Hamza** 88 | 89 | - GitHub: [hamzaoutdoors](https://github.com/Hamzaoutdoors) 90 | - LinkedIn : [Hamza Ellaouzi](https://www.linkedin.com/in/hamza-ellaouzi-137a45b8/) 91 | - Twitter: [Hamza Ellaouzi](https://twitter.com/EllaouziHamza) 92 | 93 | 👤 **Emmanuel Isabirye** 94 | 95 | - GitHub: [Emmanuelaaron](https://github.com/Emmanuelaaron) 96 | - LinkedIn : [Emmanuel Isabirye](https://www.linkedin.com/in/fullstackwebdev-emma/) 97 | - Twitter: [Emmanuel Isabirye](https://twitter.com/EmmanuelIsabir1) 98 | 99 | # 🤝 Contributing 100 | 101 | Contributions, issues, and feature requests are welcome! 102 | 103 | Feel free to check the [issues page](https://github.com/Hamzaoutdoors/js_capstone/issues). 104 | 105 | # Show your support 106 | 107 | Give a ⭐️ if you like this project! 108 | -------------------------------------------------------------------------------- /src/dom/commentPopUp.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-cycle */ 2 | import homePage from './homePage.js'; 3 | import itemsCounter from '../function/itemsCounter.js'; 4 | 5 | const commentPopUp = (image, title, language, runtime, status, rating, commentsArray = [{ username: 'No', comment: 'comments' }]) => { 6 | const popUpOverLay = document.getElementById('overlay'); 7 | popUpOverLay.classList.remove('d-none'); 8 | popUpOverLay.classList.add('d-block', 'd-flex'); 9 | 10 | const headerPopUp = document.createElement('div'); 11 | const closeBtn = document.createElement('h2'); 12 | closeBtn.innerHTML = '+'; 13 | closeBtn.classList.add('close-btn'); 14 | closeBtn.addEventListener('click', async () => { 15 | popUpOverLay.classList.remove('d-block'); 16 | popUpOverLay.classList.add('d-none'); 17 | homePage(); 18 | popUpOverLay.innerHTML = ''; 19 | }); 20 | headerPopUp.classList.add('w-100', 'd-flex', 'justify-content-end'); 21 | headerPopUp.appendChild(closeBtn); 22 | 23 | const foreGroundPopUp = document.createElement('div'); 24 | foreGroundPopUp.classList.add( 25 | 'foreground-overlay', 26 | 'd-flex', 27 | 'flex-column', 28 | 'align-items-center', 29 | ); 30 | 31 | const popUpFooter = document.createElement('div'); 32 | popUpFooter.classList.add('d-flex', 'w-50', 'justify-content-evenly'); 33 | 34 | const popUpFooterLeft = document.createElement('div'); 35 | const languagePop = document.createElement('h5'); 36 | const runtimePop = document.createElement('h5'); 37 | languagePop.innerHTML = `Language: ${language}`; 38 | runtimePop.innerHTML = `Runtime: ${runtime}`; 39 | 40 | popUpFooterLeft.appendChild(languagePop); 41 | popUpFooterLeft.appendChild(runtimePop); 42 | 43 | const popUpFooterRight = document.createElement('div'); 44 | const statusPop = document.createElement('h5'); 45 | const ratingPop = document.createElement('h5'); 46 | ratingPop.classList.add('w-100'); 47 | statusPop.innerHTML = `Status: ${status}`; 48 | ratingPop.innerHTML = `Rating: ${rating}`; 49 | 50 | popUpFooterRight.appendChild(statusPop); 51 | popUpFooterRight.appendChild(ratingPop); 52 | 53 | popUpFooter.appendChild(popUpFooterLeft); 54 | popUpFooter.appendChild(popUpFooterRight); 55 | 56 | const commentSection = document.createElement('div'); 57 | commentSection.id = 'commentSection'; 58 | commentSection.classList.add('w-75'); 59 | const commentHeading = document.createElement('h5'); 60 | commentHeading.classList.add('mb-3'); 61 | const itemsCount = itemsCounter(commentsArray); 62 | commentHeading.innerHTML = `Comments(${itemsCount})`; 63 | commentSection.appendChild(commentHeading); 64 | 65 | const commentsCountainer = document.createElement('div'); 66 | 67 | commentsArray.forEach((comment) => { 68 | const myComment = document.createElement('p'); 69 | myComment.className = 'commentClass'; 70 | myComment.innerHTML = `${comment.username}: ${comment.comment}`; 71 | if (comment.username === 'No') { 72 | commentHeading.innerHTML = 'No comments for this show'; 73 | commentsCountainer.classList.remove('comments-countainer'); 74 | } 75 | commentsCountainer.classList.add('comments-countainer'); 76 | commentsCountainer.appendChild(myComment); 77 | }); 78 | 79 | const addComment = document.createElement('div'); 80 | const addCommHeading = document.createElement('h5'); 81 | addCommHeading.innerHTML = 'Add Comment'; 82 | 83 | const imageDiv = document.createElement('div'); 84 | imageDiv.appendChild(image); 85 | imageDiv.classList.add( 86 | 'w-100', 'h-50', 87 | 'd-flex', 'justify-content-evenly', 88 | 'align-items-center', 89 | ); 90 | const form = document.createElement('form'); 91 | 92 | const nameInput = document.createElement('input'); 93 | nameInput.required = true; 94 | nameInput.classList.add('form-control', 'p-2', 'w-100', 'bd-highlight'); 95 | nameInput.id = 'name'; 96 | nameInput.required = true; 97 | nameInput.placeholder = 'Your Name'; 98 | 99 | const commentInput = document.createElement('textarea'); 100 | commentInput.required = true; 101 | commentInput.classList.add('form-control', 'p-2', 'w-100'); 102 | commentInput.id = 'comment'; 103 | commentInput.required = true; 104 | commentInput.placeholder = 'Your Insights'; 105 | const myBr = document.createElement('br'); 106 | const myBr1 = document.createElement('br'); 107 | const myBr2 = document.createElement('br'); 108 | const myBr3 = document.createElement('br'); 109 | 110 | const button = document.createElement('button'); 111 | button.classList.add('btn', 'btn-warning', 'p-1'); 112 | button.id = 'commentBtn'; 113 | button.innerText = 'Comment'; 114 | 115 | form.appendChild(nameInput); 116 | form.appendChild(myBr); 117 | form.appendChild(myBr1); 118 | form.appendChild(commentInput); 119 | form.appendChild(myBr2); 120 | form.appendChild(myBr3); 121 | form.appendChild(button); 122 | 123 | addComment.appendChild(addCommHeading); 124 | addComment.appendChild(form); 125 | 126 | imageDiv.appendChild(addComment); 127 | title.classList.add('mt-2'); 128 | 129 | foreGroundPopUp.appendChild(headerPopUp); 130 | foreGroundPopUp.appendChild(imageDiv); 131 | foreGroundPopUp.appendChild(title); 132 | foreGroundPopUp.appendChild(popUpFooter); 133 | commentSection.appendChild(commentsCountainer); 134 | foreGroundPopUp.appendChild(commentSection); 135 | popUpOverLay.appendChild(foreGroundPopUp); 136 | }; 137 | 138 | export default commentPopUp; 139 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,700&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,500;0,700;1,100;1,200;1,300&display=swap'); 3 | 4 | /* Variables */ 5 | :root { 6 | --primary_color: #ffc55c; 7 | --secondary-color: #ffd68a; 8 | --dark-color: #754c00; 9 | } 10 | 11 | body { 12 | background-color: #f39f86; 13 | background-image: linear-gradient(315deg, #6d3929 0%, #f9d976 74%); 14 | overflow-x: hidden; 15 | } 16 | 17 | *, 18 | *::after, 19 | *::before { 20 | margin: 0; 21 | padding: 0; 22 | box-sizing: border-box; 23 | font-family: 'Playfair Display', serif; 24 | } 25 | 26 | section { 27 | margin-bottom: 5rem; 28 | } 29 | 30 | /* Navbar */ 31 | 32 | .logo { 33 | width: 6rem; 34 | padding: 5px; 35 | margin: 0 9rem; 36 | } 37 | 38 | .nav-link { 39 | display: inline; 40 | margin-left: 3.5rem; 41 | } 42 | 43 | .nav-link:hover { 44 | background-color: orange; 45 | border-radius: 10px; 46 | } 47 | 48 | .nav-link.active { 49 | text-decoration: underline; 50 | } 51 | 52 | /* Home page content */ 53 | .color-orange { 54 | color: var(--dark-color); 55 | font-family: 'Pacifico', cursive; 56 | } 57 | 58 | .showCard { 59 | padding: 2rem 0; 60 | box-shadow: -1px 1px 11px 3px #000; 61 | background-color: #ffdc159f; 62 | border-radius: 25px 0 25px 0; 63 | color: var(--black); 64 | } 65 | 66 | strong { 67 | font-family: 'Poppins', sans-serif; 68 | font-weight: bold; 69 | color: #000; 70 | } 71 | 72 | .show-image { 73 | width: 60%; 74 | height: 75%; 75 | box-shadow: 5px 5px 15px 5px #000; 76 | } 77 | 78 | .show-image:hover { 79 | transition: 1.1s; 80 | transform: scale(1.1); 81 | } 82 | 83 | .popup-image { 84 | width: 33%; 85 | height: 79%; 86 | box-shadow: 5px 5px 15px 5px #000; 87 | } 88 | 89 | .title-bg { 90 | background-color: var(--secondary-color); 91 | box-shadow: 2px 7px 27px -1px #a36a00; 92 | border-radius: 5px; 93 | } 94 | 95 | .comment-bg { 96 | box-shadow: 2px 7px 27px -1px #a36a00; 97 | border-radius: 5px; 98 | margin: 20px; 99 | } 100 | 101 | /* footer */ 102 | a { 103 | text-decoration: none; 104 | color: var(--dark-color); 105 | font-family: 'Poppins', sans-serif; 106 | font-weight: bold; 107 | } 108 | 109 | #sticky-footer { 110 | position: fixed; 111 | height: 8vh; 112 | background-color: var(--secondary-color); 113 | bottom: 0; 114 | left: 0; 115 | right: 0; 116 | margin-bottom: 0; 117 | } 118 | 119 | .footer-logo { 120 | width: 4.2rem; 121 | margin: 0 2rem; 122 | } 123 | 124 | .popup-bg { 125 | justify-content: center; 126 | position: fixed; 127 | opacity: 0.95; 128 | width: 100%; 129 | height: 100vh; 130 | top: 0; 131 | left: 0; 132 | right: 0; 133 | bottom: 0; 134 | z-index: 2; 135 | background-color: rgba(0, 0, 0, 0.8); 136 | } 137 | 138 | .foreground-overlay { 139 | height: 97%; 140 | width: 95%; 141 | background-color: white; 142 | padding: 20px; 143 | margin-top: 10px; 144 | position: relative; 145 | z-index: 130; 146 | border: 3px solid var(--dark-color); 147 | border-radius: 10px; 148 | } 149 | 150 | .close-btn { 151 | transform: rotate(45deg); 152 | cursor: pointer; 153 | } 154 | 155 | /* Like button */ 156 | .heart-btn { 157 | margin: 0 0 0.5rem 0; 158 | cursor: pointer; 159 | } 160 | 161 | .heart { 162 | background: transparent; 163 | border: none; 164 | font-size: 2rem; 165 | outline: none; 166 | color: grey; 167 | margin-left: 1rem; 168 | } 169 | 170 | .heart i:hover { 171 | border: none; 172 | } 173 | 174 | .content { 175 | padding: 3px 9px; 176 | display: flex; 177 | align-items: center; 178 | border: 2px solid #eae2e1; 179 | border-radius: 5px; 180 | font-family: 'Poppins', sans-serif; 181 | background-color: white; 182 | } 183 | 184 | .content.heart-active { 185 | border-color: #f9b9c4; 186 | background: #fbd0d8; 187 | } 188 | 189 | .numb { 190 | width: 100%; 191 | font-size: 1rem; 192 | margin-left: 7px; 193 | font-weight: 600; 194 | color: #9c9496; 195 | } 196 | 197 | .red-bg { 198 | background-color: #ff726f; 199 | color: #000; 200 | border: 2px solid #000; 201 | } 202 | 203 | .numb.heart-active::before { 204 | color: #000; 205 | } 206 | 207 | .text.heart-active { 208 | color: #000; 209 | } 210 | 211 | /* Show Page */ 212 | #header { 213 | font-family: "Trebuchet MS", sans-serif; 214 | font-size: 4em; 215 | letter-spacing: -2px; 216 | border-bottom: 2px double black; 217 | text-transform: uppercase; 218 | } 219 | 220 | /* Popup module */ 221 | 222 | .comments-countainer { 223 | height: 100px; 224 | width: 100%; 225 | overflow-y: scroll; 226 | padding: 5px; 227 | border: 3px solid #9c9496; 228 | } 229 | 230 | .commentClass { 231 | border-bottom: 1px double var(--dark-color); 232 | padding-bottom: 5px; 233 | } 234 | 235 | @media only screen and (max-width: 992px) { 236 | #header { 237 | font-family: "Trebuchet MS", sans-serif; 238 | font-size: 2em; 239 | border-bottom: 1px double black; 240 | text-transform: capitalize; 241 | } 242 | 243 | .logo { 244 | margin: 0 1rem; 245 | } 246 | 247 | .showCard { 248 | border-radius: 25px; 249 | height: 75%; 250 | } 251 | 252 | .popup-image { 253 | width: 25vw; 254 | margin-right: 2rem; 255 | } 256 | 257 | .show-image { 258 | width: 80%; 259 | } 260 | 261 | .footer-logo { 262 | width: 2rem; 263 | margin: 0 0.5rem; 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /dist/main.bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var n={426:(n,e,r)=>{r.d(e,{Z:()=>a});var t=r(645),o=r.n(t)()((function(n){return n[1]}));o.push([n.id,"@import url(https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,700&display=swap);"]),o.push([n.id,"@import url(https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,500;0,700;1,100;1,200;1,300&display=swap);"]),o.push([n.id,"/* Variables */\r\n:root {\r\n --primary_color: #ffc55c;\r\n --secondary-color: #ffd68a;\r\n --dark-color: #754c00;\r\n}\r\n\r\nbody {\r\n background-color: #f39f86;\r\n background-image: linear-gradient(315deg, #6d3929 0%, #f9d976 74%);\r\n overflow-x: hidden;\r\n}\r\n\r\n*,\r\n*::after,\r\n*::before {\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n font-family: 'Playfair Display', serif;\r\n}\r\n\r\nsection {\r\n margin-bottom: 5rem;\r\n}\r\n\r\n/* Navbar */\r\n\r\n.logo {\r\n width: 6rem;\r\n padding: 5px;\r\n margin: 0 9rem;\r\n}\r\n\r\n.nav-link {\r\n display: inline;\r\n margin-left: 3.5rem;\r\n}\r\n\r\n.nav-link:hover {\r\n background-color: orange;\r\n border-radius: 10px;\r\n}\r\n\r\n.nav-link.active {\r\n text-decoration: underline;\r\n}\r\n\r\n/* Home page content */\r\n.color-orange {\r\n color: var(--dark-color);\r\n font-family: 'Pacifico', cursive;\r\n}\r\n\r\n.showCard {\r\n padding: 2rem 0;\r\n box-shadow: -1px 1px 11px 3px #000;\r\n background-color: #ffdc159f;\r\n border-radius: 25px 0 25px 0;\r\n color: var(--black);\r\n}\r\n\r\nstrong {\r\n font-family: 'Poppins', sans-serif;\r\n font-weight: bold;\r\n color: #000;\r\n}\r\n\r\n.show-image {\r\n width: 60%;\r\n height: 75%;\r\n box-shadow: 5px 5px 15px 5px #000;\r\n}\r\n\r\n.show-image:hover {\r\n transition: 1.1s;\r\n transform: scale(1.1);\r\n}\r\n\r\n.popup-image {\r\n width: 33%;\r\n height: 79%;\r\n box-shadow: 5px 5px 15px 5px #000;\r\n}\r\n\r\n.title-bg {\r\n background-color: var(--secondary-color);\r\n box-shadow: 2px 7px 27px -1px #a36a00;\r\n border-radius: 5px;\r\n}\r\n\r\n.comment-bg {\r\n box-shadow: 2px 7px 27px -1px #a36a00;\r\n border-radius: 5px;\r\n margin: 20px;\r\n}\r\n\r\n/* footer */\r\na {\r\n text-decoration: none;\r\n color: var(--dark-color);\r\n font-family: 'Poppins', sans-serif;\r\n font-weight: bold;\r\n}\r\n\r\n#sticky-footer {\r\n position: fixed;\r\n height: 8vh;\r\n background-color: var(--secondary-color);\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n margin-bottom: 0;\r\n}\r\n\r\n.footer-logo {\r\n width: 4.2rem;\r\n margin: 0 2rem;\r\n}\r\n\r\n.popup-bg {\r\n justify-content: center;\r\n position: fixed;\r\n opacity: 0.95;\r\n width: 100%;\r\n height: 100vh;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n z-index: 2;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n.foreground-overlay {\r\n height: 97%;\r\n width: 95%;\r\n background-color: white;\r\n padding: 20px;\r\n margin-top: 10px;\r\n position: relative;\r\n z-index: 130;\r\n border: 3px solid var(--dark-color);\r\n border-radius: 10px;\r\n}\r\n\r\n.close-btn {\r\n transform: rotate(45deg);\r\n cursor: pointer;\r\n}\r\n\r\n/* Like button */\r\n.heart-btn {\r\n margin: 0 0 0.5rem 0;\r\n cursor: pointer;\r\n}\r\n\r\n.heart {\r\n background: transparent;\r\n border: none;\r\n font-size: 2rem;\r\n outline: none;\r\n color: grey;\r\n margin-left: 1rem;\r\n}\r\n\r\n.heart i:hover {\r\n border: none;\r\n}\r\n\r\n.content {\r\n padding: 3px 9px;\r\n display: flex;\r\n align-items: center;\r\n border: 2px solid #eae2e1;\r\n border-radius: 5px;\r\n font-family: 'Poppins', sans-serif;\r\n background-color: white;\r\n}\r\n\r\n.content.heart-active {\r\n border-color: #f9b9c4;\r\n background: #fbd0d8;\r\n}\r\n\r\n.numb {\r\n width: 100%;\r\n font-size: 1rem;\r\n margin-left: 7px;\r\n font-weight: 600;\r\n color: #9c9496;\r\n}\r\n\r\n.red-bg {\r\n background-color: #ff726f;\r\n color: #000;\r\n border: 2px solid #000;\r\n}\r\n\r\n.numb.heart-active::before {\r\n color: #000;\r\n}\r\n\r\n.text.heart-active {\r\n color: #000;\r\n}\r\n\r\n/* Show Page */\r\n#header {\r\n font-family: \"Trebuchet MS\", sans-serif;\r\n font-size: 4em;\r\n letter-spacing: -2px;\r\n border-bottom: 2px double black;\r\n text-transform: uppercase;\r\n}\r\n\r\n/* Popup module */\r\n\r\n.comments-countainer {\r\n height: 100px;\r\n width: 100%;\r\n overflow-y: scroll;\r\n padding: 5px;\r\n border: 3px solid #9c9496;\r\n}\r\n\r\n.commentClass {\r\n border-bottom: 1px double var(--dark-color);\r\n padding-bottom: 5px;\r\n}\r\n\r\n@media only screen and (max-width: 992px) {\r\n #header {\r\n font-family: \"Trebuchet MS\", sans-serif;\r\n font-size: 2em;\r\n border-bottom: 1px double black;\r\n text-transform: capitalize;\r\n }\r\n\r\n .logo {\r\n margin: 0 1rem;\r\n }\r\n\r\n .showCard {\r\n border-radius: 25px;\r\n height: 75%;\r\n }\r\n\r\n .popup-image {\r\n width: 25vw;\r\n margin-right: 2rem;\r\n }\r\n\r\n .show-image {\r\n width: 80%;\r\n }\r\n\r\n .footer-logo {\r\n width: 2rem;\r\n margin: 0 0.5rem;\r\n }\r\n}\r\n",""]);const a=o},645:n=>{n.exports=function(n){var e=[];return e.toString=function(){return this.map((function(e){var r=n(e);return e[2]?"@media ".concat(e[2]," {").concat(r,"}"):r})).join("")},e.i=function(n,r,t){"string"==typeof n&&(n=[[null,n,""]]);var o={};if(t)for(var a=0;a{var e=[];function r(n){for(var r=-1,t=0;t{var e={};n.exports=function(n,r){var t=function(n){if(void 0===e[n]){var r=document.querySelector(n);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(n){r=null}e[n]=r}return e[n]}(n);if(!t)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");t.appendChild(r)}},216:n=>{n.exports=function(n){var e=document.createElement("style");return n.setAttributes(e,n.attributes),n.insert(e),e}},565:(n,e,r)=>{n.exports=function(n){var e=r.nc;e&&n.setAttribute("nonce",e)}},795:n=>{n.exports=function(n){var e=n.insertStyleElement(n);return{update:function(r){!function(n,e,r){var t=r.css,o=r.media,a=r.sourceMap;o?n.setAttribute("media",o):n.removeAttribute("media"),a&&"undefined"!=typeof btoa&&(t+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(t,n)}(e,n,r)},remove:function(){!function(n){if(null===n.parentNode)return!1;n.parentNode.removeChild(n)}(e)}}}},589:n=>{n.exports=function(n,e){if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}}},e={};function r(t){var o=e[t];if(void 0!==o)return o.exports;var a=e[t]={id:t,exports:{}};return n[t](a,a.exports,r),a.exports}r.n=n=>{var e=n&&n.__esModule?()=>n.default:()=>n;return r.d(e,{a:e}),e},r.d=(n,e)=>{for(var t in e)r.o(e,t)&&!r.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},r.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e),(()=>{var n=r(379),e=r.n(n),t=r(795),o=r.n(t),a=r(569),i=r.n(a),d=r(565),c=r.n(d),s=r(216),l=r.n(s),m=r(589),p=r.n(m),u=r(426),h={};h.styleTagTransform=p(),h.setAttributes=c(),h.insert=i().bind(null,"head"),h.domAPI=o(),h.insertStyleElement=l(),e()(u.Z,h),u.Z&&u.Z.locals&&u.Z.locals;const f=n=>n.length,g=(n,e,r,t,o,a,i=[{username:"No",comment:"comments"}])=>{const d=document.getElementById("overlay");d.classList.remove("d-none"),d.classList.add("d-block","d-flex");const c=document.createElement("div"),s=document.createElement("h2");s.innerHTML="+",s.classList.add("close-btn"),s.addEventListener("click",(async()=>{d.classList.remove("d-block"),d.classList.add("d-none"),y(),d.innerHTML=""})),c.classList.add("w-100","d-flex","justify-content-end"),c.appendChild(s);const l=document.createElement("div");l.classList.add("foreground-overlay","d-flex","flex-column","align-items-center");const m=document.createElement("div");m.classList.add("d-flex","w-50","justify-content-evenly");const p=document.createElement("div"),u=document.createElement("h5"),h=document.createElement("h5");u.innerHTML=`Language: ${r}`,h.innerHTML=`Runtime: ${t}`,p.appendChild(u),p.appendChild(h);const g=document.createElement("div"),b=document.createElement("h5"),v=document.createElement("h5");v.classList.add("w-100"),b.innerHTML=`Status: ${o}`,v.innerHTML=`Rating: ${a}`,g.appendChild(b),g.appendChild(v),m.appendChild(p),m.appendChild(g);const x=document.createElement("div");x.id="commentSection",x.classList.add("w-75");const w=document.createElement("h5");w.classList.add("mb-3");const L=f(i);w.innerHTML=`Comments(${L})`,x.appendChild(w);const E=document.createElement("div");i.forEach((n=>{const e=document.createElement("p");e.className="commentClass",e.innerHTML=`${n.username}: ${n.comment}`,"No"===n.username&&(w.innerHTML="No comments for this show",E.classList.remove("comments-countainer")),E.classList.add("comments-countainer"),E.appendChild(e)}));const C=document.createElement("div"),k=document.createElement("h5");k.innerHTML="Add Comment";const M=document.createElement("div");M.appendChild(n),M.classList.add("w-100","h-50","d-flex","justify-content-evenly","align-items-center");const T=document.createElement("form"),H=document.createElement("input");H.required=!0,H.classList.add("form-control","p-2","w-100","bd-highlight"),H.id="name",H.required=!0,H.placeholder="Your Name";const $=document.createElement("textarea");$.required=!0,$.classList.add("form-control","p-2","w-100"),$.id="comment",$.required=!0,$.placeholder="Your Insights";const S=document.createElement("br"),I=document.createElement("br"),P=document.createElement("br"),j=document.createElement("br"),A=document.createElement("button");A.classList.add("btn","btn-warning","p-1"),A.id="commentBtn",A.innerText="Comment",T.appendChild(H),T.appendChild(S),T.appendChild(I),T.appendChild($),T.appendChild(P),T.appendChild(j),T.appendChild(A),C.appendChild(k),C.appendChild(T),M.appendChild(C),e.classList.add("mt-2"),l.appendChild(c),l.appendChild(M),l.appendChild(e),l.appendChild(m),x.appendChild(E),l.appendChild(x),d.appendChild(l)},b=async n=>{const e=await fetch(n);return await e.json()},v="https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/Likes/",x=(n,e,r)=>{const t=n.filter((n=>n.item_id===r));0!==t.length&&(e.innerHTML=`${t[0].likes} likes`),0===t.length&&(e.innerHTML="0 likes")},y=async()=>{const n=document.getElementById("homePage"),e=document.getElementById("counter");let r=await(async()=>{const n=await fetch("https://api.tvmaze.com/shows"),e=await n.json();return e&&(document.getElementById("loading").style.display="none"),e})();r=r.slice(160,169),e.innerHTML=`(${f(r)})`,r.forEach((e=>{const r=document.createElement("div");r.classList.add("col");const t=document.createElement("div");t.classList.add("card","h-100","border-warning","d-flex","flex-column","align-items-center","showCard","mb-3"),t.classList.add("col-12");const o=document.createElement("img");o.classList.add("show-image");const a=e.image.original;o.setAttribute("src",a);const i=document.createElement("img");i.classList.add("popup-image"),i.setAttribute("src",a);const d=document.createElement("h5");d.classList.add("p-2","px-5","mt-3","title-bg"),d.innerHTML=e.name;const c=document.createElement("div");c.classList.add("d-flex","flex-column","align-items-center","justify-content-center"),((n,e)=>{const r=document.createElement("div"),t=document.createElement("span"),o=document.createElement("div"),a=document.createElement("button");r.classList.add("heart-btn"),r.id=n,o.classList.add("content"),b(v).then((e=>{x(e,t,`item${n}`)})),t.id=`numb${n}`,t.setAttribute("class","numb"),a.classList.add("heart"),a.id=`like${n}`,o.appendChild(t),a.innerHTML="🤍",a.addEventListener("click",(async n=>{const{id:e}=n.target,r=e.slice(4);n.preventDefault(),e&&e.includes("like")&&(document.getElementById(`${e}`).innerHTML="❤️",o.classList.add("red-bg"),await(async n=>{await fetch("https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/Likes/",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({item_id:`item${n}`})})})(r)),setTimeout((()=>{document.getElementById(`${e}`).innerHTML="🤍",o.classList.remove("red-bg")}),10),b(v).then((n=>{x(n,t,`item${r}`)}))})),r.appendChild(o),r.insertBefore(a,r.childNodes[0]),e.appendChild(r)})(e.id,c);const s=document.createElement("h5");s.classList.add("p-2"),s.innerHTML=e.name;const l=document.createElement("button");l.classList.add("btn","btn-warning","comment-bg","h-50","font-weight-bold"),l.innerHTML="comment",l.id=`item${e.id}`;const m=document.createElement("div");m.classList.add("d-flex","justify-content-between"),l.addEventListener("click",(async n=>{n.preventDefault();const r=await(async n=>{const e=`https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/comments?item_id=item${n}`,r=await fetch(e,{method:"GET"});return await r.json()})(e.id);r.error?g(i,s,e.language,e.runtime,e.status,e.rating.average):g(i,s,e.language,e.runtime,e.status,e.rating.average,r);const t=document.getElementById("name"),o=document.getElementById("comment"),a=document.getElementById("commentBtn"),d=document.getElementById("commentSection"),c=document.getElementsByClassName("commentClass");a.addEventListener("click",(n=>{n.preventDefault(),(async(n,e,r)=>{const t={item_id:r,username:n,comment:e};await fetch("https://us-central1-involvement-api.cloudfunctions.net/capstoneApi/apps/9YYfJY5gRMr3MgkvmC9i/comments",{method:"POST",headers:{"Content-type":"application/json; charset=UTF-8"},body:JSON.stringify(t)})})(t.value,o.value,`item${e.id}`);const r=document.createElement("p");r.innerHTML=`${t.value}: ${o.value}`,d.appendChild(r),"No: comments"===c[0].innerHTML&&(c[0].innerHTML=""),t.value="",o.value=""}))})),t.appendChild(o),t.appendChild(d),m.appendChild(l),m.appendChild(c),t.appendChild(m),r.appendChild(t),n.appendChild(r)}))};window.addEventListener("DOMContentLoaded",(()=>{y()}))})()})(); --------------------------------------------------------------------------------