├── 01-Fundamentals-Part-1
├── final
│ ├── index.html
│ └── script.js
└── starter
│ └── index.html
├── 02-Fundamentals-Part-2
├── final
│ ├── index.html
│ └── script.js
└── starter
│ ├── index.html
│ └── script.js
├── 03-Developer-Skills
├── final
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
└── starter
│ ├── index.html
│ └── script.js
├── 04-HTML-CSS
└── final
│ ├── index.html
│ └── style.css
├── 05-Guess-My-Number
├── final
│ ├── .prettierrc
│ ├── index.html
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── index.html
│ ├── script.js
│ └── style.css
├── 06-Modal
├── final
│ ├── .prettierrc
│ ├── index.html
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── index.html
│ ├── script.js
│ └── style.css
├── 07-Pig-Game
├── final
│ ├── .prettierrc
│ ├── dice-1.png
│ ├── dice-2.png
│ ├── dice-3.png
│ ├── dice-4.png
│ ├── dice-5.png
│ ├── dice-6.png
│ ├── index.html
│ ├── pig-game-flowchart.png
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── dice-1.png
│ ├── dice-2.png
│ ├── dice-3.png
│ ├── dice-4.png
│ ├── dice-5.png
│ ├── dice-6.png
│ ├── index.html
│ ├── pig-game-flowchart.png
│ ├── script.js
│ └── style.css
├── 08-Behind-the-Scenes
├── final
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
└── starter
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
├── 09-Data-Structures-Operators
├── final
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
└── starter
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
├── 10-Functions
├── final
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
└── starter
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
├── 11-Arrays-Bankist
├── final
│ ├── .prettierrc
│ ├── Bankist-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── Bankist-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── script.js
│ └── style.css
├── 12-Numbers-Dates-Timers-Bankist
├── final
│ ├── .prettierrc
│ ├── Bankist-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── Bankist-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── script.js
│ └── style.css
├── 13-Advanced-DOM-Bankist
├── final
│ ├── .prettierrc
│ ├── img
│ │ ├── card-lazy.jpg
│ │ ├── card.jpg
│ │ ├── digital-lazy.jpg
│ │ ├── digital.jpg
│ │ ├── grow-lazy.jpg
│ │ ├── grow.jpg
│ │ ├── hero.png
│ │ ├── icon.png
│ │ ├── icons.svg
│ │ ├── img-1.jpg
│ │ ├── img-2.jpg
│ │ ├── img-3.jpg
│ │ ├── img-4.jpg
│ │ ├── logo.png
│ │ ├── user-1.jpg
│ │ ├── user-2.jpg
│ │ └── user-3.jpg
│ ├── index.html
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── img
│ ├── card-lazy.jpg
│ ├── card.jpg
│ ├── digital-lazy.jpg
│ ├── digital.jpg
│ ├── grow-lazy.jpg
│ ├── grow.jpg
│ ├── hero.png
│ ├── icon.png
│ ├── icons.svg
│ ├── img-1.jpg
│ ├── img-2.jpg
│ ├── img-3.jpg
│ ├── img-4.jpg
│ ├── logo.png
│ ├── user-1.jpg
│ ├── user-2.jpg
│ └── user-3.jpg
│ ├── index.html
│ ├── script.js
│ └── style.css
├── 14-OOP
├── final
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
└── starter
│ ├── .prettierrc
│ ├── index.html
│ └── script.js
├── 15-Mapty
├── final
│ ├── .prettierrc
│ ├── Mapty-architecture-final.png
│ ├── Mapty-architecture-part-1.png
│ ├── Mapty-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── other.js
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── Mapty-architecture-final.png
│ ├── Mapty-architecture-part-1.png
│ ├── Mapty-flowchart.png
│ ├── icon.png
│ ├── index.html
│ ├── logo.png
│ ├── script.js
│ └── style.css
├── 16-Asynchronous
├── final
│ ├── .prettierrc
│ ├── img
│ │ ├── img-1.jpg
│ │ ├── img-2.jpg
│ │ └── img-3.jpg
│ ├── index.html
│ ├── script.js
│ └── style.css
└── starter
│ ├── .prettierrc
│ ├── img
│ ├── img-1.jpg
│ ├── img-2.jpg
│ └── img-3.jpg
│ ├── index.html
│ ├── script.js
│ └── style.css
├── 17-Modern-JS-Modules-Tooling
├── final
│ ├── .prettierrc
│ ├── clean.js
│ ├── dist
│ │ ├── index.html
│ │ ├── index.js
│ │ ├── index.js.map
│ │ ├── script.0b6e4fd3.js
│ │ ├── script.0b6e4fd3.js.map
│ │ ├── script.75da7f30.js
│ │ └── script.75da7f30.js.map
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ ├── script.js
│ └── shoppingCart.js
└── starter
│ ├── .prettierrc
│ ├── clean.js
│ ├── index.html
│ └── script.js
├── 18-forkify
├── final
│ ├── .gitignore
│ ├── .prettierrc
│ ├── README.md
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ │ ├── img
│ │ ├── favicon.png
│ │ ├── icons.svg
│ │ └── logo.png
│ │ ├── js
│ │ ├── config.js
│ │ ├── controller.js
│ │ ├── helpers.js
│ │ ├── model.js
│ │ └── views
│ │ │ ├── View.js
│ │ │ ├── addRecipeView.js
│ │ │ ├── bookmarksView.js
│ │ │ ├── paginationView.js
│ │ │ ├── previewView.js
│ │ │ ├── recipeView.js
│ │ │ ├── resultsView.js
│ │ │ └── searchView.js
│ │ └── sass
│ │ ├── _base.scss
│ │ ├── _components.scss
│ │ ├── _header.scss
│ │ ├── _preview.scss
│ │ ├── _recipe.scss
│ │ ├── _searchResults.scss
│ │ ├── _upload.scss
│ │ └── main.scss
└── starter
│ ├── .prettierrc
│ ├── forkify-architecture-recipe-loading.png
│ ├── forkify-flowchart-part-1.png
│ ├── forkify-flowchart-part-2.png
│ ├── forkify-flowchart-part-3.png
│ ├── index.html
│ └── src
│ ├── img
│ ├── favicon.png
│ ├── icons.svg
│ └── logo.png
│ ├── js
│ └── controller.js
│ └── sass
│ ├── _base.scss
│ ├── _components.scss
│ ├── _header.scss
│ ├── _preview.scss
│ ├── _recipe.scss
│ ├── _searchResults.scss
│ ├── _upload.scss
│ └── main.scss
└── README.md
/01-Fundamentals-Part-1/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | JavaScript Fundamentals – Part 1
8 |
25 |
26 |
27 | JavaScript Fundamentals – Part 1
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/01-Fundamentals-Part-1/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | JavaScript Fundamentals – Part 1
8 |
25 |
26 |
27 | JavaScript Fundamentals – Part 1
28 |
29 |
30 |
--------------------------------------------------------------------------------
/02-Fundamentals-Part-2/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | JavaScript Fundamentals – Part 2
8 |
25 |
26 |
27 | JavaScript Fundamentals – Part 2
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/02-Fundamentals-Part-2/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | JavaScript Fundamentals – Part 2
8 |
25 |
26 |
27 | JavaScript Fundamentals – Part 2
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/02-Fundamentals-Part-2/starter/script.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/02-Fundamentals-Part-2/starter/script.js
--------------------------------------------------------------------------------
/03-Developer-Skills/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/03-Developer-Skills/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Developer Skills & Editor Setup
8 |
25 |
26 |
27 | Developer Skills & Editor Setup
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/03-Developer-Skills/final/script.js:
--------------------------------------------------------------------------------
1 | // Remember, we're gonna use strict mode in all scripts now!
2 | 'use strict';
3 |
4 | /*
5 | ///////////////////////////////////////
6 | // Using Google, StackOverflow and MDN
7 |
8 | // PROBLEM 1:
9 | // We work for a company building a smart home thermometer. Our most recent task is this: "Given an array of temperatures of one day, calculate the temperature amplitude. Keep in mind that sometimes there might be a sensor error."
10 |
11 | const temperatures = [3, -2, -6, -1, 'error', 9, 13, 17, 15, 14, 9, 5];
12 |
13 | // 1) Understanding the problem
14 | // - What is temp amplitude? Answer: difference between highest and lowest temp
15 | // - How to compute max and min temperatures?
16 | // - What's a sensor error? And what do do?
17 |
18 | // 2) Breaking up into sub-problems
19 | // - How to ignore errors?
20 | // - Find max value in temp array
21 | // - Find min value in temp array
22 | // - Subtract min from max (amplitude) and return it
23 |
24 | const calcTempAmplitude = function (temps) {
25 | let max = temps[0];
26 | let min = temps[0];
27 |
28 | for (let i = 0; i < temps.length; i++) {
29 | const curTemp = temps[i];
30 | if (typeof curTemp !== 'number') continue;
31 |
32 | if (curTemp > max) max = curTemp;
33 | if (curTemp < min) min = curTemp;
34 | }
35 | console.log(max, min);
36 | return max - min;
37 | };
38 | const amplitude = calcTempAmplitude(temperatures);
39 | console.log(amplitude);
40 |
41 | // PROBLEM 2:
42 | // Function should now receive 2 arrays of temps
43 |
44 | // 1) Understanding the problem
45 | // - With 2 arrays, should we implement functionality twice? NO! Just merge two arrays
46 |
47 | // 2) Breaking up into sub-problems
48 | // - Merge 2 arrays
49 |
50 | const calcTempAmplitudeNew = function (t1, t2) {
51 | const temps = t1.concat(t2);
52 | console.log(temps);
53 |
54 | let max = temps[0];
55 | let min = temps[0];
56 |
57 | for (let i = 0; i < temps.length; i++) {
58 | const curTemp = temps[i];
59 | if (typeof curTemp !== 'number') continue;
60 |
61 | if (curTemp > max) max = curTemp;
62 | if (curTemp < min) min = curTemp;
63 | }
64 | console.log(max, min);
65 | return max - min;
66 | };
67 | const amplitudeNew = calcTempAmplitudeNew([3, 5, 1], [9, 0, 5]);
68 | console.log(amplitudeNew);
69 |
70 |
71 | ///////////////////////////////////////
72 | // Debugging with the Console and Breakpoints
73 | const measureKelvin = function () {
74 | const measurement = {
75 | type: 'temp',
76 | unit: 'celsius',
77 |
78 | // C) FIX
79 | // value: Number(prompt('Degrees celsius:')),
80 | value: 10,
81 | };
82 |
83 | // B) FIND
84 | console.table(measurement);
85 |
86 | // console.log(measurement.value);
87 | // console.warn(measurement.value);
88 | // console.error(measurement.value);
89 |
90 | const kelvin = measurement.value + 273;
91 | return kelvin;
92 | };
93 | // A) IDENTIFY
94 | console.log(measureKelvin());
95 |
96 | // Using a debugger
97 | const calcTempAmplitudeBug = function (t1, t2) {
98 | const temps = t1.concat(t2);
99 | console.log(temps);
100 |
101 | let max = 0;
102 | let min = 0;
103 |
104 | for (let i = 0; i < temps.length; i++) {
105 | const curTemp = temps[i];
106 | if (typeof curTemp !== 'number') continue;
107 |
108 | if (curTemp > max) max = curTemp;
109 | if (curTemp < min) min = curTemp;
110 | }
111 | console.log(max, min);
112 | return max - min;
113 | };
114 | const amplitudeBug = calcTempAmplitudeBug([3, 5, 1], [9, 4, 5]);
115 | // A) IDENTIFY
116 | console.log(amplitudeBug);
117 | */
118 |
119 | ///////////////////////////////////////
120 | // Coding Challenge #1
121 |
122 | /*
123 | Given an array of forecasted maximum temperatures, the thermometer displays a string with these temperatures.
124 |
125 | Example: [17, 21, 23] will print "... 17ºC in 1 days ... 21ºC in 2 days ... 23ºC in 3 days ..."
126 |
127 | Create a function 'printForecast' which takes in an array 'arr' and logs a string like the above to the console.
128 |
129 | Use the problem-solving framework: Understand the problem and break it up into sub-problems!
130 |
131 | TEST DATA 1: [17, 21, 23]
132 | TEST DATA 2: [12, 5, -5, 0, 4]
133 | */
134 |
135 | /*
136 | // 1) Understanding the problem
137 | // - Array transformed to string, separated by ...
138 | // - What is the X days? Answer: index + 1
139 |
140 | // 2) Breaking up into sub-problems
141 | // - Transform array into string
142 | // - Transform each element to string with ºC
143 | // - Strings needs to contain day (index + 1)
144 | // - Add ... between elements and start and end of string
145 | // - Log string to console
146 |
147 | const data1 = [17, 21, 23];
148 | const data2 = [12, 5, -5, 0, 4];
149 |
150 | console.log(`... ${data1[0]}ºC ... ${data1[1]}ºC ... ${data1[2]}ºC ...`);
151 |
152 | const printForecast = function (arr) {
153 | let str = '';
154 | for (let i = 0; i < arr.length; i++) {
155 | str += `${arr[i]}ºC in ${i + 1} days ... `;
156 | }
157 | console.log('...' + str);
158 | };
159 | printForecast(data1);
160 | */
161 |
162 |
--------------------------------------------------------------------------------
/03-Developer-Skills/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Developer Skills & Editor Setup
8 |
25 |
26 |
27 | Developer Skills & Editor Setup
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/03-Developer-Skills/starter/script.js:
--------------------------------------------------------------------------------
1 | // Remember, we're gonna use strict mode in all scripts now!
2 | 'use strict';
3 |
4 |
--------------------------------------------------------------------------------
/04-HTML-CSS/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Learning HTML & CSS
10 |
11 |
12 | JavaScript is fun, but so is HTML & CSS!
13 |
14 | You can learn JavaScript without HTML and CSS, but for DOM manipulation
15 | it's useful to have some basic ideas of HTML & CSS. You can learn more
16 | about it
17 | on Udemy .
18 |
19 |
20 | Another heading
21 |
22 | Just another paragraph
23 |
24 |
25 |
29 |
30 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/04-HTML-CSS/final/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | body {
8 | background-color: rgb(255, 247, 201);
9 | font-family: Arial;
10 | font-size: 20px;
11 | padding: 50px;
12 | }
13 |
14 | h1 {
15 | font-size: 35px;
16 | margin-bottom: 25px;
17 | }
18 |
19 | h2 {
20 | margin-bottom: 20px;
21 | text-align: center;
22 | }
23 |
24 | p {
25 | margin-bottom: 20px;
26 | }
27 |
28 | .first {
29 | color: red;
30 | }
31 |
32 | #your-name {
33 | background-color: rgb(255, 220, 105);
34 | border: 5px solid #444;
35 | width: 400px;
36 | padding: 25px;
37 | margin-top: 30px;
38 | }
39 |
40 | input,
41 | button {
42 | padding: 10px;
43 | font-size: 16px;
44 | }
45 |
46 | a {
47 | background-color: yellowgreen;
48 | }
49 |
50 | #course-image {
51 | width: 300px;
52 | }
53 |
54 | #your-name h2 {
55 | color: olivedrab;
56 | }
57 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Guess My Number!
9 |
10 |
11 |
12 | Guess My Number!
13 | (Between 1 and 20)
14 | Again!
15 | ?
16 |
17 |
18 |
22 |
23 | Start guessing...
24 | 💯 Score: 20
25 |
26 | 🥇 Highscore: 0
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/final/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | console.log(document.querySelector('.message').textContent);
5 | document.querySelector('.message').textContent = '🎉 Correct Number!';
6 |
7 | document.querySelector('.number').textContent = 13;
8 | document.querySelector('.score').textContent = 10;
9 |
10 | document.querySelector('.guess').value = 23;
11 | console.log(document.querySelector('.guess').value);
12 | */
13 |
14 | let secretNumber = Math.trunc(Math.random() * 20) + 1;
15 | let score = 20;
16 | let highscore = 0;
17 |
18 | const displayMessage = function (message) {
19 | document.querySelector('.message').textContent = message;
20 | };
21 |
22 | document.querySelector('.check').addEventListener('click', function () {
23 | const guess = Number(document.querySelector('.guess').value);
24 | console.log(guess, typeof guess);
25 |
26 | // When there is no input
27 | if (!guess) {
28 | // document.querySelector('.message').textContent = '⛔️ No number!';
29 | displayMessage('⛔️ No number!');
30 |
31 | // When player wins
32 | } else if (guess === secretNumber) {
33 | // document.querySelector('.message').textContent = '🎉 Correct Number!';
34 | displayMessage('🎉 Correct Number!');
35 | document.querySelector('.number').textContent = secretNumber;
36 |
37 | document.querySelector('body').style.backgroundColor = '#60b347';
38 | document.querySelector('.number').style.width = '30rem';
39 |
40 | if (score > highscore) {
41 | highscore = score;
42 | document.querySelector('.highscore').textContent = highscore;
43 | }
44 |
45 | // When guess is wrong
46 | } else if (guess !== secretNumber) {
47 | if (score > 1) {
48 | // document.querySelector('.message').textContent =
49 | // guess > secretNumber ? '📈 Too high!' : '📉 Too low!';
50 | displayMessage(guess > secretNumber ? '📈 Too high!' : '📉 Too low!');
51 | score--;
52 | document.querySelector('.score').textContent = score;
53 | } else {
54 | // document.querySelector('.message').textContent = '💥 You lost the game!';
55 | displayMessage('💥 You lost the game!');
56 | document.querySelector('.score').textContent = 0;
57 | }
58 | }
59 |
60 | // // When guess is too high
61 | // } else if (guess > secretNumber) {
62 | // if (score > 1) {
63 | // document.querySelector('.message').textContent = '📈 Too high!';
64 | // score--;
65 | // document.querySelector('.score').textContent = score;
66 | // } else {
67 | // document.querySelector('.message').textContent = '💥 You lost the game!';
68 | // document.querySelector('.score').textContent = 0;
69 | // }
70 |
71 | // // When guess is too low
72 | // } else if (guess < secretNumber) {
73 | // if (score > 1) {
74 | // document.querySelector('.message').textContent = '📉 Too low!';
75 | // score--;
76 | // document.querySelector('.score').textContent = score;
77 | // } else {
78 | // document.querySelector('.message').textContent = '💥 You lost the game!';
79 | // document.querySelector('.score').textContent = 0;
80 | // }
81 | // }
82 | });
83 |
84 | document.querySelector('.again').addEventListener('click', function () {
85 | score = 20;
86 | secretNumber = Math.trunc(Math.random() * 20) + 1;
87 |
88 | // document.querySelector('.message').textContent = 'Start guessing...';
89 | displayMessage('Start guessing...');
90 | document.querySelector('.score').textContent = score;
91 | document.querySelector('.number').textContent = '?';
92 | document.querySelector('.guess').value = '';
93 |
94 | document.querySelector('body').style.backgroundColor = '#222';
95 | document.querySelector('.number').style.width = '15rem';
96 | });
97 |
98 | ///////////////////////////////////////
99 | // Coding Challenge #1
100 |
101 | /*
102 | Implement a game rest functionality, so that the player can make a new guess! Here is how:
103 |
104 | 1. Select the element with the 'again' class and attach a click event handler
105 | 2. In the handler function, restore initial values of the score and secretNumber variables
106 | 3. Restore the initial conditions of the message, number, score and guess input field
107 | 4. Also restore the original background color (#222) and number width (15rem)
108 |
109 | GOOD LUCK 😀
110 | */
111 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/final/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap');
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: inherit;
7 | }
8 |
9 | html {
10 | font-size: 62.5%;
11 | box-sizing: border-box;
12 | }
13 |
14 | body {
15 | font-family: 'Press Start 2P', sans-serif;
16 | color: #eee;
17 | background-color: #222;
18 | /* background-color: #60b347; */
19 | }
20 |
21 | /* LAYOUT */
22 | header {
23 | position: relative;
24 | height: 35vh;
25 | border-bottom: 7px solid #eee;
26 | }
27 |
28 | main {
29 | height: 65vh;
30 | color: #eee;
31 | display: flex;
32 | align-items: center;
33 | justify-content: space-around;
34 | }
35 |
36 | .left {
37 | width: 52rem;
38 | display: flex;
39 | flex-direction: column;
40 | align-items: center;
41 | }
42 |
43 | .right {
44 | width: 52rem;
45 | font-size: 2rem;
46 | }
47 |
48 | /* ELEMENTS STYLE */
49 | h1 {
50 | font-size: 4rem;
51 | text-align: center;
52 | position: absolute;
53 | width: 100%;
54 | top: 52%;
55 | left: 50%;
56 | transform: translate(-50%, -50%);
57 | }
58 |
59 | .number {
60 | background: #eee;
61 | color: #333;
62 | font-size: 6rem;
63 | width: 15rem;
64 | padding: 3rem 0rem;
65 | text-align: center;
66 | position: absolute;
67 | bottom: 0;
68 | left: 50%;
69 | transform: translate(-50%, 50%);
70 | }
71 |
72 | .between {
73 | font-size: 1.4rem;
74 | position: absolute;
75 | top: 2rem;
76 | right: 2rem;
77 | }
78 |
79 | .again {
80 | position: absolute;
81 | top: 2rem;
82 | left: 2rem;
83 | }
84 |
85 | .guess {
86 | background: none;
87 | border: 4px solid #eee;
88 | font-family: inherit;
89 | color: inherit;
90 | font-size: 5rem;
91 | padding: 2.5rem;
92 | width: 25rem;
93 | text-align: center;
94 | display: block;
95 | margin-bottom: 3rem;
96 | }
97 |
98 | .btn {
99 | border: none;
100 | background-color: #eee;
101 | color: #222;
102 | font-size: 2rem;
103 | font-family: inherit;
104 | padding: 2rem 3rem;
105 | cursor: pointer;
106 | }
107 |
108 | .btn:hover {
109 | background-color: #ccc;
110 | }
111 |
112 | .message {
113 | margin-bottom: 8rem;
114 | height: 3rem;
115 | }
116 |
117 | .label-score {
118 | margin-bottom: 2rem;
119 | }
120 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Guess My Number!
9 |
10 |
11 |
12 | Guess My Number!
13 | (Between 1 and 20)
14 | Again!
15 | ?
16 |
17 |
18 |
22 |
23 | Start guessing...
24 | 💯 Score: 20
25 |
26 | 🥇 Highscore: 0
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/05-Guess-My-Number/starter/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap');
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: inherit;
7 | }
8 |
9 | html {
10 | font-size: 62.5%;
11 | box-sizing: border-box;
12 | }
13 |
14 | body {
15 | font-family: 'Press Start 2P', sans-serif;
16 | color: #eee;
17 | background-color: #222;
18 | /* background-color: #60b347; */
19 | }
20 |
21 | /* LAYOUT */
22 | header {
23 | position: relative;
24 | height: 35vh;
25 | border-bottom: 7px solid #eee;
26 | }
27 |
28 | main {
29 | height: 65vh;
30 | color: #eee;
31 | display: flex;
32 | align-items: center;
33 | justify-content: space-around;
34 | }
35 |
36 | .left {
37 | width: 52rem;
38 | display: flex;
39 | flex-direction: column;
40 | align-items: center;
41 | }
42 |
43 | .right {
44 | width: 52rem;
45 | font-size: 2rem;
46 | }
47 |
48 | /* ELEMENTS STYLE */
49 | h1 {
50 | font-size: 4rem;
51 | text-align: center;
52 | position: absolute;
53 | width: 100%;
54 | top: 52%;
55 | left: 50%;
56 | transform: translate(-50%, -50%);
57 | }
58 |
59 | .number {
60 | background: #eee;
61 | color: #333;
62 | font-size: 6rem;
63 | width: 15rem;
64 | padding: 3rem 0rem;
65 | text-align: center;
66 | position: absolute;
67 | bottom: 0;
68 | left: 50%;
69 | transform: translate(-50%, 50%);
70 | }
71 |
72 | .between {
73 | font-size: 1.4rem;
74 | position: absolute;
75 | top: 2rem;
76 | right: 2rem;
77 | }
78 |
79 | .again {
80 | position: absolute;
81 | top: 2rem;
82 | left: 2rem;
83 | }
84 |
85 | .guess {
86 | background: none;
87 | border: 4px solid #eee;
88 | font-family: inherit;
89 | color: inherit;
90 | font-size: 5rem;
91 | padding: 2.5rem;
92 | width: 25rem;
93 | text-align: center;
94 | display: block;
95 | margin-bottom: 3rem;
96 | }
97 |
98 | .btn {
99 | border: none;
100 | background-color: #eee;
101 | color: #222;
102 | font-size: 2rem;
103 | font-family: inherit;
104 | padding: 2rem 3rem;
105 | cursor: pointer;
106 | }
107 |
108 | .btn:hover {
109 | background-color: #ccc;
110 | }
111 |
112 | .message {
113 | margin-bottom: 8rem;
114 | height: 3rem;
115 | }
116 |
117 | .label-score {
118 | margin-bottom: 2rem;
119 | }
120 |
--------------------------------------------------------------------------------
/06-Modal/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/06-Modal/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Modal window
9 |
10 |
11 | Show modal 1
12 | Show modal 2
13 | Show modal 3
14 |
15 |
16 |
×
17 |
I'm a modal window 😍
18 |
19 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
20 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
21 | veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
22 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
23 | velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
24 | occaecat cupidatat non proident, sunt in culpa qui officia deserunt
25 | mollit anim id est laborum.
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/06-Modal/final/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const modal = document.querySelector('.modal');
4 | const overlay = document.querySelector('.overlay');
5 | const btnCloseModal = document.querySelector('.close-modal');
6 | const btnsOpenModal = document.querySelectorAll('.show-modal');
7 |
8 | const openModal = function () {
9 | modal.classList.remove('hidden');
10 | overlay.classList.remove('hidden');
11 | };
12 |
13 | const closeModal = function () {
14 | modal.classList.add('hidden');
15 | overlay.classList.add('hidden');
16 | };
17 |
18 | for (let i = 0; i < btnsOpenModal.length; i++)
19 | btnsOpenModal[i].addEventListener('click', openModal);
20 |
21 | btnCloseModal.addEventListener('click', closeModal);
22 | overlay.addEventListener('click', closeModal);
23 |
24 | document.addEventListener('keydown', function (e) {
25 | // console.log(e.key);
26 |
27 | if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
28 | closeModal();
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/06-Modal/final/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: inherit;
5 | }
6 |
7 | html {
8 | font-size: 62.5%;
9 | box-sizing: border-box;
10 | }
11 |
12 | body {
13 | font-family: sans-serif;
14 | color: #333;
15 | line-height: 1.5;
16 | height: 100vh;
17 | position: relative;
18 | display: flex;
19 | align-items: flex-start;
20 | justify-content: center;
21 | background: linear-gradient(to top left, #28b487, #7dd56f);
22 | }
23 |
24 | .show-modal {
25 | font-size: 2rem;
26 | font-weight: 600;
27 | padding: 1.75rem 3.5rem;
28 | margin: 5rem 2rem;
29 | border: none;
30 | background-color: #fff;
31 | color: #444;
32 | border-radius: 10rem;
33 | cursor: pointer;
34 | }
35 |
36 | .close-modal {
37 | position: absolute;
38 | top: 1.2rem;
39 | right: 2rem;
40 | font-size: 5rem;
41 | color: #333;
42 | cursor: pointer;
43 | border: none;
44 | background: none;
45 | }
46 |
47 | h1 {
48 | font-size: 2.5rem;
49 | margin-bottom: 2rem;
50 | }
51 |
52 | p {
53 | font-size: 1.8rem;
54 | }
55 |
56 | /* -------------------------- */
57 | /* CLASSES TO MAKE MODAL WORK */
58 | .hidden {
59 | display: none;
60 | }
61 |
62 | .modal {
63 | position: absolute;
64 | top: 50%;
65 | left: 50%;
66 | transform: translate(-50%, -50%);
67 | width: 70%;
68 |
69 | background-color: white;
70 | padding: 6rem;
71 | border-radius: 5px;
72 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3);
73 | z-index: 10;
74 | }
75 |
76 | .overlay {
77 | position: absolute;
78 | top: 0;
79 | left: 0;
80 | width: 100%;
81 | height: 100%;
82 | background-color: rgba(0, 0, 0, 0.6);
83 | backdrop-filter: blur(3px);
84 | z-index: 5;
85 | }
86 |
--------------------------------------------------------------------------------
/06-Modal/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/06-Modal/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Modal window
9 |
10 |
11 | Show modal 1
12 | Show modal 2
13 | Show modal 3
14 |
15 |
16 |
×
17 |
I'm a modal window 😍
18 |
19 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
20 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
21 | veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
22 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
23 | velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
24 | occaecat cupidatat non proident, sunt in culpa qui officia deserunt
25 | mollit anim id est laborum.
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/06-Modal/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/06-Modal/starter/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: inherit;
5 | }
6 |
7 | html {
8 | font-size: 62.5%;
9 | box-sizing: border-box;
10 | }
11 |
12 | body {
13 | font-family: sans-serif;
14 | color: #333;
15 | line-height: 1.5;
16 | height: 100vh;
17 | position: relative;
18 | display: flex;
19 | align-items: flex-start;
20 | justify-content: center;
21 | background: linear-gradient(to top left, #28b487, #7dd56f);
22 | }
23 |
24 | .show-modal {
25 | font-size: 2rem;
26 | font-weight: 600;
27 | padding: 1.75rem 3.5rem;
28 | margin: 5rem 2rem;
29 | border: none;
30 | background-color: #fff;
31 | color: #444;
32 | border-radius: 10rem;
33 | cursor: pointer;
34 | }
35 |
36 | .close-modal {
37 | position: absolute;
38 | top: 1.2rem;
39 | right: 2rem;
40 | font-size: 5rem;
41 | color: #333;
42 | cursor: pointer;
43 | border: none;
44 | background: none;
45 | }
46 |
47 | h1 {
48 | font-size: 2.5rem;
49 | margin-bottom: 2rem;
50 | }
51 |
52 | p {
53 | font-size: 1.8rem;
54 | }
55 |
56 | /* -------------------------- */
57 | /* CLASSES TO MAKE MODAL WORK */
58 | .hidden {
59 | display: none;
60 | }
61 |
62 | .modal {
63 | position: absolute;
64 | top: 50%;
65 | left: 50%;
66 | transform: translate(-50%, -50%);
67 | width: 70%;
68 |
69 | background-color: white;
70 | padding: 6rem;
71 | border-radius: 5px;
72 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3);
73 | z-index: 10;
74 | }
75 |
76 | .overlay {
77 | position: absolute;
78 | top: 0;
79 | left: 0;
80 | width: 100%;
81 | height: 100%;
82 | background-color: rgba(0, 0, 0, 0.6);
83 | backdrop-filter: blur(3px);
84 | z-index: 5;
85 | }
86 |
--------------------------------------------------------------------------------
/07-Pig-Game/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-1.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-2.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-3.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-4.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-5.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/dice-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/dice-6.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Pig Game
9 |
10 |
11 |
12 |
13 | Player 1
14 | 43
15 |
19 |
20 |
21 | Player 2
22 | 24
23 |
27 |
28 |
29 |
30 | 🔄 New game
31 | 🎲 Roll dice
32 | 📥 Hold
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/07-Pig-Game/final/pig-game-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/final/pig-game-flowchart.png
--------------------------------------------------------------------------------
/07-Pig-Game/final/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Selecting elements
4 | const player0El = document.querySelector('.player--0');
5 | const player1El = document.querySelector('.player--1');
6 | const score0El = document.querySelector('#score--0');
7 | const score1El = document.getElementById('score--1');
8 | const current0El = document.getElementById('current--0');
9 | const current1El = document.getElementById('current--1');
10 |
11 | const diceEl = document.querySelector('.dice');
12 | const btnNew = document.querySelector('.btn--new');
13 | const btnRoll = document.querySelector('.btn--roll');
14 | const btnHold = document.querySelector('.btn--hold');
15 |
16 | let scores, currentScore, activePlayer, playing;
17 |
18 | // Starting conditions
19 | const init = function () {
20 | scores = [0, 0];
21 | currentScore = 0;
22 | activePlayer = 0;
23 | playing = true;
24 |
25 | score0El.textContent = 0;
26 | score1El.textContent = 0;
27 | current0El.textContent = 0;
28 | current1El.textContent = 0;
29 |
30 | diceEl.classList.add('hidden');
31 | player0El.classList.remove('player--winner');
32 | player1El.classList.remove('player--winner');
33 | player0El.classList.add('player--active');
34 | player1El.classList.remove('player--active');
35 | };
36 | init();
37 |
38 | const switchPlayer = function () {
39 | document.getElementById(`current--${activePlayer}`).textContent = 0;
40 | currentScore = 0;
41 | activePlayer = activePlayer === 0 ? 1 : 0;
42 | player0El.classList.toggle('player--active');
43 | player1El.classList.toggle('player--active');
44 | };
45 |
46 | // Rolling dice functionality
47 | btnRoll.addEventListener('click', function () {
48 | if (playing) {
49 | // 1. Generating a random dice roll
50 | const dice = Math.trunc(Math.random() * 6) + 1;
51 |
52 | // 2. Display dice
53 | diceEl.classList.remove('hidden');
54 | diceEl.src = `dice-${dice}.png`;
55 |
56 | // 3. Check for rolled 1
57 | if (dice !== 1) {
58 | // Add dice to current score
59 | currentScore += dice;
60 | document.getElementById(
61 | `current--${activePlayer}`
62 | ).textContent = currentScore;
63 | } else {
64 | // Switch to next player
65 | switchPlayer();
66 | }
67 | }
68 | });
69 |
70 | btnHold.addEventListener('click', function () {
71 | if (playing) {
72 | // 1. Add current score to active player's score
73 | scores[activePlayer] += currentScore;
74 | // scores[1] = scores[1] + currentScore
75 |
76 | document.getElementById(`score--${activePlayer}`).textContent =
77 | scores[activePlayer];
78 |
79 | // 2. Check if player's score is >= 100
80 | if (scores[activePlayer] >= 100) {
81 | // Finish the game
82 | playing = false;
83 | diceEl.classList.add('hidden');
84 |
85 | document
86 | .querySelector(`.player--${activePlayer}`)
87 | .classList.add('player--winner');
88 | document
89 | .querySelector(`.player--${activePlayer}`)
90 | .classList.remove('player--active');
91 | } else {
92 | // Switch to the next player
93 | switchPlayer();
94 | }
95 | }
96 | });
97 |
98 | btnNew.addEventListener('click', init);
99 |
--------------------------------------------------------------------------------
/07-Pig-Game/final/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: inherit;
7 | }
8 |
9 | html {
10 | font-size: 62.5%;
11 | box-sizing: border-box;
12 | }
13 |
14 | body {
15 | font-family: 'Nunito', sans-serif;
16 | font-weight: 400;
17 | height: 100vh;
18 | color: #333;
19 | background-image: linear-gradient(to top left, #753682 0%, #bf2e34 100%);
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | }
24 |
25 | /* LAYOUT */
26 | main {
27 | position: relative;
28 | width: 100rem;
29 | height: 60rem;
30 | background-color: rgba(255, 255, 255, 0.35);
31 | backdrop-filter: blur(200px);
32 | filter: blur();
33 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25);
34 | border-radius: 9px;
35 | overflow: hidden;
36 | display: flex;
37 | }
38 |
39 | .player {
40 | flex: 50%;
41 | padding: 9rem;
42 | display: flex;
43 | flex-direction: column;
44 | align-items: center;
45 | transition: all 0.75s;
46 | }
47 |
48 | /* ELEMENTS */
49 | .name {
50 | position: relative;
51 | font-size: 4rem;
52 | text-transform: uppercase;
53 | letter-spacing: 1px;
54 | word-spacing: 2px;
55 | font-weight: 300;
56 | margin-bottom: 1rem;
57 | }
58 |
59 | .score {
60 | font-size: 8rem;
61 | font-weight: 300;
62 | color: #c7365f;
63 | margin-bottom: auto;
64 | }
65 |
66 | .player--active {
67 | background-color: rgba(255, 255, 255, 0.4);
68 | }
69 | .player--active .name {
70 | font-weight: 700;
71 | }
72 | .player--active .score {
73 | font-weight: 400;
74 | }
75 |
76 | .player--active .current {
77 | opacity: 1;
78 | }
79 |
80 | .current {
81 | background-color: #c7365f;
82 | opacity: 0.8;
83 | border-radius: 9px;
84 | color: #fff;
85 | width: 65%;
86 | padding: 2rem;
87 | text-align: center;
88 | transition: all 0.75s;
89 | }
90 |
91 | .current-label {
92 | text-transform: uppercase;
93 | margin-bottom: 1rem;
94 | font-size: 1.7rem;
95 | color: #ddd;
96 | }
97 |
98 | .current-score {
99 | font-size: 3.5rem;
100 | }
101 |
102 | /* ABSOLUTE POSITIONED ELEMENTS */
103 | .btn {
104 | position: absolute;
105 | left: 50%;
106 | transform: translateX(-50%);
107 | color: #444;
108 | background: none;
109 | border: none;
110 | font-family: inherit;
111 | font-size: 1.8rem;
112 | text-transform: uppercase;
113 | cursor: pointer;
114 | font-weight: 400;
115 | transition: all 0.2s;
116 |
117 | background-color: white;
118 | background-color: rgba(255, 255, 255, 0.6);
119 | backdrop-filter: blur(10px);
120 |
121 | padding: 0.7rem 2.5rem;
122 | border-radius: 50rem;
123 | box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1);
124 | }
125 |
126 | .btn::first-letter {
127 | font-size: 2.4rem;
128 | display: inline-block;
129 | margin-right: 0.7rem;
130 | }
131 |
132 | .btn--new {
133 | top: 4rem;
134 | }
135 | .btn--roll {
136 | top: 39.3rem;
137 | }
138 | .btn--hold {
139 | top: 46.1rem;
140 | }
141 |
142 | .btn:active {
143 | transform: translate(-50%, 3px);
144 | box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15);
145 | }
146 |
147 | .btn:focus {
148 | outline: none;
149 | }
150 |
151 | .dice {
152 | position: absolute;
153 | left: 50%;
154 | top: 16.5rem;
155 | transform: translateX(-50%);
156 | height: 10rem;
157 | box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2);
158 | }
159 |
160 | .player--winner {
161 | background-color: #2f2f2f;
162 | }
163 |
164 | .player--winner .name {
165 | font-weight: 700;
166 | color: #c7365f;
167 | }
168 |
169 | .hidden {
170 | display: none;
171 | }
172 |
--------------------------------------------------------------------------------
/07-Pig-Game/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-1.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-2.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-3.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-4.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-5.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/dice-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/dice-6.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Pig Game
9 |
10 |
11 |
12 |
13 | Player 1
14 | 43
15 |
19 |
20 |
21 | Player 2
22 | 24
23 |
27 |
28 |
29 |
30 | 🔄 New game
31 | 🎲 Roll dice
32 | 📥 Hold
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/07-Pig-Game/starter/pig-game-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/07-Pig-Game/starter/pig-game-flowchart.png
--------------------------------------------------------------------------------
/07-Pig-Game/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/07-Pig-Game/starter/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: inherit;
7 | }
8 |
9 | html {
10 | font-size: 62.5%;
11 | box-sizing: border-box;
12 | }
13 |
14 | body {
15 | font-family: 'Nunito', sans-serif;
16 | font-weight: 400;
17 | height: 100vh;
18 | color: #333;
19 | background-image: linear-gradient(to top left, #753682 0%, #bf2e34 100%);
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | }
24 |
25 | /* LAYOUT */
26 | main {
27 | position: relative;
28 | width: 100rem;
29 | height: 60rem;
30 | background-color: rgba(255, 255, 255, 0.35);
31 | backdrop-filter: blur(200px);
32 | filter: blur();
33 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25);
34 | border-radius: 9px;
35 | overflow: hidden;
36 | display: flex;
37 | }
38 |
39 | .player {
40 | flex: 50%;
41 | padding: 9rem;
42 | display: flex;
43 | flex-direction: column;
44 | align-items: center;
45 | transition: all 0.75s;
46 | }
47 |
48 | /* ELEMENTS */
49 | .name {
50 | position: relative;
51 | font-size: 4rem;
52 | text-transform: uppercase;
53 | letter-spacing: 1px;
54 | word-spacing: 2px;
55 | font-weight: 300;
56 | margin-bottom: 1rem;
57 | }
58 |
59 | .score {
60 | font-size: 8rem;
61 | font-weight: 300;
62 | color: #c7365f;
63 | margin-bottom: auto;
64 | }
65 |
66 | .player--active {
67 | background-color: rgba(255, 255, 255, 0.4);
68 | }
69 | .player--active .name {
70 | font-weight: 700;
71 | }
72 | .player--active .score {
73 | font-weight: 400;
74 | }
75 |
76 | .player--active .current {
77 | opacity: 1;
78 | }
79 |
80 | .current {
81 | background-color: #c7365f;
82 | opacity: 0.8;
83 | border-radius: 9px;
84 | color: #fff;
85 | width: 65%;
86 | padding: 2rem;
87 | text-align: center;
88 | transition: all 0.75s;
89 | }
90 |
91 | .current-label {
92 | text-transform: uppercase;
93 | margin-bottom: 1rem;
94 | font-size: 1.7rem;
95 | color: #ddd;
96 | }
97 |
98 | .current-score {
99 | font-size: 3.5rem;
100 | }
101 |
102 | /* ABSOLUTE POSITIONED ELEMENTS */
103 | .btn {
104 | position: absolute;
105 | left: 50%;
106 | transform: translateX(-50%);
107 | color: #444;
108 | background: none;
109 | border: none;
110 | font-family: inherit;
111 | font-size: 1.8rem;
112 | text-transform: uppercase;
113 | cursor: pointer;
114 | font-weight: 400;
115 | transition: all 0.2s;
116 |
117 | background-color: white;
118 | background-color: rgba(255, 255, 255, 0.6);
119 | backdrop-filter: blur(10px);
120 |
121 | padding: 0.7rem 2.5rem;
122 | border-radius: 50rem;
123 | box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1);
124 | }
125 |
126 | .btn::first-letter {
127 | font-size: 2.4rem;
128 | display: inline-block;
129 | margin-right: 0.7rem;
130 | }
131 |
132 | .btn--new {
133 | top: 4rem;
134 | }
135 | .btn--roll {
136 | top: 39.3rem;
137 | }
138 | .btn--hold {
139 | top: 46.1rem;
140 | }
141 |
142 | .btn:active {
143 | transform: translate(-50%, 3px);
144 | box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15);
145 | }
146 |
147 | .btn:focus {
148 | outline: none;
149 | }
150 |
151 | .dice {
152 | position: absolute;
153 | left: 50%;
154 | top: 16.5rem;
155 | transform: translateX(-50%);
156 | height: 10rem;
157 | box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2);
158 | }
159 |
160 | .player--winner {
161 | background-color: #2f2f2f;
162 | }
163 |
164 | .player--winner .name {
165 | font-weight: 700;
166 | color: #c7365f;
167 | }
168 |
--------------------------------------------------------------------------------
/08-Behind-the-Scenes/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/08-Behind-the-Scenes/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | How JavaScript Works Behind the Scenes
8 |
25 |
26 |
27 | How JavaScript Works Behind the Scenes
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/08-Behind-the-Scenes/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/08-Behind-the-Scenes/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | How JavaScript Works Behind the Scenes
8 |
25 |
26 |
27 | How JavaScript Works Behind the Scenes
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/08-Behind-the-Scenes/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/09-Data-Structures-Operators/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/09-Data-Structures-Operators/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Data Structures and Modern Operators
8 |
34 |
35 |
36 | Data Structures and Modern Operators
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/09-Data-Structures-Operators/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/09-Data-Structures-Operators/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Data Structures and Modern Operators
8 |
34 |
35 |
36 | Data Structures and Modern Operators
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/09-Data-Structures-Operators/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Data needed for a later exercise
4 | const flights =
5 | '_Delayed_Departure;fao93766109;txl2133758440;11:25+_Arrival;bru0943384722;fao93766109;11:45+_Delayed_Arrival;hel7439299980;fao93766109;12:05+_Departure;fao93766109;lis2323639855;12:30';
6 |
7 | // Data needed for first part of the section
8 | const restaurant = {
9 | name: 'Classico Italiano',
10 | location: 'Via Angelo Tavanti 23, Firenze, Italy',
11 | categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
12 | starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
13 | mainMenu: ['Pizza', 'Pasta', 'Risotto'],
14 |
15 | openingHours: {
16 | thu: {
17 | open: 12,
18 | close: 22,
19 | },
20 | fri: {
21 | open: 11,
22 | close: 23,
23 | },
24 | sat: {
25 | open: 0, // Open 24 hours
26 | close: 24,
27 | },
28 | },
29 | };
30 |
--------------------------------------------------------------------------------
/10-Functions/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/10-Functions/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | A Closer Look at Functions
8 |
38 |
39 |
40 | A Closer Look at Functions
41 | Buy new plane 🛩
42 | Answer poll ⁉️
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/10-Functions/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/10-Functions/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | A Closer Look at Functions
8 |
38 |
39 |
40 | A Closer Look at Functions
41 | Buy new plane 🛩
42 | Answer poll ⁉️
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/10-Functions/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/11-Arrays-Bankist/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/11-Arrays-Bankist/final/Bankist-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/final/Bankist-flowchart.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/final/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/final/icon.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 | Bankist
16 |
17 |
18 |
19 |
20 | Log in to get started
21 |
22 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Current balance
44 |
45 | As of 05/03/2037
46 |
47 |
48 |
0000€
49 |
50 |
51 |
52 |
53 |
54 |
2 deposit
55 |
3 days ago
56 |
4 000€
57 |
58 |
59 |
60 | 1 withdrawal
61 |
62 |
24/01/2037
63 |
-378€
64 |
65 |
66 |
67 |
68 |
69 |
In
70 |
0000€
71 |
Out
72 |
0000€
73 |
Interest
74 |
0000€
75 |
↓ SORT
76 |
77 |
78 |
79 |
80 |
Transfer money
81 |
88 |
89 |
90 |
91 |
92 |
Request loan
93 |
98 |
99 |
100 |
101 |
102 |
Close account
103 |
114 |
115 |
116 |
117 |
118 | You will be logged out in 05:00
119 |
120 |
121 |
122 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/11-Arrays-Bankist/final/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/final/logo.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/Bankist-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/starter/Bankist-flowchart.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/starter/icon.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 | Bankist
16 |
17 |
18 |
19 |
20 | Log in to get started
21 |
22 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Current balance
44 |
45 | As of 05/03/2037
46 |
47 |
48 |
0000€
49 |
50 |
51 |
52 |
53 |
54 |
2 deposit
55 |
3 days ago
56 |
4 000€
57 |
58 |
59 |
60 | 1 withdrawal
61 |
62 |
24/01/2037
63 |
-378€
64 |
65 |
66 |
67 |
68 |
69 |
In
70 |
0000€
71 |
Out
72 |
0000€
73 |
Interest
74 |
0000€
75 |
↓ SORT
76 |
77 |
78 |
79 |
80 |
Transfer money
81 |
88 |
89 |
90 |
91 |
92 |
Request loan
93 |
98 |
99 |
100 |
101 |
102 |
Close account
103 |
114 |
115 |
116 |
117 |
118 | You will be logged out in 05:00
119 |
120 |
121 |
122 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/11-Arrays-Bankist/starter/logo.png
--------------------------------------------------------------------------------
/11-Arrays-Bankist/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /////////////////////////////////////////////////
4 | /////////////////////////////////////////////////
5 | // BANKIST APP
6 |
7 | // Data
8 | const account1 = {
9 | owner: 'Jonas Schmedtmann',
10 | movements: [200, 450, -400, 3000, -650, -130, 70, 1300],
11 | interestRate: 1.2, // %
12 | pin: 1111,
13 | };
14 |
15 | const account2 = {
16 | owner: 'Jessica Davis',
17 | movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30],
18 | interestRate: 1.5,
19 | pin: 2222,
20 | };
21 |
22 | const account3 = {
23 | owner: 'Steven Thomas Williams',
24 | movements: [200, -200, 340, -300, -20, 50, 400, -460],
25 | interestRate: 0.7,
26 | pin: 3333,
27 | };
28 |
29 | const account4 = {
30 | owner: 'Sarah Smith',
31 | movements: [430, 1000, 700, 50, 90],
32 | interestRate: 1,
33 | pin: 4444,
34 | };
35 |
36 | const accounts = [account1, account2, account3, account4];
37 |
38 | // Elements
39 | const labelWelcome = document.querySelector('.welcome');
40 | const labelDate = document.querySelector('.date');
41 | const labelBalance = document.querySelector('.balance__value');
42 | const labelSumIn = document.querySelector('.summary__value--in');
43 | const labelSumOut = document.querySelector('.summary__value--out');
44 | const labelSumInterest = document.querySelector('.summary__value--interest');
45 | const labelTimer = document.querySelector('.timer');
46 |
47 | const containerApp = document.querySelector('.app');
48 | const containerMovements = document.querySelector('.movements');
49 |
50 | const btnLogin = document.querySelector('.login__btn');
51 | const btnTransfer = document.querySelector('.form__btn--transfer');
52 | const btnLoan = document.querySelector('.form__btn--loan');
53 | const btnClose = document.querySelector('.form__btn--close');
54 | const btnSort = document.querySelector('.btn--sort');
55 |
56 | const inputLoginUsername = document.querySelector('.login__input--user');
57 | const inputLoginPin = document.querySelector('.login__input--pin');
58 | const inputTransferTo = document.querySelector('.form__input--to');
59 | const inputTransferAmount = document.querySelector('.form__input--amount');
60 | const inputLoanAmount = document.querySelector('.form__input--loan-amount');
61 | const inputCloseUsername = document.querySelector('.form__input--user');
62 | const inputClosePin = document.querySelector('.form__input--pin');
63 |
64 | /////////////////////////////////////////////////
65 | /////////////////////////////////////////////////
66 | // LECTURES
67 |
68 | const currencies = new Map([
69 | ['USD', 'United States dollar'],
70 | ['EUR', 'Euro'],
71 | ['GBP', 'Pound sterling'],
72 | ]);
73 |
74 | const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
75 |
76 | /////////////////////////////////////////////////
77 |
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/final/Bankist-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/final/Bankist-flowchart.png
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/final/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/final/icon.png
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 | Bankist
16 |
17 |
18 |
19 |
20 | Log in to get started
21 |
22 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Current balance
44 |
45 | As of 05/03/2037
46 |
47 |
48 |
0000€
49 |
50 |
51 |
52 |
53 |
54 |
2 deposit
55 |
3 days ago
56 |
4 000€
57 |
58 |
59 |
60 | 1 withdrawal
61 |
62 |
24/01/2037
63 |
-378€
64 |
65 |
66 |
67 |
68 |
69 |
In
70 |
0000€
71 |
Out
72 |
0000€
73 |
Interest
74 |
0000€
75 |
↓ SORT
76 |
77 |
78 |
79 |
80 |
Transfer money
81 |
88 |
89 |
90 |
91 |
92 |
Request loan
93 |
98 |
99 |
100 |
101 |
102 |
Close account
103 |
114 |
115 |
116 |
117 |
118 | You will be logged out in 05:00
119 |
120 |
121 |
122 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/final/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/final/logo.png
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/starter/Bankist-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/starter/Bankist-flowchart.png
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/starter/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/starter/icon.png
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 | Bankist
16 |
17 |
18 |
19 |
20 | Log in to get started
21 |
22 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Current balance
44 |
45 | As of 05/03/2037
46 |
47 |
48 |
0000€
49 |
50 |
51 |
52 |
53 |
54 |
2 deposit
55 |
3 days ago
56 |
4 000€
57 |
58 |
59 |
60 | 1 withdrawal
61 |
62 |
24/01/2037
63 |
-378€
64 |
65 |
66 |
67 |
68 |
69 |
In
70 |
0000€
71 |
Out
72 |
0000€
73 |
Interest
74 |
0000€
75 |
↓ SORT
76 |
77 |
78 |
79 |
80 |
Transfer money
81 |
88 |
89 |
90 |
91 |
92 |
Request loan
93 |
98 |
99 |
100 |
101 |
102 |
Close account
103 |
114 |
115 |
116 |
117 |
118 | You will be logged out in 05:00
119 |
120 |
121 |
122 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/12-Numbers-Dates-Timers-Bankist/starter/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/12-Numbers-Dates-Timers-Bankist/starter/logo.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/card-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/card-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/card.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/card.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/digital-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/digital-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/digital.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/digital.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/grow-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/grow-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/grow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/grow.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/hero.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/icon.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/img-1.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/img-2.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/img-3.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/img-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/img-4.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/logo.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/user-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/user-1.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/user-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/user-2.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/final/img/user-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/final/img/user-3.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/card-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/card-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/card.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/card.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/digital-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/digital-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/digital.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/digital.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/grow-lazy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/grow-lazy.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/grow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/grow.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/hero.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/icon.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/img-1.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/img-2.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/img-3.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/img-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/img-4.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/logo.png
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/user-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/user-1.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/user-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/user-2.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/img/user-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/13-Advanced-DOM-Bankist/starter/img/user-3.jpg
--------------------------------------------------------------------------------
/13-Advanced-DOM-Bankist/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | ///////////////////////////////////////
4 | // Modal window
5 |
6 | const modal = document.querySelector('.modal');
7 | const overlay = document.querySelector('.overlay');
8 | const btnCloseModal = document.querySelector('.btn--close-modal');
9 | const btnsOpenModal = document.querySelectorAll('.btn--show-modal');
10 |
11 | const openModal = function () {
12 | modal.classList.remove('hidden');
13 | overlay.classList.remove('hidden');
14 | };
15 |
16 | const closeModal = function () {
17 | modal.classList.add('hidden');
18 | overlay.classList.add('hidden');
19 | };
20 |
21 | for (let i = 0; i < btnsOpenModal.length; i++)
22 | btnsOpenModal[i].addEventListener('click', openModal);
23 |
24 | btnCloseModal.addEventListener('click', closeModal);
25 | overlay.addEventListener('click', closeModal);
26 |
27 | document.addEventListener('keydown', function (e) {
28 | if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
29 | closeModal();
30 | }
31 | });
32 |
--------------------------------------------------------------------------------
/14-OOP/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/14-OOP/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Object Oriented Programming (OOP) With JavaScript
8 |
25 |
26 |
27 |
28 | Object Oriented Programming (OOP) With JavaScript
29 |
30 |
31 |
--------------------------------------------------------------------------------
/14-OOP/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/14-OOP/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Object Oriented Programming (OOP) With JavaScript
8 |
25 |
26 |
27 |
28 | Object Oriented Programming (OOP) With JavaScript
29 |
30 |
31 |
--------------------------------------------------------------------------------
/14-OOP/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/15-Mapty/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/15-Mapty/final/Mapty-architecture-final.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/final/Mapty-architecture-final.png
--------------------------------------------------------------------------------
/15-Mapty/final/Mapty-architecture-part-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/final/Mapty-architecture-part-1.png
--------------------------------------------------------------------------------
/15-Mapty/final/Mapty-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/final/Mapty-flowchart.png
--------------------------------------------------------------------------------
/15-Mapty/final/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/final/icon.png
--------------------------------------------------------------------------------
/15-Mapty/final/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/final/logo.png
--------------------------------------------------------------------------------
/15-Mapty/final/other.js:
--------------------------------------------------------------------------------
1 | const firstName = 'Jonas';
2 | console.log(months);
3 |
--------------------------------------------------------------------------------
/15-Mapty/final/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --color-brand--1: #ffb545;
3 | --color-brand--2: #00c46a;
4 |
5 | --color-dark--1: #2d3439;
6 | --color-dark--2: #42484d;
7 | --color-light--1: #aaa;
8 | --color-light--2: #ececec;
9 | --color-light--3: rgb(214, 222, 224);
10 | }
11 |
12 | * {
13 | margin: 0;
14 | padding: 0;
15 | box-sizing: inherit;
16 | }
17 |
18 | html {
19 | font-size: 62.5%;
20 | box-sizing: border-box;
21 | }
22 |
23 | body {
24 | font-family: 'Manrope', sans-serif;
25 | color: var(--color-light--2);
26 | font-weight: 400;
27 | line-height: 1.6;
28 | height: 100vh;
29 | overscroll-behavior-y: none;
30 |
31 | background-color: #fff;
32 | padding: 2.5rem;
33 |
34 | display: flex;
35 | }
36 |
37 | /* GENERAL */
38 | a:link,
39 | a:visited {
40 | color: var(--color-brand--1);
41 | }
42 |
43 | /* SIDEBAR */
44 | .sidebar {
45 | flex-basis: 50rem;
46 | background-color: var(--color-dark--1);
47 | padding: 3rem 5rem 4rem 5rem;
48 | display: flex;
49 | flex-direction: column;
50 | }
51 |
52 | .logo {
53 | height: 5.2rem;
54 | align-self: center;
55 | margin-bottom: 4rem;
56 | }
57 |
58 | .workouts {
59 | list-style: none;
60 | height: 77vh;
61 | overflow-y: scroll;
62 | overflow-x: hidden;
63 | }
64 |
65 | .workouts::-webkit-scrollbar {
66 | width: 0;
67 | }
68 |
69 | .workout {
70 | background-color: var(--color-dark--2);
71 | border-radius: 5px;
72 | padding: 1.5rem 2.25rem;
73 | margin-bottom: 1.75rem;
74 | cursor: pointer;
75 |
76 | display: grid;
77 | grid-template-columns: 1fr 1fr 1fr 1fr;
78 | gap: 0.75rem 1.5rem;
79 | }
80 | .workout--running {
81 | border-left: 5px solid var(--color-brand--2);
82 | }
83 | .workout--cycling {
84 | border-left: 5px solid var(--color-brand--1);
85 | }
86 |
87 | .workout__title {
88 | font-size: 1.7rem;
89 | font-weight: 600;
90 | grid-column: 1 / -1;
91 | }
92 |
93 | .workout__details {
94 | display: flex;
95 | align-items: baseline;
96 | }
97 |
98 | .workout__icon {
99 | font-size: 1.8rem;
100 | margin-right: 0.2rem;
101 | height: 0.28rem;
102 | }
103 |
104 | .workout__value {
105 | font-size: 1.5rem;
106 | margin-right: 0.5rem;
107 | }
108 |
109 | .workout__unit {
110 | font-size: 1.1rem;
111 | color: var(--color-light--1);
112 | text-transform: uppercase;
113 | font-weight: 800;
114 | }
115 |
116 | .form {
117 | background-color: var(--color-dark--2);
118 | border-radius: 5px;
119 | padding: 1.5rem 2.75rem;
120 | margin-bottom: 1.75rem;
121 |
122 | display: grid;
123 | grid-template-columns: 1fr 1fr;
124 | gap: 0.5rem 2.5rem;
125 |
126 | /* Match height and activity boxes */
127 | height: 9.25rem;
128 | transition: all 0.5s, transform 1ms;
129 | }
130 |
131 | .form.hidden {
132 | transform: translateY(-30rem);
133 | height: 0;
134 | padding: 0 2.25rem;
135 | margin-bottom: 0;
136 | opacity: 0;
137 | }
138 |
139 | .form__row {
140 | display: flex;
141 | align-items: center;
142 | }
143 |
144 | .form__row--hidden {
145 | display: none;
146 | }
147 |
148 | .form__label {
149 | flex: 0 0 50%;
150 | font-size: 1.5rem;
151 | font-weight: 600;
152 | }
153 |
154 | .form__input {
155 | width: 100%;
156 | padding: 0.3rem 1.1rem;
157 | font-family: inherit;
158 | font-size: 1.4rem;
159 | border: none;
160 | border-radius: 3px;
161 | background-color: var(--color-light--3);
162 | transition: all 0.2s;
163 | }
164 |
165 | .form__input:focus {
166 | outline: none;
167 | background-color: #fff;
168 | }
169 |
170 | .form__btn {
171 | display: none;
172 | }
173 |
174 | .copyright {
175 | margin-top: auto;
176 | font-size: 1.3rem;
177 | text-align: center;
178 | color: var(--color-light--1);
179 | }
180 |
181 | .twitter-link:link,
182 | .twitter-link:visited {
183 | color: var(--color-light--1);
184 | transition: all 0.2s;
185 | }
186 |
187 | .twitter-link:hover,
188 | .twitter-link:active {
189 | color: var(--color-light--2);
190 | }
191 |
192 | /* MAP */
193 | #map {
194 | flex: 1;
195 | height: 100%;
196 | background-color: var(--color-light--1);
197 | }
198 |
199 | /* Popup width is defined in JS using options */
200 | .leaflet-popup .leaflet-popup-content-wrapper {
201 | background-color: var(--color-dark--1);
202 | color: var(--color-light--2);
203 | border-radius: 5px;
204 | padding-right: 0.6rem;
205 | }
206 |
207 | .leaflet-popup .leaflet-popup-content {
208 | font-size: 1.5rem;
209 | }
210 |
211 | .leaflet-popup .leaflet-popup-tip {
212 | background-color: var(--color-dark--1);
213 | }
214 |
215 | .running-popup .leaflet-popup-content-wrapper {
216 | border-left: 5px solid var(--color-brand--2);
217 | }
218 | .cycling-popup .leaflet-popup-content-wrapper {
219 | border-left: 5px solid var(--color-brand--1);
220 | }
221 |
--------------------------------------------------------------------------------
/15-Mapty/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/15-Mapty/starter/Mapty-architecture-final.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/starter/Mapty-architecture-final.png
--------------------------------------------------------------------------------
/15-Mapty/starter/Mapty-architecture-part-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/starter/Mapty-architecture-part-1.png
--------------------------------------------------------------------------------
/15-Mapty/starter/Mapty-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/starter/Mapty-flowchart.png
--------------------------------------------------------------------------------
/15-Mapty/starter/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/starter/icon.png
--------------------------------------------------------------------------------
/15-Mapty/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | mapty // Map your workouts
18 |
19 |
20 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/15-Mapty/starter/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/15-Mapty/starter/logo.png
--------------------------------------------------------------------------------
/15-Mapty/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // prettier-ignore
4 | const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
5 |
6 | const form = document.querySelector('.form');
7 | const containerWorkouts = document.querySelector('.workouts');
8 | const inputType = document.querySelector('.form__input--type');
9 | const inputDistance = document.querySelector('.form__input--distance');
10 | const inputDuration = document.querySelector('.form__input--duration');
11 | const inputCadence = document.querySelector('.form__input--cadence');
12 | const inputElevation = document.querySelector('.form__input--elevation');
13 |
--------------------------------------------------------------------------------
/15-Mapty/starter/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --color-brand--1: #ffb545;
3 | --color-brand--2: #00c46a;
4 |
5 | --color-dark--1: #2d3439;
6 | --color-dark--2: #42484d;
7 | --color-light--1: #aaa;
8 | --color-light--2: #ececec;
9 | --color-light--3: rgb(214, 222, 224);
10 | }
11 |
12 | * {
13 | margin: 0;
14 | padding: 0;
15 | box-sizing: inherit;
16 | }
17 |
18 | html {
19 | font-size: 62.5%;
20 | box-sizing: border-box;
21 | }
22 |
23 | body {
24 | font-family: 'Manrope', sans-serif;
25 | color: var(--color-light--2);
26 | font-weight: 400;
27 | line-height: 1.6;
28 | height: 100vh;
29 | overscroll-behavior-y: none;
30 |
31 | background-color: #fff;
32 | padding: 2.5rem;
33 |
34 | display: flex;
35 | }
36 |
37 | /* GENERAL */
38 | a:link,
39 | a:visited {
40 | color: var(--color-brand--1);
41 | }
42 |
43 | /* SIDEBAR */
44 | .sidebar {
45 | flex-basis: 50rem;
46 | background-color: var(--color-dark--1);
47 | padding: 3rem 5rem 4rem 5rem;
48 | display: flex;
49 | flex-direction: column;
50 | }
51 |
52 | .logo {
53 | height: 5.2rem;
54 | align-self: center;
55 | margin-bottom: 4rem;
56 | }
57 |
58 | .workouts {
59 | list-style: none;
60 | height: 77vh;
61 | overflow-y: scroll;
62 | overflow-x: hidden;
63 | }
64 |
65 | .workouts::-webkit-scrollbar {
66 | width: 0;
67 | }
68 |
69 | .workout {
70 | background-color: var(--color-dark--2);
71 | border-radius: 5px;
72 | padding: 1.5rem 2.25rem;
73 | margin-bottom: 1.75rem;
74 | cursor: pointer;
75 |
76 | display: grid;
77 | grid-template-columns: 1fr 1fr 1fr 1fr;
78 | gap: 0.75rem 1.5rem;
79 | }
80 | .workout--running {
81 | border-left: 5px solid var(--color-brand--2);
82 | }
83 | .workout--cycling {
84 | border-left: 5px solid var(--color-brand--1);
85 | }
86 |
87 | .workout__title {
88 | font-size: 1.7rem;
89 | font-weight: 600;
90 | grid-column: 1 / -1;
91 | }
92 |
93 | .workout__details {
94 | display: flex;
95 | align-items: baseline;
96 | }
97 |
98 | .workout__icon {
99 | font-size: 1.8rem;
100 | margin-right: 0.2rem;
101 | height: 0.28rem;
102 | }
103 |
104 | .workout__value {
105 | font-size: 1.5rem;
106 | margin-right: 0.5rem;
107 | }
108 |
109 | .workout__unit {
110 | font-size: 1.1rem;
111 | color: var(--color-light--1);
112 | text-transform: uppercase;
113 | font-weight: 800;
114 | }
115 |
116 | .form {
117 | background-color: var(--color-dark--2);
118 | border-radius: 5px;
119 | padding: 1.5rem 2.75rem;
120 | margin-bottom: 1.75rem;
121 |
122 | display: grid;
123 | grid-template-columns: 1fr 1fr;
124 | gap: 0.5rem 2.5rem;
125 |
126 | /* Match height and activity boxes */
127 | height: 9.25rem;
128 | transition: all 0.5s, transform 1ms;
129 | }
130 |
131 | .form.hidden {
132 | transform: translateY(-30rem);
133 | height: 0;
134 | padding: 0 2.25rem;
135 | margin-bottom: 0;
136 | opacity: 0;
137 | }
138 |
139 | .form__row {
140 | display: flex;
141 | align-items: center;
142 | }
143 |
144 | .form__row--hidden {
145 | display: none;
146 | }
147 |
148 | .form__label {
149 | flex: 0 0 50%;
150 | font-size: 1.5rem;
151 | font-weight: 600;
152 | }
153 |
154 | .form__input {
155 | width: 100%;
156 | padding: 0.3rem 1.1rem;
157 | font-family: inherit;
158 | font-size: 1.4rem;
159 | border: none;
160 | border-radius: 3px;
161 | background-color: var(--color-light--3);
162 | transition: all 0.2s;
163 | }
164 |
165 | .form__input:focus {
166 | outline: none;
167 | background-color: #fff;
168 | }
169 |
170 | .form__btn {
171 | display: none;
172 | }
173 |
174 | .copyright {
175 | margin-top: auto;
176 | font-size: 1.3rem;
177 | text-align: center;
178 | color: var(--color-light--1);
179 | }
180 |
181 | .twitter-link:link,
182 | .twitter-link:visited {
183 | color: var(--color-light--1);
184 | transition: all 0.2s;
185 | }
186 |
187 | .twitter-link:hover,
188 | .twitter-link:active {
189 | color: var(--color-light--2);
190 | }
191 |
192 | /* MAP */
193 | #map {
194 | flex: 1;
195 | height: 100%;
196 | background-color: var(--color-light--1);
197 | }
198 |
199 | /* Popup width is defined in JS using options */
200 | .leaflet-popup .leaflet-popup-content-wrapper {
201 | background-color: var(--color-dark--1);
202 | color: var(--color-light--2);
203 | border-radius: 5px;
204 | padding-right: 0.6rem;
205 | }
206 |
207 | .leaflet-popup .leaflet-popup-content {
208 | font-size: 1.5rem;
209 | }
210 |
211 | .leaflet-popup .leaflet-popup-tip {
212 | background-color: var(--color-dark--1);
213 | }
214 |
215 | .running-popup .leaflet-popup-content-wrapper {
216 | border-left: 5px solid var(--color-brand--2);
217 | }
218 | .cycling-popup .leaflet-popup-content-wrapper {
219 | border-left: 5px solid var(--color-brand--1);
220 | }
221 |
--------------------------------------------------------------------------------
/16-Asynchronous/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/16-Asynchronous/final/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/final/img/img-1.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/final/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/final/img/img-2.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/final/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/final/img/img-3.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Asynchronous JavaScript
10 |
11 |
12 |
13 |
14 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/16-Asynchronous/final/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: inherit;
5 | }
6 |
7 | html {
8 | font-size: 62.5%;
9 | box-sizing: border-box;
10 | }
11 |
12 | body {
13 | font-family: system-ui;
14 | color: #555;
15 | background-color: #f7f7f7;
16 | min-height: 100vh;
17 |
18 | display: flex;
19 | align-items: center;
20 | justify-content: center;
21 | }
22 |
23 | .container {
24 | display: flex;
25 | flex-flow: column;
26 | align-items: center;
27 | }
28 |
29 | .countries {
30 | /* margin-bottom: 8rem; */
31 | display: flex;
32 |
33 | font-size: 2rem;
34 | opacity: 0;
35 | transition: opacity 1s;
36 | }
37 |
38 | .country {
39 | background-color: #fff;
40 | box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
41 | font-size: 1.8rem;
42 | width: 30rem;
43 | border-radius: 0.7rem;
44 | margin: 0 3rem;
45 | /* overflow: hidden; */
46 | }
47 |
48 | .neighbour::before {
49 | content: 'Neighbour country';
50 | width: 100%;
51 | position: absolute;
52 | top: -4rem;
53 |
54 | text-align: center;
55 | font-size: 1.8rem;
56 | font-weight: 600;
57 | text-transform: uppercase;
58 | color: #888;
59 | }
60 |
61 | .neighbour {
62 | transform: scale(0.8) translateY(1rem);
63 | margin-left: 0;
64 | }
65 |
66 | .country__img {
67 | width: 30rem;
68 | height: 17rem;
69 | object-fit: cover;
70 | background-color: #eee;
71 | border-top-left-radius: 0.7rem;
72 | border-top-right-radius: 0.7rem;
73 | }
74 |
75 | .country__data {
76 | padding: 2.5rem 3.75rem 3rem 3.75rem;
77 | }
78 |
79 | .country__name {
80 | font-size: 2.7rem;
81 | margin-bottom: 0.7rem;
82 | }
83 |
84 | .country__region {
85 | font-size: 1.4rem;
86 | margin-bottom: 2.5rem;
87 | text-transform: uppercase;
88 | color: #888;
89 | }
90 |
91 | .country__row:not(:last-child) {
92 | margin-bottom: 1rem;
93 | }
94 |
95 | .country__row span {
96 | display: inline-block;
97 | margin-right: 2rem;
98 | font-size: 2.4rem;
99 | }
100 |
101 | .btn-country {
102 | border: none;
103 | font-size: 2rem;
104 | padding: 2rem 5rem;
105 | border-radius: 0.7rem;
106 | color: white;
107 | background-color: orangered;
108 | cursor: pointer;
109 | }
110 |
111 | .images {
112 | display: flex;
113 | }
114 |
115 | .images img {
116 | display: block;
117 | width: 80rem;
118 | margin: 4rem;
119 | }
120 |
121 | .images img.parallel {
122 | width: 40rem;
123 | margin: 2rem;
124 | border: 3rem solid white;
125 | box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
126 | }
127 |
--------------------------------------------------------------------------------
/16-Asynchronous/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/16-Asynchronous/starter/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/starter/img/img-1.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/starter/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/starter/img/img-2.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/starter/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/16-Asynchronous/starter/img/img-3.jpg
--------------------------------------------------------------------------------
/16-Asynchronous/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Asynchronous JavaScript
10 |
11 |
12 |
13 |
14 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/16-Asynchronous/starter/script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const btn = document.querySelector('.btn-country');
4 | const countriesContainer = document.querySelector('.countries');
5 |
6 | ///////////////////////////////////////
7 |
--------------------------------------------------------------------------------
/16-Asynchronous/starter/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: inherit;
5 | }
6 |
7 | html {
8 | font-size: 62.5%;
9 | box-sizing: border-box;
10 | }
11 |
12 | body {
13 | font-family: system-ui;
14 | color: #555;
15 | background-color: #f7f7f7;
16 | min-height: 100vh;
17 |
18 | display: flex;
19 | align-items: center;
20 | justify-content: center;
21 | }
22 |
23 | .container {
24 | display: flex;
25 | flex-flow: column;
26 | align-items: center;
27 | }
28 |
29 | .countries {
30 | /* margin-bottom: 8rem; */
31 | display: flex;
32 |
33 | font-size: 2rem;
34 | opacity: 0;
35 | transition: opacity 1s;
36 | }
37 |
38 | .country {
39 | background-color: #fff;
40 | box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
41 | font-size: 1.8rem;
42 | width: 30rem;
43 | border-radius: 0.7rem;
44 | margin: 0 3rem;
45 | /* overflow: hidden; */
46 | }
47 |
48 | .neighbour::before {
49 | content: 'Neighbour country';
50 | width: 100%;
51 | position: absolute;
52 | top: -4rem;
53 |
54 | text-align: center;
55 | font-size: 1.8rem;
56 | font-weight: 600;
57 | text-transform: uppercase;
58 | color: #888;
59 | }
60 |
61 | .neighbour {
62 | transform: scale(0.8) translateY(1rem);
63 | margin-left: 0;
64 | }
65 |
66 | .country__img {
67 | width: 30rem;
68 | height: 17rem;
69 | object-fit: cover;
70 | background-color: #eee;
71 | border-top-left-radius: 0.7rem;
72 | border-top-right-radius: 0.7rem;
73 | }
74 |
75 | .country__data {
76 | padding: 2.5rem 3.75rem 3rem 3.75rem;
77 | }
78 |
79 | .country__name {
80 | font-size: 2.7rem;
81 | margin-bottom: 0.7rem;
82 | }
83 |
84 | .country__region {
85 | font-size: 1.4rem;
86 | margin-bottom: 2.5rem;
87 | text-transform: uppercase;
88 | color: #888;
89 | }
90 |
91 | .country__row:not(:last-child) {
92 | margin-bottom: 1rem;
93 | }
94 |
95 | .country__row span {
96 | display: inline-block;
97 | margin-right: 2rem;
98 | font-size: 2.4rem;
99 | }
100 |
101 | .btn-country {
102 | border: none;
103 | font-size: 2rem;
104 | padding: 2rem 5rem;
105 | border-radius: 0.7rem;
106 | color: white;
107 | background-color: orangered;
108 | cursor: pointer;
109 | }
110 |
111 | .images {
112 | display: flex;
113 | }
114 |
115 | .images img {
116 | display: block;
117 | width: 80rem;
118 | margin: 4rem;
119 | }
120 |
121 | .images img.parallel {
122 | width: 40rem;
123 | margin: 2rem;
124 | border: 3rem solid white;
125 | box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
126 | }
127 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/clean.js:
--------------------------------------------------------------------------------
1 | 'strict mode';
2 |
3 | const budget = Object.freeze([
4 | { value: 250, description: 'Sold old TV 📺', user: 'jonas' },
5 | { value: -45, description: 'Groceries 🥑', user: 'jonas' },
6 | { value: 3500, description: 'Monthly salary 👩💻', user: 'jonas' },
7 | { value: 300, description: 'Freelancing 👩💻', user: 'jonas' },
8 | { value: -1100, description: 'New iPhone 📱', user: 'jonas' },
9 | { value: -20, description: 'Candy 🍭', user: 'matilda' },
10 | { value: -125, description: 'Toys 🚂', user: 'matilda' },
11 | { value: -1800, description: 'New Laptop 💻', user: 'jonas' },
12 | ]);
13 |
14 | const spendingLimits = Object.freeze({
15 | jonas: 1500,
16 | matilda: 100,
17 | });
18 | // spendingLimits.jay = 200;
19 |
20 | // const limit = spendingLimits[user] ? spendingLimits[user] : 0;
21 | const getLimit = (limits, user) => limits?.[user] ?? 0;
22 |
23 | // Pure function :D
24 | const addExpense = function (
25 | state,
26 | limits,
27 | value,
28 | description,
29 | user = 'jonas'
30 | ) {
31 | const cleanUser = user.toLowerCase();
32 |
33 | return value <= getLimit(limits, cleanUser)
34 | ? [...state, { value: -value, description, user: cleanUser }]
35 | : state;
36 | };
37 |
38 | const newBudget1 = addExpense(budget, spendingLimits, 10, 'Pizza 🍕');
39 | const newBudget2 = addExpense(
40 | newBudget1,
41 | spendingLimits,
42 | 100,
43 | 'Going to movies 🍿',
44 | 'Matilda'
45 | );
46 | const newBudget3 = addExpense(newBudget2, spendingLimits, 200, 'Stuff', 'Jay');
47 |
48 | // const checkExpenses2 = function (state, limits) {
49 | // return state.map(entry => {
50 | // return entry.value < -getLimit(limits, entry.user)
51 | // ? { ...entry, flag: 'limit' }
52 | // : entry;
53 | // });
54 | // // for (const entry of newBudget3)
55 | // // if (entry.value < -getLimit(limits, entry.user)) entry.flag = 'limit';
56 | // };
57 |
58 | const checkExpenses = (state, limits) =>
59 | state.map(entry =>
60 | entry.value < -getLimit(limits, entry.user)
61 | ? { ...entry, flag: 'limit' }
62 | : entry
63 | );
64 |
65 | const finalBudget = checkExpenses(newBudget3, spendingLimits);
66 | console.log(finalBudget);
67 |
68 | // Impure
69 | const logBigExpenses = function (state, bigLimit) {
70 | const bigExpenses = state
71 | .filter(entry => entry.value <= -bigLimit)
72 | .map(entry => entry.description.slice(-2))
73 | .join(' / ');
74 | // .reduce((str, cur) => `${str} / ${cur.description.slice(-2)}`, '');
75 |
76 | console.log(bigExpenses);
77 |
78 | // let output = '';
79 | // for (const entry of budget)
80 | // output +=
81 | // entry.value <= -bigLimit ? `${entry.description.slice(-2)} / ` : '';
82 | // output = output.slice(0, -2); // Remove last '/ '
83 | // console.log(output);
84 | };
85 |
86 | logBigExpenses(finalBudget, 500);
87 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Modern JavaScript Development: Modules and Tooling
11 |
26 |
27 |
28 | Modern JavaScript Development: Modules and Tooling
29 |
30 |
31 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["node_modules/parcel/src/builtins/bundle-url.js","node_modules/parcel/src/builtins/css-loader.js"],"names":["bundleURL","getBundleURLCached","getBundleURL","Error","err","matches","stack","match","getBaseURL","url","replace","exports","bundle","require","updateLink","link","newLink","cloneNode","onload","remove","href","split","Date","now","parentNode","insertBefore","nextSibling","cssTimeout","reloadCSS","setTimeout","links","document","querySelectorAll","i","length","module"],"mappings":"AAAA,ACAA,IDAIA,ACAAY,MAAM,GDAG,ACAAC,GDAG,IAAhB,ACAoB,CAAC,cAAD,CAApB;;ADCA,ACCA,SDDSZ,ACCAa,UAAT,CAAoBC,IAApB,EAA0B,CDD1B,GAA8B;AAC5B,ACCA,MDDI,ACCAC,CDDChB,MCCM,GDDX,ACCce,EDDE,ECCE,CAACE,SAAL,EAAd;ADAEjB,IAAAA,SAAS,GAAGE,YAAY,EAAxB;AACD,ACADc,EAAAA,OAAO,CAACE,MAAR,GAAiB,YAAY;AAC3BH,IAAAA,IAAI,CAACI,MAAL;ADCF,ACAC,GAFD,MDEOnB,SAAP;AACD;ACACgB,EAAAA,OAAO,CAACI,IAAR,GAAeL,IAAI,CAACK,IAAL,CAAUC,KAAV,CAAgB,GAAhB,EAAqB,CAArB,IAA0B,GAA1B,GAAgCC,IAAI,CAACC,GAAL,EAA/C;ADEF,ACDER,EAAAA,IAAI,CAACS,EDCEtB,QCDP,CAAgBuB,GDClB,GAAwB,MCDtB,CAA6BT,OAA7B,EAAsCD,IAAI,CAACW,WAA3C;ADEA,ACDD;ADEC,MAAI;AACF,ACDJ,IAAIC,MDCM,IAAIxB,ACDA,GAAG,EDCP,EAAN,ACDJ;ADEG,GAFD,CAEE,OAAOC,GAAP,EAAY;AACZ,ACFJ,QDEQC,CCFCuB,MDEM,GAAG,ACFlB,CDEmB,ECFE,GDEGxB,GAAG,CAACE,KAAV,EAAiBC,KAAjB,CAAuB,+DAAvB,CAAd;ACDF,MAAIoB,UAAJ,EAAgB;ADEd,ACDA,QDCItB,OAAJ,EAAa;AACX,ACDH,aDCUG,UAAU,CAACH,OAAO,CAAC,CAAD,CAAR,CAAjB;AACD;AACF,ACDDsB,EAAAA,UAAU,GAAGE,UAAU,CAAC,YAAY;AAClC,QAAIC,KAAK,GAAGC,QAAQ,CAACC,gBAAT,CAA0B,wBAA1B,CAAZ;ADEF,SAAO,GAAP;AACD,ACFG,SAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGH,KAAK,CAACI,MAA1B,EAAkCD,CAAC,EAAnC,EAAuC;AACrC,UAAIrB,MAAM,CAACJ,UAAP,CAAkBsB,KAAK,CAACG,CAAD,CAAL,CAASb,IAA3B,MAAqCR,MAAM,CAACV,YAAP,EAAzC,EAAgE;ADGtE,ACFQY,QAAAA,CDECN,SCFS,CDElB,ACFmBsB,CDECrB,GAApB,CCFwB,CDEC,ACFAwB,CAAD,CAAN,CAAV;ADGN,ACFK,SDEE,CAAC,KAAKxB,GAAN,EAAWC,OAAX,CAAmB,sEAAnB,EAA2F,IAA3F,IAAmG,GAA1G;AACD,ACFI;;ADILC,ACFIgB,IAAAA,GDEG,CAACzB,MCFM,GAAG,GDEjB,CCFI,EDEmBD,kBAAvB;AACAU,ACFG,GATsB,EASpB,EDEE,ACXkB,CDWjBH,ACXN,UDWF,GAAqBA,UAArB;ACDC;;AAED2B,MAAM,CAACxB,OAAP,GAAiBiB,SAAjB","file":"index.js","sourceRoot":"..","sourcesContent":["var bundleURL = null;\nfunction getBundleURLCached() {\n if (!bundleURL) {\n bundleURL = getBundleURL();\n }\n\n return bundleURL;\n}\n\nfunction getBundleURL() {\n // Attempt to find the URL of the current script and use that as the base URL\n try {\n throw new Error;\n } catch (err) {\n var matches = ('' + err.stack).match(/(https?|file|ftp|chrome-extension|moz-extension):\\/\\/[^)\\n]+/g);\n if (matches) {\n return getBaseURL(matches[0]);\n }\n }\n\n return '/';\n}\n\nfunction getBaseURL(url) {\n return ('' + url).replace(/^((?:https?|file|ftp|chrome-extension|moz-extension):\\/\\/.+)\\/[^/]+$/, '$1') + '/';\n}\n\nexports.getBundleURL = getBundleURLCached;\nexports.getBaseURL = getBaseURL;\n","var bundle = require('./bundle-url');\n\nfunction updateLink(link) {\n var newLink = link.cloneNode();\n newLink.onload = function () {\n link.remove();\n };\n newLink.href = link.href.split('?')[0] + '?' + Date.now();\n link.parentNode.insertBefore(newLink, link.nextSibling);\n}\n\nvar cssTimeout = null;\nfunction reloadCSS() {\n if (cssTimeout) {\n return;\n }\n\n cssTimeout = setTimeout(function () {\n var links = document.querySelectorAll('link[rel=\"stylesheet\"]');\n for (var i = 0; i < links.length; i++) {\n if (bundle.getBaseURL(links[i].href) === bundle.getBundleURL()) {\n updateLink(links[i]);\n }\n }\n\n cssTimeout = null;\n }, 50);\n}\n\nmodule.exports = reloadCSS;\n"]}
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Modern JavaScript Development: Modules and Tooling
12 |
29 |
30 |
31 | Modern JavaScript Development: Modules and Tooling
32 |
33 |
34 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "17-modern-js-modules-tooling",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "script.js",
6 | "scripts": {
7 | "start": "parcel index.html",
8 | "build": "parcel build index.html"
9 | },
10 | "author": "Jonas",
11 | "license": "ISC",
12 | "dependencies": {
13 | "core-js": "^3.6.5",
14 | "leaflet": "^1.6.0",
15 | "lodash-es": "^4.17.15",
16 | "regenerator-runtime": "^0.13.7"
17 | },
18 | "devDependencies": {
19 | "parcel": "^1.12.4"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/script.js:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////
2 | // Exporting and Importing in ES6 Modules
3 |
4 | // Importing module
5 | // import { addToCart, totalPrice as price, tq } from './shoppingCart.js';
6 | // addToCart('bread', 5);
7 | // console.log(price, tq);
8 |
9 | console.log('Importing module');
10 | // console.log(shippingCost);
11 |
12 | // import * as ShoppingCart from './shoppingCart.js';
13 | // ShoppingCart.addToCart('bread', 5);
14 | // console.log(ShoppingCart.totalPrice);
15 |
16 | // import add, { addToCart, totalPrice as price, tq } from './shoppingCart.js';
17 | // console.log(price);
18 |
19 | import add, { cart } from './shoppingCart.js';
20 | add('pizza', 2);
21 | add('bread', 5);
22 | add('apples', 4);
23 |
24 | console.log(cart);
25 |
26 | /*
27 | ///////////////////////////////////////
28 | // The Module Pattern
29 |
30 | const ShoppingCart2 = (function () {
31 | const cart = [];
32 | const shippingCost = 10;
33 | const totalPrice = 237;
34 | const totalQuantity = 23;
35 |
36 | const addToCart = function (product, quantity) {
37 | cart.push({ product, quantity });
38 | console.log(
39 | `${quantity} ${product} added to cart (sipping cost is ${shippingCost})`
40 | );
41 | };
42 |
43 | const orderStock = function (product, quantity) {
44 | console.log(`${quantity} ${product} ordered from supplier`);
45 | };
46 |
47 | return {
48 | addToCart,
49 | cart,
50 | totalPrice,
51 | totalQuantity,
52 | };
53 | })();
54 |
55 | ShoppingCart2.addToCart('apple', 4);
56 | ShoppingCart2.addToCart('pizza', 2);
57 | console.log(ShoppingCart2);
58 | console.log(ShoppingCart2.shippingCost);
59 |
60 |
61 | ///////////////////////////////////////
62 | // CommonJS Modules
63 | // Export
64 | export.addTocart = function (product, quantity) {
65 | cart.push({ product, quantity });
66 | console.log(
67 | `${quantity} ${product} added to cart (sipping cost is ${shippingCost})`
68 | );
69 | };
70 |
71 | // Import
72 | const { addTocart } = require('./shoppingCart.js');
73 | */
74 |
75 | ///////////////////////////////////////
76 | // Introduction to NPM
77 | // import cloneDeep from './node_modules/lodash-es/cloneDeep.js';
78 | import cloneDeep from 'lodash-es';
79 |
80 | const state = {
81 | cart: [
82 | { product: 'bread', quantity: 5 },
83 | { product: 'pizza', quantity: 5 },
84 | ],
85 | user: { loggedIn: true },
86 | };
87 | const stateClone = Object.assign({}, state);
88 | const stateDeepClone = cloneDeep(state);
89 |
90 | state.user.loggedIn = false;
91 | console.log(stateClone);
92 |
93 | console.log(stateDeepClone);
94 |
95 | if (module.hot) {
96 | module.hot.accept();
97 | }
98 |
99 | class Person {
100 | #greeting = 'Hey';
101 | constructor(name) {
102 | this.name = name;
103 | console.log(`${this.#greeting}, ${this.name}`);
104 | }
105 | }
106 | const jonas = new Person('Jonas');
107 |
108 | console.log('Jonas' ?? null);
109 |
110 | console.log(cart.find(el => el.quantity >= 2));
111 | Promise.resolve('TEST').then(x => console.log(x));
112 |
113 | import 'core-js/stable';
114 | // import 'core-js/stable/array/find';
115 | // import 'core-js/stable/promise';
116 |
117 | // Polifilling async functions
118 | import 'regenerator-runtime/runtime';
119 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/final/shoppingCart.js:
--------------------------------------------------------------------------------
1 | // Exporting module
2 | console.log('Exporting module');
3 |
4 | const shippingCost = 10;
5 | export const cart = [];
6 |
7 | export const addToCart = function (product, quantity) {
8 | cart.push({ product, quantity });
9 | console.log(`${quantity} ${product} added to cart`);
10 | };
11 |
12 | const totalPrice = 237;
13 | const totalQuantity = 23;
14 |
15 | export { totalPrice, totalQuantity as tq };
16 |
17 | export default function (product, quantity) {
18 | cart.push({ product, quantity });
19 | console.log(`${quantity} ${product} added to cart`);
20 | }
21 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/starter/clean.js:
--------------------------------------------------------------------------------
1 | var budget = [
2 | { value: 250, description: 'Sold old TV 📺', user: 'jonas' },
3 | { value: -45, description: 'Groceries 🥑', user: 'jonas' },
4 | { value: 3500, description: 'Monthly salary 👩💻', user: 'jonas' },
5 | { value: 300, description: 'Freelancing 👩💻', user: 'jonas' },
6 | { value: -1100, description: 'New iPhone 📱', user: 'jonas' },
7 | { value: -20, description: 'Candy 🍭', user: 'matilda' },
8 | { value: -125, description: 'Toys 🚂', user: 'matilda' },
9 | { value: -1800, description: 'New Laptop 💻', user: 'jonas' },
10 | ];
11 |
12 | var limits = {
13 | jonas: 1500,
14 | matilda: 100,
15 | };
16 |
17 | var add = function (value, description, user) {
18 | if (!user) user = 'jonas';
19 | user = user.toLowerCase();
20 |
21 | var lim;
22 | if (limits[user]) {
23 | lim = limits[user];
24 | } else {
25 | lim = 0;
26 | }
27 |
28 | if (value <= lim) {
29 | budget.push({ value: -value, description: description, user: user });
30 | }
31 | };
32 | add(10, 'Pizza 🍕');
33 | add(100, 'Going to movies 🍿', 'Matilda');
34 | add(200, 'Stuff', 'Jay');
35 | console.log(budget);
36 |
37 | var check = function () {
38 | for (var el of budget) {
39 | var lim;
40 | if (limits[el.user]) {
41 | lim = limits[el.user];
42 | } else {
43 | lim = 0;
44 | }
45 |
46 | if (el.value < -lim) {
47 | el.flag = 'limit';
48 | }
49 | }
50 | };
51 | check();
52 |
53 | console.log(budget);
54 |
55 | var bigExpenses = function (limit) {
56 | var output = '';
57 | for (var el of budget) {
58 | if (el.value <= -limit) {
59 | output += el.description.slice(-2) + ' / '; // Emojis are 2 chars
60 | }
61 | }
62 | output = output.slice(0, -2); // Remove last '/ '
63 | console.log(output);
64 | };
65 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/starter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Modern JavaScript Development: Modules and Tooling
9 |
26 |
27 |
28 | Modern JavaScript Development: Modules and Tooling
29 |
30 |
31 |
--------------------------------------------------------------------------------
/17-Modern-JS-Modules-Tooling/starter/script.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/17-Modern-JS-Modules-Tooling/starter/script.js
--------------------------------------------------------------------------------
/18-forkify/final/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .parcel-cache
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/18-forkify/final/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/18-forkify/final/README.md:
--------------------------------------------------------------------------------
1 | # forkify Project
2 |
3 | Recipe application with custom recipe uploads.
4 |
--------------------------------------------------------------------------------
/18-forkify/final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "forkify",
3 | "version": "1.0.0",
4 | "description": "Recipe application",
5 | "default": "index.html",
6 | "scripts": {
7 | "start": "parcel index.html",
8 | "build": "parcel build index.html --dist-dir ./dist"
9 | },
10 | "author": "Jonas Schedtmann",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "parcel": "^2.0.0-beta.1",
14 | "sass": "^1.26.10"
15 | },
16 | "dependencies": {
17 | "core-js": "^3.6.5",
18 | "fractional": "^1.0.0",
19 | "regenerator-runtime": "^0.13.7"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/18-forkify/final/src/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/final/src/img/favicon.png
--------------------------------------------------------------------------------
/18-forkify/final/src/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/final/src/img/logo.png
--------------------------------------------------------------------------------
/18-forkify/final/src/js/config.js:
--------------------------------------------------------------------------------
1 | export const API_URL = 'https://forkify-api.herokuapp.com/api/v2/recipes/';
2 | export const TIMEOUT_SEC = 10;
3 | export const RES_PER_PAGE = 10;
4 | export const KEY = '';
5 | export const MODAL_CLOSE_SEC = 2.5;
6 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/controller.js:
--------------------------------------------------------------------------------
1 | import * as model from './model.js';
2 | import { MODAL_CLOSE_SEC } from './config.js';
3 | import recipeView from './views/recipeView.js';
4 | import searchView from './views/searchView.js';
5 | import resultsView from './views/resultsView.js';
6 | import paginationView from './views/paginationView.js';
7 | import bookmarksView from './views/bookmarksView.js';
8 | import addRecipeView from './views/addRecipeView.js';
9 |
10 | import 'core-js/stable';
11 | import 'regenerator-runtime/runtime';
12 | import { async } from 'regenerator-runtime';
13 |
14 | const controlRecipes = async function () {
15 | try {
16 | const id = window.location.hash.slice(1);
17 |
18 | if (!id) return;
19 | recipeView.renderSpinner();
20 |
21 | // 0) Update results view to mark selected search result
22 | resultsView.update(model.getSearchResultsPage());
23 |
24 | // 1) Updating bookmarks view
25 | bookmarksView.update(model.state.bookmarks);
26 |
27 | // 2) Loading recipe
28 | await model.loadRecipe(id);
29 |
30 | // 3) Rendering recipe
31 | recipeView.render(model.state.recipe);
32 | } catch (err) {
33 | recipeView.renderError();
34 | console.error(err);
35 | }
36 | };
37 |
38 | const controlSearchResults = async function () {
39 | try {
40 | resultsView.renderSpinner();
41 |
42 | // 1) Get search query
43 | const query = searchView.getQuery();
44 | if (!query) return;
45 |
46 | // 2) Load search results
47 | await model.loadSearchResults(query);
48 |
49 | // 3) Render results
50 | resultsView.render(model.getSearchResultsPage());
51 |
52 | // 4) Render initial pagination buttons
53 | paginationView.render(model.state.search);
54 | } catch (err) {
55 | console.log(err);
56 | }
57 | };
58 |
59 | const controlPagination = function (goToPage) {
60 | // 1) Render NEW results
61 | resultsView.render(model.getSearchResultsPage(goToPage));
62 |
63 | // 2) Render NEW pagination buttons
64 | paginationView.render(model.state.search);
65 | };
66 |
67 | const controlServings = function (newServings) {
68 | // Update the recipe servings (in state)
69 | model.updateServings(newServings);
70 |
71 | // Update the recipe view
72 | recipeView.update(model.state.recipe);
73 | };
74 |
75 | const controlAddBookmark = function () {
76 | // 1) Add/remove bookmark
77 | if (!model.state.recipe.bookmarked) model.addBookmark(model.state.recipe);
78 | else model.deleteBookmark(model.state.recipe.id);
79 |
80 | // 2) Update recipe view
81 | recipeView.update(model.state.recipe);
82 |
83 | // 3) Render bookmarks
84 | bookmarksView.render(model.state.bookmarks);
85 | };
86 |
87 | const controlBookmarks = function () {
88 | bookmarksView.render(model.state.bookmarks);
89 | };
90 |
91 | const controlAddRecipe = async function (newRecipe) {
92 | try {
93 | // Show loading spinner
94 | addRecipeView.renderSpinner();
95 |
96 | // Upload the new recipe data
97 | await model.uploadRecipe(newRecipe);
98 | console.log(model.state.recipe);
99 |
100 | // Render recipe
101 | recipeView.render(model.state.recipe);
102 |
103 | // Success message
104 | addRecipeView.renderMessage();
105 |
106 | // Render bookmark view
107 | bookmarksView.render(model.state.bookmarks);
108 |
109 | // Change ID in URL
110 | window.history.pushState(null, '', `#${model.state.recipe.id}`);
111 |
112 | // Close form window
113 | setTimeout(function () {
114 | addRecipeView.toggleWindow();
115 | }, MODAL_CLOSE_SEC * 1000);
116 | } catch (err) {
117 | console.error('💥', err);
118 | addRecipeView.renderError(err.message);
119 | }
120 | };
121 |
122 | const init = function () {
123 | bookmarksView.addHandlerRender(controlBookmarks);
124 | recipeView.addHandlerRender(controlRecipes);
125 | recipeView.addHandlerUpdateServings(controlServings);
126 | recipeView.addHandlerAddBookmark(controlAddBookmark);
127 | searchView.addHandlerSearch(controlSearchResults);
128 | paginationView.addHandlerClick(controlPagination);
129 | addRecipeView.addHandlerUpload(controlAddRecipe);
130 | };
131 | init();
132 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/helpers.js:
--------------------------------------------------------------------------------
1 | import { async } from 'regenerator-runtime';
2 | import { TIMEOUT_SEC } from './config.js';
3 |
4 | const timeout = function (s) {
5 | return new Promise(function (_, reject) {
6 | setTimeout(function () {
7 | reject(new Error(`Request took too long! Timeout after ${s} second`));
8 | }, s * 1000);
9 | });
10 | };
11 |
12 | export const AJAX = async function (url, uploadData = undefined) {
13 | try {
14 | const fetchPro = uploadData
15 | ? fetch(url, {
16 | method: 'POST',
17 | headers: {
18 | 'Content-Type': 'application/json',
19 | },
20 | body: JSON.stringify(uploadData),
21 | })
22 | : fetch(url);
23 |
24 | const res = await Promise.race([fetchPro, timeout(TIMEOUT_SEC)]);
25 | const data = await res.json();
26 |
27 | if (!res.ok) throw new Error(`${data.message} (${res.status})`);
28 | return data;
29 | } catch (err) {
30 | throw err;
31 | }
32 | };
33 |
34 | /*
35 | export const getJSON = async function (url) {
36 | try {
37 | const fetchPro = fetch(url);
38 | const res = await Promise.race([fetchPro, timeout(TIMEOUT_SEC)]);
39 | const data = await res.json();
40 |
41 | if (!res.ok) throw new Error(`${data.message} (${res.status})`);
42 | return data;
43 | } catch (err) {
44 | throw err;
45 | }
46 | };
47 |
48 | export const sendJSON = async function (url, uploadData) {
49 | try {
50 | const fetchPro = fetch(url, {
51 | method: 'POST',
52 | headers: {
53 | 'Content-Type': 'application/json',
54 | },
55 | body: JSON.stringify(uploadData),
56 | });
57 |
58 | const res = await Promise.race([fetchPro, timeout(TIMEOUT_SEC)]);
59 | const data = await res.json();
60 |
61 | if (!res.ok) throw new Error(`${data.message} (${res.status})`);
62 | return data;
63 | } catch (err) {
64 | throw err;
65 | }
66 | };
67 | */
68 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/model.js:
--------------------------------------------------------------------------------
1 | import { async } from 'regenerator-runtime';
2 | import { API_URL, RES_PER_PAGE, KEY } from './config.js';
3 | // import { getJSON, sendJSON } from './helpers.js';
4 | import { AJAX } from './helpers.js';
5 |
6 | export const state = {
7 | recipe: {},
8 | search: {
9 | query: '',
10 | results: [],
11 | page: 1,
12 | resultsPerPage: RES_PER_PAGE,
13 | },
14 | bookmarks: [],
15 | };
16 |
17 | const createRecipeObject = function (data) {
18 | const { recipe } = data.data;
19 | return {
20 | id: recipe.id,
21 | title: recipe.title,
22 | publisher: recipe.publisher,
23 | sourceUrl: recipe.source_url,
24 | image: recipe.image_url,
25 | servings: recipe.servings,
26 | cookingTime: recipe.cooking_time,
27 | ingredients: recipe.ingredients,
28 | ...(recipe.key && { key: recipe.key }),
29 | };
30 | };
31 |
32 | export const loadRecipe = async function (id) {
33 | try {
34 | const data = await AJAX(`${API_URL}${id}?key=${KEY}`);
35 | state.recipe = createRecipeObject(data);
36 |
37 | if (state.bookmarks.some(bookmark => bookmark.id === id))
38 | state.recipe.bookmarked = true;
39 | else state.recipe.bookmarked = false;
40 |
41 | console.log(state.recipe);
42 | } catch (err) {
43 | // Temp error handling
44 | console.error(`${err} 💥💥💥💥`);
45 | throw err;
46 | }
47 | };
48 |
49 | export const loadSearchResults = async function (query) {
50 | try {
51 | state.search.query = query;
52 |
53 | const data = await AJAX(`${API_URL}?search=${query}&key=${KEY}`);
54 | console.log(data);
55 |
56 | state.search.results = data.data.recipes.map(rec => {
57 | return {
58 | id: rec.id,
59 | title: rec.title,
60 | publisher: rec.publisher,
61 | image: rec.image_url,
62 | ...(rec.key && { key: rec.key }),
63 | };
64 | });
65 | state.search.page = 1;
66 | } catch (err) {
67 | console.error(`${err} 💥💥💥💥`);
68 | throw err;
69 | }
70 | };
71 |
72 | export const getSearchResultsPage = function (page = state.search.page) {
73 | state.search.page = page;
74 |
75 | const start = (page - 1) * state.search.resultsPerPage; // 0
76 | const end = page * state.search.resultsPerPage; // 9
77 |
78 | return state.search.results.slice(start, end);
79 | };
80 |
81 | export const updateServings = function (newServings) {
82 | state.recipe.ingredients.forEach(ing => {
83 | ing.quantity = (ing.quantity * newServings) / state.recipe.servings;
84 | // newQt = oldQt * newServings / oldServings // 2 * 8 / 4 = 4
85 | });
86 |
87 | state.recipe.servings = newServings;
88 | };
89 |
90 | const persistBookmarks = function () {
91 | localStorage.setItem('bookmarks', JSON.stringify(state.bookmarks));
92 | };
93 |
94 | export const addBookmark = function (recipe) {
95 | // Add bookmark
96 | state.bookmarks.push(recipe);
97 |
98 | // Mark current recipe as bookmarked
99 | if (recipe.id === state.recipe.id) state.recipe.bookmarked = true;
100 |
101 | persistBookmarks();
102 | };
103 |
104 | export const deleteBookmark = function (id) {
105 | // Delete bookmark
106 | const index = state.bookmarks.findIndex(el => el.id === id);
107 | state.bookmarks.splice(index, 1);
108 |
109 | // Mark current recipe as NOT bookmarked
110 | if (id === state.recipe.id) state.recipe.bookmarked = false;
111 |
112 | persistBookmarks();
113 | };
114 |
115 | const init = function () {
116 | const storage = localStorage.getItem('bookmarks');
117 | if (storage) state.bookmarks = JSON.parse(storage);
118 | };
119 | init();
120 |
121 | const clearBookmarks = function () {
122 | localStorage.clear('bookmarks');
123 | };
124 | // clearBookmarks();
125 |
126 | export const uploadRecipe = async function (newRecipe) {
127 | try {
128 | const ingredients = Object.entries(newRecipe)
129 | .filter(entry => entry[0].startsWith('ingredient') && entry[1] !== '')
130 | .map(ing => {
131 | const ingArr = ing[1].split(',').map(el => el.trim());
132 | // const ingArr = ing[1].replaceAll(' ', '').split(',');
133 | if (ingArr.length !== 3)
134 | throw new Error(
135 | 'Wrong ingredient fromat! Please use the correct format :)'
136 | );
137 |
138 | const [quantity, unit, description] = ingArr;
139 |
140 | return { quantity: quantity ? +quantity : null, unit, description };
141 | });
142 |
143 | const recipe = {
144 | title: newRecipe.title,
145 | source_url: newRecipe.sourceUrl,
146 | image_url: newRecipe.image,
147 | publisher: newRecipe.publisher,
148 | cooking_time: +newRecipe.cookingTime,
149 | servings: +newRecipe.servings,
150 | ingredients,
151 | };
152 |
153 | const data = await AJAX(`${API_URL}?key=${KEY}`, recipe);
154 | state.recipe = createRecipeObject(data);
155 | addBookmark(state.recipe);
156 | } catch (err) {
157 | throw err;
158 | }
159 | };
160 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/View.js:
--------------------------------------------------------------------------------
1 | import icons from 'url:../../img/icons.svg'; // Parcel 2
2 |
3 | export default class View {
4 | _data;
5 |
6 | /**
7 | * Render the received object to the DOM
8 | * @param {Object | Object[]} data The data to be rendered (e.g. recipe)
9 | * @param {boolean} [render=true] If false, create markup string instead of rendering to the DOM
10 | * @returns {undefined | string} A markup string is returned if render=false
11 | * @this {Object} View instance
12 | * @author Jonas Schmedtmann
13 | * @todo Finish implementation
14 | */
15 | render(data, render = true) {
16 | if (!data || (Array.isArray(data) && data.length === 0))
17 | return this.renderError();
18 |
19 | this._data = data;
20 | const markup = this._generateMarkup();
21 |
22 | if (!render) return markup;
23 |
24 | this._clear();
25 | this._parentElement.insertAdjacentHTML('afterbegin', markup);
26 | }
27 |
28 | update(data) {
29 | this._data = data;
30 | const newMarkup = this._generateMarkup();
31 |
32 | const newDOM = document.createRange().createContextualFragment(newMarkup);
33 | const newElements = Array.from(newDOM.querySelectorAll('*'));
34 | const curElements = Array.from(this._parentElement.querySelectorAll('*'));
35 |
36 | newElements.forEach((newEl, i) => {
37 | const curEl = curElements[i];
38 | // console.log(curEl, newEl.isEqualNode(curEl));
39 |
40 | // Updates changed TEXT
41 | if (
42 | !newEl.isEqualNode(curEl) &&
43 | newEl.firstChild?.nodeValue.trim() !== ''
44 | ) {
45 | // console.log('💥', newEl.firstChild.nodeValue.trim());
46 | curEl.textContent = newEl.textContent;
47 | }
48 |
49 | // Updates changed ATTRIBUES
50 | if (!newEl.isEqualNode(curEl))
51 | Array.from(newEl.attributes).forEach(attr =>
52 | curEl.setAttribute(attr.name, attr.value)
53 | );
54 | });
55 | }
56 |
57 | _clear() {
58 | this._parentElement.innerHTML = '';
59 | }
60 |
61 | renderSpinner() {
62 | const markup = `
63 |
64 |
65 |
66 |
67 |
68 | `;
69 | this._clear();
70 | this._parentElement.insertAdjacentHTML('afterbegin', markup);
71 | }
72 |
73 | renderError(message = this._errorMessage) {
74 | const markup = `
75 |
76 |
77 |
78 |
79 |
80 |
81 |
${message}
82 |
83 | `;
84 | this._clear();
85 | this._parentElement.insertAdjacentHTML('afterbegin', markup);
86 | }
87 |
88 | renderMessage(message = this._message) {
89 | const markup = `
90 |
91 |
92 |
93 |
94 |
95 |
96 |
${message}
97 |
98 | `;
99 | this._clear();
100 | this._parentElement.insertAdjacentHTML('afterbegin', markup);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/addRecipeView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 | import icons from 'url:../../img/icons.svg'; // Parcel 2
3 |
4 | class AddRecipeView extends View {
5 | _parentElement = document.querySelector('.upload');
6 | _message = 'Recipe was successfully uploaded :)';
7 |
8 | _window = document.querySelector('.add-recipe-window');
9 | _overlay = document.querySelector('.overlay');
10 | _btnOpen = document.querySelector('.nav__btn--add-recipe');
11 | _btnClose = document.querySelector('.btn--close-modal');
12 |
13 | constructor() {
14 | super();
15 | this._addHandlerShowWindow();
16 | this._addHandlerHideWindow();
17 | }
18 |
19 | toggleWindow() {
20 | this._overlay.classList.toggle('hidden');
21 | this._window.classList.toggle('hidden');
22 | }
23 |
24 | _addHandlerShowWindow() {
25 | this._btnOpen.addEventListener('click', this.toggleWindow.bind(this));
26 | }
27 |
28 | _addHandlerHideWindow() {
29 | this._btnClose.addEventListener('click', this.toggleWindow.bind(this));
30 | this._overlay.addEventListener('click', this.toggleWindow.bind(this));
31 | }
32 |
33 | addHandlerUpload(handler) {
34 | this._parentElement.addEventListener('submit', function (e) {
35 | e.preventDefault();
36 | const dataArr = [...new FormData(this)];
37 | const data = Object.fromEntries(dataArr);
38 | handler(data);
39 | });
40 | }
41 |
42 | _generateMarkup() {}
43 | }
44 |
45 | export default new AddRecipeView();
46 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/bookmarksView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 | import previewView from './previewView.js';
3 | import icons from 'url:../../img/icons.svg'; // Parcel 2
4 |
5 | class BookmarksView extends View {
6 | _parentElement = document.querySelector('.bookmarks__list');
7 | _errorMessage = 'No bookmarks yet. Find a nice recipe and bookmark it ;)';
8 | _message = '';
9 |
10 | addHandlerRender(handler) {
11 | window.addEventListener('load', handler);
12 | }
13 |
14 | _generateMarkup() {
15 | return this._data
16 | .map(bookmark => previewView.render(bookmark, false))
17 | .join('');
18 | }
19 | }
20 |
21 | export default new BookmarksView();
22 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/paginationView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 | import icons from 'url:../../img/icons.svg'; // Parcel 2
3 |
4 | class PaginationView extends View {
5 | _parentElement = document.querySelector('.pagination');
6 |
7 | addHandlerClick(handler) {
8 | this._parentElement.addEventListener('click', function (e) {
9 | const btn = e.target.closest('.btn--inline');
10 | if (!btn) return;
11 |
12 | const goToPage = +btn.dataset.goto;
13 | handler(goToPage);
14 | });
15 | }
16 |
17 | _generateMarkup() {
18 | const curPage = this._data.page;
19 | const numPages = Math.ceil(
20 | this._data.results.length / this._data.resultsPerPage
21 | );
22 |
23 | // Page 1, and there are other pages
24 | if (curPage === 1 && numPages > 1) {
25 | return `
26 |
34 | `;
35 | }
36 |
37 | // Last page
38 | if (curPage === numPages && numPages > 1) {
39 | return `
40 |
48 | `;
49 | }
50 |
51 | // Other page
52 | if (curPage < numPages) {
53 | return `
54 |
62 |
70 | `;
71 | }
72 |
73 | // Page 1, and there are NO other pages
74 | return '';
75 | }
76 | }
77 |
78 | export default new PaginationView();
79 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/previewView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 | import icons from 'url:../../img/icons.svg'; // Parcel 2
3 |
4 | class PreviewView extends View {
5 | _parentElement = '';
6 |
7 | _generateMarkup() {
8 | const id = window.location.hash.slice(1);
9 |
10 | return `
11 |
12 |
15 |
16 |
17 |
18 |
19 |
${this._data.title}
20 |
${this._data.publisher}
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | `;
32 | }
33 | }
34 |
35 | export default new PreviewView();
36 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/recipeView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 |
3 | // import icons from '../img/icons.svg'; // Parcel 1
4 | import icons from 'url:../../img/icons.svg'; // Parcel 2
5 | import { Fraction } from 'fractional';
6 |
7 | class RecipeView extends View {
8 | _parentElement = document.querySelector('.recipe');
9 | _errorMessage = 'We could not find that recipe. Please try another one!';
10 | _message = '';
11 |
12 | addHandlerRender(handler) {
13 | ['hashchange', 'load'].forEach(ev => window.addEventListener(ev, handler));
14 | }
15 |
16 | addHandlerUpdateServings(handler) {
17 | this._parentElement.addEventListener('click', function (e) {
18 | const btn = e.target.closest('.btn--update-servings');
19 | if (!btn) return;
20 | const { updateTo } = btn.dataset;
21 | if (+updateTo > 0) handler(+updateTo);
22 | });
23 | }
24 |
25 | addHandlerAddBookmark(handler) {
26 | this._parentElement.addEventListener('click', function (e) {
27 | const btn = e.target.closest('.btn--bookmark');
28 | if (!btn) return;
29 | handler();
30 | });
31 | }
32 |
33 | _generateMarkup() {
34 | return `
35 |
36 |
39 |
40 | ${this._data.title}
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | ${
50 | this._data.cookingTime
51 | }
52 | minutes
53 |
54 |
55 |
56 |
57 |
58 |
${
59 | this._data.servings
60 | }
61 |
servings
62 |
63 |
64 |
67 |
68 |
69 |
70 |
71 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
91 |
92 |
93 |
94 |
95 |
96 |
Recipe ingredients
97 |
98 | ${this._data.ingredients.map(this._generateMarkupIngredient).join('')}
99 |
100 |
101 |
102 |
How to cook it
103 |
104 | This recipe was carefully designed and tested by
105 | ${
106 | this._data.publisher
107 | } . Please check out
108 | directions at their website.
109 |
110 |
115 | Directions
116 |
117 |
118 |
119 |
120 |
121 | `;
122 | }
123 |
124 | _generateMarkupIngredient(ing) {
125 | return `
126 |
127 |
128 |
129 |
130 | ${
131 | ing.quantity ? new Fraction(ing.quantity).toString() : ''
132 | }
133 |
134 | ${ing.unit}
135 | ${ing.description}
136 |
137 |
138 | `;
139 | }
140 | }
141 |
142 | export default new RecipeView();
143 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/resultsView.js:
--------------------------------------------------------------------------------
1 | import View from './View.js';
2 | import previewView from './previewView.js';
3 | import icons from 'url:../../img/icons.svg'; // Parcel 2
4 |
5 | class ResultsView extends View {
6 | _parentElement = document.querySelector('.results');
7 | _errorMessage = 'No recipes found for your query! Please try again ;)';
8 | _message = '';
9 |
10 | _generateMarkup() {
11 | return this._data.map(result => previewView.render(result, false)).join('');
12 | }
13 | }
14 |
15 | export default new ResultsView();
16 |
--------------------------------------------------------------------------------
/18-forkify/final/src/js/views/searchView.js:
--------------------------------------------------------------------------------
1 | class SearchView {
2 | _parentEl = document.querySelector('.search');
3 |
4 | getQuery() {
5 | const query = this._parentEl.querySelector('.search__field').value;
6 | this._clearInput();
7 | return query;
8 | }
9 |
10 | _clearInput() {
11 | this._parentEl.querySelector('.search__field').value = '';
12 | }
13 |
14 | addHandlerSearch(handler) {
15 | this._parentEl.addEventListener('submit', function (e) {
16 | e.preventDefault();
17 | handler();
18 | });
19 | }
20 | }
21 |
22 | export default new SearchView();
23 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_base.scss:
--------------------------------------------------------------------------------
1 | // $color-primary: #f59a83;
2 | $color-primary: #f38e82;
3 | $color-grad-1: #fbdb89;
4 | $color-grad-2: #f48982;
5 |
6 | $color-grey-light-1: #f9f5f3; // Light background
7 | $color-grey-light-2: #f2efee; // Light lines
8 | $color-grey-light-3: #d3c7c3; // Light text (placeholder)
9 | $color-grey-dark-1: #615551; // Normal text
10 | $color-grey-dark-2: #918581; // Lighter text
11 |
12 | $gradient: linear-gradient(to right bottom, $color-grad-1, $color-grad-2);
13 |
14 | $bp-large: 78.15em; // 1250px
15 | $bp-medium: 61.25em; // 980px
16 | $bp-small: 37.5em; // 600px
17 | $bp-smallest: 31.25em; // 500px
18 |
19 | * {
20 | margin: 0;
21 | padding: 0;
22 | }
23 |
24 | *,
25 | *::before,
26 | *::after {
27 | box-sizing: inherit;
28 | }
29 |
30 | html {
31 | box-sizing: border-box;
32 | font-size: 62.5%;
33 |
34 | @media only screen and (max-width: $bp-medium) {
35 | font-size: 50%;
36 | }
37 | }
38 |
39 | body {
40 | font-family: 'Nunito Sans', sans-serif;
41 | font-weight: 400;
42 | line-height: 1.6;
43 | color: $color-grey-dark-1;
44 | background-image: $gradient;
45 | background-size: cover;
46 | background-repeat: no-repeat;
47 | min-height: calc(100vh - 2 * 4vw);
48 | }
49 |
50 | .container {
51 | max-width: 120rem;
52 | min-height: 117rem;
53 | margin: 4vw auto;
54 | background-color: #fff;
55 | border-radius: 9px;
56 | overflow: hidden;
57 | box-shadow: 0 2rem 6rem 0.5rem rgba($color-grey-dark-1, 0.2);
58 |
59 | display: grid;
60 | grid-template-rows: 10rem minmax(100rem, auto);
61 | grid-template-columns: 1fr 2fr;
62 | grid-template-areas:
63 | 'head head'
64 | 'list recipe';
65 |
66 | @media only screen and (max-width: $bp-large) {
67 | max-width: 100%;
68 | margin: 0;
69 | border-radius: 0;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_components.scss:
--------------------------------------------------------------------------------
1 | %btn {
2 | background-image: $gradient;
3 | border-radius: 10rem;
4 | border: none;
5 | text-transform: uppercase;
6 | color: #fff;
7 | cursor: pointer;
8 | display: flex;
9 | align-items: center;
10 | transition: all 0.2s;
11 |
12 | &:hover {
13 | transform: scale(1.05);
14 | }
15 |
16 | &:focus {
17 | outline: none;
18 | }
19 |
20 | & > *:first-child {
21 | margin-right: 1rem;
22 | }
23 | }
24 |
25 | .btn {
26 | @extend %btn;
27 |
28 | padding: 1.5rem 4rem;
29 | font-size: 1.5rem;
30 | font-weight: 600;
31 |
32 | svg {
33 | height: 2.25rem;
34 | width: 2.25rem;
35 | fill: currentColor;
36 | }
37 | }
38 |
39 | .btn--small {
40 | &,
41 | &:link,
42 | &:visited {
43 | @extend %btn;
44 |
45 | font-size: 1.4rem;
46 | font-weight: 600;
47 | padding: 1.25rem 2.25rem;
48 | text-decoration: none;
49 |
50 | svg {
51 | height: 1.75rem;
52 | width: 1.75rem;
53 | fill: currentColor;
54 | }
55 | }
56 | }
57 |
58 | .btn--inline {
59 | color: $color-primary;
60 | font-size: 1.3rem;
61 | font-weight: 600;
62 | border: none;
63 | background-color: $color-grey-light-1;
64 | padding: 0.8rem 1.2rem;
65 | border-radius: 10rem;
66 | cursor: pointer;
67 |
68 | display: flex;
69 | align-items: center;
70 | transition: all 0.2s;
71 |
72 | svg {
73 | height: 1.6rem;
74 | width: 1.6rem;
75 | fill: currentColor;
76 | margin: 0 0.2rem;
77 | }
78 |
79 | span {
80 | margin: 0 0.4rem;
81 | }
82 |
83 | &:hover {
84 | color: $color-grad-2;
85 | background-color: $color-grey-light-2;
86 | }
87 |
88 | &:focus {
89 | outline: none;
90 | }
91 | }
92 |
93 | .btn--round {
94 | background-image: $gradient;
95 | border-radius: 50%;
96 | border: none;
97 | cursor: pointer;
98 | height: 4.5rem;
99 | width: 4.5rem;
100 | // margin-left: auto;
101 | transition: all 0.2s;
102 |
103 | display: flex;
104 | align-items: center;
105 | justify-content: center;
106 |
107 | &:hover {
108 | transform: scale(1.07);
109 | }
110 |
111 | &:focus {
112 | outline: none;
113 | }
114 |
115 | svg {
116 | height: 2.5rem;
117 | width: 2.5rem;
118 | fill: #fff;
119 | }
120 | }
121 |
122 | .btn--tiny {
123 | height: 2rem;
124 | width: 2rem;
125 | border: none;
126 | background: none;
127 | cursor: pointer;
128 |
129 | svg {
130 | height: 100%;
131 | width: 100%;
132 | fill: $color-primary;
133 | transition: all 0.3s;
134 | }
135 |
136 | &:focus {
137 | outline: none;
138 | }
139 |
140 | &:hover svg {
141 | fill: $color-grad-2;
142 | transform: translateY(-1px);
143 | }
144 |
145 | &:active svg {
146 | fill: $color-grad-2;
147 | transform: translateY(0);
148 | }
149 |
150 | &:not(:last-child) {
151 | margin-right: 0.3rem;
152 | }
153 | }
154 |
155 | .heading--2 {
156 | font-size: 2rem;
157 | font-weight: 700;
158 | color: $color-primary;
159 | text-transform: uppercase;
160 | margin-bottom: 2.5rem;
161 | text-align: center;
162 | // transform: skewY(-3deg);
163 | }
164 |
165 | .link:link,
166 | .link:visited {
167 | color: $color-grey-dark-2;
168 | }
169 |
170 | .spinner {
171 | margin: 5rem auto;
172 | text-align: center;
173 |
174 | svg {
175 | height: 6rem;
176 | width: 6rem;
177 | fill: $color-primary;
178 | animation: rotate 2s infinite linear;
179 | }
180 | }
181 |
182 | @keyframes rotate {
183 | 0% {
184 | transform: rotate(0);
185 | }
186 |
187 | 100% {
188 | transform: rotate(360deg);
189 | }
190 | }
191 |
192 | .message,
193 | .error {
194 | max-width: 40rem;
195 | margin: 0 auto;
196 | padding: 5rem 4rem;
197 |
198 | display: flex;
199 |
200 | svg {
201 | height: 3rem;
202 | width: 3rem;
203 | fill: $color-primary;
204 | transform: translateY(-0.3rem);
205 | }
206 |
207 | p {
208 | margin-left: 1.5rem;
209 | font-size: 1.8rem;
210 | line-height: 1.5;
211 | font-weight: 600;
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_header.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | grid-area: head;
3 | background-color: $color-grey-light-1;
4 | display: flex;
5 | align-items: center;
6 | justify-content: space-between;
7 |
8 | &__logo {
9 | margin-left: 4rem;
10 | height: 4.6rem;
11 | display: block;
12 | }
13 | }
14 |
15 | .search {
16 | background-color: #fff;
17 | border-radius: 10rem;
18 | display: flex;
19 | align-items: center;
20 | padding-left: 3rem;
21 | transition: all 0.3s;
22 |
23 | &:focus-within {
24 | transform: translateY(-2px);
25 | box-shadow: 0 0.7rem 3rem rgba($color-grey-dark-1, 0.08);
26 | }
27 |
28 | &__field {
29 | border: none;
30 | background: none;
31 | font-family: inherit;
32 | color: inherit;
33 | font-size: 1.7rem;
34 | width: 30rem;
35 |
36 | &:focus {
37 | outline: none;
38 | }
39 |
40 | &::placeholder {
41 | color: $color-grey-light-3;
42 | }
43 |
44 | @media only screen and (max-width: $bp-medium) {
45 | width: auto;
46 |
47 | &::placeholder {
48 | color: white;
49 | }
50 | }
51 | }
52 |
53 | &__btn {
54 | font-weight: 600;
55 | font-family: inherit;
56 | }
57 | }
58 |
59 | .nav {
60 | align-self: stretch;
61 | margin-right: 2.5rem;
62 |
63 | &__list {
64 | list-style: none;
65 | display: flex;
66 | height: 100%;
67 | }
68 |
69 | &__item {
70 | position: relative;
71 | }
72 |
73 | &__btn {
74 | height: 100%;
75 | font-family: inherit;
76 | color: inherit;
77 | font-size: 1.4rem;
78 | font-weight: 700;
79 | text-transform: uppercase;
80 | background: none;
81 | border: none;
82 | cursor: pointer;
83 | padding: 0 1.5rem;
84 | transition: all 0.3s;
85 |
86 | display: flex;
87 | align-items: center;
88 |
89 | svg {
90 | height: 2.4rem;
91 | width: 2.4rem;
92 | fill: $color-primary;
93 | margin-right: 0.7rem;
94 | transform: translateY(-1px);
95 | }
96 |
97 | &:focus {
98 | outline: none;
99 | }
100 |
101 | &:hover {
102 | background-color: $color-grey-light-2;
103 | }
104 | }
105 | }
106 |
107 | .bookmarks {
108 | padding: 1rem 0;
109 | position: absolute;
110 | // right: 0;
111 | right: -2.5rem;
112 | z-index: 10;
113 | width: 40rem;
114 | background-color: #fff;
115 | box-shadow: 0 0.8rem 5rem 2rem rgba($color-grey-dark-1, 0.1);
116 |
117 | visibility: hidden;
118 | opacity: 0;
119 | transition: all 0.5s 0.2s;
120 |
121 | &__list {
122 | list-style: none;
123 | }
124 |
125 | &__field {
126 | cursor: pointer;
127 | padding: 0 4rem;
128 |
129 | display: flex;
130 | align-items: center;
131 | height: 100%;
132 | transition: all 0.3s;
133 |
134 | &:hover {
135 | background-color: $color-grey-light-2;
136 | }
137 | }
138 |
139 | &:hover,
140 | .nav__btn--bookmarks:hover + & {
141 | visibility: visible;
142 | opacity: 1;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_preview.scss:
--------------------------------------------------------------------------------
1 | .preview {
2 | &__link {
3 | &:link,
4 | &:visited {
5 | display: flex;
6 | align-items: center;
7 | padding: 1.5rem 3.25rem;
8 | transition: all 0.3s;
9 | border-right: 1px solid #fff;
10 | text-decoration: none;
11 | }
12 |
13 | &:hover {
14 | background-color: $color-grey-light-1;
15 | transform: translateY(-2px);
16 | }
17 |
18 | &--active {
19 | background-color: $color-grey-light-1;
20 | }
21 | }
22 |
23 | &__fig {
24 | flex: 0 0 5.8rem;
25 | border-radius: 50%;
26 | overflow: hidden;
27 | height: 5.8rem;
28 | margin-right: 2rem;
29 | position: relative;
30 | backface-visibility: hidden;
31 |
32 | &::before {
33 | content: '';
34 | display: block;
35 | height: 100%;
36 | width: 100%;
37 | position: absolute;
38 | top: 0;
39 | left: 0;
40 | background-image: linear-gradient(
41 | to right bottom,
42 | $color-grad-1,
43 | $color-grad-2
44 | );
45 | opacity: 0.4;
46 | }
47 |
48 | img {
49 | display: block;
50 | width: 100%;
51 | height: 100%;
52 | object-fit: cover;
53 | transition: all 0.3s;
54 | }
55 | }
56 |
57 | &__data {
58 | display: grid;
59 | width: 100%;
60 | grid-template-columns: 1fr 2rem;
61 | row-gap: 0.1rem;
62 | align-items: center;
63 | }
64 |
65 | &__title {
66 | grid-column: 1/-1;
67 | font-size: 1.45rem;
68 | color: $color-primary;
69 | text-transform: uppercase;
70 | font-weight: 600;
71 |
72 | // This is how text is truncated!
73 | text-overflow: ellipsis;
74 | max-width: 25rem;
75 | white-space: nowrap;
76 | overflow: hidden;
77 | }
78 |
79 | &__publisher {
80 | font-size: 1.15rem;
81 | color: $color-grey-dark-2;
82 | text-transform: uppercase;
83 | font-weight: 600;
84 | }
85 |
86 | &__user-generated {
87 | background-color: darken($color-grey-light-2, 2%);
88 |
89 | display: flex;
90 | align-items: center;
91 | justify-content: center;
92 | height: 2rem;
93 | width: 2rem;
94 | border-radius: 10rem;
95 |
96 | margin-left: auto;
97 | margin-right: 1.75rem;
98 |
99 | svg {
100 | height: 1.2rem;
101 | width: 1.2rem;
102 | fill: $color-primary;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_recipe.scss:
--------------------------------------------------------------------------------
1 | .recipe {
2 | background-color: $color-grey-light-1;
3 |
4 | ///////////
5 | // FIGURE
6 | &__fig {
7 | height: 32rem;
8 | position: relative;
9 | // transform: scale(1.04) translateY(-1px);
10 | transform-origin: top;
11 |
12 | &::before {
13 | content: '';
14 | display: block;
15 | height: 100%;
16 | width: 100%;
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | background-image: linear-gradient(
21 | to right bottom,
22 | $color-grad-1,
23 | $color-grad-2
24 | );
25 | opacity: 0.6;
26 | }
27 | }
28 |
29 | &__img {
30 | width: 100%;
31 | display: block;
32 | height: 100%;
33 | object-fit: cover;
34 | }
35 |
36 | &__title {
37 | position: absolute;
38 | bottom: 0;
39 | left: 50%;
40 | transform: translate(-50%, 20%) skewY(-6deg);
41 | color: #fff;
42 | font-weight: 700;
43 | font-size: 3.25rem;
44 | text-transform: uppercase;
45 | width: 50%;
46 | line-height: 1.95;
47 | text-align: center;
48 |
49 | span {
50 | -webkit-box-decoration-break: clone;
51 | box-decoration-break: clone;
52 | padding: 1.3rem 2rem;
53 | background-image: linear-gradient(
54 | to right bottom,
55 | $color-grad-1,
56 | $color-grad-2
57 | );
58 | }
59 |
60 | @media only screen and (max-width: $bp-medium) {
61 | width: 70%;
62 | }
63 | }
64 |
65 | ///////////
66 | // DETAILS
67 | &__details {
68 | display: flex;
69 | align-items: center;
70 | padding: 7.5rem 8rem 3.5rem 8rem;
71 | }
72 |
73 | &__info {
74 | font-size: 1.65rem;
75 | text-transform: uppercase;
76 | display: flex;
77 | align-items: center;
78 |
79 | &:not(:last-child) {
80 | margin-right: 4.5rem;
81 | }
82 | }
83 |
84 | &__info-icon {
85 | height: 2.35rem;
86 | width: 2.35rem;
87 | fill: $color-primary;
88 | margin-right: 1.15rem;
89 | }
90 |
91 | &__info-data {
92 | margin-right: 0.5rem;
93 | font-weight: 700;
94 | }
95 |
96 | &__info-buttons {
97 | display: flex;
98 | margin-left: 1.6rem;
99 | transform: translateY(-1px);
100 | }
101 |
102 | &__user-generated {
103 | background-color: darken($color-grey-light-2, 2%);
104 |
105 | display: flex;
106 | align-items: center;
107 | justify-content: center;
108 | height: 4rem;
109 | width: 4rem;
110 | border-radius: 10rem;
111 |
112 | margin-left: auto;
113 | margin-right: 1.75rem;
114 |
115 | svg {
116 | height: 2.25rem;
117 | width: 2.25rem;
118 | fill: $color-primary;
119 | }
120 | }
121 |
122 | ///////////
123 | // INGREDIENTS
124 | &__ingredients {
125 | padding: 5rem 8rem;
126 | font-size: 1.6rem;
127 | line-height: 1.4;
128 | background-color: $color-grey-light-2;
129 | display: flex;
130 | flex-direction: column;
131 | align-items: center;
132 | }
133 |
134 | &__ingredient-list {
135 | display: grid;
136 | grid-template-columns: 1fr 1fr;
137 | gap: 2.5rem 3rem;
138 | list-style: none;
139 | }
140 |
141 | &__ingredient {
142 | display: flex;
143 | }
144 |
145 | &__icon {
146 | height: 2rem;
147 | width: 2rem;
148 | fill: $color-primary;
149 | margin-right: 1.1rem;
150 | flex: 0 0 auto;
151 | margin-top: 0.1rem;
152 | }
153 |
154 | &__quantity {
155 | margin-right: 0.5rem;
156 | flex: 0 0 auto;
157 | }
158 |
159 | ///////////
160 | // DIRECTIONS
161 | &__directions {
162 | padding: 5rem 10rem;
163 | padding-bottom: 5rem;
164 | display: flex;
165 | flex-direction: column;
166 | align-items: center;
167 | }
168 |
169 | &__directions-text {
170 | font-size: 1.7rem;
171 | text-align: center;
172 | margin-bottom: 3.5rem;
173 | color: $color-grey-dark-2;
174 | }
175 |
176 | &__publisher {
177 | font-weight: 700;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_searchResults.scss:
--------------------------------------------------------------------------------
1 | .search-results {
2 | padding: 3rem 0;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | .results {
8 | list-style: none;
9 | margin-bottom: 2rem;
10 | }
11 |
12 | .pagination {
13 | margin-top: auto;
14 | padding: 0 3.5rem;
15 |
16 | &::after {
17 | content: '';
18 | display: table;
19 | clear: both;
20 | }
21 |
22 | &__btn {
23 | &--prev {
24 | float: left;
25 | }
26 | &--next {
27 | float: right;
28 | }
29 | }
30 | }
31 |
32 | .copyright {
33 | color: $color-grey-dark-2;
34 | font-size: 1.2rem;
35 | padding: 0 3.5rem;
36 | margin-top: 4rem;
37 |
38 | .twitter-link:link,
39 | .twitter-link:visited {
40 | color: $color-grey-dark-2;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/_upload.scss:
--------------------------------------------------------------------------------
1 | .add-recipe-window {
2 | position: fixed;
3 | top: 50%;
4 | left: 50%;
5 | transform: translate(-50%, -50%);
6 | width: 100rem;
7 | background-color: white;
8 | border-radius: 9px;
9 |
10 | padding: 5rem 6rem;
11 | box-shadow: 0 4rem 6rem rgba(0, 0, 0, 0.25);
12 | z-index: 1000;
13 | transition: all 0.5s;
14 |
15 | .btn--close-modal {
16 | font-family: inherit;
17 | color: inherit;
18 | position: absolute;
19 | top: 0.5rem;
20 | right: 1.6rem;
21 | font-size: 3.5rem;
22 | cursor: pointer;
23 | border: none;
24 | background: none;
25 | }
26 | }
27 |
28 | .overlay {
29 | position: fixed;
30 | top: 0;
31 | left: 0;
32 | width: 100%;
33 | height: 100%;
34 | background-color: rgba(0, 0, 0, 0.4);
35 | backdrop-filter: blur(4px);
36 | z-index: 100;
37 | transition: all 0.5s;
38 | }
39 |
40 | .hidden {
41 | visibility: hidden;
42 | opacity: 0;
43 | }
44 |
45 | .upload {
46 | display: grid;
47 | grid-template-columns: 1fr 1fr;
48 | gap: 4rem 6rem;
49 |
50 | &__column {
51 | display: grid;
52 | grid-template-columns: 1fr 2.8fr;
53 | align-items: center;
54 | gap: 1.5rem;
55 |
56 | & label {
57 | font-size: 1.5rem;
58 | font-weight: 600;
59 | color: inherit;
60 | }
61 |
62 | & input {
63 | font-size: 1.5rem;
64 | padding: 0.8rem 1rem;
65 | border: 1px solid #ddd;
66 | border-radius: 0.5rem;
67 | transition: all 0.2s;
68 |
69 | &::placeholder {
70 | color: $color-grey-light-3;
71 | }
72 |
73 | &:focus {
74 | outline: none;
75 | border: 1px solid $color-primary;
76 | background-color: $color-grey-light-1;
77 | }
78 | }
79 |
80 | & button {
81 | grid-column: 1 / span 2;
82 | justify-self: center;
83 | margin-top: 1rem;
84 | }
85 | }
86 |
87 | &__heading {
88 | font-size: 2.25rem;
89 | font-weight: 700;
90 | text-transform: uppercase;
91 | margin-bottom: 1rem;
92 | grid-column: 1/-1;
93 | }
94 |
95 | &__btn {
96 | grid-column: 1 / -1;
97 | justify-self: center;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/18-forkify/final/src/sass/main.scss:
--------------------------------------------------------------------------------
1 | @import 'base';
2 | @import 'components';
3 | @import 'header';
4 | @import 'preview';
5 | @import 'searchResults';
6 | @import 'recipe';
7 | @import 'upload';
8 |
--------------------------------------------------------------------------------
/18-forkify/starter/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "arrowParens": "avoid"
4 | }
5 |
--------------------------------------------------------------------------------
/18-forkify/starter/forkify-architecture-recipe-loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/forkify-architecture-recipe-loading.png
--------------------------------------------------------------------------------
/18-forkify/starter/forkify-flowchart-part-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/forkify-flowchart-part-1.png
--------------------------------------------------------------------------------
/18-forkify/starter/forkify-flowchart-part-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/forkify-flowchart-part-2.png
--------------------------------------------------------------------------------
/18-forkify/starter/forkify-flowchart-part-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/forkify-flowchart-part-3.png
--------------------------------------------------------------------------------
/18-forkify/starter/src/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/src/img/favicon.png
--------------------------------------------------------------------------------
/18-forkify/starter/src/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/complete-javascript-course/0a217ff24696034937dcc0a7a19f57c4735bc289/18-forkify/starter/src/img/logo.png
--------------------------------------------------------------------------------
/18-forkify/starter/src/js/controller.js:
--------------------------------------------------------------------------------
1 | const recipeContainer = document.querySelector('.recipe');
2 |
3 | const timeout = function (s) {
4 | return new Promise(function (_, reject) {
5 | setTimeout(function () {
6 | reject(new Error(`Request took too long! Timeout after ${s} second`));
7 | }, s * 1000);
8 | });
9 | };
10 |
11 | // https://forkify-api.herokuapp.com/v2
12 |
13 | ///////////////////////////////////////
14 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_base.scss:
--------------------------------------------------------------------------------
1 | // $color-primary: #f59a83;
2 | $color-primary: #f38e82;
3 | $color-grad-1: #fbdb89;
4 | $color-grad-2: #f48982;
5 |
6 | $color-grey-light-1: #f9f5f3; // Light background
7 | $color-grey-light-2: #f2efee; // Light lines
8 | $color-grey-light-3: #d3c7c3; // Light text (placeholder)
9 | $color-grey-dark-1: #615551; // Normal text
10 | $color-grey-dark-2: #918581; // Lighter text
11 |
12 | $gradient: linear-gradient(to right bottom, $color-grad-1, $color-grad-2);
13 |
14 | $bp-large: 78.15em; // 1250px
15 | $bp-medium: 61.25em; // 980px
16 | $bp-small: 37.5em; // 600px
17 | $bp-smallest: 31.25em; // 500px
18 |
19 | * {
20 | margin: 0;
21 | padding: 0;
22 | }
23 |
24 | *,
25 | *::before,
26 | *::after {
27 | box-sizing: inherit;
28 | }
29 |
30 | html {
31 | box-sizing: border-box;
32 | font-size: 62.5%;
33 |
34 | @media only screen and (max-width: $bp-medium) {
35 | font-size: 50%;
36 | }
37 | }
38 |
39 | body {
40 | font-family: 'Nunito Sans', sans-serif;
41 | font-weight: 400;
42 | line-height: 1.6;
43 | color: $color-grey-dark-1;
44 | background-image: $gradient;
45 | background-size: cover;
46 | background-repeat: no-repeat;
47 | min-height: calc(100vh - 2 * 4vw);
48 | }
49 |
50 | .container {
51 | max-width: 120rem;
52 | min-height: 117rem;
53 | margin: 4vw auto;
54 | background-color: #fff;
55 | border-radius: 9px;
56 | overflow: hidden;
57 | box-shadow: 0 2rem 6rem 0.5rem rgba($color-grey-dark-1, 0.2);
58 |
59 | display: grid;
60 | grid-template-rows: 10rem minmax(100rem, auto);
61 | grid-template-columns: 1fr 2fr;
62 | grid-template-areas:
63 | 'head head'
64 | 'list recipe';
65 |
66 | @media only screen and (max-width: $bp-large) {
67 | max-width: 100%;
68 | margin: 0;
69 | border-radius: 0;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_components.scss:
--------------------------------------------------------------------------------
1 | %btn {
2 | background-image: $gradient;
3 | border-radius: 10rem;
4 | border: none;
5 | text-transform: uppercase;
6 | color: #fff;
7 | cursor: pointer;
8 | display: flex;
9 | align-items: center;
10 | transition: all 0.2s;
11 |
12 | &:hover {
13 | transform: scale(1.05);
14 | }
15 |
16 | &:focus {
17 | outline: none;
18 | }
19 |
20 | & > *:first-child {
21 | margin-right: 1rem;
22 | }
23 | }
24 |
25 | .btn {
26 | @extend %btn;
27 |
28 | padding: 1.5rem 4rem;
29 | font-size: 1.5rem;
30 | font-weight: 600;
31 |
32 | svg {
33 | height: 2.25rem;
34 | width: 2.25rem;
35 | fill: currentColor;
36 | }
37 | }
38 |
39 | .btn--small {
40 | &,
41 | &:link,
42 | &:visited {
43 | @extend %btn;
44 |
45 | font-size: 1.4rem;
46 | font-weight: 600;
47 | padding: 1.25rem 2.25rem;
48 | text-decoration: none;
49 |
50 | svg {
51 | height: 1.75rem;
52 | width: 1.75rem;
53 | fill: currentColor;
54 | }
55 | }
56 | }
57 |
58 | .btn--inline {
59 | color: $color-primary;
60 | font-size: 1.3rem;
61 | font-weight: 600;
62 | border: none;
63 | background-color: $color-grey-light-1;
64 | padding: 0.8rem 1.2rem;
65 | border-radius: 10rem;
66 | cursor: pointer;
67 |
68 | display: flex;
69 | align-items: center;
70 | transition: all 0.2s;
71 |
72 | svg {
73 | height: 1.6rem;
74 | width: 1.6rem;
75 | fill: currentColor;
76 | margin: 0 0.2rem;
77 | }
78 |
79 | span {
80 | margin: 0 0.4rem;
81 | }
82 |
83 | &:hover {
84 | color: $color-grad-2;
85 | background-color: $color-grey-light-2;
86 | }
87 |
88 | &:focus {
89 | outline: none;
90 | }
91 | }
92 |
93 | .btn--round {
94 | background-image: $gradient;
95 | border-radius: 50%;
96 | border: none;
97 | cursor: pointer;
98 | height: 4.5rem;
99 | width: 4.5rem;
100 | // margin-left: auto;
101 | transition: all 0.2s;
102 |
103 | display: flex;
104 | align-items: center;
105 | justify-content: center;
106 |
107 | &:hover {
108 | transform: scale(1.07);
109 | }
110 |
111 | &:focus {
112 | outline: none;
113 | }
114 |
115 | svg {
116 | height: 2.5rem;
117 | width: 2.5rem;
118 | fill: #fff;
119 | }
120 | }
121 |
122 | .btn--tiny {
123 | height: 2rem;
124 | width: 2rem;
125 | border: none;
126 | background: none;
127 | cursor: pointer;
128 |
129 | svg {
130 | height: 100%;
131 | width: 100%;
132 | fill: $color-primary;
133 | transition: all 0.3s;
134 | }
135 |
136 | &:focus {
137 | outline: none;
138 | }
139 |
140 | &:hover svg {
141 | fill: $color-grad-2;
142 | transform: translateY(-1px);
143 | }
144 |
145 | &:active svg {
146 | fill: $color-grad-2;
147 | transform: translateY(0);
148 | }
149 |
150 | &:not(:last-child) {
151 | margin-right: 0.3rem;
152 | }
153 | }
154 |
155 | .heading--2 {
156 | font-size: 2rem;
157 | font-weight: 700;
158 | color: $color-primary;
159 | text-transform: uppercase;
160 | margin-bottom: 2.5rem;
161 | text-align: center;
162 | // transform: skewY(-3deg);
163 | }
164 |
165 | .link:link,
166 | .link:visited {
167 | color: $color-grey-dark-2;
168 | }
169 |
170 | .spinner {
171 | margin: 5rem auto;
172 | text-align: center;
173 |
174 | svg {
175 | height: 6rem;
176 | width: 6rem;
177 | fill: $color-primary;
178 | animation: rotate 2s infinite linear;
179 | }
180 | }
181 |
182 | @keyframes rotate {
183 | 0% {
184 | transform: rotate(0);
185 | }
186 |
187 | 100% {
188 | transform: rotate(360deg);
189 | }
190 | }
191 |
192 | .message,
193 | .error {
194 | max-width: 40rem;
195 | margin: 0 auto;
196 | padding: 5rem 4rem;
197 |
198 | display: flex;
199 |
200 | svg {
201 | height: 3rem;
202 | width: 3rem;
203 | fill: $color-primary;
204 | transform: translateY(-0.3rem);
205 | }
206 |
207 | p {
208 | margin-left: 1.5rem;
209 | font-size: 1.8rem;
210 | line-height: 1.5;
211 | font-weight: 600;
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_header.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | grid-area: head;
3 | background-color: $color-grey-light-1;
4 | display: flex;
5 | align-items: center;
6 | justify-content: space-between;
7 |
8 | &__logo {
9 | margin-left: 4rem;
10 | height: 4.6rem;
11 | display: block;
12 | }
13 | }
14 |
15 | .search {
16 | background-color: #fff;
17 | border-radius: 10rem;
18 | display: flex;
19 | align-items: center;
20 | padding-left: 3rem;
21 | transition: all 0.3s;
22 |
23 | &:focus-within {
24 | transform: translateY(-2px);
25 | box-shadow: 0 0.7rem 3rem rgba($color-grey-dark-1, 0.08);
26 | }
27 |
28 | &__field {
29 | border: none;
30 | background: none;
31 | font-family: inherit;
32 | color: inherit;
33 | font-size: 1.7rem;
34 | width: 30rem;
35 |
36 | &:focus {
37 | outline: none;
38 | }
39 |
40 | &::placeholder {
41 | color: $color-grey-light-3;
42 | }
43 |
44 | @media only screen and (max-width: $bp-medium) {
45 | width: auto;
46 |
47 | &::placeholder {
48 | color: white;
49 | }
50 | }
51 | }
52 |
53 | &__btn {
54 | font-weight: 600;
55 | font-family: inherit;
56 | }
57 | }
58 |
59 | .nav {
60 | align-self: stretch;
61 | margin-right: 2.5rem;
62 |
63 | &__list {
64 | list-style: none;
65 | display: flex;
66 | height: 100%;
67 | }
68 |
69 | &__item {
70 | position: relative;
71 | }
72 |
73 | &__btn {
74 | height: 100%;
75 | font-family: inherit;
76 | color: inherit;
77 | font-size: 1.4rem;
78 | font-weight: 700;
79 | text-transform: uppercase;
80 | background: none;
81 | border: none;
82 | cursor: pointer;
83 | padding: 0 1.5rem;
84 | transition: all 0.3s;
85 |
86 | display: flex;
87 | align-items: center;
88 |
89 | svg {
90 | height: 2.4rem;
91 | width: 2.4rem;
92 | fill: $color-primary;
93 | margin-right: 0.7rem;
94 | transform: translateY(-1px);
95 | }
96 |
97 | &:focus {
98 | outline: none;
99 | }
100 |
101 | &:hover {
102 | background-color: $color-grey-light-2;
103 | }
104 | }
105 | }
106 |
107 | .bookmarks {
108 | padding: 1rem 0;
109 | position: absolute;
110 | // right: 0;
111 | right: -2.5rem;
112 | z-index: 10;
113 | width: 40rem;
114 | background-color: #fff;
115 | box-shadow: 0 0.8rem 5rem 2rem rgba($color-grey-dark-1, 0.1);
116 |
117 | visibility: hidden;
118 | opacity: 0;
119 | transition: all 0.5s 0.2s;
120 |
121 | &__list {
122 | list-style: none;
123 | }
124 |
125 | &__field {
126 | cursor: pointer;
127 | padding: 0 4rem;
128 |
129 | display: flex;
130 | align-items: center;
131 | height: 100%;
132 | transition: all 0.3s;
133 |
134 | &:hover {
135 | background-color: $color-grey-light-2;
136 | }
137 | }
138 |
139 | &:hover,
140 | .nav__btn--bookmarks:hover + & {
141 | visibility: visible;
142 | opacity: 1;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_preview.scss:
--------------------------------------------------------------------------------
1 | .preview {
2 | &__link {
3 | &:link,
4 | &:visited {
5 | display: flex;
6 | align-items: center;
7 | padding: 1.5rem 3.25rem;
8 | transition: all 0.3s;
9 | border-right: 1px solid #fff;
10 | text-decoration: none;
11 | }
12 |
13 | &:hover {
14 | background-color: $color-grey-light-1;
15 | transform: translateY(-2px);
16 | }
17 |
18 | &--active {
19 | background-color: $color-grey-light-1;
20 | }
21 | }
22 |
23 | &__fig {
24 | flex: 0 0 5.8rem;
25 | border-radius: 50%;
26 | overflow: hidden;
27 | height: 5.8rem;
28 | margin-right: 2rem;
29 | position: relative;
30 | backface-visibility: hidden;
31 |
32 | &::before {
33 | content: '';
34 | display: block;
35 | height: 100%;
36 | width: 100%;
37 | position: absolute;
38 | top: 0;
39 | left: 0;
40 | background-image: linear-gradient(
41 | to right bottom,
42 | $color-grad-1,
43 | $color-grad-2
44 | );
45 | opacity: 0.4;
46 | }
47 |
48 | img {
49 | display: block;
50 | width: 100%;
51 | height: 100%;
52 | object-fit: cover;
53 | transition: all 0.3s;
54 | }
55 | }
56 |
57 | &__data {
58 | display: grid;
59 | width: 100%;
60 | grid-template-columns: 1fr 2rem;
61 | row-gap: 0.1rem;
62 | align-items: center;
63 | }
64 |
65 | &__title {
66 | grid-column: 1/-1;
67 | font-size: 1.45rem;
68 | color: $color-primary;
69 | text-transform: uppercase;
70 | font-weight: 600;
71 |
72 | // This is how text is truncated!
73 | text-overflow: ellipsis;
74 | max-width: 25rem;
75 | white-space: nowrap;
76 | overflow: hidden;
77 | }
78 |
79 | &__publisher {
80 | font-size: 1.15rem;
81 | color: $color-grey-dark-2;
82 | text-transform: uppercase;
83 | font-weight: 600;
84 | }
85 |
86 | &__user-generated {
87 | background-color: darken($color-grey-light-2, 2%);
88 |
89 | display: flex;
90 | align-items: center;
91 | justify-content: center;
92 | height: 2rem;
93 | width: 2rem;
94 | border-radius: 10rem;
95 |
96 | margin-left: auto;
97 | margin-right: 1.75rem;
98 |
99 | svg {
100 | height: 1.2rem;
101 | width: 1.2rem;
102 | fill: $color-primary;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_recipe.scss:
--------------------------------------------------------------------------------
1 | .recipe {
2 | background-color: $color-grey-light-1;
3 |
4 | ///////////
5 | // FIGURE
6 | &__fig {
7 | height: 32rem;
8 | position: relative;
9 | // transform: scale(1.04) translateY(-1px);
10 | transform-origin: top;
11 |
12 | &::before {
13 | content: '';
14 | display: block;
15 | height: 100%;
16 | width: 100%;
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | background-image: linear-gradient(
21 | to right bottom,
22 | $color-grad-1,
23 | $color-grad-2
24 | );
25 | opacity: 0.6;
26 | }
27 | }
28 |
29 | &__img {
30 | width: 100%;
31 | display: block;
32 | height: 100%;
33 | object-fit: cover;
34 | }
35 |
36 | &__title {
37 | position: absolute;
38 | bottom: 0;
39 | left: 50%;
40 | transform: translate(-50%, 20%) skewY(-6deg);
41 | color: #fff;
42 | font-weight: 700;
43 | font-size: 3.25rem;
44 | text-transform: uppercase;
45 | width: 50%;
46 | line-height: 1.95;
47 | text-align: center;
48 |
49 | span {
50 | -webkit-box-decoration-break: clone;
51 | box-decoration-break: clone;
52 | padding: 1.3rem 2rem;
53 | background-image: linear-gradient(
54 | to right bottom,
55 | $color-grad-1,
56 | $color-grad-2
57 | );
58 | }
59 |
60 | @media only screen and (max-width: $bp-medium) {
61 | width: 70%;
62 | }
63 | }
64 |
65 | ///////////
66 | // DETAILS
67 | &__details {
68 | display: flex;
69 | align-items: center;
70 | padding: 7.5rem 8rem 3.5rem 8rem;
71 | }
72 |
73 | &__info {
74 | font-size: 1.65rem;
75 | text-transform: uppercase;
76 | display: flex;
77 | align-items: center;
78 |
79 | &:not(:last-child) {
80 | margin-right: 4.5rem;
81 | }
82 | }
83 |
84 | &__info-icon {
85 | height: 2.35rem;
86 | width: 2.35rem;
87 | fill: $color-primary;
88 | margin-right: 1.15rem;
89 | }
90 |
91 | &__info-data {
92 | margin-right: 0.5rem;
93 | font-weight: 700;
94 | }
95 |
96 | &__info-buttons {
97 | display: flex;
98 | margin-left: 1.6rem;
99 | transform: translateY(-1px);
100 | }
101 |
102 | &__user-generated {
103 | background-color: darken($color-grey-light-2, 2%);
104 |
105 | display: flex;
106 | align-items: center;
107 | justify-content: center;
108 | height: 4rem;
109 | width: 4rem;
110 | border-radius: 10rem;
111 |
112 | margin-left: auto;
113 | margin-right: 1.75rem;
114 |
115 | svg {
116 | height: 2.25rem;
117 | width: 2.25rem;
118 | fill: $color-primary;
119 | }
120 | }
121 |
122 | ///////////
123 | // INGREDIENTS
124 | &__ingredients {
125 | padding: 5rem 8rem;
126 | font-size: 1.6rem;
127 | line-height: 1.4;
128 | background-color: $color-grey-light-2;
129 | display: flex;
130 | flex-direction: column;
131 | align-items: center;
132 | }
133 |
134 | &__ingredient-list {
135 | display: grid;
136 | grid-template-columns: 1fr 1fr;
137 | gap: 2.5rem 3rem;
138 | list-style: none;
139 | }
140 |
141 | &__ingredient {
142 | display: flex;
143 | }
144 |
145 | &__icon {
146 | height: 2rem;
147 | width: 2rem;
148 | fill: $color-primary;
149 | margin-right: 1.1rem;
150 | flex: 0 0 auto;
151 | margin-top: 0.1rem;
152 | }
153 |
154 | &__quantity {
155 | margin-right: 0.5rem;
156 | flex: 0 0 auto;
157 | }
158 |
159 | ///////////
160 | // DIRECTIONS
161 | &__directions {
162 | padding: 5rem 10rem;
163 | padding-bottom: 5rem;
164 | display: flex;
165 | flex-direction: column;
166 | align-items: center;
167 | }
168 |
169 | &__directions-text {
170 | font-size: 1.7rem;
171 | text-align: center;
172 | margin-bottom: 3.5rem;
173 | color: $color-grey-dark-2;
174 | }
175 |
176 | &__publisher {
177 | font-weight: 700;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_searchResults.scss:
--------------------------------------------------------------------------------
1 | .search-results {
2 | padding: 3rem 0;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | .results {
8 | list-style: none;
9 | margin-bottom: 2rem;
10 | }
11 |
12 | .pagination {
13 | margin-top: auto;
14 | padding: 0 3.5rem;
15 |
16 | &::after {
17 | content: '';
18 | display: table;
19 | clear: both;
20 | }
21 |
22 | &__btn {
23 | &--prev {
24 | float: left;
25 | }
26 | &--next {
27 | float: right;
28 | }
29 | }
30 | }
31 |
32 | .copyright {
33 | color: $color-grey-dark-2;
34 | font-size: 1.2rem;
35 | padding: 0 3.5rem;
36 | margin-top: 4rem;
37 |
38 | .twitter-link:link,
39 | .twitter-link:visited {
40 | color: $color-grey-dark-2;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/_upload.scss:
--------------------------------------------------------------------------------
1 | .add-recipe-window {
2 | position: fixed;
3 | top: 50%;
4 | left: 50%;
5 | transform: translate(-50%, -50%);
6 | width: 100rem;
7 | background-color: white;
8 | border-radius: 9px;
9 |
10 | padding: 5rem 6rem;
11 | box-shadow: 0 4rem 6rem rgba(0, 0, 0, 0.25);
12 | z-index: 1000;
13 | transition: all 0.5s;
14 |
15 | .btn--close-modal {
16 | font-family: inherit;
17 | color: inherit;
18 | position: absolute;
19 | top: 0.5rem;
20 | right: 1.6rem;
21 | font-size: 3.5rem;
22 | cursor: pointer;
23 | border: none;
24 | background: none;
25 | }
26 | }
27 |
28 | .overlay {
29 | position: fixed;
30 | top: 0;
31 | left: 0;
32 | width: 100%;
33 | height: 100%;
34 | background-color: rgba(0, 0, 0, 0.4);
35 | backdrop-filter: blur(4px);
36 | z-index: 100;
37 | transition: all 0.5s;
38 | }
39 |
40 | .hidden {
41 | visibility: hidden;
42 | opacity: 0;
43 | }
44 |
45 | .upload {
46 | display: grid;
47 | grid-template-columns: 1fr 1fr;
48 | gap: 4rem 6rem;
49 |
50 | &__column {
51 | display: grid;
52 | grid-template-columns: 1fr 2.8fr;
53 | align-items: center;
54 | gap: 1.5rem;
55 |
56 | & label {
57 | font-size: 1.5rem;
58 | font-weight: 600;
59 | color: inherit;
60 | }
61 |
62 | & input {
63 | font-size: 1.5rem;
64 | padding: 0.8rem 1rem;
65 | border: 1px solid #ddd;
66 | border-radius: 0.5rem;
67 | transition: all 0.2s;
68 |
69 | &::placeholder {
70 | color: $color-grey-light-3;
71 | }
72 |
73 | &:focus {
74 | outline: none;
75 | border: 1px solid $color-primary;
76 | background-color: $color-grey-light-1;
77 | }
78 | }
79 |
80 | & button {
81 | grid-column: 1 / span 2;
82 | justify-self: center;
83 | margin-top: 1rem;
84 | }
85 | }
86 |
87 | &__heading {
88 | font-size: 2.25rem;
89 | font-weight: 700;
90 | text-transform: uppercase;
91 | margin-bottom: 1rem;
92 | grid-column: 1/-1;
93 | }
94 |
95 | &__btn {
96 | grid-column: 1 / -1;
97 | justify-self: center;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/18-forkify/starter/src/sass/main.scss:
--------------------------------------------------------------------------------
1 | @import 'base';
2 | @import 'components';
3 | @import 'header';
4 | @import 'preview';
5 | @import 'searchResults';
6 | @import 'recipe';
7 | @import 'upload';
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Course Material and FAQ for my Complete JavaScript Course
2 |
3 | This repo contains starter files and final code for all sections and projects contained in the course.
4 |
5 | Use starter code to start each section, and **final code to compare it with your own code whenever something doesn't work**!
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 entire code, hit the green button saying "Code", and then choose the "Download ZIP" option. If you can't see the button (on mobile), use [this link](https://github.com/jonasschmedtmann/complete-javascript-course/archive/master.zip) instead.
14 |
15 | ### Q2: I'm looking for the old course version (v1) files. Where can I find them?
16 |
17 | **A:** They are in this same repo, but in the [v1 branch](https://github.com/jonasschmedtmann/complete-javascript-course/tree/v1). So just go to [v1](https://github.com/jonasschmedtmann/complete-javascript-course/tree/v1), and download the code from there.
18 |
19 | ### Q3: I'm stuck! Where do I get help?
20 |
21 | **A:** Have you actually tried to fix the problem on your own? Have you compared your code to the final code? If you failed fixing your problem, please **post a detailed 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 there. Please don't send me a personal message or email to fix coding problems.
22 |
23 | ### Q4: What VSCode theme are you using?
24 |
25 | **A:** I use Monokai Pro for all my coding and course production. It's a paid theme (I', **not** affiliated with them), but you can actually use the free demo version forever 😅
26 |
27 | ### Q5: Can I see a final version of the course projects?
28 |
29 | **A:** Sure! Here you go:
30 |
31 | - [Pig Game](https://pig-game-v2.netlify.app) (DOM Manipulation)
32 | - [Bankist](https://bankist.netlify.app/) (Arrays, Numbers, Dates, Timers. Fake "log in" with user `js` and PIN `1111`)
33 | - [Bankist Site](https://bankist-dom.netlify.app/) (Advanced DOM and Events)
34 | - [Mapty](https://mapty.netlify.app/) (OOP, Geolocation, Project planning)
35 | - [forkify](https://forkify-v2.netlify.app/) (Final advanced project)
36 |
37 | ### Q6: Videos don't load, can you fix it?
38 |
39 | **A:** Unfortunately, there is nothing I can do about it. The course is hosted on Udemy, and sometimes they have technical issues like this. Please just come back a bit later or [contact their support team](https://support.udemy.com/hc/en-us).
40 |
41 | ### Q7: Videos are blurred / have low quality, can you fix it?
42 |
43 | **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).
44 |
45 | ### Q8: Are the videos downloadable?
46 |
47 | **A:** Yes! I made all videos downloadable from Udemy 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. Videos have to be downloaded individually.
48 |
49 | ### Q9: I want to put these projects in my portfolio. Is that allowed?
50 |
51 | **A:** Absolutely! Just make sure you actually built them yourself by following the course, and that you understand what you did. What is **not allowed** is that you create your own course/videos/articles based on this course's content!
52 |
53 | ### Q10: You mentioned your resources page. Where can I find it?
54 |
55 | **A:** It's on my website at . You can subscribe for updates 😉
56 |
57 | ### Q11: I love your courses and want to get updates on new courses. How?
58 |
59 | **A:** First, you can subscribe to my email list [at my website](http://codingheroes.io/resources). Plus, I make important announcements on twitter [@jonasschmedtman](https://twitter.com/jonasschmedtman), so you should definitely follow me there 🔥
60 |
61 | ### Q12: How do I get my certificate of completion?
62 |
63 | **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).
64 |
65 | ### Q13: Can you add subtitles in my language?
66 |
67 | **A:** No. I provide professional English captions, but Udemy is responsible for subtitles in all other languages (automatic translations). So please [contact the Udemy support team](https://support.udemy.com/hc/en-us) to request your own language.
68 |
69 | ### Q14: Do you accept pull requests?
70 |
71 | **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.
72 |
--------------------------------------------------------------------------------