├── 2-JS-basics ├── .DS_Store ├── final │ ├── .DS_Store │ ├── index.html │ └── script.js └── starter │ └── index.html ├── 3-how-JS-works ├── .DS_Store ├── final │ ├── index.html │ └── script.js └── starter │ ├── index.html │ └── script.js ├── 4-DOM-pig-game ├── .DS_Store ├── final │ ├── .DS_Store │ ├── app.js │ ├── back.jpg │ ├── challenges.js │ ├── dice-1.png │ ├── dice-2.png │ ├── dice-3.png │ ├── dice-4.png │ ├── dice-5.png │ ├── dice-6.png │ ├── index.html │ └── style.css └── starter │ ├── app.js │ ├── back.jpg │ ├── dice-1.png │ ├── dice-2.png │ ├── dice-3.png │ ├── dice-4.png │ ├── dice-5.png │ ├── dice-6.png │ ├── index.html │ └── style.css ├── 5-advanced-JS ├── .DS_Store ├── final │ ├── index.html │ └── script.js └── starter │ ├── index.html │ └── script.js ├── 6-budgety ├── .DS_Store ├── final │ ├── .DS_Store │ ├── app.js │ ├── back.png │ ├── index.html │ └── style.css └── starter │ ├── app.js │ ├── back.png │ ├── index.html │ └── style.css ├── 7-ES6 ├── .DS_Store ├── final │ ├── .DS_Store │ ├── index.html │ ├── polyfill.min.js │ ├── script-transpiled.js │ └── script.js └── starter │ ├── index.html │ └── script.js ├── 8-asynchronous-JS ├── .DS_Store ├── final │ └── asynchronous.html └── starter │ └── asynchronous.html ├── 9-forkify ├── .DS_Store ├── final │ ├── .DS_Store │ ├── .babelrc │ ├── dist │ │ ├── .DS_Store │ │ ├── css │ │ │ └── style.css │ │ ├── img │ │ │ ├── .DS_Store │ │ │ ├── favicon.png │ │ │ ├── icons.svg │ │ │ ├── logo.png │ │ │ ├── test-1.jpg │ │ │ ├── test-10.jpg │ │ │ ├── test-2.jpg │ │ │ ├── test-3.jpg │ │ │ ├── test-4.jpg │ │ │ ├── test-5.jpg │ │ │ ├── test-6.jpg │ │ │ ├── test-7.jpg │ │ │ ├── test-8.jpg │ │ │ └── test-9.jpg │ │ ├── index.html │ │ └── js │ │ │ └── bundle.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── .DS_Store │ │ ├── index.html │ │ └── js │ │ │ ├── config.js │ │ │ ├── index.js │ │ │ ├── models │ │ │ ├── Likes.js │ │ │ ├── List.js │ │ │ ├── Recipe.js │ │ │ └── Search.js │ │ │ └── views │ │ │ ├── base.js │ │ │ ├── likesView.js │ │ │ ├── listView.js │ │ │ ├── recipeView.js │ │ │ └── searchView.js │ └── webpack.config.js └── starter │ ├── .DS_Store │ ├── dist │ ├── .DS_Store │ ├── css │ │ └── style.css │ └── img │ │ ├── .DS_Store │ │ ├── favicon.png │ │ ├── icons.svg │ │ ├── logo.png │ │ ├── test-1.jpg │ │ ├── test-10.jpg │ │ ├── test-2.jpg │ │ ├── test-3.jpg │ │ ├── test-4.jpg │ │ ├── test-5.jpg │ │ ├── test-6.jpg │ │ ├── test-7.jpg │ │ ├── test-8.jpg │ │ └── test-9.jpg │ └── src │ ├── .DS_Store │ ├── index.html │ └── js │ └── index.js ├── 99-bonus-1 ├── final │ ├── data │ │ ├── data.json │ │ └── img │ │ │ ├── asus-zenbook-flip-s.jpg │ │ │ ├── dell-xps-13.png │ │ │ ├── huawei-matebook-pro.jpg │ │ │ ├── macbook-pro-15.jpg │ │ │ └── samsung-notebook-9.jpg │ ├── index.js │ ├── laptop.html │ ├── overview.html │ └── templates │ │ ├── template-card.html │ │ ├── template-laptop.html │ │ └── template-overview.html └── starter │ ├── data │ ├── data.json │ └── img │ │ ├── asus-zenbook-flip-s.jpg │ │ ├── dell-xps-13.png │ │ ├── huawei-matebook-pro.jpg │ │ ├── macbook-pro-15.jpg │ │ └── samsung-notebook-9.jpg │ ├── laptop.html │ └── overview.html ├── README.md ├── budgety-planning-guide.pdf ├── editors-setup.md └── slides-students-C03.pdf /2-JS-basics/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/2-JS-basics/.DS_Store -------------------------------------------------------------------------------- /2-JS-basics/final/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/2-JS-basics/final/.DS_Store -------------------------------------------------------------------------------- /2-JS-basics/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 2: JavaScript Language Basics 6 | 7 | 8 | 9 |

Section 2: JavaScript Language Basics

10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /2-JS-basics/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 2: JavaScript Language Basics 6 | 7 | 8 | 9 |

Section 2: JavaScript Language Basics

10 | 11 | -------------------------------------------------------------------------------- /3-how-JS-works/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/3-how-JS-works/.DS_Store -------------------------------------------------------------------------------- /3-how-JS-works/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 3: How JavaScript Works Behind the Scenes 6 | 7 | 8 | 9 |

Section 3: How JavaScript Works Behind the Scenes

10 | 11 | 12 | -------------------------------------------------------------------------------- /3-how-JS-works/final/script.js: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////// 2 | // Lecture: Hoisting 3 | 4 | /* 5 | // functions 6 | calculateAge(1965); 7 | 8 | function calculateAge(year) { 9 | console.log(2016 - year); 10 | } 11 | 12 | // retirement(1956); 13 | var retirement = function(year) { 14 | console.log(65 - (2016 - year)); 15 | } 16 | 17 | 18 | // variables 19 | 20 | console.log(age); 21 | var age = 23; 22 | 23 | function foo() { 24 | console.log(age); 25 | var age = 65; 26 | console.log(age); 27 | } 28 | foo(); 29 | console.log(age); 30 | */ 31 | 32 | 33 | 34 | ///////////////////////////////////// 35 | // Lecture: Scoping 36 | 37 | /* 38 | // First scoping example 39 | var a = 'Hello!'; 40 | first(); 41 | 42 | function first() { 43 | var b = 'Hi!'; 44 | second(); 45 | 46 | function second() { 47 | var c = 'Hey!'; 48 | console.log(a + b + c); 49 | } 50 | } 51 | 52 | 53 | // Example to show the differece between execution stack and scope chain 54 | var a = 'Hello!'; 55 | first(); 56 | 57 | function first() { 58 | var b = 'Hi!'; 59 | second(); 60 | 61 | function second() { 62 | var c = 'Hey!'; 63 | third() 64 | } 65 | } 66 | 67 | function third() { 68 | var d = 'John'; 69 | //console.log(c); 70 | console.log(a+d); 71 | } 72 | */ 73 | 74 | 75 | 76 | ///////////////////////////////////// 77 | // Lecture: The this keyword 78 | 79 | /* 80 | //console.log(this); 81 | 82 | calculateAge(1985); 83 | 84 | function calculateAge(year) { 85 | console.log(2016 - year); 86 | console.log(this); 87 | } 88 | 89 | var john = { 90 | name: 'John', 91 | yearOfBirth: 1990, 92 | calculateAge: function() { 93 | console.log(this); 94 | console.log(2016 - this.yearOfBirth); 95 | 96 | function innerFunction() { 97 | console.log(this); 98 | } 99 | innerFunction(); 100 | } 101 | } 102 | 103 | john.calculateAge(); 104 | 105 | var mike = { 106 | name: 'Mike', 107 | yearOfBirth: 1984 108 | }; 109 | 110 | 111 | mike.calculateAge = john.calculateAge; 112 | mike.calculateAge(); 113 | */ 114 | -------------------------------------------------------------------------------- /3-how-JS-works/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 3: How JavaScript Works Behind the Scenes 6 | 7 | 8 | 9 |

Section 3: How JavaScript Works Behind the Scenes

