├── 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 |
30 |
31 |
32 |
New game
33 |
Roll dice
34 |
Hold
35 |
36 |
37 |
38 |
39 |
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 |
30 |
31 |
32 |
New game
33 |
Roll dice
34 |
Hold
35 |
36 |
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 |
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 |
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 |
2 |
3 |
4 | triangle-left
5 |
6 |
7 |
8 | triangle-right
9 |
10 |
11 |
12 | check
13 |
14 |
15 |
16 | circle-with-cross
17 |
18 |
19 |
20 | circle-with-minus
21 |
22 |
23 |
24 | circle-with-plus
25 |
26 |
27 |
28 | cw
29 |
30 |
31 |
32 | heart-outlined
33 |
34 |
35 |
36 | heart
37 |
38 |
39 |
40 | magnifying-glass
41 |
42 |
43 |
44 | man
45 |
46 |
47 |
48 | shopping-cart
49 |
50 |
51 |
52 | squared-cross
53 |
54 |
55 |
56 | stopwatch
57 |
58 |
59 |
60 |
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 |
19 |
20 |
21 |
22 |
${limitRecipeTitle(like.title)}
23 |
${like.author}
24 |
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 |
10 | ${item.ingredient}
11 |
12 |
13 |
14 |
15 |
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 |
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 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
82 |
83 |
84 |
85 |
86 |
87 | ${recipe.ingredients.map(el => createIngredient(el)).join('')}
88 |
89 |
90 |
91 |
92 |
93 |
94 | Add to shopping list
95 |
96 |
97 |
98 |
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 |
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 |
66 | Page ${type === 'prev' ? page - 1 : page + 1}
67 |
68 |
69 |
70 |
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 |
2 |
3 |
4 | triangle-left
5 |
6 |
7 |
8 | triangle-right
9 |
10 |
11 |
12 | check
13 |
14 |
15 |
16 | circle-with-cross
17 |
18 |
19 |
20 | circle-with-minus
21 |
22 |
23 |
24 | circle-with-plus
25 |
26 |
27 |
28 | cw
29 |
30 |
31 |
32 | heart-outlined
33 |
34 |
35 |
36 | heart
37 |
38 |
39 |
40 | magnifying-glass
41 |
42 |
43 |
44 | man
45 |
46 |
47 |
48 | shopping-cart
49 |
50 |
51 |
52 | squared-cross
53 |
54 |
55 |
56 | stopwatch
57 |
58 |
59 |
60 |
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 |
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 |
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
--------------------------------------------------------------------------------