10 | 11 | 12 | -------------------------------------------------------------------------------- /3-how-JS-works/starter/script.js: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////// 2 | // Lecture: Hoisting 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | /////////////////////////////////////// 21 | // Lecture: Scoping 22 | 23 | 24 | // First scoping example 25 | 26 | /* 27 | var a = 'Hello!'; 28 | first(); 29 | 30 | function first() { 31 | var b = 'Hi!'; 32 | second(); 33 | 34 | function second() { 35 | var c = 'Hey!'; 36 | console.log(a + b + c); 37 | } 38 | } 39 | */ 40 | 41 | 42 | 43 | // Example to show the differece between execution stack and scope chain 44 | 45 | /* 46 | var a = 'Hello!'; 47 | first(); 48 | 49 | function first() { 50 | var b = 'Hi!'; 51 | second(); 52 | 53 | function second() { 54 | var c = 'Hey!'; 55 | third() 56 | } 57 | } 58 | 59 | function third() { 60 | var d = 'John'; 61 | console.log(a + b + c + d); 62 | } 63 | */ 64 | 65 | 66 | 67 | /////////////////////////////////////// 68 | // Lecture: The this keyword 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /4-DOM-pig-game/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/.DS_Store -------------------------------------------------------------------------------- /4-DOM-pig-game/final/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/.DS_Store -------------------------------------------------------------------------------- /4-DOM-pig-game/final/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | GAME RULES: 3 | 4 | - The game has 2 players, playing in rounds 5 | - In each turn, a player rolls a dice as many times as he whishes. Each result get added to his ROUND score 6 | - BUT, if the player rolls a 1, all his ROUND score gets lost. After that, it's the next player's turn 7 | - The player can choose to 'Hold', which means that his ROUND score gets added to his GLBAL score. After that, it's the next player's turn 8 | - The first player to reach 100 points on GLOBAL score wins the game 9 | 10 | */ 11 | 12 | var scores, roundScore, activePlayer, gamePlaying; 13 | 14 | init(); 15 | 16 | 17 | document.querySelector('.btn-roll').addEventListener('click', function() { 18 | if(gamePlaying) { 19 | // 1. Random number 20 | var dice = Math.floor(Math.random() * 6) + 1; 21 | 22 | //2. Display the result 23 | var diceDOM = document.querySelector('.dice'); 24 | diceDOM.style.display = 'block'; 25 | diceDOM.src = 'dice-' + dice + '.png'; 26 | 27 | 28 | //3. Update the round score IF the rolled number was NOT a 1 29 | if (dice !== 1) { 30 | //Add score 31 | roundScore += dice; 32 | document.querySelector('#current-' + activePlayer).textContent = roundScore; 33 | } else { 34 | //Next player 35 | nextPlayer(); 36 | } 37 | } 38 | }); 39 | 40 | 41 | document.querySelector('.btn-hold').addEventListener('click', function() { 42 | if (gamePlaying) { 43 | // Add CURRENT score to GLOBAL score 44 | scores[activePlayer] += roundScore; 45 | 46 | // Update the UI 47 | document.querySelector('#score-' + activePlayer).textContent = scores[activePlayer]; 48 | 49 | // Check if player won the game 50 | if (scores[activePlayer] >= 100) { 51 | document.querySelector('#name-' + activePlayer).textContent = 'Winner!'; 52 | document.querySelector('.dice').style.display = 'none'; 53 | document.querySelector('.player-' + activePlayer + '-panel').classList.add('winner'); 54 | document.querySelector('.player-' + activePlayer + '-panel').classList.remove('active'); 55 | gamePlaying = false; 56 | } else { 57 | //Next player 58 | nextPlayer(); 59 | } 60 | } 61 | }); 62 | 63 | 64 | function nextPlayer() { 65 | //Next player 66 | activePlayer === 0 ? activePlayer = 1 : activePlayer = 0; 67 | roundScore = 0; 68 | 69 | document.getElementById('current-0').textContent = '0'; 70 | document.getElementById('current-1').textContent = '0'; 71 | 72 | document.querySelector('.player-0-panel').classList.toggle('active'); 73 | document.querySelector('.player-1-panel').classList.toggle('active'); 74 | 75 | //document.querySelector('.player-0-panel').classList.remove('active'); 76 | //document.querySelector('.player-1-panel').classList.add('active'); 77 | 78 | document.querySelector('.dice').style.display = 'none'; 79 | } 80 | 81 | document.querySelector('.btn-new').addEventListener('click', init); 82 | 83 | function init() { 84 | scores = [0, 0]; 85 | activePlayer = 0; 86 | roundScore = 0; 87 | gamePlaying = true; 88 | 89 | document.querySelector('.dice').style.display = 'none'; 90 | 91 | document.getElementById('score-0').textContent = '0'; 92 | document.getElementById('score-1').textContent = '0'; 93 | document.getElementById('current-0').textContent = '0'; 94 | document.getElementById('current-1').textContent = '0'; 95 | document.getElementById('name-0').textContent = 'Player 1'; 96 | document.getElementById('name-1').textContent = 'Player 2'; 97 | document.querySelector('.player-0-panel').classList.remove('winner'); 98 | document.querySelector('.player-1-panel').classList.remove('winner'); 99 | document.querySelector('.player-0-panel').classList.remove('active'); 100 | document.querySelector('.player-1-panel').classList.remove('active'); 101 | document.querySelector('.player-0-panel').classList.add('active'); 102 | } 103 | 104 | //document.querySelector('#current-' + activePlayer).textContent = dice; 105 | //document.querySelector('#current-' + activePlayer).innerHTML = '' + dice + ''; 106 | //var x = document.querySelector('#score-0').textContent; 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | /* 116 | YOUR 3 CHALLENGES 117 | Change the game to follow these rules: 118 | 119 | 1. A player looses his ENTIRE score when he rolls two 6 in a row. After that, it's the next player's turn. (Hint: Always save the previous dice roll in a separate variable) 120 | 2. Add an input field to the HTML where players can set the winning score, so that they can change the predefined score of 100. (Hint: you can read that value with the .value property in JavaScript. This is a good oportunity to use google to figure this out :) 121 | 3. Add another dice to the game, so that there are two dices now. The player looses his current score when one of them is a 1. (Hint: you will need CSS to position the second dice, so take a look at the CSS code for the first one.) 122 | */ 123 | -------------------------------------------------------------------------------- /4-DOM-pig-game/final/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/back.jpg -------------------------------------------------------------------------------- /4-DOM-pig-game/final/challenges.js: -------------------------------------------------------------------------------- 1 | /* 2 | YOUR 3 CHALLENGES 3 | Change the game to follow these rules: 4 | 5 | 1. A player looses his ENTIRE score when he rolls two 6 in a row. After that, it's the next player's turn. (Hint: Always save the previous dice roll in a separate variable) 6 | 2. Add an input field to the HTML where players can set the winning score, so that they can change the predefined score of 100. (Hint: you can read that value with the .value property in JavaScript. This is a good oportunity to use google to figure this out :) 7 | 3. Add another dice to the game, so that there are two dices now. The player looses his current score when one of them is a 1. (Hint: you will need CSS to position the second dice, so take a look at the CSS code for the first one.) 8 | */ 9 | 10 | var scores, roundScore, activePlayer, gamePlaying; 11 | 12 | init(); 13 | 14 | var lastDice; 15 | 16 | document.querySelector('.btn-roll').addEventListener('click', function() { 17 | if(gamePlaying) { 18 | // 1. Random number 19 | var dice1 = Math.floor(Math.random() * 6) + 1; 20 | var dice2 = Math.floor(Math.random() * 6) + 1; 21 | 22 | //2. Display the result 23 | document.getElementById('dice-1').style.display = 'block'; 24 | document.getElementById('dice-2').style.display = 'block'; 25 | document.getElementById('dice-1').src = 'dice-' + dice1 + '.png'; 26 | document.getElementById('dice-2').src = 'dice-' + dice2 + '.png'; 27 | 28 | //3. Update the round score IF the rolled number was NOT a 1 29 | if (dice1 !== 1 && dice2 !== 1) { 30 | //Add score 31 | roundScore += dice1 + dice2; 32 | document.querySelector('#current-' + activePlayer).textContent = roundScore; 33 | } else { 34 | //Next player 35 | nextPlayer(); 36 | } 37 | 38 | /* 39 | if (dice === 6 && lastDice === 6) { 40 | //Player looses score 41 | scores[activePlayer] = 0; 42 | document.querySelector('#score-' + activePlayer).textContent = '0'; 43 | nextPlayer(); 44 | } else if (dice !== 1) { 45 | //Add score 46 | roundScore += dice; 47 | document.querySelector('#current-' + activePlayer).textContent = roundScore; 48 | } else { 49 | //Next player 50 | nextPlayer(); 51 | } 52 | lastDice = dice; 53 | */ 54 | } 55 | }); 56 | 57 | 58 | document.querySelector('.btn-hold').addEventListener('click', function() { 59 | if (gamePlaying) { 60 | // Add CURRENT score to GLOBAL score 61 | scores[activePlayer] += roundScore; 62 | 63 | // Update the UI 64 | document.querySelector('#score-' + activePlayer).textContent = scores[activePlayer]; 65 | 66 | var input = document.querySelector('.final-score').value; 67 | var winningScore; 68 | 69 | // Undefined, 0, null or "" are COERCED to false 70 | // Anything else is COERCED to true 71 | if(input) { 72 | winningScore = input; 73 | } else { 74 | winningScore = 100; 75 | } 76 | 77 | // Check if player won the game 78 | if (scores[activePlayer] >= winningScore) { 79 | document.querySelector('#name-' + activePlayer).textContent = 'Winner!'; 80 | document.getElementById('dice-1').style.display = 'none'; 81 | document.getElementById('dice-2').style.display = 'none'; 82 | document.querySelector('.player-' + activePlayer + '-panel').classList.add('winner'); 83 | document.querySelector('.player-' + activePlayer + '-panel').classList.remove('active'); 84 | gamePlaying = false; 85 | } else { 86 | //Next player 87 | nextPlayer(); 88 | } 89 | } 90 | }); 91 | 92 | 93 | function nextPlayer() { 94 | //Next player 95 | activePlayer === 0 ? activePlayer = 1 : activePlayer = 0; 96 | roundScore = 0; 97 | 98 | document.getElementById('current-0').textContent = '0'; 99 | document.getElementById('current-1').textContent = '0'; 100 | 101 | document.querySelector('.player-0-panel').classList.toggle('active'); 102 | document.querySelector('.player-1-panel').classList.toggle('active'); 103 | 104 | //document.querySelector('.player-0-panel').classList.remove('active'); 105 | //document.querySelector('.player-1-panel').classList.add('active'); 106 | 107 | document.getElementById('dice-1').style.display = 'none'; 108 | document.getElementById('dice-2').style.display = 'none'; 109 | } 110 | 111 | document.querySelector('.btn-new').addEventListener('click', init); 112 | 113 | function init() { 114 | scores = [0, 0]; 115 | activePlayer = 0; 116 | roundScore = 0; 117 | gamePlaying = true; 118 | 119 | document.getElementById('dice-1').style.display = 'none'; 120 | document.getElementById('dice-2').style.display = 'none'; 121 | 122 | document.getElementById('score-0').textContent = '0'; 123 | document.getElementById('score-1').textContent = '0'; 124 | document.getElementById('current-0').textContent = '0'; 125 | document.getElementById('current-1').textContent = '0'; 126 | document.getElementById('name-0').textContent = 'Player 1'; 127 | document.getElementById('name-1').textContent = 'Player 2'; 128 | document.querySelector('.player-0-panel').classList.remove('winner'); 129 | document.querySelector('.player-1-panel').classList.remove('winner'); 130 | document.querySelector('.player-0-panel').classList.remove('active'); 131 | document.querySelector('.player-1-panel').classList.remove('active'); 132 | document.querySelector('.player-0-panel').classList.add('active'); 133 | } -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-1.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-2.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-3.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-4.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-5.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/dice-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/final/dice-6.png -------------------------------------------------------------------------------- /4-DOM-pig-game/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pig Game 10 | 11 | 12 | 13 |
14 |
15 |
Player 1
16 |
43
17 |
18 |
Current
19 |
11
20 |
21 |
22 | 23 |
24 |
Player 2
25 |
72
26 |
27 |
Current
28 |
0
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Dice 39 | Dice 40 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /4-DOM-pig-game/final/style.css: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | *** GENERAL 3 | **********************************************/ 4 | 5 | .final-score { 6 | position: absolute; 7 | left: 50%; 8 | transform: translateX(-50%); 9 | top: 520px; 10 | color: #555; 11 | font-size: 18px; 12 | font-family: 'Lato'; 13 | text-align: center; 14 | padding: 10px; 15 | width: 160px; 16 | text-transform: uppercase; 17 | } 18 | 19 | .final-score:focus { outline: none; } 20 | 21 | #dice-1 { top: 120px; } 22 | #dice-2 { top: 250px; } 23 | 24 | 25 | * { 26 | margin: 0; 27 | padding: 0; 28 | box-sizing: border-box; 29 | 30 | } 31 | 32 | .clearfix::after { 33 | content: ""; 34 | display: table; 35 | clear: both; 36 | } 37 | 38 | body { 39 | background-image: linear-gradient(rgba(62, 20, 20, 0.4), rgba(62, 20, 20, 0.4)), url(back.jpg); 40 | background-size: cover; 41 | background-position: center; 42 | font-family: Lato; 43 | font-weight: 300; 44 | position: relative; 45 | height: 100vh; 46 | color: #555; 47 | } 48 | 49 | .wrapper { 50 | width: 1000px; 51 | position: absolute; 52 | top: 50%; 53 | left: 50%; 54 | transform: translate(-50%, -50%); 55 | background-color: #fff; 56 | box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.3); 57 | overflow: hidden; 58 | } 59 | 60 | .player-0-panel, 61 | .player-1-panel { 62 | width: 50%; 63 | float: left; 64 | height: 600px; 65 | padding: 100px; 66 | } 67 | 68 | 69 | 70 | /********************************************** 71 | *** PLAYERS 72 | **********************************************/ 73 | 74 | .player-name { 75 | font-size: 40px; 76 | text-align: center; 77 | text-transform: uppercase; 78 | letter-spacing: 2px; 79 | font-weight: 100; 80 | margin-top: 20px; 81 | margin-bottom: 10px; 82 | position: relative; 83 | } 84 | 85 | .player-score { 86 | text-align: center; 87 | font-size: 80px; 88 | font-weight: 100; 89 | color: #EB4D4D; 90 | margin-bottom: 130px; 91 | } 92 | 93 | .active { background-color: #f7f7f7; } 94 | .active .player-name { font-weight: 300; } 95 | 96 | .active .player-name::after { 97 | content: "\2022"; 98 | font-size: 47px; 99 | position: absolute; 100 | color: #EB4D4D; 101 | top: -7px; 102 | right: 10px; 103 | 104 | } 105 | 106 | .player-current-box { 107 | background-color: #EB4D4D; 108 | color: #fff; 109 | width: 40%; 110 | margin: 0 auto; 111 | padding: 12px; 112 | text-align: center; 113 | } 114 | 115 | .player-current-label { 116 | text-transform: uppercase; 117 | margin-bottom: 10px; 118 | font-size: 12px; 119 | color: #222; 120 | } 121 | 122 | .player-current-score { 123 | font-size: 30px; 124 | } 125 | 126 | button { 127 | position: absolute; 128 | width: 200px; 129 | left: 50%; 130 | transform: translateX(-50%); 131 | color: #555; 132 | background: none; 133 | border: none; 134 | font-family: Lato; 135 | font-size: 20px; 136 | text-transform: uppercase; 137 | cursor: pointer; 138 | font-weight: 300; 139 | transition: background-color 0.3s, color 0.3s; 140 | } 141 | 142 | button:hover { font-weight: 600; } 143 | button:hover i { margin-right: 20px; } 144 | 145 | button:focus { 146 | outline: none; 147 | } 148 | 149 | i { 150 | color: #EB4D4D; 151 | display: inline-block; 152 | margin-right: 15px; 153 | font-size: 32px; 154 | line-height: 1; 155 | vertical-align: text-top; 156 | margin-top: -4px; 157 | transition: margin 0.3s; 158 | } 159 | 160 | .btn-new { top: 45px;} 161 | .btn-roll { top: 403px;} 162 | .btn-hold { top: 467px;} 163 | 164 | .dice { 165 | position: absolute; 166 | left: 50%; 167 | top: 178px; 168 | transform: translateX(-50%); 169 | height: 100px; 170 | box-shadow: 0px 10px 60px rgba(0, 0, 0, 0.10); 171 | } 172 | 173 | .winner { background-color: #f7f7f7; } 174 | .winner .player-name { font-weight: 300; color: #EB4D4D; } -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | GAME RULES: 3 | 4 | - The game has 2 players, playing in rounds 5 | - In each turn, a player rolls a dice as many times as he whishes. Each result get added to his ROUND score 6 | - BUT, if the player rolls a 1, all his ROUND score gets lost. After that, it's the next player's turn 7 | - The player can choose to 'Hold', which means that his ROUND score gets added to his GLBAL score. After that, it's the next player's turn 8 | - The first player to reach 100 points on GLOBAL score wins the game 9 | 10 | */ -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/back.jpg -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-1.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-2.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-3.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-4.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-5.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/dice-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/4-DOM-pig-game/starter/dice-6.png -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pig Game 10 | 11 | 12 | 13 |
14 |
15 |
Player 1
16 |
43
17 |
18 |
Current
19 |
11
20 |
21 |
22 | 23 |
24 |
Player 2
25 |
72
26 |
27 |
Current
28 |
0
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | Dice 37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /4-DOM-pig-game/starter/style.css: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | *** GENERAL 3 | **********************************************/ 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | 10 | } 11 | 12 | .clearfix::after { 13 | content: ""; 14 | display: table; 15 | clear: both; 16 | } 17 | 18 | body { 19 | background-image: linear-gradient(rgba(62, 20, 20, 0.4), rgba(62, 20, 20, 0.4)), url(back.jpg); 20 | background-size: cover; 21 | background-position: center; 22 | font-family: Lato; 23 | font-weight: 300; 24 | position: relative; 25 | height: 100vh; 26 | color: #555; 27 | } 28 | 29 | .wrapper { 30 | width: 1000px; 31 | position: absolute; 32 | top: 50%; 33 | left: 50%; 34 | transform: translate(-50%, -50%); 35 | background-color: #fff; 36 | box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.3); 37 | overflow: hidden; 38 | } 39 | 40 | .player-0-panel, 41 | .player-1-panel { 42 | width: 50%; 43 | float: left; 44 | height: 600px; 45 | padding: 100px; 46 | } 47 | 48 | 49 | 50 | /********************************************** 51 | *** PLAYERS 52 | **********************************************/ 53 | 54 | .player-name { 55 | font-size: 40px; 56 | text-align: center; 57 | text-transform: uppercase; 58 | letter-spacing: 2px; 59 | font-weight: 100; 60 | margin-top: 20px; 61 | margin-bottom: 10px; 62 | position: relative; 63 | } 64 | 65 | .player-score { 66 | text-align: center; 67 | font-size: 80px; 68 | font-weight: 100; 69 | color: #EB4D4D; 70 | margin-bottom: 130px; 71 | } 72 | 73 | .active { background-color: #f7f7f7; } 74 | .active .player-name { font-weight: 300; } 75 | 76 | .active .player-name::after { 77 | content: "\2022"; 78 | font-size: 47px; 79 | position: absolute; 80 | color: #EB4D4D; 81 | top: -7px; 82 | right: 10px; 83 | 84 | } 85 | 86 | .player-current-box { 87 | background-color: #EB4D4D; 88 | color: #fff; 89 | width: 40%; 90 | margin: 0 auto; 91 | padding: 12px; 92 | text-align: center; 93 | } 94 | 95 | .player-current-label { 96 | text-transform: uppercase; 97 | margin-bottom: 10px; 98 | font-size: 12px; 99 | color: #222; 100 | } 101 | 102 | .player-current-score { 103 | font-size: 30px; 104 | } 105 | 106 | button { 107 | position: absolute; 108 | width: 200px; 109 | left: 50%; 110 | transform: translateX(-50%); 111 | color: #555; 112 | background: none; 113 | border: none; 114 | font-family: Lato; 115 | font-size: 20px; 116 | text-transform: uppercase; 117 | cursor: pointer; 118 | font-weight: 300; 119 | transition: background-color 0.3s, color 0.3s; 120 | } 121 | 122 | button:hover { font-weight: 600; } 123 | button:hover i { margin-right: 20px; } 124 | 125 | button:focus { 126 | outline: none; 127 | } 128 | 129 | i { 130 | color: #EB4D4D; 131 | display: inline-block; 132 | margin-right: 15px; 133 | font-size: 32px; 134 | line-height: 1; 135 | vertical-align: text-top; 136 | margin-top: -4px; 137 | transition: margin 0.3s; 138 | } 139 | 140 | .btn-new { top: 45px;} 141 | .btn-roll { top: 403px;} 142 | .btn-hold { top: 467px;} 143 | 144 | .dice { 145 | position: absolute; 146 | left: 50%; 147 | top: 178px; 148 | transform: translateX(-50%); 149 | height: 100px; 150 | box-shadow: 0px 10px 60px rgba(0, 0, 0, 0.10); 151 | } 152 | 153 | .winner { background-color: #f7f7f7; } 154 | .winner .player-name { font-weight: 300; color: #EB4D4D; } -------------------------------------------------------------------------------- /5-advanced-JS/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/5-advanced-JS/.DS_Store -------------------------------------------------------------------------------- /5-advanced-JS/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 5: Advanced JavaScript: Objects and Functions 6 | 7 | 8 | 9 |

Section 5: Advanced JavaScript: Objects and Functions

10 | 11 | 12 | -------------------------------------------------------------------------------- /5-advanced-JS/final/script.js: -------------------------------------------------------------------------------- 1 | ///////////////////////////// 2 | // Lecture: Function constructor 3 | /* 4 | var john = { 5 | name: 'John', 6 | yearOfBirth: 1990, 7 | job: 'teacher' 8 | }; 9 | 10 | var Person = function(name, yearOfBirth, job) { 11 | this.name = name; 12 | this.yearOfBirth = yearOfBirth; 13 | this.job = job; 14 | } 15 | 16 | Person.prototype.calculateAge = function() { 17 | console.log(2016 - this.yearOfBirth); 18 | }; 19 | 20 | Person.prototype.lastName = 'Smith'; 21 | 22 | var john = new Person('John', 1990, 'teacher'); 23 | var jane = new Person('Jane', 1969, 'designer'); 24 | var mark = new Person('Mark', 1948, 'retired'); 25 | 26 | john.calculateAge(); 27 | jane.calculateAge(); 28 | mark.calculateAge(); 29 | 30 | console.log(john.lastName); 31 | console.log(jane.lastName); 32 | console.log(mark.lastName); 33 | */ 34 | 35 | 36 | 37 | ///////////////////////////// 38 | // Lecture: Object.create 39 | /* 40 | var personProto = { 41 | calculateAge: function() { 42 | console.log(2016 - this.yearOfBirth); 43 | } 44 | }; 45 | 46 | var john = Object.create(personProto); 47 | john.name = 'John'; 48 | john.yearOfBirth = 1990; 49 | john.job = 'teacher'; 50 | 51 | var jane = Object.create(personProto, { 52 | name: { value: 'Jane' }, 53 | yearOfBirth: { value: 1969 }, 54 | job: { value: 'designer' } 55 | }); 56 | */ 57 | 58 | 59 | 60 | ///////////////////////////// 61 | // Lecture: Primitives vs objects 62 | /* 63 | // Primitives 64 | var a = 23; 65 | var b = a; 66 | a = 46; 67 | console.log(a); 68 | console.log(b); 69 | 70 | 71 | 72 | // Objects 73 | var obj1 = { 74 | name: 'John', 75 | age: 26 76 | }; 77 | var obj2 = obj1; 78 | obj1.age = 30; 79 | console.log(obj1.age); 80 | console.log(obj2.age); 81 | 82 | // Functions 83 | var age = 27; 84 | var obj = { 85 | name: 'Jonas', 86 | city: 'Lisbon' 87 | }; 88 | 89 | function change(a, b) { 90 | a = 30; 91 | b.city = 'San Francisco'; 92 | } 93 | 94 | change(age, obj); 95 | 96 | console.log(age); 97 | console.log(obj.city); 98 | */ 99 | 100 | 101 | 102 | ///////////////////////////// 103 | // Lecture: Passing functions as arguments 104 | /* 105 | var years = [1990, 1965, 1937, 2005, 1998]; 106 | 107 | function arrayCalc(arr, fn) { 108 | var arrRes = []; 109 | for (var i = 0; i < arr.length; i++) { 110 | arrRes.push(fn(arr[i])); 111 | } 112 | return arrRes; 113 | } 114 | 115 | function calculateAge(el) { 116 | return 2016 - el; 117 | } 118 | 119 | function isFullAge(el) { 120 | return el >= 18; 121 | } 122 | 123 | function maxHeartRate(el) { 124 | if (el >= 18 && el <= 81) { 125 | return Math.round(206.9 - (0.67 * el)); 126 | } else { 127 | return -1; 128 | } 129 | } 130 | 131 | 132 | var ages = arrayCalc(years, calculateAge); 133 | var fullAges = arrayCalc(ages, isFullAge); 134 | var rates = arrayCalc(ages, maxHeartRate); 135 | 136 | console.log(ages); 137 | console.log(rates); 138 | */ 139 | 140 | 141 | 142 | ///////////////////////////// 143 | // Lecture: Functions returning functions 144 | /* 145 | function interviewQuestion(job) { 146 | if (job === 'designer') { 147 | return function(name) { 148 | console.log(name + ', can you please explain what UX design is?'); 149 | } 150 | } else if (job === 'teacher') { 151 | return function(name) { 152 | console.log('What subject do you teach, ' + name + '?'); 153 | } 154 | } else { 155 | return function(name) { 156 | console.log('Hello ' + name + ', what do you do?'); 157 | } 158 | } 159 | } 160 | 161 | var teacherQuestion = interviewQuestion('teacher'); 162 | var designerQuestion = interviewQuestion('designer'); 163 | 164 | 165 | teacherQuestion('John'); 166 | designerQuestion('John'); 167 | designerQuestion('jane'); 168 | designerQuestion('Mark'); 169 | designerQuestion('Mike'); 170 | 171 | interviewQuestion('teacher')('Mark'); 172 | */ 173 | 174 | 175 | 176 | ///////////////////////////// 177 | // Lecture: IIFE 178 | /* 179 | function game() { 180 | var score = Math.random() * 10; 181 | console.log(score >= 5); 182 | } 183 | game(); 184 | 185 | 186 | (function () { 187 | var score = Math.random() * 10; 188 | console.log(score >= 5); 189 | })(); 190 | 191 | //console.log(score); 192 | 193 | 194 | (function (goodLuck) { 195 | var score = Math.random() * 10; 196 | console.log(score >= 5 - goodLuck); 197 | })(5); 198 | */ 199 | 200 | 201 | 202 | ///////////////////////////// 203 | // Lecture: Closures 204 | /* 205 | function retirement(retirementAge) { 206 | var a = ' years left until retirement.'; 207 | return function(yearOfBirth) { 208 | var age = 2016 - yearOfBirth; 209 | console.log((retirementAge - age) + a); 210 | } 211 | } 212 | 213 | var retirementUS = retirement(66); 214 | var retirementGermany = retirement(65); 215 | var retirementIceland = retirement(67); 216 | 217 | retirementGermany(1990); 218 | retirementUS(1990); 219 | retirementIceland(1990); 220 | 221 | //retirement(66)(1990); 222 | 223 | 224 | function interviewQuestion(job) { 225 | return function(name) { 226 | if (job === 'designer') { 227 | console.log(name + ', can you please explain what UX design is?'); 228 | } else if (job === 'teacher') { 229 | console.log('What subject do you teach, ' + name + '?'); 230 | } else { 231 | console.log('Hello ' + name + ', what do you do?'); 232 | } 233 | } 234 | } 235 | 236 | interviewQuestion('teacher')('John'); 237 | */ 238 | 239 | 240 | 241 | ///////////////////////////// 242 | // Lecture: Bind, call and apply 243 | /* 244 | var john = { 245 | name: 'John', 246 | age: 26, 247 | job: 'teacher', 248 | presentation: function(style, timeOfDay) { 249 | if (style === 'formal') { 250 | console.log('Good ' + timeOfDay + ', Ladies and gentlemen! I\'m ' + this.name + ', I\'m a ' + this.job + ' and I\'m ' + this.age + ' years old.'); 251 | } else if (style === 'friendly') { 252 | console.log('Hey! What\'s up? I\'m ' + this.name + ', I\'m a ' + this.job + ' and I\'m ' + this.age + ' years old. Have a nice ' + timeOfDay + '.'); 253 | } 254 | } 255 | }; 256 | 257 | var emily = { 258 | name: 'Emily', 259 | age: 35, 260 | job: 'designer' 261 | }; 262 | 263 | john.presentation('formal', 'morning'); 264 | 265 | john.presentation.call(emily, 'friendly', 'afternoon'); 266 | 267 | //john.presentation.apply(emily, ['friendly', 'afternoon']); 268 | 269 | var johnFriendly = john.presentation.bind(john, 'friendly'); 270 | 271 | johnFriendly('morning'); 272 | johnFriendly('night'); 273 | 274 | var emilyFormal = john.presentation.bind(emily, 'formal'); 275 | emilyFormal('afternoon'); 276 | 277 | 278 | // Another cool example 279 | var years = [1990, 1965, 1937, 2005, 1998]; 280 | 281 | function arrayCalc(arr, fn) { 282 | var arrRes = []; 283 | for (var i = 0; i < arr.length; i++) { 284 | arrRes.push(fn(arr[i])); 285 | } 286 | return arrRes; 287 | } 288 | 289 | function calculateAge(el) { 290 | return 2016 - el; 291 | } 292 | 293 | function isFullAge(limit, el) { 294 | return el >= limit; 295 | } 296 | 297 | var ages = arrayCalc(years, calculateAge); 298 | var fullJapan = arrayCalc(ages, isFullAge.bind(this, 20)); 299 | console.log(ages); 300 | console.log(fullJapan); 301 | */ 302 | 303 | 304 | 305 | 306 | ///////////////////////////// 307 | // CODING CHALLENGE 308 | 309 | 310 | /* 311 | --- Let's build a fun quiz game in the console! --- 312 | 313 | 1. Build a function constructor called Question to describe a question. A question should include: 314 | a) question itself 315 | b) the answers from which the player can choose the correct one (choose an adequate data structure here, array, object, etc.) 316 | c) correct answer (I would use a number for this) 317 | 318 | 2. Create a couple of questions using the constructor 319 | 320 | 3. Store them all inside an array 321 | 322 | 4. Select one random question and log it on the console, together with the possible answers (each question should have a number) (Hint: write a method for the Question objects for this task). 323 | 324 | 5. Use the 'prompt' function to ask the user for the correct answer. The user should input the number of the correct answer such as you displayed it on Task 4. 325 | 326 | 6. Check if the answer is correct and print to the console whether the answer is correct ot nor (Hint: write another method for this). 327 | 328 | 7. Suppose this code would be a plugin for other programmers to use in their code. So make sure that all your code is private and doesn't interfere with the other programmers code (Hint: we learned a special technique to do exactly that). 329 | */ 330 | 331 | 332 | /* 333 | (function() { 334 | function Question(question, answers, correct) { 335 | this.question = question; 336 | this.answers = answers; 337 | this.correct = correct; 338 | } 339 | 340 | Question.prototype.displayQuestion = function() { 341 | console.log(this.question); 342 | 343 | for (var i = 0; i < this.answers.length; i++) { 344 | console.log(i + ': ' + this.answers[i]); 345 | } 346 | } 347 | 348 | Question.prototype.checkAnswer = function(ans) { 349 | if (ans === this.correct) { 350 | console.log('Correct answer!'); 351 | 352 | } else { 353 | console.log('Wrong answer. Try again :)') 354 | } 355 | } 356 | 357 | var q1 = new Question('Is JavaScript the coolest programming language in the world?', 358 | ['Yes', 'No'], 359 | 0); 360 | 361 | var q2 = new Question('What is the name of this course\'s teacher?', 362 | ['John', 'Micheal', 'Jonas'], 363 | 2); 364 | 365 | var q3 = new Question('What does best describe coding?', 366 | ['Boring', 'Hard', 'Fun', 'Tediuos'], 367 | 2); 368 | 369 | var questions = [q1, q2, q3]; 370 | 371 | var n = Math.floor(Math.random() * questions.length); 372 | 373 | questions[n].displayQuestion(); 374 | 375 | var answer = parseInt(prompt('Please select the correct answer.')); 376 | 377 | questions[n].checkAnswer(answer); 378 | })(); 379 | */ 380 | 381 | 382 | 383 | /* 384 | --- Expert level --- 385 | 386 | 8. After you display the result, display the next random question, so that the game never ends (Hint: write a function for this and call it right after displaying the result) 387 | 388 | 9. Be careful: after Task 8, the game literally never ends. So include the option to quit the game if the user writes 'exit' instead of the answer. In this case, DON'T call the function from task 8. 389 | 390 | 10. Track the user's score to make the game more fun! So each time an answer is correct, add 1 point to the score (Hint: I'm going to use the power of closures for this, but you don't have to, just do this with the tools you feel more comfortable at this point). 391 | 392 | 11. Display the score in the console. Use yet another method for this. 393 | */ 394 | 395 | 396 | /* 397 | (function() { 398 | function Question(question, answers, correct) { 399 | this.question = question; 400 | this.answers = answers; 401 | this.correct = correct; 402 | } 403 | 404 | Question.prototype.displayQuestion = function() { 405 | console.log(this.question); 406 | 407 | for (var i = 0; i < this.answers.length; i++) { 408 | console.log(i + ': ' + this.answers[i]); 409 | } 410 | } 411 | 412 | Question.prototype.checkAnswer = function(ans, callback) { 413 | var sc; 414 | 415 | if (ans === this.correct) { 416 | console.log('Correct answer!'); 417 | sc = callback(true); 418 | } else { 419 | console.log('Wrong answer. Try again :)'); 420 | sc = callback(false); 421 | } 422 | 423 | this.displayScore(sc); 424 | } 425 | 426 | Question.prototype.displayScore = function(score) { 427 | console.log('Your current score is: ' + score); 428 | console.log('------------------------------'); 429 | } 430 | 431 | 432 | var q1 = new Question('Is JavaScript the coolest programming language in the world?', 433 | ['Yes', 'No'], 434 | 0); 435 | 436 | var q2 = new Question('What is the name of this course\'s teacher?', 437 | ['John', 'Micheal', 'Jonas'], 438 | 2); 439 | 440 | var q3 = new Question('What does best describe coding?', 441 | ['Boring', 'Hard', 'Fun', 'Tediuos'], 442 | 2); 443 | 444 | var questions = [q1, q2, q3]; 445 | 446 | function score() { 447 | var sc = 0; 448 | return function(correct) { 449 | if (correct) { 450 | sc++; 451 | } 452 | return sc; 453 | } 454 | } 455 | var keepScore = score(); 456 | 457 | 458 | function nextQuestion() { 459 | 460 | var n = Math.floor(Math.random() * questions.length); 461 | questions[n].displayQuestion(); 462 | 463 | var answer = prompt('Please select the correct answer.'); 464 | 465 | if(answer !== 'exit') { 466 | questions[n].checkAnswer(parseInt(answer), keepScore); 467 | 468 | nextQuestion(); 469 | } 470 | } 471 | 472 | nextQuestion(); 473 | 474 | })(); 475 | */ -------------------------------------------------------------------------------- /5-advanced-JS/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 5: Advanced JavaScript: Objects and Functions 6 | 7 | 8 | 9 |

Section 5: Advanced JavaScript: Objects and Functions

10 | 11 | 12 | -------------------------------------------------------------------------------- /5-advanced-JS/starter/script.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/5-advanced-JS/starter/script.js -------------------------------------------------------------------------------- /6-budgety/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/6-budgety/.DS_Store -------------------------------------------------------------------------------- /6-budgety/final/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/6-budgety/final/.DS_Store -------------------------------------------------------------------------------- /6-budgety/final/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/6-budgety/final/back.png -------------------------------------------------------------------------------- /6-budgety/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Budgety 9 | 10 | 11 | 12 |
13 |
14 |
15 | Available Budget in %Month%: 16 |
17 | 18 |
+ 2,345.64
19 | 20 |
21 |
Income
22 |
23 |
+ 4,300.00
24 |
 
25 |
26 |
27 | 28 |
29 |
Expenses
30 |
31 |
- 1,954.36
32 |
45%
33 |
34 |
35 |
36 |
37 | 38 | 39 | 40 |
41 |
42 |
43 | 47 | 48 | 49 | 50 |
51 |
52 | 53 |
54 |
55 |

Income

56 | 57 |
58 | 59 | 82 | 83 |
84 |
85 | 86 | 87 | 88 |
89 |

Expenses

90 | 91 |
92 | 93 | 116 | 117 |
118 |
119 |
120 | 121 | 122 |
123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /6-budgety/final/style.css: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | *** GENERAL 3 | **********************************************/ 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | } 10 | 11 | .clearfix::after { 12 | content: ""; 13 | display: table; 14 | clear: both; 15 | } 16 | 17 | body { 18 | color: #555; 19 | font-family: Open Sans; 20 | font-size: 16px; 21 | position: relative; 22 | height: 100vh; 23 | font-weight: 400; 24 | } 25 | 26 | .right { float: right; } 27 | .red { color: #FF5049 !important; } 28 | .red-focus:focus { border: 1px solid #FF5049 !important; } 29 | 30 | /********************************************** 31 | *** TOP PART 32 | **********************************************/ 33 | 34 | .top { 35 | height: 40vh; 36 | background-image: linear-gradient(rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.35)), url(back.png); 37 | background-size: cover; 38 | background-position: center; 39 | position: relative; 40 | } 41 | 42 | .budget { 43 | position: absolute; 44 | width: 350px; 45 | top: 50%; 46 | left: 50%; 47 | transform: translate(-50%, -50%); 48 | color: #fff; 49 | } 50 | 51 | .budget__title { 52 | font-size: 18px; 53 | text-align: center; 54 | margin-bottom: 10px; 55 | font-weight: 300; 56 | } 57 | 58 | .budget__value { 59 | font-weight: 300; 60 | font-size: 46px; 61 | text-align: center; 62 | margin-bottom: 25px; 63 | letter-spacing: 2px; 64 | } 65 | 66 | .budget__income, 67 | .budget__expenses { 68 | padding: 12px; 69 | text-transform: uppercase; 70 | } 71 | 72 | .budget__income { 73 | margin-bottom: 10px; 74 | background-color: #28B9B5; 75 | } 76 | 77 | .budget__expenses { 78 | background-color: #FF5049; 79 | } 80 | 81 | .budget__income--text, 82 | .budget__expenses--text { 83 | float: left; 84 | font-size: 13px; 85 | color: #444; 86 | margin-top: 2px; 87 | } 88 | 89 | .budget__income--value, 90 | .budget__expenses--value { 91 | letter-spacing: 1px; 92 | float: left; 93 | } 94 | 95 | .budget__income--percentage, 96 | .budget__expenses--percentage { 97 | float: left; 98 | width: 34px; 99 | font-size: 11px; 100 | padding: 3px 0; 101 | margin-left: 10px; 102 | } 103 | 104 | .budget__expenses--percentage { 105 | background-color: rgba(255, 255, 255, 0.2); 106 | text-align: center; 107 | border-radius: 3px; 108 | } 109 | 110 | 111 | /********************************************** 112 | *** BOTTOM PART 113 | **********************************************/ 114 | 115 | /***** FORM *****/ 116 | .add { 117 | padding: 14px; 118 | border-bottom: 1px solid #e7e7e7; 119 | background-color: #f7f7f7; 120 | } 121 | 122 | .add__container { 123 | margin: 0 auto; 124 | text-align: center; 125 | } 126 | 127 | .add__type { 128 | width: 55px; 129 | border: 1px solid #e7e7e7; 130 | height: 44px; 131 | font-size: 18px; 132 | color: inherit; 133 | background-color: #fff; 134 | margin-right: 10px; 135 | font-weight: 300; 136 | transition: border 0.3s; 137 | } 138 | 139 | .add__description, 140 | .add__value { 141 | border: 1px solid #e7e7e7; 142 | background-color: #fff; 143 | color: inherit; 144 | font-family: inherit; 145 | font-size: 14px; 146 | padding: 12px 15px; 147 | margin-right: 10px; 148 | border-radius: 5px; 149 | transition: border 0.3s; 150 | } 151 | 152 | .add__description { width: 400px;} 153 | .add__value { width: 100px;} 154 | 155 | .add__btn { 156 | font-size: 35px; 157 | background: none; 158 | border: none; 159 | color: #28B9B5; 160 | cursor: pointer; 161 | display: inline-block; 162 | vertical-align: middle; 163 | line-height: 1.1; 164 | margin-left: 10px; 165 | } 166 | 167 | .add__btn:active { transform: translateY(2px); } 168 | 169 | .add__type:focus, 170 | .add__description:focus, 171 | .add__value:focus { 172 | outline: none; 173 | border: 1px solid #28B9B5; 174 | } 175 | 176 | .add__btn:focus { outline: none; } 177 | 178 | /***** LISTS *****/ 179 | .container { 180 | width: 1000px; 181 | margin: 60px auto; 182 | } 183 | 184 | .income { 185 | float: left; 186 | width: 475px; 187 | margin-right: 50px; 188 | } 189 | 190 | .expenses { 191 | float: left; 192 | width: 475px; 193 | } 194 | 195 | h2 { 196 | text-transform: uppercase; 197 | font-size: 18px; 198 | font-weight: 400; 199 | margin-bottom: 15px; 200 | } 201 | 202 | .icome__title { color: #28B9B5; } 203 | .expenses__title { color: #FF5049; } 204 | 205 | .item { 206 | padding: 13px; 207 | border-bottom: 1px solid #e7e7e7; 208 | } 209 | 210 | .item:first-child { border-top: 1px solid #e7e7e7; } 211 | .item:nth-child(even) { background-color: #f7f7f7; } 212 | 213 | .item__description { 214 | float: left; 215 | } 216 | 217 | .item__value { 218 | float: left; 219 | transition: transform 0.3s; 220 | } 221 | 222 | .item__percentage { 223 | float: left; 224 | margin-left: 20px; 225 | transition: transform 0.3s; 226 | font-size: 11px; 227 | background-color: #FFDAD9; 228 | padding: 3px; 229 | border-radius: 3px; 230 | width: 32px; 231 | text-align: center; 232 | } 233 | 234 | .income .item__value, 235 | .income .item__delete--btn { 236 | color: #28B9B5; 237 | } 238 | 239 | .expenses .item__value, 240 | .expenses .item__percentage, 241 | .expenses .item__delete--btn { 242 | color: #FF5049; 243 | } 244 | 245 | 246 | .item__delete { 247 | float: left; 248 | } 249 | 250 | .item__delete--btn { 251 | font-size: 22px; 252 | background: none; 253 | border: none; 254 | cursor: pointer; 255 | display: inline-block; 256 | vertical-align: middle; 257 | line-height: 1; 258 | display: none; 259 | } 260 | 261 | .item__delete--btn:focus { outline: none; } 262 | .item__delete--btn:active { transform: translateY(2px); } 263 | 264 | .item:hover .item__delete--btn { display: block; } 265 | .item:hover .item__value { transform: translateX(-20px); } 266 | .item:hover .item__percentage { transform: translateX(-20px); } 267 | 268 | 269 | .unpaid { 270 | background-color: #FFDAD9 !important; 271 | cursor: pointer; 272 | color: #FF5049; 273 | 274 | } 275 | 276 | .unpaid .item__percentage { box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1); } 277 | .unpaid:hover .item__description { font-weight: 900; } 278 | 279 | -------------------------------------------------------------------------------- /6-budgety/starter/app.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/6-budgety/starter/app.js -------------------------------------------------------------------------------- /6-budgety/starter/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/6-budgety/starter/back.png -------------------------------------------------------------------------------- /6-budgety/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Budgety 9 | 10 | 11 | 12 |
13 |
14 |
15 | Available Budget in %Month%: 16 |
17 | 18 |
+ 2,345.64
19 | 20 |
21 |
Income
22 |
23 |
+ 4,300.00
24 |
 
25 |
26 |
27 | 28 |
29 |
Expenses
30 |
31 |
- 1,954.36
32 |
45%
33 |
34 |
35 |
36 |
37 | 38 | 39 | 40 |
41 |
42 |
43 | 47 | 48 | 49 | 50 |
51 |
52 | 53 |
54 |
55 |

Income

56 | 57 |
58 | 59 | 80 | 81 |
82 |
83 | 84 | 85 | 86 |
87 |

Expenses

88 | 89 |
90 | 91 | 114 | 115 |
116 |
117 |
118 | 119 | 120 |
121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /6-budgety/starter/style.css: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | *** GENERAL 3 | **********************************************/ 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | } 10 | 11 | .clearfix::after { 12 | content: ""; 13 | display: table; 14 | clear: both; 15 | } 16 | 17 | body { 18 | color: #555; 19 | font-family: Open Sans; 20 | font-size: 16px; 21 | position: relative; 22 | height: 100vh; 23 | font-weight: 400; 24 | } 25 | 26 | .right { float: right; } 27 | .red { color: #FF5049 !important; } 28 | .red-focus:focus { border: 1px solid #FF5049 !important; } 29 | 30 | /********************************************** 31 | *** TOP PART 32 | **********************************************/ 33 | 34 | .top { 35 | height: 40vh; 36 | background-image: linear-gradient(rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.35)), url(back.png); 37 | background-size: cover; 38 | background-position: center; 39 | position: relative; 40 | } 41 | 42 | .budget { 43 | position: absolute; 44 | width: 350px; 45 | top: 50%; 46 | left: 50%; 47 | transform: translate(-50%, -50%); 48 | color: #fff; 49 | } 50 | 51 | .budget__title { 52 | font-size: 18px; 53 | text-align: center; 54 | margin-bottom: 10px; 55 | font-weight: 300; 56 | } 57 | 58 | .budget__value { 59 | font-weight: 300; 60 | font-size: 46px; 61 | text-align: center; 62 | margin-bottom: 25px; 63 | letter-spacing: 2px; 64 | } 65 | 66 | .budget__income, 67 | .budget__expenses { 68 | padding: 12px; 69 | text-transform: uppercase; 70 | } 71 | 72 | .budget__income { 73 | margin-bottom: 10px; 74 | background-color: #28B9B5; 75 | } 76 | 77 | .budget__expenses { 78 | background-color: #FF5049; 79 | } 80 | 81 | .budget__income--text, 82 | .budget__expenses--text { 83 | float: left; 84 | font-size: 13px; 85 | color: #444; 86 | margin-top: 2px; 87 | } 88 | 89 | .budget__income--value, 90 | .budget__expenses--value { 91 | letter-spacing: 1px; 92 | float: left; 93 | } 94 | 95 | .budget__income--percentage, 96 | .budget__expenses--percentage { 97 | float: left; 98 | width: 34px; 99 | font-size: 11px; 100 | padding: 3px 0; 101 | margin-left: 10px; 102 | } 103 | 104 | .budget__expenses--percentage { 105 | background-color: rgba(255, 255, 255, 0.2); 106 | text-align: center; 107 | border-radius: 3px; 108 | } 109 | 110 | 111 | /********************************************** 112 | *** BOTTOM PART 113 | **********************************************/ 114 | 115 | /***** FORM *****/ 116 | .add { 117 | padding: 14px; 118 | border-bottom: 1px solid #e7e7e7; 119 | background-color: #f7f7f7; 120 | } 121 | 122 | .add__container { 123 | margin: 0 auto; 124 | text-align: center; 125 | } 126 | 127 | .add__type { 128 | width: 55px; 129 | border: 1px solid #e7e7e7; 130 | height: 44px; 131 | font-size: 18px; 132 | color: inherit; 133 | background-color: #fff; 134 | margin-right: 10px; 135 | font-weight: 300; 136 | transition: border 0.3s; 137 | } 138 | 139 | .add__description, 140 | .add__value { 141 | border: 1px solid #e7e7e7; 142 | background-color: #fff; 143 | color: inherit; 144 | font-family: inherit; 145 | font-size: 14px; 146 | padding: 12px 15px; 147 | margin-right: 10px; 148 | border-radius: 5px; 149 | transition: border 0.3s; 150 | } 151 | 152 | .add__description { width: 400px;} 153 | .add__value { width: 100px;} 154 | 155 | .add__btn { 156 | font-size: 35px; 157 | background: none; 158 | border: none; 159 | color: #28B9B5; 160 | cursor: pointer; 161 | display: inline-block; 162 | vertical-align: middle; 163 | line-height: 1.1; 164 | margin-left: 10px; 165 | } 166 | 167 | .add__btn:active { transform: translateY(2px); } 168 | 169 | .add__type:focus, 170 | .add__description:focus, 171 | .add__value:focus { 172 | outline: none; 173 | border: 1px solid #28B9B5; 174 | } 175 | 176 | .add__btn:focus { outline: none; } 177 | 178 | /***** LISTS *****/ 179 | .container { 180 | width: 1000px; 181 | margin: 60px auto; 182 | } 183 | 184 | .income { 185 | float: left; 186 | width: 475px; 187 | margin-right: 50px; 188 | } 189 | 190 | .expenses { 191 | float: left; 192 | width: 475px; 193 | } 194 | 195 | h2 { 196 | text-transform: uppercase; 197 | font-size: 18px; 198 | font-weight: 400; 199 | margin-bottom: 15px; 200 | } 201 | 202 | .icome__title { color: #28B9B5; } 203 | .expenses__title { color: #FF5049; } 204 | 205 | .item { 206 | padding: 13px; 207 | border-bottom: 1px solid #e7e7e7; 208 | } 209 | 210 | .item:first-child { border-top: 1px solid #e7e7e7; } 211 | .item:nth-child(even) { background-color: #f7f7f7; } 212 | 213 | .item__description { 214 | float: left; 215 | } 216 | 217 | .item__value { 218 | float: left; 219 | transition: transform 0.3s; 220 | } 221 | 222 | .item__percentage { 223 | float: left; 224 | margin-left: 20px; 225 | transition: transform 0.3s; 226 | font-size: 11px; 227 | background-color: #FFDAD9; 228 | padding: 3px; 229 | border-radius: 3px; 230 | width: 32px; 231 | text-align: center; 232 | } 233 | 234 | .income .item__value, 235 | .income .item__delete--btn { 236 | color: #28B9B5; 237 | } 238 | 239 | .expenses .item__value, 240 | .expenses .item__percentage, 241 | .expenses .item__delete--btn { 242 | color: #FF5049; 243 | } 244 | 245 | 246 | .item__delete { 247 | float: left; 248 | } 249 | 250 | .item__delete--btn { 251 | font-size: 22px; 252 | background: none; 253 | border: none; 254 | cursor: pointer; 255 | display: inline-block; 256 | vertical-align: middle; 257 | line-height: 1; 258 | display: none; 259 | } 260 | 261 | .item__delete--btn:focus { outline: none; } 262 | .item__delete--btn:active { transform: translateY(2px); } 263 | 264 | .item:hover .item__delete--btn { display: block; } 265 | .item:hover .item__value { transform: translateX(-20px); } 266 | .item:hover .item__percentage { transform: translateX(-20px); } 267 | 268 | 269 | .unpaid { 270 | background-color: #FFDAD9 !important; 271 | cursor: pointer; 272 | color: #FF5049; 273 | 274 | } 275 | 276 | .unpaid .item__percentage { box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1); } 277 | .unpaid:hover .item__description { font-weight: 900; } 278 | 279 | -------------------------------------------------------------------------------- /7-ES6/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/7-ES6/.DS_Store -------------------------------------------------------------------------------- /7-ES6/final/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/7-ES6/final/.DS_Store -------------------------------------------------------------------------------- /7-ES6/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 7: Get Ready for the Future: ES6 / ES2015 6 | 7 | 21 | 22 | 23 | 24 | 25 |

Section 7: Get Ready for the Future: ES6 / ES2015

26 | 27 |
I'm green!
28 |
I'm blue!
29 |
I'm orange!
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /7-ES6/starter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Section 7: Get Ready for the Future: ES6 / ES2015 6 | 7 | 21 | 22 | 23 | 24 | 25 |

Section 7: Get Ready for the Future: ES6 / ES2015

26 | 27 |
I'm green!
28 |
I'm blue!
29 |
I'm orange!
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /7-ES6/starter/script.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/7-ES6/starter/script.js -------------------------------------------------------------------------------- /8-asynchronous-JS/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/8-asynchronous-JS/.DS_Store -------------------------------------------------------------------------------- /8-asynchronous-JS/final/asynchronous.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Asynchronous JavaScript 8 | 9 | 10 |

Asynchronous JavaScript

11 | 135 | 136 | -------------------------------------------------------------------------------- /8-asynchronous-JS/starter/asynchronous.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Asynchronous JavaScript 8 | 9 | 10 |

Asynchronous JavaScript

11 | 14 | 15 | -------------------------------------------------------------------------------- /9-forkify/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/.DS_Store -------------------------------------------------------------------------------- /9-forkify/final/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/.DS_Store -------------------------------------------------------------------------------- /9-forkify/final/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "targets": { 5 | "browsers": [ 6 | "last 5 versions", 7 | "ie >= 8" 8 | ] 9 | } 10 | }] 11 | ] 12 | } -------------------------------------------------------------------------------- /9-forkify/final/dist/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/.DS_Store -------------------------------------------------------------------------------- /9-forkify/final/dist/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; } 4 | 5 | *, 6 | *::before, 7 | *::after { 8 | box-sizing: inherit; } 9 | 10 | html { 11 | box-sizing: border-box; 12 | font-size: 62.5%; } 13 | @media only screen and (max-width: 68.75em) { 14 | html { 15 | font-size: 50%; } } 16 | 17 | body { 18 | font-family: 'Nunito Sans', sans-serif; 19 | font-weight: 400; 20 | line-height: 1.6; 21 | color: #655A56; 22 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); 23 | background-size: cover; 24 | background-repeat: no-repeat; 25 | min-height: calc(100vh - 2 * 4vw); } 26 | 27 | .container { 28 | max-width: 120rem; 29 | margin: 4vw auto; 30 | background-color: #fff; 31 | border-radius: 6px; 32 | overflow: hidden; 33 | box-shadow: 0 2rem 6rem 0.5rem rgba(101, 90, 86, 0.2); 34 | display: grid; 35 | grid-template-rows: 10rem minmax(100rem, auto); 36 | grid-template-columns: 1.1fr 2fr 1.1fr; 37 | grid-template-areas: "head head head" "list recipe shopping"; } 38 | @media only screen and (max-width: 68.75em) { 39 | .container { 40 | width: 100%; 41 | margin: 0; 42 | border-radius: 0; } } 43 | 44 | .btn, .btn-small, .btn-small:link, .btn-small:visited { 45 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); 46 | border-radius: 10rem; 47 | border: none; 48 | text-transform: uppercase; 49 | color: #fff; 50 | cursor: pointer; 51 | display: flex; 52 | align-items: center; 53 | transition: all .2s; } 54 | .btn:hover, .btn-small:hover { 55 | transform: scale(1.05); } 56 | .btn:focus, .btn-small:focus { 57 | outline: none; } 58 | .btn > *:first-child, .btn-small > *:first-child { 59 | margin-right: 1rem; } 60 | 61 | .btn { 62 | padding: 1.3rem 3rem; 63 | font-size: 1.4rem; } 64 | .btn svg { 65 | height: 2.25rem; 66 | width: 2.25rem; 67 | fill: currentColor; } 68 | 69 | .btn-small, .btn-small:link, .btn-small:visited { 70 | font-size: 1.3rem; 71 | padding: 1rem 1.75rem; 72 | text-decoration: none; } 73 | .btn-small svg, .btn-small:link svg, .btn-small:visited svg { 74 | height: 1.5rem; 75 | width: 1.5rem; 76 | fill: currentColor; } 77 | 78 | .btn-inline { 79 | color: #F59A83; 80 | font-size: 1.2rem; 81 | border: none; 82 | background-color: #F9F5F3; 83 | padding: .8rem 1.2rem; 84 | border-radius: 10rem; 85 | cursor: pointer; 86 | display: flex; 87 | align-items: center; 88 | transition: all .2s; } 89 | .btn-inline svg { 90 | height: 1.5rem; 91 | width: 1.5rem; 92 | fill: currentColor; 93 | margin: 0 .2rem; } 94 | .btn-inline span { 95 | margin: 0 .4rem; } 96 | .btn-inline:hover { 97 | color: #F48982; 98 | background-color: #F2EFEE; } 99 | .btn-inline:focus { 100 | outline: none; } 101 | 102 | .btn-tiny { 103 | height: 1.75rem; 104 | width: 1.75rem; 105 | border: none; 106 | background: none; 107 | cursor: pointer; } 108 | .btn-tiny svg { 109 | height: 100%; 110 | width: 100%; 111 | fill: #F59A83; 112 | transition: all .3s; } 113 | .btn-tiny:focus { 114 | outline: none; } 115 | .btn-tiny:hover svg { 116 | fill: #F48982; 117 | transform: translateY(-1px); } 118 | .btn-tiny:active svg { 119 | fill: #F48982; 120 | transform: translateY(0); } 121 | .btn-tiny:not(:last-child) { 122 | margin-right: .3rem; } 123 | 124 | .heading-2 { 125 | font-size: 1.8rem; 126 | font-weight: 600; 127 | color: #F59A83; 128 | text-transform: uppercase; 129 | margin-bottom: 2.5rem; 130 | text-align: center; 131 | transform: skewY(-3deg); } 132 | 133 | .copyright { 134 | color: #968B87; 135 | font-size: 1.2rem; 136 | margin-top: auto; } 137 | 138 | .link:link, 139 | .link:visited { 140 | color: #968B87; } 141 | 142 | .loader { 143 | margin: 5rem auto; 144 | text-align: center; } 145 | .loader svg { 146 | height: 5.5rem; 147 | width: 5.5rem; 148 | fill: #F59A83; 149 | transform-origin: 44% 50%; 150 | animation: rotate 1.5s infinite linear; } 151 | 152 | @keyframes rotate { 153 | 0% { 154 | transform: rotate(0); } 155 | 100% { 156 | transform: rotate(360deg); } } 157 | 158 | .header { 159 | grid-area: head; 160 | background-color: #F9F5F3; 161 | display: flex; 162 | align-items: center; 163 | justify-content: space-between; } 164 | .header__logo { 165 | margin-left: 4rem; 166 | height: 4.5rem; 167 | display: block; } 168 | 169 | .search { 170 | background-color: #fff; 171 | border-radius: 10rem; 172 | display: flex; 173 | align-items: center; 174 | padding-left: 3rem; 175 | transition: all .3s; } 176 | .search:focus-within { 177 | transform: translateY(-2px); 178 | box-shadow: 0 0.7rem 3rem rgba(101, 90, 86, 0.08); } 179 | .search__field { 180 | border: none; 181 | background: none; 182 | font-family: inherit; 183 | color: inherit; 184 | font-size: 1.7rem; 185 | width: 30rem; } 186 | .search__field:focus { 187 | outline: none; } 188 | .search__field::placeholder { 189 | color: #DAD0CC; } 190 | 191 | .likes { 192 | position: relative; 193 | align-self: stretch; 194 | padding: 0 !important; } 195 | .likes__field { 196 | cursor: pointer; 197 | padding: 0 4rem; 198 | display: flex; 199 | align-items: center; 200 | height: 100%; 201 | transition: all .3s; } 202 | .likes__field:hover { 203 | background-color: #F2EFEE; } 204 | .likes__panel:hover, 205 | .likes__field:hover + .likes__panel { 206 | visibility: visible; 207 | opacity: 1; } 208 | .likes__icon { 209 | fill: #F59A83; 210 | height: 3.75rem; 211 | width: 3.75rem; } 212 | .likes__panel { 213 | position: absolute; 214 | right: 0; 215 | top: 10rem; 216 | z-index: 10; 217 | padding: 2rem 0; 218 | width: 34rem; 219 | background-color: #fff; 220 | box-shadow: 0 0.8rem 5rem 2rem rgba(101, 90, 86, 0.1); 221 | visibility: hidden; 222 | opacity: 0; 223 | transition: all .5s .2s; } 224 | 225 | .results, 226 | .likes { 227 | padding: 3rem 0; } 228 | .results__list, 229 | .likes__list { 230 | list-style: none; } 231 | .results__link:link, .results__link:visited, 232 | .likes__link:link, 233 | .likes__link:visited { 234 | display: flex; 235 | align-items: center; 236 | padding: 1.5rem 3rem; 237 | transition: all .3s; 238 | border-right: 1px solid #fff; 239 | text-decoration: none; } 240 | .results__link:hover, 241 | .likes__link:hover { 242 | background-color: #F9F5F3; 243 | transform: translateY(-2px); } 244 | .results__link--active, 245 | .likes__link--active { 246 | background-color: #F9F5F3; } 247 | .results__fig, 248 | .likes__fig { 249 | flex: 0 0 5.5rem; 250 | border-radius: 50%; 251 | overflow: hidden; 252 | height: 5.5rem; 253 | margin-right: 2rem; 254 | position: relative; 255 | backface-visibility: hidden; } 256 | .results__fig::before, 257 | .likes__fig::before { 258 | content: ''; 259 | display: block; 260 | height: 100%; 261 | width: 100%; 262 | position: absolute; 263 | top: 0; 264 | left: 0; 265 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); 266 | opacity: .4; } 267 | .results__fig img, 268 | .likes__fig img { 269 | display: block; 270 | width: 100%; 271 | height: 100%; 272 | object-fit: cover; 273 | transition: all .3s; } 274 | .results__name, 275 | .likes__name { 276 | font-size: 1.3rem; 277 | color: #F59A83; 278 | text-transform: uppercase; 279 | font-weight: 600; 280 | margin-bottom: .3rem; } 281 | .results__author, 282 | .likes__author { 283 | font-size: 1.1rem; 284 | color: #968B87; 285 | text-transform: uppercase; 286 | font-weight: 600; } 287 | .results__pages, 288 | .likes__pages { 289 | margin-top: 3rem; 290 | padding: 0 3rem; } 291 | .results__pages::after, 292 | .likes__pages::after { 293 | content: ""; 294 | display: table; 295 | clear: both; } 296 | .results__btn--prev, 297 | .likes__btn--prev { 298 | float: left; 299 | flex-direction: row-reverse; } 300 | .results__btn--next, 301 | .likes__btn--next { 302 | float: right; } 303 | 304 | .recipe { 305 | background-color: #F9F5F3; 306 | border-top: 1px solid #fff; } 307 | .recipe__fig { 308 | height: 30rem; 309 | position: relative; 310 | transform: scale(1.04) translateY(-1px); 311 | transform-origin: top; } 312 | .recipe__fig::before { 313 | content: ''; 314 | display: block; 315 | height: 100%; 316 | width: 100%; 317 | position: absolute; 318 | top: 0; 319 | left: 0; 320 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); 321 | opacity: .6; } 322 | .recipe__img { 323 | width: 100%; 324 | display: block; 325 | height: 100%; 326 | object-fit: cover; } 327 | .recipe__title { 328 | position: absolute; 329 | bottom: 0; 330 | left: 50%; 331 | transform: translate(-50%, 20%) skewY(-6deg); 332 | color: #fff; 333 | font-weight: 700; 334 | font-size: 2.75rem; 335 | text-transform: uppercase; 336 | width: 70%; 337 | line-height: 1.95; 338 | text-align: center; } 339 | .recipe__title span { 340 | -webkit-box-decoration-break: clone; 341 | box-decoration-break: clone; 342 | padding: 1.3rem 2rem; 343 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); } 344 | .recipe__details { 345 | display: flex; 346 | align-items: center; 347 | padding: 8rem 3rem 3rem 3rem; } 348 | .recipe__info { 349 | font-size: 1.5rem; 350 | text-transform: uppercase; 351 | display: flex; 352 | align-items: center; } 353 | .recipe__info:not(:last-child) { 354 | margin-right: 4rem; } 355 | .recipe__info-icon { 356 | height: 2rem; 357 | width: 2rem; 358 | fill: #F59A83; 359 | margin-right: 1rem; } 360 | .recipe__info-data { 361 | margin-right: .4rem; 362 | font-weight: 600; } 363 | .recipe__info-buttons { 364 | display: flex; 365 | margin-left: 1.5rem; 366 | visibility: hidden; 367 | opacity: 0; 368 | transform: translateY(5px); 369 | transition: all .4s; } 370 | .recipe:hover .recipe__info-buttons { 371 | visibility: visible; 372 | opacity: 1; 373 | transform: translateY(0); } 374 | .recipe__love { 375 | background-image: linear-gradient(to right bottom, #FBDB89, #F48982); 376 | border-radius: 50%; 377 | border: none; 378 | cursor: pointer; 379 | height: 4.5rem; 380 | width: 4.5rem; 381 | margin-left: auto; 382 | transition: all .2s; 383 | display: flex; 384 | align-items: center; 385 | justify-content: center; } 386 | .recipe__love:hover { 387 | transform: scale(1.07); } 388 | .recipe__love:focus { 389 | outline: none; } 390 | .recipe__love svg { 391 | height: 2.75rem; 392 | width: 2.75rem; 393 | fill: #fff; } 394 | .recipe__ingredients { 395 | padding: 4rem 5rem; 396 | font-size: 1.5rem; 397 | line-height: 1.4; 398 | background-color: #F2EFEE; 399 | display: flex; 400 | flex-direction: column; 401 | align-items: center; } 402 | .recipe__ingredient-list { 403 | display: grid; 404 | grid-template-columns: 1fr 1fr; 405 | grid-column-gap: 1.5rem; 406 | grid-row-gap: 2.5rem; 407 | list-style: none; 408 | margin-bottom: 3rem; } 409 | .recipe__item { 410 | display: flex; } 411 | .recipe__icon { 412 | height: 1.8rem; 413 | width: 1.8rem; 414 | fill: #F59A83; 415 | border: 1px solid #F59A83; 416 | border-radius: 50%; 417 | padding: 2px; 418 | margin-right: 1rem; 419 | flex: 0 0 auto; 420 | margin-top: .1rem; } 421 | .recipe__count { 422 | margin-right: .5rem; 423 | flex: 0 0 auto; } 424 | .recipe__directions { 425 | padding: 4rem; 426 | padding-bottom: 5rem; 427 | display: flex; 428 | flex-direction: column; 429 | align-items: center; } 430 | .recipe__directions-text { 431 | font-size: 1.5rem; 432 | text-align: center; 433 | width: 90%; 434 | margin-bottom: 3rem; 435 | color: #968B87; } 436 | .recipe__by { 437 | font-weight: 700; } 438 | 439 | .shopping { 440 | padding: 3rem 4rem; 441 | display: flex; 442 | flex-direction: column; } 443 | .shopping__list { 444 | list-style: none; 445 | max-height: 77rem; 446 | overflow: scroll; } 447 | .shopping__item { 448 | display: flex; 449 | align-items: flex-start; 450 | padding: 1.3rem 0; 451 | border-bottom: 1px solid #F2EFEE; 452 | position: relative; } 453 | .shopping__count { 454 | flex: 0 0 7.5rem; 455 | padding: .4rem .5rem; 456 | border: 1px solid #F2EFEE; 457 | border-radius: 3px; 458 | margin-right: 2rem; 459 | cursor: pointer; 460 | display: flex; 461 | justify-content: space-between; } 462 | .shopping__count input { 463 | color: inherit; 464 | font-family: inherit; 465 | font-size: 1.2rem; 466 | text-align: center; 467 | border: none; 468 | width: 3.7rem; 469 | border-radius: 3px; } 470 | .shopping__count input:focus { 471 | outline: none; 472 | background-color: #F2EFEE; } 473 | .shopping__count p { 474 | font-size: 1.2rem; } 475 | .shopping__description { 476 | flex: 1; 477 | font-size: 1.3rem; 478 | margin-top: .4rem; 479 | margin-right: 1.5rem; } 480 | .shopping__delete { 481 | margin-top: .5rem; 482 | position: absolute; 483 | right: 0; 484 | background-image: linear-gradient(to right, transparent 0%, #fff 40%, #fff 100%); 485 | width: 3.75rem; 486 | padding-left: 2rem; 487 | visibility: hidden; 488 | opacity: 0; 489 | transition: all .5s; } 490 | .shopping__item:hover .shopping__delete { 491 | opacity: 1; 492 | visibility: visible; } 493 | -------------------------------------------------------------------------------- /9-forkify/final/dist/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/.DS_Store -------------------------------------------------------------------------------- /9-forkify/final/dist/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/favicon.png -------------------------------------------------------------------------------- /9-forkify/final/dist/img/icons.svg: -------------------------------------------------------------------------------- 1 | 61 | -------------------------------------------------------------------------------- /9-forkify/final/dist/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/logo.png -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-1.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-10.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-2.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-3.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-4.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-5.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-6.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-7.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-8.jpg -------------------------------------------------------------------------------- /9-forkify/final/dist/img/test-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/dist/img/test-9.jpg -------------------------------------------------------------------------------- /9-forkify/final/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forkify", 3 | "version": "1.0.0", 4 | "description": "forkify project", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack --mode development", 8 | "build": "webpack --mode production", 9 | "start": "webpack-dev-server --mode development --open" 10 | }, 11 | "author": "Jonas Schmedtmann", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "babel-core": "^6.26.0", 15 | "babel-loader": "^7.1.4", 16 | "babel-preset-env": "^1.6.1", 17 | "html-webpack-plugin": "^3.0.7", 18 | "webpack": "^4.2.0", 19 | "webpack-cli": "^2.0.12", 20 | "webpack-dev-server": "^3.1.1" 21 | }, 22 | "dependencies": { 23 | "axios": "^0.18.0", 24 | "babel-polyfill": "^6.26.0", 25 | "fractional": "^1.0.0", 26 | "uniqid": "^4.1.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /9-forkify/final/src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/final/src/.DS_Store -------------------------------------------------------------------------------- /9-forkify/final/src/js/config.js: -------------------------------------------------------------------------------- 1 | export const proxy = 'https://cors-anywhere.herokuapp.com/'; 2 | export const key = '462b1cc8d4f2730081462fbc65136320'; 3 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/index.js: -------------------------------------------------------------------------------- 1 | import Search from './models/Search'; 2 | import Recipe from './models/Recipe'; 3 | import List from './models/List'; 4 | import Likes from './models/Likes'; 5 | import * as searchView from './views/searchView'; 6 | import * as recipeView from './views/recipeView'; 7 | import * as listView from './views/listView'; 8 | import * as likesView from './views/likesView'; 9 | import { elements, renderLoader, clearLoader } from './views/base'; 10 | 11 | /** Global state of the app 12 | * - Search object 13 | * - Current recipe object 14 | * - Shopping list object 15 | * - Liked recipes 16 | */ 17 | const state = {}; 18 | 19 | /** 20 | * SEARCH CONTROLLER 21 | */ 22 | const controlSearch = async () => { 23 | // 1) Get query from view 24 | const query = searchView.getInput(); 25 | 26 | if (query) { 27 | // 2) New search object and add to state 28 | state.search = new Search(query); 29 | 30 | // 3) Prepare UI for results 31 | searchView.clearInput(); 32 | searchView.clearResults(); 33 | renderLoader(elements.searchRes); 34 | 35 | try { 36 | // 4) Search for recipes 37 | await state.search.getResults(); 38 | 39 | // 5) Render results on UI 40 | clearLoader(); 41 | searchView.renderResults(state.search.result); 42 | } catch (err) { 43 | alert('Something wrong with the search...'); 44 | clearLoader(); 45 | } 46 | } 47 | } 48 | 49 | elements.searchForm.addEventListener('submit', e => { 50 | e.preventDefault(); 51 | controlSearch(); 52 | }); 53 | 54 | 55 | elements.searchResPages.addEventListener('click', e => { 56 | const btn = e.target.closest('.btn-inline'); 57 | if (btn) { 58 | const goToPage = parseInt(btn.dataset.goto, 10); 59 | searchView.clearResults(); 60 | searchView.renderResults(state.search.result, goToPage); 61 | } 62 | }); 63 | 64 | 65 | /** 66 | * RECIPE CONTROLLER 67 | */ 68 | const controlRecipe = async () => { 69 | // Get ID from url 70 | const id = window.location.hash.replace('#', ''); 71 | 72 | if (id) { 73 | // Prepare UI for changes 74 | recipeView.clearRecipe(); 75 | renderLoader(elements.recipe); 76 | 77 | // Highlight selected search item 78 | if (state.search) searchView.highlightSelected(id); 79 | 80 | // Create new recipe object 81 | state.recipe = new Recipe(id); 82 | 83 | try { 84 | // Get recipe data and parse ingredients 85 | await state.recipe.getRecipe(); 86 | state.recipe.parseIngredients(); 87 | 88 | // Calculate servings and time 89 | state.recipe.calcTime(); 90 | state.recipe.calcServings(); 91 | 92 | // Render recipe 93 | clearLoader(); 94 | recipeView.renderRecipe( 95 | state.recipe, 96 | state.likes.isLiked(id) 97 | ); 98 | 99 | } catch (err) { 100 | console.log(err); 101 | alert('Error processing recipe!'); 102 | } 103 | } 104 | }; 105 | 106 | ['hashchange', 'load'].forEach(event => window.addEventListener(event, controlRecipe)); 107 | 108 | 109 | /** 110 | * LIST CONTROLLER 111 | */ 112 | const controlList = () => { 113 | // Create a new list IF there in none yet 114 | if (!state.list) state.list = new List(); 115 | 116 | // Add each ingredient to the list and UI 117 | state.recipe.ingredients.forEach(el => { 118 | const item = state.list.addItem(el.count, el.unit, el.ingredient); 119 | listView.renderItem(item); 120 | }); 121 | } 122 | 123 | // Handle delete and update list item events 124 | elements.shopping.addEventListener('click', e => { 125 | const id = e.target.closest('.shopping__item').dataset.itemid; 126 | 127 | // Handle the delete button 128 | if (e.target.matches('.shopping__delete, .shopping__delete *')) { 129 | // Delete from state 130 | state.list.deleteItem(id); 131 | 132 | // Delete from UI 133 | listView.deleteItem(id); 134 | 135 | // Handle the count update 136 | } else if (e.target.matches('.shopping__count-value')) { 137 | const val = parseFloat(e.target.value, 10); 138 | state.list.updateCount(id, val); 139 | } 140 | }); 141 | 142 | 143 | /** 144 | * LIKE CONTROLLER 145 | */ 146 | const controlLike = () => { 147 | if (!state.likes) state.likes = new Likes(); 148 | const currentID = state.recipe.id; 149 | 150 | // User has NOT yet liked current recipe 151 | if (!state.likes.isLiked(currentID)) { 152 | // Add like to the state 153 | const newLike = state.likes.addLike( 154 | currentID, 155 | state.recipe.title, 156 | state.recipe.author, 157 | state.recipe.img 158 | ); 159 | // Toggle the like button 160 | likesView.toggleLikeBtn(true); 161 | 162 | // Add like to UI list 163 | likesView.renderLike(newLike); 164 | 165 | // User HAS liked current recipe 166 | } else { 167 | // Remove like from the state 168 | state.likes.deleteLike(currentID); 169 | 170 | // Toggle the like button 171 | likesView.toggleLikeBtn(false); 172 | 173 | // Remove like from UI list 174 | likesView.deleteLike(currentID); 175 | } 176 | likesView.toggleLikeMenu(state.likes.getNumLikes()); 177 | }; 178 | 179 | // Restore liked recipes on page load 180 | window.addEventListener('load', () => { 181 | state.likes = new Likes(); 182 | 183 | // Restore likes 184 | state.likes.readStorage(); 185 | 186 | // Toggle like menu button 187 | likesView.toggleLikeMenu(state.likes.getNumLikes()); 188 | 189 | // Render the existing likes 190 | state.likes.likes.forEach(like => likesView.renderLike(like)); 191 | }); 192 | 193 | 194 | // Handling recipe button clicks 195 | elements.recipe.addEventListener('click', e => { 196 | if (e.target.matches('.btn-decrease, .btn-decrease *')) { 197 | // Decrease button is clicked 198 | if (state.recipe.servings > 1) { 199 | state.recipe.updateServings('dec'); 200 | recipeView.updateServingsIngredients(state.recipe); 201 | } 202 | } else if (e.target.matches('.btn-increase, .btn-increase *')) { 203 | // Increase button is clicked 204 | state.recipe.updateServings('inc'); 205 | recipeView.updateServingsIngredients(state.recipe); 206 | } else if (e.target.matches('.recipe__btn--add, .recipe__btn--add *')) { 207 | // Add ingredients to shopping list 208 | controlList(); 209 | } else if (e.target.matches('.recipe__love, .recipe__love *')) { 210 | // Like controller 211 | controlLike(); 212 | } 213 | }); 214 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/models/Likes.js: -------------------------------------------------------------------------------- 1 | export default class Likes { 2 | constructor() { 3 | this.likes = []; 4 | } 5 | 6 | addLike(id, title, author, img) { 7 | const like = { id, title, author, img }; 8 | this.likes.push(like); 9 | 10 | // Perist data in localStorage 11 | this.persistData(); 12 | 13 | return like; 14 | } 15 | 16 | deleteLike(id) { 17 | const index = this.likes.findIndex(el => el.id === id); 18 | this.likes.splice(index, 1); 19 | 20 | // Perist data in localStorage 21 | this.persistData(); 22 | } 23 | 24 | isLiked(id) { 25 | return this.likes.findIndex(el => el.id === id) !== -1; 26 | } 27 | 28 | getNumLikes() { 29 | return this.likes.length; 30 | } 31 | 32 | persistData() { 33 | localStorage.setItem('likes', JSON.stringify(this.likes)); 34 | } 35 | 36 | readStorage() { 37 | const storage = JSON.parse(localStorage.getItem('likes')); 38 | 39 | // Restoring likes from the localStorage 40 | if (storage) this.likes = storage; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/models/List.js: -------------------------------------------------------------------------------- 1 | import uniqid from 'uniqid'; 2 | 3 | export default class List { 4 | constructor() { 5 | this.items = []; 6 | } 7 | 8 | addItem(count, unit, ingredient) { 9 | const item = { 10 | id: uniqid(), 11 | count, 12 | unit, 13 | ingredient 14 | } 15 | this.items.push(item); 16 | return item; 17 | } 18 | 19 | deleteItem(id) { 20 | const index = this.items.findIndex(el => el.id === id); 21 | // [2,4,8] splice(1, 2) -> returns [4, 8], original array is [2] 22 | // [2,4,8] slice(1, 2) -> returns 4, original array is [2,4,8] 23 | this.items.splice(index, 1); 24 | } 25 | 26 | updateCount(id, newCount) { 27 | this.items.find(el => el.id === id).count = newCount; 28 | } 29 | } -------------------------------------------------------------------------------- /9-forkify/final/src/js/models/Recipe.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { key, proxy } from '../config'; 3 | 4 | export default class Recipe { 5 | constructor(id) { 6 | this.id = id; 7 | } 8 | 9 | async getRecipe() { 10 | try { 11 | const res = await axios(`${proxy}http://food2fork.com/api/get?key=${key}&rId=${this.id}`); 12 | this.title = res.data.recipe.title; 13 | this.author = res.data.recipe.publisher; 14 | this.img = res.data.recipe.image_url; 15 | this.url = res.data.recipe.source_url; 16 | this.ingredients = res.data.recipe.ingredients; 17 | } catch (error) { 18 | console.log(error); 19 | alert('Something went wrong :('); 20 | } 21 | } 22 | 23 | calcTime() { 24 | // Assuming that we need 15 min for each 3 ingredients 25 | const numIng = this.ingredients.length; 26 | const periods = Math.ceil(numIng / 3); 27 | this.time = periods * 15; 28 | } 29 | 30 | calcServings() { 31 | this.servings = 4; 32 | } 33 | 34 | parseIngredients() { 35 | const unitsLong = ['tablespoons', 'tablespoon', 'ounces', 'ounce', 'teaspoons', 'teaspoon', 'cups', 'pounds']; 36 | const unitsShort = ['tbsp', 'tbsp', 'oz', 'oz', 'tsp', 'tsp', 'cup', 'pound']; 37 | const units = [...unitsShort, 'kg', 'g']; 38 | 39 | const newIngredients = this.ingredients.map(el => { 40 | // 1) Uniform units 41 | let ingredient = el.toLowerCase(); 42 | unitsLong.forEach((unit, i) => { 43 | ingredient = ingredient.replace(unit, unitsShort[i]); 44 | }); 45 | 46 | // 2) Remove parentheses 47 | ingredient = ingredient.replace(/ *\([^)]*\) */g, ' '); 48 | 49 | // 3) Parse ingredients into count, unit and ingredient 50 | const arrIng = ingredient.split(' '); 51 | const unitIndex = arrIng.findIndex(el2 => units.includes(el2)); 52 | 53 | let objIng; 54 | if (unitIndex > -1) { 55 | // There is a unit 56 | // Ex. 4 1/2 cups, arrCount is [4, 1/2] --> eval("4+1/2") --> 4.5 57 | // Ex. 4 cups, arrCount is [4] 58 | const arrCount = arrIng.slice(0, unitIndex); 59 | 60 | let count; 61 | if (arrCount.length === 1) { 62 | count = eval(arrIng[0].replace('-', '+')); 63 | } else { 64 | count = eval(arrIng.slice(0, unitIndex).join('+')); 65 | } 66 | 67 | objIng = { 68 | count, 69 | unit: arrIng[unitIndex], 70 | ingredient: arrIng.slice(unitIndex + 1).join(' ') 71 | }; 72 | 73 | } else if (parseInt(arrIng[0], 10)) { 74 | // There is NO unit, but 1st element is number 75 | objIng = { 76 | count: parseInt(arrIng[0], 10), 77 | unit: '', 78 | ingredient: arrIng.slice(1).join(' ') 79 | } 80 | } else if (unitIndex === -1) { 81 | // There is NO unit and NO number in 1st position 82 | objIng = { 83 | count: 1, 84 | unit: '', 85 | ingredient 86 | } 87 | } 88 | 89 | return objIng; 90 | }); 91 | this.ingredients = newIngredients; 92 | } 93 | 94 | updateServings (type) { 95 | // Servings 96 | const newServings = type === 'dec' ? this.servings - 1 : this.servings + 1; 97 | 98 | // Ingredients 99 | this.ingredients.forEach(ing => { 100 | ing.count *= (newServings / this.servings); 101 | }); 102 | 103 | this.servings = newServings; 104 | } 105 | } -------------------------------------------------------------------------------- /9-forkify/final/src/js/models/Search.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { key, proxy } from '../config'; 3 | 4 | export default class Search { 5 | constructor(query) { 6 | this.query = query; 7 | } 8 | 9 | async getResults() { 10 | try { 11 | const res = await axios(`${proxy}http://food2fork.com/api/search?key=${key}&q=${this.query}`); 12 | this.result = res.data.recipes; 13 | // console.log(this.result); 14 | } catch (error) { 15 | alert(error); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/views/base.js: -------------------------------------------------------------------------------- 1 | export const elements = { 2 | searchForm: document.querySelector('.search'), 3 | searchInput: document.querySelector('.search__field'), 4 | searchRes: document.querySelector('.results'), 5 | searchResList: document.querySelector('.results__list'), 6 | searchResPages: document.querySelector('.results__pages'), 7 | recipe: document.querySelector('.recipe'), 8 | shopping: document.querySelector('.shopping__list'), 9 | likesMenu: document.querySelector('.likes__field'), 10 | likesList: document.querySelector('.likes__list') 11 | }; 12 | 13 | export const elementStrings = { 14 | loader: 'loader' 15 | }; 16 | 17 | export const renderLoader = parent => { 18 | const loader = ` 19 |
20 | 21 | 22 | 23 |
24 | `; 25 | parent.insertAdjacentHTML('afterbegin', loader); 26 | }; 27 | 28 | export const clearLoader = () => { 29 | const loader = document.querySelector(`.${elementStrings.loader}`); 30 | if (loader) loader.parentElement.removeChild(loader); 31 | }; 32 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/views/likesView.js: -------------------------------------------------------------------------------- 1 | import { elements } from './base'; 2 | import { limitRecipeTitle } from './searchView'; 3 | 4 | export const toggleLikeBtn = isLiked => { 5 | const iconString = isLiked ? 'icon-heart' : 'icon-heart-outlined'; 6 | document.querySelector('.recipe__love use').setAttribute('href', `img/icons.svg#${iconString}`); 7 | // icons.svg#icon-heart-outlined 8 | }; 9 | 10 | export const toggleLikeMenu = numLikes => { 11 | elements.likesMenu.style.visibility = numLikes > 0 ? 'visible' : 'hidden'; 12 | }; 13 | 14 | export const renderLike = like => { 15 | const markup = ` 16 |
  • 17 | 18 | 21 | 25 | 26 |
  • 27 | `; 28 | elements.likesList.insertAdjacentHTML('beforeend', markup); 29 | }; 30 | 31 | export const deleteLike = id => { 32 | const el = document.querySelector(`.likes__link[href*="${id}"]`).parentElement; 33 | if (el) el.parentElement.removeChild(el); 34 | } -------------------------------------------------------------------------------- /9-forkify/final/src/js/views/listView.js: -------------------------------------------------------------------------------- 1 | import { elements } from './base'; 2 | 3 | export const renderItem = item => { 4 | const markup = ` 5 |
  • 6 |
    7 | 8 |

    ${item.unit}

    9 |
    10 |

    ${item.ingredient}

    11 | 16 |
  • 17 | `; 18 | elements.shopping.insertAdjacentHTML('beforeend', markup); 19 | }; 20 | 21 | export const deleteItem = id => { 22 | const item = document.querySelector(`[data-itemid="${id}"]`); 23 | if (item) item.parentElement.removeChild(item); 24 | }; 25 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/views/recipeView.js: -------------------------------------------------------------------------------- 1 | import { elements } from './base'; 2 | import { Fraction } from 'fractional'; 3 | 4 | export const clearRecipe = () => { 5 | elements.recipe.innerHTML = ''; 6 | }; 7 | const formatCount = count => { 8 | if (count) { 9 | // count = 2.5 --> 5/2 --> 2 1/2 10 | // count = 0.5 --> 1/2 11 | const newCount = Math.round(count * 10000) / 10000; 12 | const [int, dec] = newCount.toString().split('.').map(el => parseInt(el, 10)); 13 | 14 | if (!dec) return newCount; 15 | 16 | if (int === 0) { 17 | const fr = new Fraction(newCount); 18 | return `${fr.numerator}/${fr.denominator}`; 19 | } else { 20 | const fr = new Fraction(newCount - int); 21 | return `${int} ${fr.numerator}/${fr.denominator}`; 22 | } 23 | } 24 | return '?'; 25 | }; 26 | 27 | const createIngredient = ingredient => ` 28 |
  • 29 | 30 | 31 | 32 |
    ${formatCount(ingredient.count)}
    33 |
    34 | ${ingredient.unit} 35 | ${ingredient.ingredient} 36 |
    37 |
  • 38 | `; 39 | 40 | export const renderRecipe = (recipe, isLiked) => { 41 | const markup = ` 42 |
    43 | ${recipe.title} 44 |

    45 | ${recipe.title} 46 |

    47 |
    48 | 49 |
    50 |
    51 | 52 | 53 | 54 | ${recipe.time} 55 | minutes 56 |
    57 |
    58 | 59 | 60 | 61 | ${recipe.servings} 62 | servings 63 | 64 |
    65 | 70 | 75 |
    76 | 77 |
    78 | 83 |
    84 | 85 |
    86 | 89 | 90 | 96 |
    97 | 98 |
    99 |

    How to cook it

    100 |

    101 | This recipe was carefully designed and tested by 102 | ${recipe.author}. Please check out directions at their website. 103 |

    104 | 105 | Directions 106 | 107 | 108 | 109 | 110 | 111 |
    112 | `; 113 | elements.recipe.insertAdjacentHTML('afterbegin', markup); 114 | }; 115 | 116 | export const updateServingsIngredients = recipe => { 117 | // Update servings 118 | document.querySelector('.recipe__info-data--people').textContent = recipe.servings; 119 | 120 | // Update ingredeints 121 | const countElements = Array.from(document.querySelectorAll('.recipe__count')); 122 | countElements.forEach((el, i) => { 123 | el.textContent = formatCount(recipe.ingredients[i].count); 124 | }); 125 | }; 126 | -------------------------------------------------------------------------------- /9-forkify/final/src/js/views/searchView.js: -------------------------------------------------------------------------------- 1 | import { elements } from './base'; 2 | 3 | export const getInput = () => elements.searchInput.value; 4 | 5 | export const clearInput = () => { 6 | elements.searchInput.value = ''; 7 | }; 8 | 9 | export const clearResults = () => { 10 | elements.searchResList.innerHTML = ''; 11 | elements.searchResPages.innerHTML = ''; 12 | }; 13 | 14 | export const highlightSelected = id => { 15 | const resultsArr = Array.from(document.querySelectorAll('.results__link')); 16 | resultsArr.forEach(el => { 17 | el.classList.remove('results__link--active'); 18 | }); 19 | document.querySelector(`.results__link[href*="${id}"]`).classList.add('results__link--active'); 20 | }; 21 | 22 | /* 23 | // 'Pasta with tomato and spinach' 24 | acc: 0 / acc + cur.length = 5 / newTitle = ['Pasta'] 25 | acc: 5 / acc + cur.length = 9 / newTitle = ['Pasta', 'with'] 26 | acc: 9 / acc + cur.length = 15 / newTitle = ['Pasta', 'with', 'tomato'] 27 | acc: 15 / acc + cur.length = 18 / newTitle = ['Pasta', 'with', 'tomato'] 28 | acc: 18 / acc + cur.length = 24 / newTitle = ['Pasta', 'with', 'tomato'] 29 | */ 30 | export const limitRecipeTitle = (title, limit = 17) => { 31 | const newTitle = []; 32 | if (title.length > limit) { 33 | title.split(' ').reduce((acc, cur) => { 34 | if (acc + cur.length <= limit) { 35 | newTitle.push(cur); 36 | } 37 | return acc + cur.length; 38 | }, 0); 39 | 40 | // return the result 41 | return `${newTitle.join(' ')} ...`; 42 | } 43 | return title; 44 | } 45 | 46 | const renderRecipe = recipe => { 47 | const markup = ` 48 |
  • 49 | 50 |
    51 | ${recipe.title} 52 |
    53 |
    54 |

    ${limitRecipeTitle(recipe.title)}

    55 |

    ${recipe.publisher}

    56 |
    57 |
    58 |
  • 59 | `; 60 | elements.searchResList.insertAdjacentHTML('beforeend', markup); 61 | }; 62 | 63 | // type: 'prev' or 'next' 64 | const createButton = (page, type) => ` 65 | 71 | `; 72 | 73 | const renderButtons = (page, numResults, resPerPage) => { 74 | const pages = Math.ceil(numResults / resPerPage); 75 | 76 | let button; 77 | if (page === 1 && pages > 1) { 78 | // Only button to go to next page 79 | button = createButton(page, 'next'); 80 | } else if (page < pages) { 81 | // Both buttons 82 | button = ` 83 | ${createButton(page, 'prev')} 84 | ${createButton(page, 'next')} 85 | `; 86 | } else if (page === pages && pages > 1) { 87 | // Only button to go to prev page 88 | button = createButton(page, 'prev'); 89 | } 90 | 91 | elements.searchResPages.insertAdjacentHTML('afterbegin', button); 92 | }; 93 | 94 | export const renderResults = (recipes, page = 1, resPerPage = 10) => { 95 | // render results of currente page 96 | const start = (page - 1) * resPerPage; 97 | const end = page * resPerPage; 98 | 99 | recipes.slice(start, end).forEach(renderRecipe); 100 | 101 | // render pagination buttons 102 | renderButtons(page, recipes.length, resPerPage); 103 | }; 104 | -------------------------------------------------------------------------------- /9-forkify/final/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: ['babel-polyfill', './src/js/index.js'], 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'js/bundle.js' 9 | }, 10 | devServer: { 11 | contentBase: './dist' 12 | }, 13 | plugins: [ 14 | new HtmlWebpackPlugin({ 15 | filename: 'index.html', 16 | template: './src/index.html' 17 | }) 18 | ], 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.js$/, 23 | exclude: /node_modules/, 24 | use: { 25 | loader: 'babel-loader' 26 | } 27 | } 28 | ] 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /9-forkify/starter/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/.DS_Store -------------------------------------------------------------------------------- /9-forkify/starter/dist/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/.DS_Store -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/.DS_Store -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/favicon.png -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/icons.svg: -------------------------------------------------------------------------------- 1 | 61 | -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/logo.png -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-1.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-10.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-2.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-3.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-4.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-5.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-6.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-7.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-8.jpg -------------------------------------------------------------------------------- /9-forkify/starter/dist/img/test-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/dist/img/test-9.jpg -------------------------------------------------------------------------------- /9-forkify/starter/src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/9-forkify/starter/src/.DS_Store -------------------------------------------------------------------------------- /9-forkify/starter/src/js/index.js: -------------------------------------------------------------------------------- 1 | // Global app controller -------------------------------------------------------------------------------- /99-bonus-1/final/data/data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "0", 4 | "productName": "Huawei MateBook X Pro", 5 | "image": "huawei-matebook-pro.jpg", 6 | "cpu": "Intel Core i7, 8th generation", 7 | "ram": "8GB", 8 | "storage": "512 GB SSD", 9 | "screen": "13.9-inch, 3K (3,000 x 2,080)", 10 | "price": "1499", 11 | "description": "The Huawei MateBook X Pro is our pick for the best laptop money can buy in 2018. This is a gorgeously-designed laptop with a stunning screen (albeit with a rather odd aspect ratio), and it comes packed with cutting edge components that allows it to perform brilliantly, and a battery life that runs rings around many of its rivals. It also has a very competitive price, giving you features, design and performance for quite a bit less money." 12 | }, 13 | { 14 | "id": "1", 15 | "productName": "Apple Macbook Pro 2018", 16 | "image": "macbook-pro-15.jpg", 17 | "cpu": "6-core Intel i7, 8th generation", 18 | "ram": "16GB", 19 | "storage": "1TB GB SSD", 20 | "screen": "15-inch Retina display", 21 | "price": "3199", 22 | "description": "If you're after the latest and greatest laptop from Apple, we suggest you look into the 2018 model of the 15-inch MacBook Pro with Touch Bar. The headline Touch Bar – a thin OLED display at the top of the keyboard which can be used for any number of things, whether that be auto-suggesting words as you type or offering Touch ID so you can log in with just your fingerprint – is of course included. It's certainly retained Apple's sense of style, but it comes at a cost. This is a pricey machine, so you may want to consider one of the Windows alternatives. But, if you're a steadfast Apple diehard, this is definitely the best laptop for you!" 23 | }, 24 | { 25 | "id": "2", 26 | "productName": "Dell XPS 13", 27 | "image": "dell-xps-13.png", 28 | "cpu": "Intel Core i7, 8th generation", 29 | "ram": "16GB", 30 | "storage": "512 GB SSD", 31 | "screen": "13.3-inch, Full HD", 32 | "price": "1199", 33 | "description": "The Dell XPS 13 is an absolutely brilliant laptop. The 2018 version rocks an 8th-generation Intel Core i5 or i7 processor and a bezel-less ‘Infinity Edge’ display, this Dell XPS 13 continues to be the most popular Windows laptop in the world. What’s more, there’s a wide range of customization options, so you can really make the Dell XPS 13 the best laptop for your needs. " 34 | }, 35 | { 36 | "id": "3", 37 | "productName": "Asus ZenBook Flip S", 38 | "image": "asus-zenbook-flip-s.jpg", 39 | "cpu": "Intel Core i7, 8th generation", 40 | "ram": "16GB", 41 | "storage": "512 GB SSD", 42 | "screen": "13.3-inch, Full HD touchscreen", 43 | "price": "1399", 44 | "description": "Asus has struck gold with its new refresh of its ZenBook Flip S 2-in-1 laptop. With a new Kaby Lake R 8th-generation processor powering the device, plenty of RAM and a super-fast PCIe SSD in certain models, this is an absolutely stunning laptop. Its 2-in-1 design means you can use it as both a laptop and a tablet, and while it's not as affordable as some other machines, if you have the budget you'll be really happy with this fantastic device." 45 | }, 46 | { 47 | "id": "4", 48 | "productName": "Samsung Notebook 9", 49 | "image": "samsung-notebook-9.jpg", 50 | "cpu": "Intel Core i7, 8th generation", 51 | "ram": "16GB", 52 | "storage": "256 GB SSD", 53 | "screen": "15-inch, Full HD", 54 | "price": "1499", 55 | "description": "While it may not have the best keyboard in the world, the Samsung Notebook 9 is still one of the best laptops you can buy in 2018. Packed with more horsepower than some MacBook Pros,but at a much lower price, Samsung has crafted a laptop that has just as much substance as it does style. Plus, on top of its killer specs, it’s lightweight and thin, making this one of the most portable 15-inch laptops you can buy today." 56 | } 57 | ] -------------------------------------------------------------------------------- /99-bonus-1/final/data/img/asus-zenbook-flip-s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/final/data/img/asus-zenbook-flip-s.jpg -------------------------------------------------------------------------------- /99-bonus-1/final/data/img/dell-xps-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/final/data/img/dell-xps-13.png -------------------------------------------------------------------------------- /99-bonus-1/final/data/img/huawei-matebook-pro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/final/data/img/huawei-matebook-pro.jpg -------------------------------------------------------------------------------- /99-bonus-1/final/data/img/macbook-pro-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/final/data/img/macbook-pro-15.jpg -------------------------------------------------------------------------------- /99-bonus-1/final/data/img/samsung-notebook-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/final/data/img/samsung-notebook-9.jpg -------------------------------------------------------------------------------- /99-bonus-1/final/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const http = require('http'); 3 | const url = require('url'); 4 | 5 | const json = fs.readFileSync(`${__dirname}/data/data.json`, 'utf-8'); 6 | const laptopData = JSON.parse(json); 7 | 8 | const server = http.createServer((req, res) => { 9 | 10 | const pathName = url.parse(req.url, true).pathname; 11 | const id = url.parse(req.url, true).query.id; 12 | 13 | // PRODUCTS OVERVIEW 14 | if (pathName === '/products' || pathName === '/') { 15 | res.writeHead(200, { 'Content-type': 'text/html'}); 16 | 17 | fs.readFile(`${__dirname}/templates/template-overview.html`, 'utf-8', (err, data) => { 18 | let overviewOutput = data; 19 | 20 | fs.readFile(`${__dirname}/templates/template-card.html`, 'utf-8', (err, data) => { 21 | 22 | const cardsOutput = laptopData.map(el => replaceTemplate(data, el)).join(''); 23 | overviewOutput = overviewOutput.replace('{%CARDS%}', cardsOutput); 24 | 25 | res.end(overviewOutput); 26 | }); 27 | }); 28 | 29 | 30 | } 31 | 32 | // LAPTOP DETAIL 33 | else if (pathName === '/laptop' && id < laptopData.length) { 34 | res.writeHead(200, { 'Content-type': 'text/html'}); 35 | 36 | fs.readFile(`${__dirname}/templates/template-laptop.html`, 'utf-8', (err, data) => { 37 | const laptop = laptopData[id]; 38 | const output = replaceTemplate(data, laptop); 39 | res.end(output); 40 | }); 41 | } 42 | 43 | // IMAGES 44 | else if ((/\.(jpg|jpeg|png|gif)$/i).test(pathName)) { 45 | fs.readFile(`${__dirname}/data/img${pathName}`, (err, data) => { 46 | res.writeHead(200, { 'Content-type': 'image/jpg'}); 47 | res.end(data); 48 | }); 49 | } 50 | 51 | // URL NOT FOUND 52 | else { 53 | res.writeHead(404, { 'Content-type': 'text/html'}); 54 | res.end('URL was not found on the server!'); 55 | } 56 | 57 | }); 58 | 59 | server.listen(1337, '127.0.0.1', () => { 60 | console.log('Listening for requests now'); 61 | }); 62 | 63 | function replaceTemplate(originalHtml, laptop) { 64 | let output = originalHtml.replace(/{%PRODUCTNAME%}/g, laptop.productName); 65 | output = output.replace(/{%IMAGE%}/g, laptop.image); 66 | output = output.replace(/{%PRICE%}/g, laptop.price); 67 | output = output.replace(/{%SCREEN%}/g, laptop.screen); 68 | output = output.replace(/{%CPU%}/g, laptop.cpu); 69 | output = output.replace(/{%STORAGE%}/g, laptop.storage); 70 | output = output.replace(/{%RAM%}/g, laptop.ram); 71 | output = output.replace(/{%DESCRIPTION%}/g, laptop.description); 72 | output = output.replace(/{%ID%}/g, laptop.id); 73 | return output; 74 | } -------------------------------------------------------------------------------- /99-bonus-1/final/laptop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Apple Macbook Pro 2018 /// The Laptop Store! 12 | 13 | 215 | 216 | 217 | 218 |
    219 |

    The Laptop Store!

    220 |
    221 |

    $3199

    222 | 👈Back 223 |
    224 | 225 |
    226 |

    Apple Macbook Pro 2018

    227 |
    228 |

    🖥 15-inch Retina display

    229 |

    🧮 6-core Intel i7, 8th generation

    230 |

    💾 1TB GB SSD of storage

    231 |

    📦 16GB of RAM

    232 |
    233 |

    234 | If you're after the latest and greatest laptop from Apple, we suggest you look into the 2018 model of 235 | the 15-inch MacBook Pro with Touch Bar. The headline Touch Bar – a thin OLED display at the top of the 236 | keyboard which can be used for any number of things, whether that be auto-suggesting words as you type 237 | or offering Touch ID so you can log in with just your fingerprint – is of course included. It's 238 | certainly retained Apple's sense of style, but it comes at a cost. This is a pricey machine, so you may 239 | want to consider one of the Windows alternatives. But, if you're a steadfast Apple diehard, this is 240 | definitely the best laptop for you! 241 |

    242 |

    Source: https://www.techradar.com/news/mobile-computing/laptops/best-laptops-1304361

    244 | Buy now for $3199 🥳 😍 245 |
    246 |
    247 | 248 | 249 | -------------------------------------------------------------------------------- /99-bonus-1/final/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | The Laptop Store! 12 | 13 | 169 | 170 | 171 | 172 |
    173 |

    The Laptop Store!

    174 |
    175 |
    176 |
    177 | 178 |
    179 |

    Apple Macbook Pro 2018

    180 |

    🖥 15-inch Retina display

    181 |

    🧮 6-core Intel i7, 8th generation

    182 | 186 |
    187 |
    188 |
    189 | 190 | 191 | -------------------------------------------------------------------------------- /99-bonus-1/final/templates/template-card.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {%PRODUCTNAME%} 4 |
    5 |

    {%PRODUCTNAME%}

    6 |

    🖥 {%SCREEN%}

    7 |

    🧮 {%CPU%}

    8 | 12 |
    -------------------------------------------------------------------------------- /99-bonus-1/final/templates/template-laptop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {%PRODUCTNAME%} /// The Laptop Store! 11 | 12 | 214 | 215 | 216 | 217 |
    218 |

    The Laptop Store!

    219 |
    220 |

    ${%PRICE%}

    221 | 👈Back 222 |
    223 | {%PRODUCTNAME%} 224 |
    225 |

    {%PRODUCTNAME%}

    226 |
    227 |

    🖥 {%SCREEN%}

    228 |

    🧮 {%CPU%}

    229 |

    💾 {%STORAGE%}

    230 |

    📦 {%RAM%}

    231 |
    232 |

    {%DESCRIPTION%}

    233 |

    Source: https://www.techradar.com/news/mobile-computing/laptops/best-laptops-1304361

    235 | Buy now for ${%PRICE%} 🥳 😍 236 |
    237 |
    238 | 239 | 240 | -------------------------------------------------------------------------------- /99-bonus-1/final/templates/template-overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | The Laptop Store! 11 | 12 | 168 | 169 | 170 | 171 |
    172 |

    The Laptop Store!

    173 |
    174 | {%CARDS%} 175 |
    176 |
    177 | 178 | 179 | -------------------------------------------------------------------------------- /99-bonus-1/starter/data/data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "0", 4 | "productName": "Huawei MateBook X Pro", 5 | "image": "huawei-matebook-pro.jpg", 6 | "cpu": "Intel Core i7, 8th generation", 7 | "ram": "8GB", 8 | "storage": "512 GB SSD", 9 | "screen": "13.9-inch, 3K (3,000 x 2,080)", 10 | "price": "1499", 11 | "description": "The Huawei MateBook X Pro is our pick for the best laptop money can buy in 2018. This is a gorgeously-designed laptop with a stunning screen (albeit with a rather odd aspect ratio), and it comes packed with cutting edge components that allows it to perform brilliantly, and a battery life that runs rings around many of its rivals. It also has a very competitive price, giving you features, design and performance for quite a bit less money." 12 | }, 13 | { 14 | "id": "1", 15 | "productName": "Apple Macbook Pro 2018", 16 | "image": "macbook-pro-15.jpg", 17 | "cpu": "6-core Intel i7, 8th generation", 18 | "ram": "16GB", 19 | "storage": "1TB GB SSD", 20 | "screen": "15-inch Retina display", 21 | "price": "3199", 22 | "description": "If you're after the latest and greatest laptop from Apple, we suggest you look into the 2018 model of the 15-inch MacBook Pro with Touch Bar. The headline Touch Bar – a thin OLED display at the top of the keyboard which can be used for any number of things, whether that be auto-suggesting words as you type or offering Touch ID so you can log in with just your fingerprint – is of course included. It's certainly retained Apple's sense of style, but it comes at a cost. This is a pricey machine, so you may want to consider one of the Windows alternatives. But, if you're a steadfast Apple diehard, this is definitely the best laptop for you!" 23 | }, 24 | { 25 | "id": "2", 26 | "productName": "Dell XPS 13", 27 | "image": "dell-xps-13.png", 28 | "cpu": "Intel Core i7, 8th generation", 29 | "ram": "16GB", 30 | "storage": "512 GB SSD", 31 | "screen": "13.3-inch, Full HD", 32 | "price": "1199", 33 | "description": "The Dell XPS 13 is an absolutely brilliant laptop. The 2018 version rocks an 8th-generation Intel Core i5 or i7 processor and a bezel-less ‘Infinity Edge’ display, this Dell XPS 13 continues to be the most popular Windows laptop in the world. What’s more, there’s a wide range of customization options, so you can really make the Dell XPS 13 the best laptop for your needs. " 34 | }, 35 | { 36 | "id": "3", 37 | "productName": "Asus ZenBook Flip S", 38 | "image": "asus-zenbook-flip-s.jpg", 39 | "cpu": "Intel Core i7, 8th generation", 40 | "ram": "16GB", 41 | "storage": "512 GB SSD", 42 | "screen": "13.3-inch, Full HD touchscreen", 43 | "price": "1399", 44 | "description": "Asus has struck gold with its new refresh of its ZenBook Flip S 2-in-1 laptop. With a new Kaby Lake R 8th-generation processor powering the device, plenty of RAM and a super-fast PCIe SSD in certain models, this is an absolutely stunning laptop. Its 2-in-1 design means you can use it as both a laptop and a tablet, and while it's not as affordable as some other machines, if you have the budget you'll be really happy with this fantastic device." 45 | }, 46 | { 47 | "id": "4", 48 | "productName": "Samsung Notebook 9", 49 | "image": "samsung-notebook-9.jpg", 50 | "cpu": "Intel Core i7, 8th generation", 51 | "ram": "16GB", 52 | "storage": "256 GB SSD", 53 | "screen": "15-inch, Full HD", 54 | "price": "1499", 55 | "description": "While it may not have the best keyboard in the world, the Samsung Notebook 9 is still one of the best laptops you can buy in 2018. Packed with more horsepower than some MacBook Pros,but at a much lower price, Samsung has crafted a laptop that has just as much substance as it does style. Plus, on top of its killer specs, it’s lightweight and thin, making this one of the most portable 15-inch laptops you can buy today." 56 | } 57 | ] -------------------------------------------------------------------------------- /99-bonus-1/starter/data/img/asus-zenbook-flip-s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/starter/data/img/asus-zenbook-flip-s.jpg -------------------------------------------------------------------------------- /99-bonus-1/starter/data/img/dell-xps-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/starter/data/img/dell-xps-13.png -------------------------------------------------------------------------------- /99-bonus-1/starter/data/img/huawei-matebook-pro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/starter/data/img/huawei-matebook-pro.jpg -------------------------------------------------------------------------------- /99-bonus-1/starter/data/img/macbook-pro-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/starter/data/img/macbook-pro-15.jpg -------------------------------------------------------------------------------- /99-bonus-1/starter/data/img/samsung-notebook-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/99-bonus-1/starter/data/img/samsung-notebook-9.jpg -------------------------------------------------------------------------------- /99-bonus-1/starter/laptop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Apple Macbook Pro 2018 /// The Laptop Store! 12 | 13 | 215 | 216 | 217 | 218 |
    219 |

    The Laptop Store!

    220 |
    221 |

    $3199

    222 | 👈Back 223 |
    224 | 225 |
    226 |

    Apple Macbook Pro 2018

    227 |
    228 |

    🖥 15-inch Retina display

    229 |

    🧮 6-core Intel i7, 8th generation

    230 |

    💾 1TB GB SSD of storage

    231 |

    📦 16GB of RAM

    232 |
    233 |

    234 | If you're after the latest and greatest laptop from Apple, we suggest you look into the 2018 model of 235 | the 15-inch MacBook Pro with Touch Bar. The headline Touch Bar – a thin OLED display at the top of the 236 | keyboard which can be used for any number of things, whether that be auto-suggesting words as you type 237 | or offering Touch ID so you can log in with just your fingerprint – is of course included. It's 238 | certainly retained Apple's sense of style, but it comes at a cost. This is a pricey machine, so you may 239 | want to consider one of the Windows alternatives. But, if you're a steadfast Apple diehard, this is 240 | definitely the best laptop for you! 241 |

    242 |

    Source: https://www.techradar.com/news/mobile-computing/laptops/best-laptops-1304361

    244 | Buy now for $3199 🥳 😍 245 |
    246 |
    247 | 248 | 249 | -------------------------------------------------------------------------------- /99-bonus-1/starter/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | The Laptop Store! 12 | 13 | 169 | 170 | 171 | 172 |
    173 |

    The Laptop Store!

    174 |
    175 |
    176 |
    177 | 178 |
    179 |

    Apple Macbook Pro 2018

    180 |

    🖥 15-inch Retina display

    181 |

    🧮 6-core Intel i7, 8th generation

    182 | 186 |
    187 |
    188 |
    189 | 190 | 191 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Course Material and FAQ for my Complete JavaScript Course 2 | 3 | This repo contains starter files and the finished project files for all the projects contained in the course. 4 | 5 | Plus, I made all the [course slides available for download](slides-students-C03.pdf), to make it easier to follow along the conceptual videos. 6 | 7 | 👇 **_Please read the following Frequently Asked Questions (FAQ) carefully before starting the course_** 👇 8 | 9 | ## FAQ 10 | 11 | ### Q1: How do I download the files? 12 | 13 | **A:** If you're new to GitHub and just want to download the complete package, hit the green button saying "Clone or download", choose the "Download ZIP" option, and you're good to go. 14 | 15 | ### Q2: I'm stuck in one of the projects. Where do I get help? 16 | 17 | **A:** Have you extensively tried fixing the problem on your own? If you failed at fixing it, please **post a detailled description of the problem to the Q&A area of that video over at Udemy**, along with a [codepen](https://codepen.io/pen/) containing your code. You will get help as fast as possible! Please don't send me a personal message or email to fix coding problems. 18 | 19 | ### Q3: Brackets shows me errors, but my code works. Why is that? 20 | 21 | **A:** These are _not_ errors in your code, and you can simply ignore them (they just come from so-called linters that are not correctly set up). 22 | 23 | ### Q4: You keep mentioning your resources page. Where can I find it? 24 | 25 | **A:** It's on my website at . You can subscribe for updates 😉 26 | 27 | ### Q5: What Brackets and VSCode themes are you using? 28 | 29 | **A:** I use the theme "OS X Style | Flat & Dark" in Brackets and "Oceanic Next (dimmed bg)" in VSCode. [Here is the complete setup](editors-setup.md). 30 | 31 | ### Q6: Can I see a final version of the course projects? 32 | 33 | **A:** Sure, I have an online version of all three. Here they are: [Pig Game](https://piggame2.netlify.com/) (DOM manipulation), [Budgety](http://budgety2.netlify.com/) (advanced JavaScript) and [Forkify](https://forkify.netlify.com/) (modern JavaScript and AJAX). 34 | 35 | ### Q7: Videos don't load, can you fix it? 36 | 37 | **A:** Unfortunately, there is nothing I can do about it. The course is hosted on Udemy's platform, and sometimes they have small technical issues like this one. Please just come back a bit later or [contact their support team](https://support.udemy.com/hc/en-us). 38 | 39 | ### Q8: Videos are blurred / have low quality, can you fix it? 40 | 41 | **A:** Please open video settings and change the quality from 'Auto' to another value, for example 720p. If that doesn't help, please [contact the Udemy support team](https://support.udemy.com/hc/en-us). 42 | 43 | ### Q9: Are the videos downloadable? 44 | 45 | **A:** Yes, I made all videos downloadable on the Udemy platform so you can learn even without an internet connection. To download a video, use the settings icon in the right bottom corner of the video player. 46 | 47 | ### Q10: I love your courses and want to get updates on new courses. How? 48 | 49 | **A:** First, you can subscribe to my email list [at my website](http://codingheroes.io/newsletter). Plus, I make important announcements on twitter [@jonasschmedtman](https://twitter.com/jonasschmedtman), so you should definitely follow me there 🔥 50 | 51 | ### Q11: How do I get my certificate of completion? 52 | 53 | **A:** A certificate of completion is provided by Udemy after you complete 100% of the course. After completing the course, just click on the "Your progress" indicator in the top right-hand corner of the course page. If you want to change your name on the certificate, please [contact the Udemy support team](https://support.udemy.com/hc/en-us). 54 | 55 | ### Q12: Do you accept pull requests? 56 | 57 | **A:** No, for the simple reason that I want this repository to contain the _exact_ same code that is shown in the videos. However, please feel free to add an issue if you found one. 58 | -------------------------------------------------------------------------------- /budgety-planning-guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/budgety-planning-guide.pdf -------------------------------------------------------------------------------- /editors-setup.md: -------------------------------------------------------------------------------- 1 | # Code editor setup used in the course 2 | 3 | ## Brackets (First part of the course) 4 | 5 | ### Theme 6 | 7 | I use the `OS X Style | Flat & Dark` Brackets theme throughout most of the course. 8 | 9 | ### Extensions used in course videos 10 | 11 | `Autosave Files on Window Blur` to automatically save files when leaving the Brackets app. 12 | 13 | `Brackets Icons` to display colorful filetype icons in the filetree. 14 | 15 | 16 | ## VSCode (Second part of the course) 17 | 18 | ### Theme 19 | 20 | I use the `Oceanic Next` theme with the dimmed bg option. [Link →](https://marketplace.visualstudio.com/items?itemName=naumovs.theme-oceanicnext) 21 | 22 | ### Extensions used in course videos 23 | 24 | For each of the extensions, read the overview page in order to learn how to use it. 25 | 26 | `Auto Close Tag` to automatically close HTML tags. [Link →](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag) 27 | 28 | `Auto Rename Tag` to automatically change matching HTML tags. [Link →](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag) 29 | 30 | `Color Highlight` to, as the name says, highlight colors in CSS. [Link →](https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight) 31 | 32 | `Paste and Indent` to automatically indent pasted code. [Link →](https://marketplace.visualstudio.com/items?itemName=Rubymaniac.vscode-paste-and-indent) 33 | 34 | `Path Intellisense` to autocomplete filenames. [Link →](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) 35 | 36 | `Prettier` to automatically format code. [Link →](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 37 | 38 | ### Settings 39 | 40 | If you want your editor to work and look exactly the same way as mine does in the course videos, you can copy these settings to your own settings file. Just go to settings in VSCode, and on the right side, you can paste this code. 41 | 42 | ``` 43 | { 44 | "workbench.colorTheme": "Oceanic Next (dimmed bg)", 45 | "files.autoSave": "onFocusChange", 46 | "editor.minimap.enabled": true, 47 | "workbench.statusBar.visible": true, 48 | "workbench.activityBar.visible": true, 49 | "editor.formatOnSave": false, 50 | 51 | "workbench.colorCustomizations": { 52 | "statusBar.background": "#333333", 53 | "statusBar.noFolderBackground": "#333333", 54 | "statusBar.debuggingBackground": "#263238" 55 | }, 56 | "editor.fontSize": 16, 57 | 58 | "css.validate": false, 59 | "scss.validate": false, 60 | "less.validate": false, 61 | "editor.wordWrap": "on" 62 | } 63 | ``` -------------------------------------------------------------------------------- /slides-students-C03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaurabhM84/jonasschmedtmann-complete-javascript-course-learning/ee5254d8a7d383b6fc2dddcf42abcdfc8c9ea4d7/slides-students-C03.pdf --------------------------------------------------------------------------------