Improve your web development skills by building 19 different projects. In this course, you will use HTML, CSS, and JavaScript to make all sorts of web sites.
Course created by @codesistency
Full Course On Udemy: https://dub.sh/udemy-launch
Source Code: https://github.com/burakorkmez/html-css-js-projects
Diagrams: https://app.eraser.io/workspace/8yoDl1tVoPcljUboujq2
Github Gist: https://gist.github.com/burakorkmez/eca0903f564dbe545a742ce1056f6936
⭐️ Contents ⭐️
00:00:00 Course Introduction & Welcome
00:03:09 Setting up the Workspace (VS Code & Extensions)
00:09:57 Project 1: Interactive Quiz Game
01:08:24 Project 2: Random Color Palette Generator
01:48:49 Project 3: Kanban Board (HTML Drag & Drop API)
02:12:20 Project 4: Expense Tracker with Local Storage
03:07:36 Project 5: Bookmark Saver Application
03:30:36 Project 6: Registration Form Validator
04:02:32 Project 7: Password Generator with Strength Meter
05:00:39 Project 8: Functional To-Do App with Filtering
05:59:17 Project 9: Professional Contact Form (HTML/CSS)
06:24:35 Project 10: Modern Modern Pricing Cards
07:05:14 Project 11: Team Members Showcase Section
07:37:56 Project 12: Recipe Finder (MealDB API Integration)
08:29:19 Project 13: Real-Time Currency Converter
08:56:40 Project 14: GitHub User Finder (GitHub API)
09:45:39 Project 15: Custom 404 "Page Not Found" Design
09:52:11 Project 16: Newsletter Signup UI
10:05:31 Project 17: "Coming Soon" Page with Countdown Timer
11:01:21 Project 18: Contact Page UI with Form Validations
11:50:09 Project 19: Scroll Progress Indicator
Оглавление (21 сегментов)
Course Introduction & Welcome
Hone your skills in HTML, CSS, and JavaScript by building a bunch of realworld projects. In this course, Barack will teach you how to build web development projects, including UI components, games, API powered apps, and more. This course will help you understand HTML, CSS, and JavaScript at a deeper level. Welcome to 100 days of code with HTML, CSS, and JavaScript. a hands-on course where you will build real projects every single day using these core web technologies. By the end of this course, you will be confident enough to build your own projects from scratch because once you complete it, you won't just understand the concepts, but you will also have 100 completed projects to showcase on your resume. Some of the projects we'll build include an e-commerce shopping cart, a weightless UI, a QR code generator, OTP input fields, frequently asked question accordians, light and dark mode toggle, password visibility toggles, and much more. We will also create practical UI components like order history pages, progress steps, team member sections, star ratings, pricing cards, contact forms, credit card formatterers, and even a custom 404 page UI, and plus a ton of other real world applications. Now, this video that you are currently watching on YouTube is the first 12 hours of the course. You can find the full version on Udemy, and it's ridiculously cheap. I will leave a discount link in the description. And before you ask, let me answer the question. Yes, I'll still be making free courses. And if you want to support my work, you can purchase the course with the link in the description. If you want to see every single project included in this course, just scroll down to the core sections. You will find a one minute preview for each project so you know exactly what you will be building. This course is completely beginnerfriendly. I only expect you to know the basics of HTML, CSS, and JavaScript. Nothing advanced, just the basics. I'll walk you through every project step by step, explaining everything along the way, so you never feel lost. Some students have already tried a few of the projects from this course, and they absolutely love the experience, and I'm pretty confident that you will enjoy it, too. This course is perfect for anyone who wants to build daily projects, stay consistent with coding, develop strong front-end skills, and learn something new with every build. And if you're serious about learning to code, but you don't know what to build, this course give you a clear path and a solid starting point. It also comes with a 30-day money back guarantee. So, if for any reason you decide it's not for you, you can request a full refund within the first 30 days. Now, I could talk about these projects for hours and hours, but I'll just keep it short and I'll see you inside the course. I just wanted to let you know that recording this course took me a couple of months, but subscribing will take you literally a second.
Setting up the Workspace (VS Code & Extensions)
All right, so before we start coding, let's try to set up our workspace. In this tutorial, I'll be using VS Code as my code editor. If you would like to have the exact same workspace that I do, you can go ahead and install it if you don't have it already. So, just search for VS Code, click to the first link, and here you will see a big download button. Now, it doesn't really matter if you have Mac or Windows or Linux. This tutorial will work completely fine. In this case, I'm using Mac, but once again, if you have something other than Mac, that's completely fine. Okay, go ahead and install it now. Then you need to open this up. And here I'll just show you my exact same workspace. So first off, for every single project, we are going to have three empty files. So we're going to have the HTML file style. css as well as the script. js. We will always start from scratch like the content will be empty and I will walk you through it. Okay, so that's the first thing. Now in some projects, we are not going to have JavaScript. So in that case we wouldn't have this file right now. Let me walk you through the extensions that I have or the most important ones. So a lot of people ask me what theme that I use. So it looks this clean like the colors are looking very good. Let me just I don't know generate something. So for this color theme I am using Houston. It is free. You can go ahead and install it. Once you install that just say set color theme. Okay, click it and you should be good to go. Now, the other thing that I have is the live server extension. This is something that you should definitely have. Go ahead and install it. Now, what this does, let me pretty quickly display here. I have an empty Let me just delete this part. I have an empty index. html file. Right here, I'll put H1. I'll say hey. And I'll save. Now, we'll say open with live server. Now, when we go here, let me put them side by side. All right. So, I just have them side by side. Thanks to this extension, whenever you put something and save, it'll reload immediately. But if you don't open this up with the extension, whenever you update, every single time you have to come here and then reload it, which is not really convenient. So, that's one of the most important extensions. The other one that I'll be using in this course is the Google Fonts. Let's search it. I'll maximize the screen. Okay. Now, this is going to allow you to import Google fonts while being within the VSS code. So, once you install it, then you can come here. Let's say go after the title. You can press command shiftp. Okay. Command shift and P. If you're on Windows, this would be control. Go ahead and press that. You're going to get a pallet. Then here you can say Google fonts. Then we'll just select the insert link. So click to it. After a couple of seconds you're going to see all the fonts that we have in Google. So we can say something like popins, right? And this is going to install the font family. And we'll be using this a lot. This also work in CSS file. Let's go right here. I'll just give you an example. Once again, command shiftp. And we'll say Google fonts. this time insert uh you know insert as CSS import. You can get any font family. As you can tell it's going to import it. So this is something that we'll be doing time to time. For that reason I want you to install this extension. Now another important thing is the code formatting. So notice how if I add some extra spaces once I save it nicely predify my code. Right? For this, I'm using another extension called Pritier. It should be this one. I'll zoom out so you can see it clearly. Okay. So, go ahead, install that. Then scroll to the bottom and maybe copy this part. Okay. The very first line. Once you copy it, you can press command shiftp and you will say open user settings. Make sure you have, you know, the JSON right here. Okay. Go ahead and run this. you will get this file. Then you would like to paste it somewhere. It could be anywhere. Like I would say go at the very bottom and paste that line. Since I already have it, it is warning me, but you get the point. You're not going to have this. So just go ahead and paste and save this file. The other thing that we would like to do, pressing command shiftp, going under the settings. I'm sorry, we don't really need to go into the settings. So just stay in this file and here type this out. So I already have it. So you can again just have it at the very bottom. It's completely fine. Um type this out. Let me zoom in exactly in this way. So editor format on save and colon then make it to be equal to true. Now what this does is basically whenever you save right let's say once you save it's going to format it on save. Now, one of the other extensions that I'm using is called VS Code Great icons. Okay, so I'll just try to zoom out so that you can see it clearly. If you wanted to have the exact same icons that I have, like the folders look like this. I think it looks pretty cool. And this is the extension that I'm using. You can see the entire example right here. But yeah, once you install it, you just need to say set this as the file icon theme. And then of course you have to select it. One more extension that I'm using is called auto rename tag. Let's search for it. So it is this one. It's really handy. Let me display what that does. I'll zoom in. So here, let's say you have a P tag. You just have some content and then you decided to update it. So here you can just say, okay, this is going to be a span and it'll automatically update this part. If you don't have it, like if you don't have this extension, you have to copy this part and then paste it right here. Okay. So, let's say you decided to make this H6. It'll automatically update the closing tag as well. So, that's the beauty of it. I think these are all the extensions that I can mention at the moment. If you have any questions about the extensions, just let me know under the comments or the questions section. I'll just be there to help you out. All right, so that was the workspace setup. If you encounter any kind of issues, just let us know in the questions part. All right, so let's get started. In this
Project 1: Interactive Quiz Game
section, we're going to build a quiz game. And before we jump into the code, I'd like to show you the end result so that you know what you're going to have at the end of the section. So this is the UI that you're going to get when you first visit the application. We have a button where we can start the quiz. I'll just click it. The UI will be updated. We got a question and how many questions we have in total and what is our score as well as a progress bar. So let's go ahead and answer some of these questions correctly and some of them incorrectly. So here we go. We got different feedback depending on our answer. Right. So let's try to complete it. Okay. Now once we are done with it, we are going to get a feedback as well as how many correct answers we have. Depending on the answer, we will have a different feedback. So if this was five out of five, you would get something like perfect, you're a genius, something like that. And if you got like one out of five, it would say keep studying, you'll get better, and you can just restart the quiz. So this is the end result. This is what we're going to have. Now let's just jump into the code. So, I just have an empty folder in my VS Code. This is the name that I came up with. Quiz-ash game. You can call this anything. Just go ahead and open this up. Now, we're going to have two I mean three different files. I'll say index. html. Let's create style. CSS as well as the script. js file. These are the convention names. You can't really call them anything but most of the time this is what we're going to call them right all right so the first thing we'll be doing get started with HTML then we're going to put the styling and finally we will put the JavaScript to make it functionally work right so let's go into the index html and I can just zoom in shrink the left hand side and just get the boiler plate code with this exclamation point with VS Code all right let's just put the title Let's say quiz game. And then we can link our CSS file, right? We can say link colon CSS. Here we go. If your file name was something like styles, let me put styles. CSS, then you would come here and update it. But if you go with the style, this is the benefit in VS Code, right? If you just say link CSS, it is the correct name. Okay. So this is one thing that I'd like to mention at the beginning. Now we'll go ahead and build the uh HTML part right the markup. So I'll go ahead just right inside the body I'll say I'll have a dev that will be my container. So I'll say class container and then the other thing we would like to have is the start screen. Now let me display pretty quickly. When you refresh, this is the start screen, right? When you say start quiz, the start screen will just disappear. And this is what we call the quiz screen. So, we're going to build two different divs for them. I'll say one div. And let's duplicate this. Give a little bit space. This is going to be the start screen. I'll say class. It will take the class name of screen. And initially, this will be the active. And then let's put a uh put an ID so that we can select it in our JavaScript file. I'll say start dash screen. You can call this anything but I would say just follow along with me. Just do whatever I do like at least until you complete the project. Once you are done with it, you can go ahead update anything. Uh just customize the project, make it your own. But if you are following along, just go with me so that we can have the exact same output and you don't really encounter any problems. All right. Now, the first thing we would like to have is the H1. I'd like to just put them side by side. Um, let me take this if I can take that correctly. Okay, for some reason I can't. Okay, here we go. And I would like to run this demo application. So, this is the end result. But the one that we have, I'll just say open with live server. It should be right here. Here we go. Now, I got some warnings because I am already running the demo application, but that's fine. Now, we don't have any content at the moment, but let's go ahead and get started with it. The first thing we would like to put is this H1 that says quiz time. So, right inside this start screen, I'll have an H1 where I'll say quiz time and exclamation point. Right after this, we'll say P tag and we can put this text. Let me copy and paste. We can type this out. And this should be the output. We're going to add styling just to make it nice. And finally, we'll have a button. Let's say start quiz. And this will take an ID. Let's say start banan. Okay. Now let's build the other screen which is the quiz screen. Right. I'd like to maybe just shrink this a little bit more. Okay. So this is the one that we're going to build for the quiz screen. Let's say class of screen and we'll say ID will be quiz dash screen. Let's put the markup. So I'll have a div. This will be the quiz header that we have. I'll say class quiz dash header and we'll say it'll have an h2 that will have an ID. Let's say question text and we'll say question goes here. So we can put really anything here because we will update this. We will update this value whenever we got a next question. Right? As you can tell, this will be updated with JavaScript here. We can see every single time this will be something else. So I'll just say question goes here. And then we'll go ahead say div that will get the quiz info. So I'll say class quiz dash info and then we can put something like P tag and we'll say question. So this is the part that we are trying to build. We'll say question and now as you can imagine this part is dynamic. So when you select something it'll be updated. So we would like to have this as a span so that we can have an ID. I'll say current dash question and at the beginning it'll be one but we will be updating it whenever we go to the next question. Right? So for now we'll just start with one and then we'll say of um span. So once again we'll have another span because we will say questions. length. Maybe in your code you will add 10 different questions. So this will be dynamic depending on the length of the questions list right depending on the array. So for now just follow along with me. I promise everything will make sense once we just move forward with this project. All right, I can show you the entire screen. I'll just zoom out so that you can see everything in one line. Right after this P tag, we're going to put our score. Right, so I'll say give a little bit space. One more P tag and I'll say score. Now this part once again will be dynamic, right? So we'll say span. Uh, initially it'll be zero. And to be able to select it from our JavaScript code, we'll say ID of score. All right. So this is what we'll have for this span. So I would like to save my code. Right after the quiz header, I'd like to put an answer container. So this is that container here. We can see we have a bunch of different answers and we don't really know what are going to be the answers because if you take a look at it, whenever the question changes, we got different answers, right? So this will be dynamic coming from our JavaScript code. That's why we're going to leave the content empty. So let's see what I mean. We'll have a div. Let me zoom in. So we have the div. We'll say id of let's say answers container. And this will take the class name of the exact same thing. Let's say answers container. So we'll use the class to give some styling. And we'll use the ID to be able to select that query selector. Right now I'll just put a comment here. I'll say answer buttons will be inserted here from our JavaScript code later at some point. Okay, so this is what we're going to have for the answers container just an empty div. Then we can put the progress bar. I'll say div. Let's say class of progress dashbar and we'll go within this div. We'll have one more div with the let's say ID of progress and class of progress just like that the content will be empty. We will calculate it depending on where we are. Right? Okay. Now let's save. This is what we'll have. And finally we're going to have the result screen. Right. Let me just pretty quickly complete this. Okay. So this is the result screen that we're going to have. uh right after the progress bar as well as this div which is our container for the quiz screen right we'll have one more screen let's say div this is the very last one and we'll say id will be result dash screen and at the beginning of this tutorial I said we're going to have two screens but my bad turns out we are going to have three different screens the quiz screen result screen as well as the start screen right okay once again. My bad. Let me just zoom in. This will have the class name of screen as well. And if you say active on this one, which is what we're going to be doing once we complete the project, this is what you would see. But initially, this will not be the active. Then we can have an H1. Let's say quiz results. Then we're going to have this text, this one, and then the button. I'll just say div name of result dash info will have a p tag let's say you scored in the span because this will be dynamic let's say initially it'll be zero and then ID of final score within this p tag but outside of the span we'll say out of I'll just zoom out so that you can see it clearly we'll put another span let's say this will take the id of maximum score and we can say something like five and right after this p tag we would like to put the result message so I'll just say dev let's take the ID of result dash message and for now we can say something like good job but depending on your performance you'll see something else right and we're going to put this in our JavaScript code I'll say Good job. Then finally, I think that's it. Uh the only thing we left is this button. So right after this result message and this div which is the result info, just go outside and say button ID of restart btn and we'll say restart quiz. Okay, so believe it or not, this is the entire markup that we need to put have. Now, we'll just jump into the CSS file and get started with the styling. So, I'll just visit the CSS file that we have and let's get started with the basic reset. So, I'll say basic reset that we're going to have in almost every single project. So, the first thing you would like to do just say asterisk and then say margin of zero on every single element. Same thing for the padding. And then finally, and the most important one is the box sizing of border box. So I assume that everyone knows this, but just in case some of you guys don't know this, I'd like to explain pretty quickly. If you know this properly, you can just skip couple of seconds or even minutes. Okay, so I just have a diagram that we're going to go through. And this is the end result screenshots that if you wanted to have the link of this diagram will be in the description. Okay, now let's take a look at the box sizing of border box. So what this does in the first place, it changes how the browser calculates an element's total width and height. Now what happens if you don't use this, right? So let's say you don't have this in your code. Okay, this is what'll happen. Let's say you would like to have a div with 100 pixels wide but you have added some paddings such as 10 pixels horizontally from the left hand side and right hand side. Now what'll happen is this browser will say all right you wanted to have 100 pixels but now you have added 10 pixels from the right and from the left. Okay so we got 10 and 10 more. Now, in total, we have 120 pixels, which is something that we don't really want. At first, we said, "Hey, dude, we want 100 pixels wide. " But now, we have 120 pixels, which is something that is unexpected and that we don't really want and need, right? What we want is this one. We would like to say, okay, let's go ahead use the box sizing of border box. So, this is the example. if you use it. I'd like to just copy this or maybe do Ctrl + Z a little bit. Okay. So, this is what will happen. We have 100 pixels wide and we would like to add some paddings from the right hand side and left hand side. They will be added. So, we got padding from the right and left. They're equal to 10 pixels. Now the rest is going to be 80 pixels because in total we have 100 pixels. And now if you take a look at this at the end of the day you still have 100 pixels wide depth. And this is something that you would like to have 99% of the time. Trust me, you don't really ever want to have the other case where width changes because just imagine you came here in your code, right? You said I want this div to be width of 100 pixels and you write some more CSS properties and then you said all right padding is going to be let's say 20 pixels and then now the width has changed because you didn't use this property and this is something really common if you like if you have ever got unexpected results you would know that it is because of this property I hope that makes sense. At the beginning, it kind of feels complicated, but at the end of the day, it just changes how the browser calculates an element's total width and height. All right, so I'll just leave the example here. You can watch this again if you don't really understand it or you can do some quick research. Just try to play around with it until it makes sense. Okay, now with this in mind, let's move on with our styling. This is something that I wanted to explain just before we continue because this is the most important thing I think. Let's say body we're going to put the background color. This will be a custom color like F5 EF6 just like this one. And then we can say display of flex we'll say justify content center. And notice how I am using shortcuts. So I'll just say J CC and it should be completed. Same for the item uh let's say align item centers or center I should say a C. Then we can say minimum height of 100 VH and we can put the end result just next to it. Okay. So this is what we have at the moment. Let's say we would like to add padding from all directions of one rem. And then let's change the font to family to be sans serif. Let's save. This is what we got. Now we would like to update our container. I'll go ahead select this one and I'll say background color of let's say white. This is going to be for the container. We can add some border radiuses. Let's say one ram. And then we can give some box shadow. I'll say zero. We'll say 10 pixels. 30 pixels. And then we can add an RGBA color. Let's say zero. And it'll be basically black. But we're going to change the alpha value. So I'll just say 0. 1, which stands for 0. 1. If you wanted to, you can um change this. Let's say like 0. 7. It is a lot more dark, but I think it doesn't really look nice. This one is a lot better. It is just subtle, but if you wanted to, you can update it. Then we can say something like width of 100% but the maximum width will be 600 pixels. Just like that. And then we'll say overflow of hidden. Finally we'll say position relative. All right. Now we'll go ahead and just build our screens. We'll put some comments. Let's say screens. We'll have the screen class that will be display of none for all of them because we will add the active just in a second. Let's say petting of twom and then text align of center. Now everything will be disappear. Let's comment this. Okay, this is what we're going to have only if we have the active class. So we'll say if screen has the active class we'll say display of block here we can see and if you take a look at the HTML code we have the active class let's see on start screen if you cut it from here and put it onto the quiz screen here we can see now this is active so I hope that makes sense but initially the start screen should be active and by the way I have an additional folder. It's because uh I am running the end result as well as this demo application. They are both on a different port. VS Code just added this. If you don't have it, it's not really important. It is just a configuration file that I'll delete at the end of the section. All right. Now, let's go into the CSS file and keep building our styles here. I'll go ahead and just add the start screen. Okay, I'll select this start screen. Let's go ahead select the ID. I'll say H1 and we can say color of let's say E86 A33 and I'll say margin bottom of 20 pixels. Then we can say font size of 2. 5mm. Okay, let's see if this is what we got. This should be active on the start screen. Okay, I have a typo. That's why it did not work. Here we go. Now, it has been updated. Now, let's move on. I'll just go at the very bottom. I'll have the quiz screen. So, I'll say dot quiz-ash header. We'll say it'll be margin bottom of 30 pixels or you can go with two twom. It should be the similar values. And then we'll say question dash text. We can add some more styling to the colors like 333. And then we'll say font size of 1. 5 RM. Let's say margin bottom of 1 RM. And finally line height. Let's just increase it by 1. 4. And then we can say update the quiz info. I'll say quiz dash info. We'll go ahead say display flex. And you can always take a look at the end result just by going in into the diagrams. Okay, so we're going to be building the quiz info which is this part I believe. Right, we have something on the left, something on the right, etc. And we'll say display flex. Let's say justify content. Now it's going to be not center but instead space between because we have something on the right. I mean something on the left and something on the right. So they should be space between. We'll say space between. Let's give the color of six six. Then finally we'll say font size of 1mm. Do we really need it? I think we don't really need this. By default it is 1M. And finally we'll just say margin bottom of something like 10 pixels. All right let's save. And then we'll go ahead update the answers container. Okay. So right here I'll have display of flex but this time it'll be flex direction of column because as we can see we have something at the top right and then it is just going in the column direction. Then we'll go ahead say gap of 10 pixels. Finally margin bottom of 25 pixels let's say. Then we can put the answer button. So every single one of these that you see, let me change the color pretty quickly. So this is an answer button. button, right? Every one of them is an answer button. So let's go ahead and build it. I'll say dot answer dash btn. This is the class that we had. Now we'll just say background color of this custom color F8 F0 and E5. Then we'll go ahead update the color itself. Let's say it'll be 333. Then let's update the border. I'll say 2 pixels in the solid and color of E A D BC8. All right, we'll go ahead say border radius. Here we can see they have some rounded corners. So we can say 10 pixels. And then we'll give some padding. Let's say just one. And then font size. I'm sorry. Let's say cursor will be pointer. Then we can say something like text align left. And when we hover over this, we want the color change. So I'll go ahead say restart the quiz. Here we can see the background changes. So we can say something like answer btn hover and we'll say uh let's say background color will be updated to this value. I'll say e a d bc but it'll be eight this time and then we'll say border color will also be updated. We can say border color this will be d a c 0 a e. And let's actually take a look at what we have. So currently we cannot see that part because we don't really have the answers, right? anything in the markup. This would be inserted. So we cannot really test it out. But we can take a look at the end result. And I want this transition to be like smooth. As you can tell right here, it just slides the uh slowly fades in. So we can go ahead and add it right here. I'll say transition will be on everything. Let's say all and it'll be 0 3 seconds. And we can say the e is function. Okay. Then we can change the correct and incorrect styles. I'll go ahead say answer button dot correct. So if it is correct, we're going to get this green feedback. I'll say background color. It'll be this one E6 FF and zero. So it is kind of like greenish color. And then we'll have border color. It'll be something different like A 3F 0 C 4. Finally the color itself. It'll be 28 A745. Now let's duplicate this. Basically I'll select everything. Duplicate this. But this time it'll be incorrect. And for the colors, please feel free to go ahead pause the video, type this out. This is what I'll be doing. Just copy and paste. And then we can move forward with the progress bar here. I'll go ahead say select the class and we can give it a height like 10 pixels. Then we can say background color of let's say F8, F0 and E5. And this should have the hash at the beginning. Then we'll say border radius of 5 pixels. It is just a little bit subtle as you can tell. Then we'll say overflow of hidden. Finally, we can give some margin top of something like let's say 20 pixels. And then we'll just get the progress itself. So one of them is the container, right? This is the container and this is the progress itself. I hope that makes sense. We'll say the height will be 100%. So it'll just fill the container. Then we can say background color will be something like this value E8. Do we have it already? Okay, it is this one. As you can tell, we have used it previously in this button and in the title here. I'll go ahead say width of this. Initially, it'll be 0%. Right? When you first start the quiz, you don't really see it. It is width of zero. And as we move forward, as we select something, it'll just get incremented dynamically from our JavaScript code. Then we can add some transition like transition will be implemented on the width. Let's say 0. 3 seconds and ease. You can give one of them, but I'll just go with this one. Then we can finally add the results screen, which is going to look like this here. Let's go ahead select that one. And maybe I can add a comment like result screen and just scroll a little bit to give some space here. I'll just select my uh let's say ID. I was going to say class but it's an ID. We'll say result dash screen and we'll select the H1. So I'll give the color this classic color that we have. And then we'll say margin bottom of 30 pixels. Then we can select the result dash info here. I'll go ahead say background color will be this value. So it is f8 f0 e5 and we'll say border radius of 10 pixels. We'll give padding of 20 pixels and finally margin bottom of 30 pixels. Then we can select the p tag itself. Here I'll say result info and p element. We'll say it'll have the font size of 1. 2 RM. We can give the color which is going to be 333. And finally margin bottom of one rim let's say. And then we can select the result message itself which is this one. Right? We got the P, we got the H1. Now it is time to get the result message itself. I will select it with the ID. So this is the font size. The font weight it'll be a bit bold. Right? And then the color itself now we can change the button itself in general. Right? We can say just select the button elements. We'll say background color will be the primary color that we have so far. Then we can give the color itself to be white. And we can say border will be none. Border radius will be 10 pixels so that they are rounded. And then we can say padding will be 15 pixels as well as 30 pixels. Then we can say font size of 1. 1m. We'll just increment it a little bit. We'll say cursor will be pointer just like this. And finally we can add some transitions. So first I'll save. Take a look at the end result. This is what we have right. Uh when you hover over this nothing happens. So we can say button on hover state. We're going to change the background color. It'll be D4 5 B as well as 28. But there is no any transition. So we can go ahead add the transition on the background color just like what we have done previously. So now if you take a look at it, there is a transition. I think we are missing the margin top or margin bottom from this text. So let's see if I have a typo. Then we can fix it. It should be in the start screen. So we are just missing this P tag margin bottom. And here is where it comes from. I'll just add this five lines of code. We selected the P tag under the start screen. We added some margin bottom and some other styling like color and font size. Let's save. Here we go. Now it has been updated. And just before we jump into the JavaScript file, what I'd like to do just scroll to the very bottom and add some media queries so that our application is responsive. Let's take a look at the end result. So I'll just try to refresh my page and try to open up the dev tools. So whenever we hit 500 pixels, just take a look at this. the UI will just change a little bit. So everything will shrink as you can tell. Let's take a look at the quiz screen once I hit 500 pixels. Everything just shrinks a bit so that it is responsive and it is looking nice in our mobile phone. So this is what we'd like to do. Just update some stuff whenever we hit 500 pixels and below. So I'll just say responsive design and we'll say add media. Then we can say something like maximum width of 500 pixels. So this will basically tell to the browser whenever we hit so let me type when we hit 500 pixels and below go ahead and just implement the styles below. Okay. So, I hope that makes sense. Let's try to get started with it. The first thing we would like to do just maybe update the uh padding on the screen. So, I'll just say we have the screen. We would like to change the petting to be something like let's see what we had previously. I don't really remember. Let's take a look at it. Okay. So, padding is two RAM. By default, it is equal to 32 pixels. So we can basically shrink this to health. So I'll just say 1 RM, right? Then we can change the font size of the H1. So I'll just say start screen H1. It should be font size of let's say 2M. What it was at the beginning? Did we update it? Okay. So it was 2. 5 and we'll just update it to two, right? Two RM. And then I'll add a couple of more things that is not really hard. That's just super simple. This is what I have added the question text answer button and the button itself. Now let's save and try to see. So this is our application. When we hit 500 pixels, it just changes a bit, right? Okay. You can pause the video, change anything that you wish, but these are the values that I'll have. Now that we have the styling as well as the markup, we are ready to get started with the JavaScript file. Now, before we write anything here, we would like to link this file from our index. html file. So, just right above the body, I'll say script and select this source option. We'll just say script. js. Okay. Now this file is linked to our website and that means we can go ahead and get started with it. So the first thing we would like to do select our dome elements. So I'll go ahead add a comment and we'll have bunch of different selectors. Let's say the first one will be start screen that will be document getelement by id and then the ID was start dash screen. I'll duplicate this. will have another one. This will be for quiz screen. I'll basically uh select this part. Press command D or control D. Let's say this is the quiz screen. Now we'll have bunch of different elements and if you don't want to type them out, I have prepared a GitHub gest that you can find. The link will be in the description completely free. Okay. So this is what we have. Just find the quiz project. MD and you can copy this entire selectors. So I'll get into this just in a second. For now, this is what you need to copy and paste. I'll basically delete everything and paste this in. So we selected everything. This will save us a lot of time. We basically have the screens. Let's say we have the button, the question text, answer container, and all the elements that we'll be using. And then we're going to create an array of quiz questions. So, as you can tell, like I can copy and paste. No need to type this out from scratch. Okay, let's just paste this in and I'll walk you through it. And also, let's take a look at the end result. So, we have five different questions, right? First, we have an array that has five different objects. They all has the same fields. They have a question, which is the question itself, right? And then a list of answers. And each answer has a text as well as if it is the correct answer or not. So in this question the Paris is the correct answer. Right? So that's why we said this is true the others are false. And depending on this field we will give this kind of an uh feedback. So I hope that makes sense. You can add a lot more questions but for now I'll keep it simple. Just have only five different questions. Okay. Now we can shrink this list and just scroll to the bottom get started with our variables. So I'll just say quiz state bars and we'll have three different variables. So I'll say let current question index at the beginning once you start the application you will start from the very first question that's why you will say zero and we'll say let score which will be equal to zero at the beginning and answers disabled boolean which will be equal to false. Now why do we have this field? It's because let's say you click to this answer and you immediately click to it again. You don't really want the score to be incremented, right? When you first click to it, it'll be disabled until we get the next question. Really important field that we should have. And then we can now uh like update our question and total counters. So what do I mean? Let's say total questions span. This is the element that we just selected right here. We will go ahead select this and we'll say the text content will be equal to quiz questions. length. So this is what I have explained previously. Let me go ahead and save and if we say start quiz nothing happens but we will just see this in a second. Now I'll also say the maximum score span will be equal to text content of quiz questions dotlength. Okay, we'll just see these two different lines what they do in a second. Then we can add our event listeners. Let's say start button dot add event listener. Right? Once we click to it, we would like to do something which will be the start quiz method. Let's go ahead and create it. We'll say function called start quiz. For now, we'll just leave it empty. Or you know what? Let's actually say console log quiz started. And let's duplicate this one. And this time it'll be for the reset restart button. Sorry. We'll say click restart the quiz. And this will be another function that we'll just build. So we can duplicate this one and say restart quiz. Okay. Now let's open up the terminal. I'll just click to this one. Okay. What do we have? It says text content. Where do we have? Do we have a typo? Let's see. So I think we have some kind of typo because one of these is equal to undefined. So let's take a look at this. It is called total questions. I'd like to open up my index. html file. Do I have any typo? Let's say total questions. And looks like I don't even have this field. Now let's see what are we missing. So right here when we said one of it should be five, but we'll add this ID that says total questions. Okay, just go ahead add this field. We forgot to add that. But now we should be good to go. I'll click to this button. It'll say quiz started. Right. Okay. Now that we have the methods, we can I think just start building them. So the first thing we would like to do, let me first zoom in. Once we start the quiz, we would like to just reset our variables. So here I'll say reset bars and we'll say the current question index will be equal to zero because we are just starting the quiz. Score will be equal to zero. And we will just update that span. Let's say scores span dot text content will be equal to the score variable which is equal to zero. You can also put zero like this but I think this is yes let's actually do it here. I'll just say zero. Okay. Now let's move on. We will say start screen dotclass list dot remove the active class because we just started the quiz. We would like to make the quiz screen to be active. Here I'll say go ahead select the quiz screen and add a class list of active. I'll just save and test this out. I'll click to this one. Here we can see now this is active. the other one is not active. Okay, then we would like to say something like show question. So we're going to show one question at a time and we can put it into this function. So let's copy the name and create a function right here. Okay, once again we are going to reset the state that will be answers disabled of false because if we are going to show the question we would like to not disable the answers right here I'll go ahead get the current question so we'll say const current question and we can say something like quiz questions and we can add our index which is the current question index. We got the current question. Now we can update the question number right which is going to be this part. So here I'll say current question span dot text content we'll say whatever the current question index is plus one because this will start from zero we would like to say something like one. Okay. So this is the very first question. Instead of seeing zero, we'll just add one. I know that we are going really slowly, but I just really want to make sure that everyone understands whatever we do. Okay. Then the next thing is to update the progress bar. So first we need to get a percent. I'll say const progress percent. And let's try to calculate it. I'll say current question index divided by quiz questions dolength. I'll just zoom out multiplied by 100. So this is the math that will give you the percent correctly. Then we can say progress barstyle do width and we'll say whatever the percent is. This is what we have calculated. We'll say plus percent. Now imagine this is what we're doing. Let's say the percent is equal to 50. Now the width will be 50%, so it'll be something in middle right. This is exactly what we are doing. Then we can update the question text here. I'll go ahead to say question text dot text content will be equal to current question. ext I'm sorry the question itself because if you take a look at this array we have the field which is the question. It is this part right and this is exactly what we are doing. And after this, we can clear the previous answer buttons. So, I'll just say explain this in a second. Okay, I'll even add a to-do right here. I'll show you this what this does. But let's just write the code for now. I'll say answer container inner HTML will be equal to nothing. Then we can create the answer buttons, right? So, this is a button. So on and so forth. What do we want to do? Basically go through these questions. For every single answer, right? Right. For this answer, for this one, and all of these, we would like to create buttons. So, this is exactly what we'll be doing. Let's go ahead and say current question dot answers do for each answer, we would like to run this method where we would like to create a button. So let's say const button document dotcreateelement and maybe we should zoom in. I don't really know. Let's zoom in. Okay. We'll say create an element that is called as button. Right? Then we'll say button dot text content. We'll add the answer. ext such as like Venus, Mars, Jupiter, whatever that is. And then we'll go ahead say button dotcl class list dot add we would like to add this answer button so that we can get the styling and then one important thing we need to add the correct property on the button right so this is false this is true and these are false how do we add it if I click to it how my code knows that was the correct answer well we can use what we call a data set so here I'll say button data set dot correct and you can call this anything really like true but you know like anything seriously but it should be correct so that our code makes sense right this is at least what I'd like to call it and I'll say it is equal to answer correct so either it is true or false and only one of these buttons will be equal to true and I'd like to put a comment so I'll say what is data set. Now, basically, it is a property of the button element that allows you to store custom data. Okay? So, you would like to use a data set whenever you want to store some custom data. And this is exactly what we are doing. We are adding the true fields on a button. You can call this, you can use this on anything, not only on the button. Uh, but it is something to keep in mind. And I'd like to add a comment right here. It is something that you would like to use whenever you want to store some custom data. Okay. Now that we have added this field, we can add the click event into the answer itself. So when we click to it, something will happen. So we'll say button dot add event listener which is going to be the click event. We'll call the select answer method. This is something that we'll build. And finally we'll say add to container. Let's say um answer container dotappend child add the button. Now we have created the button did bunch of different things on it but we never add it to the UI. That's why we need this line to add it into the UI. All right. Now let's save. We need to create this method. Let's just scroll right above the restart function. I'll create this one. add it and just get started with it. Now when you attach an event listener by default it will get an argument called event. So we can take the event so that we know like so that we can do a bunch of different things and we're going to see what that is. Now as I said before when we click to an answer we should check if the answer is disabled or not. So we'll say if answer disabled is equal to true, we'd like to just return don't do anything. Otherwise, the score would be incremented in a way that we don't really need. So now that we check for it, this is something like an optimization check really. Then we can go ahead say answer disabled will be equal to true because we are just selecting an answer. and we'll say get the selected button. So I'll say const selected button. Now how do we know which one we clicked? Right? If I click to this one, how do we know this is the one that we clicked? This is how we can do. We'll say event. target. This will basically give you the selected button. And we can say const is correct. This will be a boolean. and it'll say select the button data set correct if it is equal to true. If this is the case that means it is correct. Now notice how this and this one is matching. So here if you said something like hello we should also say hello right they should match. So once we got the variable we would like to do something let me display. Now when we click to this one, we are getting some kind of a feedback. If you select the wrong answer, you get another feedback. So we would like to add a class that would update it. And this is exactly what we'll be doing. So I'll say array from and I'll explain why are we using it. We'll basically convert this into an array. I'll add a to-do explain this in a second. Okay, now that we got all of them, we'll say for each every single button, just run this method. We'll say if button dot data set dot correct if it is equal to true. In this case, we would like to say button. class list dot add just add the correct class. But else we would like to add the incorrect class. So I'll go ahead and just say add the incorrect class. Let's save. Right after this we would like to update the score if it is correct. So we'll say if is correct go ahead say score ++ which is equal to one and we'll say scores span. ext content is equal to score itself. Here we go. And just before we move on with the next question we would like to just wait a second. Right here we can see we have 1 second of delay right here and then we move on. And if you want to add some delays, you would use the set time out method, which would take a call back as well as the time out, which is going to be in milliseconds. So let's say we would like to wait about 1 second. So I'll put 1,00 milliseconds. And then we say current question index will be incremented. Then we'll say if current question index is less than quiz questions dolength. Now, what are we doing here? Let me add a comment. I'll say check if there are more questions or if the quiz is over because over, we're going to see this screen. But else we'll just show another question. So, if this is the case, that means we can show more questions. I'll just say call the show question method but else we'll just say show results which is another method that we need to create. So let's move on. We are almost like we are near to complete this file and I'll walk you through it from start till the end. Okay. So if we want to show the results, we need to first hide the quiz screen and show the results screen. So this is what we'll be doing. Let's say quiz screen dot class list. You would like to remove the active class and you would like to duplicate this. This time you would like to add the active class to the result screen just like this. Then we would like to update the final score text content to be the score itself. Then we'll go ahead say so we will say something like good effort or you're genius or you're really bad depending on the percentage right. So here I'd like to say get the percentage that will be equal to score divided by quiz questions dotlength multiplied by 100 and it'll say if this is equal to 100 then we can say something like uh perfect you're a genius but we'll add bunch of different else cases. So I'll say else if and instead of typing them out I just paste it here. We can see we have else if of 80% and above great job here 60 and above good effort all the way down to 40 and below. We'll just say keep studying. So this is really basic. That's why I didn't want to type this out. Let's leave the restart quiz functionality or let's just build it. It's really simple. Then we'll just test out our application here. Here I'll go ahead say something like result screen dot classist dot remove. It will just remove the active class. Then we can say start the quiz itself because we're just restarting it, right? Let's save and give it a go. I'll refresh my page and say start the quiz. Here we go. Let's put the correct answer. We can say something like again correct answer add the wrong answer this time. And there is one thing that is different from the end result. So if we select the correct answer the wrong ones are also displayed. So we can fix it by scrolling to the top where we have this else case here. I'll say else if the button is equal to select a button only then we would like to do this actually. Now, let's save and give it a go. I'll put the wrong answer. We don't really see the wrong on all of them. I think it just makes it a lot more cleaner. Let's put the wrong one. Okay. Now, we have some to-dos. Just before we get into it, let's complete the app, complete the quiz. Okay, we can restart it. Everything works as expected. Now, let's take a look at the to-dos that we have. So I will just go ahead delete this for a second and try to run my quiz. Give it an answer. Now in the next run as you can tell the previous answers did not got removed right we got the new answers but the previous ones are still here. So that's why whenever we show the questions we would like to first get rid of the previous questions. So we say the answer container will be equal to nothing. Right? Just go ahead clear the content. That was the very first to-do that we have. Now I can delete this to-do and the other to-do that we have. Let's just search for it. Okay. So we need to explain this array. Romero. Why do we need it in the first place? Now the short explanation is this is not an array. First we need to convert this to an array so that we can use dot for each method. But the longer answer is let me try to explain by displaying it. So I will copy this and whenever we start our quiz I'll just say console log this into the terminal. Okay let's open up our terminal and just try to see this in action. I'll say start the quiz. Now as you can tell this is an HTML collection and you cannot really say something like children do for each. I'll try to do it. I'll say, you know, get the element and say console log the element itself. Right now, if you take a look at it, we should get some errors because you cannot really use the for each method on it. But if you wrap this with array prompt just like this. Now this entire thing is an array. You can use for each on it. Let's save and take a look at it. Here we can see even though we got undefined but we didn't got any errors. That means it is working. So I would like to put a comment right here on this to-do. So I just deleted that to-do comment. And this is what you're going to have instead in the source code. And there is one thing that we are missing just before we end this section which is the progress bar. It's because I am missing like I am having a typo. This should be double s. So progress just like this. Now if we save hopefully it should be right here working properly. And the other thing that we have that is missing is the score variable. Now it is working correctly. But once we restart the game it is going to crash. So notice how we have three in this game. And if I say restart quiz and go with this one, now it is four. Well, the reason is when we said reset the variables here, I just said we are going to have the score that will be equal to zero. And then uh for some reason I have deleted that. So I don't know why I have done this, but this should be like this should be right here. So that when we start the quiz, it will be equal to zero. Now let's pretty quickly go over this once again. So we're going to have maybe three points once again. But if we restart the quiz and go with the correct answer, it should be one, not four. Right? So that's something to keep in mind. And with this, I think we just completed the entire project. Everything is working as expected. So with that, I'll see you in the next project. In this section, we're going to
Project 2: Random Color Palette Generator
build a color palette generator. And this is the end result. Let's take a look at it how that works. And then we'll just jump into the code and build the actual application. So when you first refresh the page, you will get a different color palette that you can copy either from the box itself or with the copy button and then you can generate a new palette like as much as you want. Every time you will get different colors. So with this in mind, let's go ahead and build our actual application. Okay. So once again I have an empty folder called color palette generator and I have three empty file right three empty files. So let's get started with the HTML. I'll get my boiler plate and let's say color palette generator as our title and then we can link our CSS file as well as the JavaScript file at the very end of the body. Maybe we can say source will be the script. js file. Okay. Now we'll go ahead and just get started with it. So the first thing I'd like to have is this container, right? It's a container which will be this white box that we can see. And then we'll just put the generate button. So we'll say button. Let's give it an ID like generate dashbtn. And then we'll say generate pallet. Okay. Now I'd like to have this icon right this fav icon on the left hand side. And how can we put this? So we're going to say something like let's have an i element that will have a class name of fas fa. We'll say sync alt. But if you save and try to see the output, let's say open with live server, we cannot see anything. It's because we didn't import the tab icon, right? So let's go ahead get the URL. I'll say cdnjs from this website. We can search for f want awesome. Okay, just go ahead copy the link tag and then we can paste it right here below to the title and we should be able to get this button as you can tell. Okay, now that we have the generate button, we would like to go below to it and we'll have another container. So, I'll say class um pallet dash container. And I think we forgot to add the H1 that will be above the button but still inside the container. I'll go ahead and just say H1 that will have the actually no class names. We'll just say color palette generator. All right. Then we'll go into the pallet container. We will just build our boxes. So as we can tell we have five different boxes, right? So let's try to build them. I'll say color box one. We'll have a div with the class name of color dashbox. Then we'll go within this div create another div with the class name of color. This will not have any content but we'll say style will be something like this. Background color of we can give the value. So you can choose any value that you wish. I'll just go with this default value. Let's say E1 F5 FE. Okay. So this is what we're going to have for the very first color. But we will be updating this whenever we say generate a new palette. So this will be a little bit later in the video. And then we'll say let's create another div that will have the class of let's say color dash info. Then we'll go ahead create a span that will hold the hex value and then an icon for the copy button. So this span will say this exact same value but uppercased. So I'll say E1 F5 FE. And let's give it a class. I'll say hex dash value. And now let's try to put this button which is going to be an i element class of f a r f a copy and we'll say uh just class name of copy button let's say copy btn okay now let's save take a look at the output this is what we got this is the actual icon that we just used right okay and we can even add a title so when you hover over this let's say title It'll say copy to clipboard. So this title will give something like this. Let me hover over that. Okay. So this is the title. This is that property that allows us to see that text. Now basically we're going to do the same thing four times. Right? At the end of the day we will have five different color boxes. So this is the very first one. I'll just try to maximize this screen and just put uh four different color boxes. So here is what I have just added the exact same thing but we have just changed the background color as well as the color itself in the hex value. So this is the second one that you can copy from the source code or just type this out. We have the same thing for this one for the uh you know the last two. And now we can go into the CSS file and try to build the UI because currently this looks disgusting and feels like I have a typo right here in this span especially for the color box of one. Okay, this should be okay. Just like that. Now we just get rid of that span text. Now we can go ahead and jump into the CSS file. So I'll just kill this one. Once again I have this extra folder. Maybe you have it, you don't have it. It's not really important. It just says we'll just change your port because you have the end result running on this port. So at the end of the section, I will go ahead and delete this folder. Okay. Now we can just get started with our CSS file. So the first thing I'd like to add will be the basic reset where we'd like to select every single element and say margin of zero and duplicate this. Do the same thing for padding. And finally, it'll say box sizing of border box. Now, one thing that I'd like to do is to update the font family in my entire document. Now, the classic way of doing it, I'll show you a better way. So, this is the classic way of doing it. You would just visit Google fonts, right? Let's say Google fonts. And then you would search for a font family. Let's say this robot robboto. How do we pronounce it? I don't know. So, we got this one. Then you would say get the font get the embed code and you would either get the link uh copy or the import copy. So for the CSS right let's say you would copy this and come back here add this then you can use it in your entire document. So you can say font family will be the one that we just uh installed. Now let's save it'll update the UI. Now you can install this without visiting the website. So you can do it from your VS code. The first thing you would like to do just install an extension called Googles. Okay. So go ahead and install it. Once you have done this, you can basically Oops. Let's just delete this part. You can basically say commandshiftp or control shiftp. Then you can search for Google fonts. And if you wanted to add it into your CSS file, you would select this one and then you would search for the font. So whatever that is in our case, let's say it is Robboto. Here we go. We got the entire URL that we can save and we're going to have the exact same result. So without this, it would not work. Just notice how the font family has changed. But if I add this, now we're using the Robboto. Right now I'd like to actually change this. Let's go ahead get something else. I'll say I'll get Poppins. Okay. Then we'll update this part. Now it is just changed a little bit more. And if this is not available for some reason, if we cannot load it, we can just fall back this with sans serif. So this is one trick that you can keep in mind. And if you're going to add it into the index. html, you can do it in the exact same way. So just under your hat element, right? So you can say command shiftp Google fonts but this time insert link let's say robboto. So this is what we got as a link import. I'll just delete that because we have it in the style. css file. So I hope this is a useful trick that you have just learned. Now let's go ahead and update our background color for the body which will be a linear gradient. So we'll go from this color to this one from left to right. So I'll just say body. The first thing I'd like to do just say background and we'll say linear dash gradient. We can say to right or what I'll be doing is to say 135°. We'll say go from this color which will be 83 A uh 8 D and F. Okay. From this one to C3 C F E2. Okay. Then we'll just say minimum height of 100 VH. So it'll take entire screen. We'll say display flex align item centered and justify content of center. Then we'll say petting of let's say 20 pixels. So this is the output that we got. Now we would like to select the container and we'll say the background color will be white. We'll say border radius will be 1 ram which is equal to 16 pixels. Then we can add the padding of 2 ram. We'll say width of 100%. And the maximum width will be 800 pixels. Let's save. This is what we got. And I'd like to add some box shadow just tiny bit. So say 0 to 10 pixels, 20 pixels. And my color, which is going to be black, but we'll just change the alpha color to 0. 1. It's really subtle, but if you would like to increase it, you can definitely do so. Let's just actually go with this one. Then after the container, we can select our H1 and say text align of center. And then we'll say margin bottom of 1. 5 ram. And we can maybe just zoom out a bit. Okay, so this is the normal level that we should have. And then I'll say color of 333. I'll say position will be relative. You will see why. And finally we can say something like petting bottom of 0. 5 ram. Okay. Now we'll be using position relative because I will create an H1 after element. We'll be using this after zero element to be able to add this underline. And this will be positioned absolutely right below to this text. Now let's see how we can make that work. Basically we'll go ahead and just say position this absolutely and then we'll say bottom will be zero but we would like to position this in the middle. Right? So we're going to say take it from the left of 50% and we would like to take it back with transform of translate x of minus 50%. So this is that trick that we are using so that it is being centered correctly and we'll say the width of this could be 50%, you can use any value like I'll display I'll show this what this does in a second. Then we'll say height could be 3 pixels. So this is what we have three pixels on the height and we'll say background color could be this one. Let's say 66 7 e. Okay, then we'll say just add a border radius of 2 pixels. Now let's save. Probably we're not going to see anything. It's because if you're using the pseudo element, you have to have the content property, right? I'll just add the content. Even though it doesn't have anything, we are able to see it. Now, if you say width will be 10%. This is what'll happen. If you say 100%, it'll be the entire H1 element. But I specifically want to go with 50%. And if you do not add this part, it's not going to be centered correctly, right? Because when you say a left of 50%, it'll go from the left 50% but it would be the starter point. So what you would like to do just take this 50% to the back. I hope that makes sense. Now this is working properly. And then we can now update the generate button. So I'll just scroll to the scroll to right after this and I'll say select the generate btn. So I'll go ahead and say background. This is going to be a linear gradient from 45° from this color to this one. So this is what we got as the output. I'll just say the text color will be white. We can say the border will be none. Let's save. Now we'll like to say petting from top and bottom 08 RAM and from left and right 1. 5 RAM. So this is exactly what we got. Now we would like to say border radius of something like 50 pixels. And then we'll say cursor will be pointer. We'll say font size or I'm sorry font weight. Let's say will be 600. So it's a little bit more bold. Maybe we can go with 500. Okay, this is a lot more cleaner. Then we can say margin bottom of 2mm. Here we go. And maybe we can update the font size like let's say 1. 1m. How it'll look like? How about 1 RM? Okay, so we can definitely go with one RM, which is a lot more cleaner, right? Then we'll just go ahead update the hover state. So I'd like to say generate dashbtn on hover state. We would like to basically uh translate this to the up direction. Right? So I'll just say transform translate y minus 2 pixels. Now let's see if I hover over this it'll just go minus 2 pixels above. So let's say - 20 pixels. It would be a little bit too much, right? Okay. And if you want this to go below, you would just say two pixels. Okay. I'll go with two pixels minus 2 pixels. And we can give a bit of box shadow on the hover state like 0 6 pixels 10 pixels. And then our color, this will be a little bit different. Let's say RGBA 102, 126, 234, and let's say 0. 3. Okay. So, as you can tell, it looks really, really clean. Now, when we click to it, it should go to the previous state. And we can do this with the active state. I'll copy this, paste this, but it'll be active. So we'll basically say transform will be translate Y of 0 pixels or just zero. Right? So when you hover over this, it goes up. If you click to it, it'll just go back to the previous state. And after this one, we would like to add the pallet container. Let's select it and I'll say display of grid. This time we'll say let's give it a gap of 1 RM. So basically this is what we would like to have just a little bit of gap in between and for the size we will say grid template columns we'll say repeat this. So the first option will be auto-ash fit and we'll say minimum and maximum we'll basically say in minimum it could be 130 pixels and maximum it will be just one fraction. Okay. Now, if you take a look at it, it'll be responsive and we'll just even make it look cleaner. Let's go ahead select the color box. I'll say this will have the border radius of 10 pixels. overflow of hidden. And we'll say give a bit of box shadow. And I can just copy and paste this value. This will be let's say 0. 01. So that looks a little bit subtle. Then we can say the transition will be transform of 0. 2 seconds. Then we can select the color box hover state. And let's go ahead say on the transform we'll say translate Y of minus 5 pixels. So that we could have this exact same output. Right? When you hover over this, it goes five pixels above. Okay. Right after this color box, we'll just say the color itself. This is another element that we have. Let's say height will be 120 pixels. Here we go. And we can say the cursor will be pointer. Okay. Now we can go ahead select the color dash info element. And it'll say background color will be white. We can go ahead add some pettings. Let's say 0. 7 RM. Save. Here we go. We'll say display of flex. So that we can say align items of centered and justify content space between so they would be spaced out. And maybe we can say font size of 0. 9 RM. I'll also go ahead select the hex value and I'll say font weight will be 500 and the letter spacing could be 0. 5 pixels so that it looks a little bit more clean and then we can get the copy button. So I'll just say dotcopy dashbtn let's say cursor will be pointer just like every single button we can say color will be this specific one I'll go with 64748b okay this is what we got now we'd like to just add a little bit of transition because in the copy button hover state let's first add this one we'll say color will change scale bit that's going to be equal to this one. Let's say now if you hover over this it'll just happen instantly. So we can say transition the color property with 0. 2 seconds. Okay. So it's just a little bit more subtle. And then finally we can make this a little bit more let's say responsive. I'll go ahead add my media query. I'll say max width of six sorry 768 pixels. We would like to say pallet container and we'll just update the grid template columns. Let's say repeat here. We'll say auto fit but we would like to change the minmax function with 100 pixels to one fraction. Here we can see once you hit 600 sorry let's just take a look at it once you hit this break point which is 786 pixels notice how from here once you hit that so it is right it'll just change a bit so that it is responsive and it's working correctly in the mobile phones as well okay so with that that's going to bit for the CSS styling now we can go ahead and jump into the JavaScript file where we can generate the pallet and copy the values. So let's go ahead close this file and open up the script. js and the very first thing we would like to do select our DOM elements. So I'll say con let's get the generate button and I'll say document getelement by id and let's put the ID which was a generate dash btn. Now I'd like to duplicate this. I was going to say but let's actually type this out. I'll say pallet container. We're going to select this one as well. That will be document query selector this time because we're going to select it with the class. So say pallet dash container. This is what we have in our code. Now we'll go ahead and just add an event listener. Right? I'll say generate button dot add event listener of click event. In this case, we would like to call our method called generate pallet. And let's create this method or the function, right? Let's say function generate pallet and just leave it as an empty function for now. Now, the other thing that we would like to do whenever we refresh our page, we would like to have another pallet, right? So I'll just go ahead say as soon as we visit this page just go ahead call this method. Now if you don't want to you can delete this part really it's not needed because by default we have a pallet. Okay so just in case if you want to get a different pallet on refresh you can basically add this one. Okay, for now I'll just keep this right here and then we can move on with this method called generate palette. So in this method we'll have a colors array that will be empty initially. Then we'll go ahead create five random colors and then we'll just push it into this array. We'll say four let i starts from zero all the way up to five so that we can just run this five times. And then in this case, we'd like to say colors. push. And we'll say generate a random color, which is going to be the method that we're going to build right now. Generate random color. Now, in this function, we're going to have a constant called letters. And this will start from zero all the way up to 16. So, we'll go like from 1 to 9. But then we'll say a b c d e f. So this is up until 9 and then 10 11 because this is how it works if you want to create colors with hex values. Right? As you can tell we have letters from a to f. Okay. So once you have this in mind we can say let will create a color. Basically the first value always will be this hash and on top of it we'll add some random values such as this one or any kind of value that you can imagine. So I'll say for let I is equal to zero and we're going to run this six times because if you have realized we have six letters every single time right just take a look at that. This is what we have. And we'll say while I is less than six, we'll just go ahead and increment it by one. And now we'll say go ahead at on top of the color variable, we'll say letters. And we would like to basically select one of them randomly. Right? So we'd like to add an index. And I'll say math do floor math dot random. and we are going to multiply this by 16. Okay. Now, I'd like to show you this what this does. Let's copy it. Open up the terminal. I'll basically paste this every single time. So, now we got 1 six. As you can tell, we are getting random values from zero all the way up to 15. Now 16 is not included because we only have 16 elements but indexes are starting from zero right. So if we have to put the indices okay this is kind of annoying but this is the index of 0 1 okay why do I even type? So 0 1 all the way up to 15. So that's why this will never give you the value of 16. At maximum this could be 15. So this is something I wanted to highlight and after this for loop we would like to basically say return the color. So it would be returned right and then this would be pushed into the array. Now if you would like to test this out you can copy this function put it into your terminal and just call that method which is called the generate random color. Just go ahead call that. So every single time you'll get a different randomly generated color as you can tell. Now we got the color. What do we want to do? So we got six different So we got five different colors. We would like to take them and update the UI with it. So we'll say update pallet display. And this is going to be a method where we'll just pass the colors. Right? So we have generated some colors and we will pass it into this method so that it can update the UI with them. Now let's go ahead and create this method. I'll say function we'll get the colors and we'll do something with it. So the first thing we would like to do just select all the color boxes. I'll go ahead say const color boxes and say document doquery selector all where we have this class name color dashbox and we would like to loop through each color box and update it with a color from our array. So I'll say color boxes dot for each method and we're going to get every single box. Also I'd like to get the index. So let's wrap this with brackets and I'll say index as well. Let's run an arrow function here. We would like to create sorry we would like to get the color itself. So I'll say colors by using the index. So we can get the color itself. We'll be doing this for every single colors, right? And then we'll say con let's say color dev. We can say box query selector of box. Sorry, what am I doing? So, this should be color. I'm sorry. Let's go ahead duplicate this. Now, we would like to get the hex dash value and we can update this variable. We'll say h value. Now, we're going to see why are we getting those in the first place. The first thing we would like to do is set the background color of the div. I'll say color divy and we'll say background color will be equal to this color whatever we have and then we would like to update the text to show the hex value. I'll say hex value dot text content will be equal to color. Okay, let's save. Hopefully it should be working out. I'll say generate pallet. As you can tell, we are just creating the values, right? We are creating all these colors and then we are updating our palette. We're just going to get every single colors, right? Then it will just loop through it so that it can update the UI. So, I'll just click to it. These colors have been generated and we have updated the UI, both the background color as well as the text itself. Okay. Now let's see what happens if we refresh the page. So every single time we're going to get a different palette because whenever we visit our page, we are running this method. But if you delete it, every single time if you refresh, you're going to get the exact same color palette. Maybe this is the behavior that you would like to have. So you can delete this line. Or if you would like to get some random colors, you could add this one. I'll just go ahead and comment this out so that we can have this on every single refresh. Now the other thing that we need to add is the copy functionality. When I click to the box or into this uh icon into this button, it should copy it. Now we would like to add an event listener for that as well. So just because we have the first event listener right here at the top, I'll just go ahead add the second one below it. So I'll just say pallet container. ventlister at event listener which is going to be the click event. We would like to run this function. Now you can either go with an arrow function like this or you can go with a default anonymous function in this way. So this is what I'll be using. It's completely optional. I'll get the event which is passed by default and I'll say if. Now we have two different checks which is this one. either we click to the button itself or into the box itself right both of them will copy the value so let's handle the first case where the user click to the copy button so I'll say if etarget doclass list this is how we can type this out class list contains the copy-bn in this case we would like to go ahead do something which is to first get the hex value. I'll say get the hex value and how can we get this? So we'll say e. target dot previous element sibling dot text content. Now that we got the h value we can copy it to the clipboard. Now why are we saying previous element sibling? Let's see why this is the case. Now, if we click to the copy button, let's take a look at the index html. Where do we have the copy button? Let's search for it. Copy-bn. Okay. Now, when we click to this element, we would like to go to the previous sibling, which is this one, and we would like to get the text content. So, this is exactly what we are doing. We just got the text content. This is the value. And we would like to copy this to our clipboard. And how can we do so? Well, you can say navigator. clipipboard. right text. Then you can basically put the hex value. Now let's save and take a look at it. If I click to this button, now it has been copied. But that was the end result. Sorry. Let's go ahead and copy this one. Now it's been copied. If you paste it right here, as you can tell, it is this value that has just been copied. Now, once the value is copied, we would like to show some success feedback just like this one. And this is working asynchronously. So, what does that mean? We can add a method like 10 at the end. And we'll say once you have copied this to the clipboard, go ahead run this method which is to show copy success. Okay, but if you got some errors, we can handle it with catch. So right after this just chain catch, we're going to run this method where we get the error itself. let's say err and you can say something like alert the error or you can just put a console log if you really wanted to just like this one. Okay, now we don't have this method. We're going to be building it right now. I'll maybe just shrink every single one of these and create this method called show copy success. So, this will be relatively simpler than you think. Just basically display something and hide something else, right? Let's take a look at the end result. We're going to display this icon and hide it. Then show this one. Once again, just before we get into this function, I'd like to scroll to the top and get the copy button with this query selector because we'll be using it in this method. So, the first thing I'd like to do just say copy button. class class list dot remove this one. Let's say f a r and f a dashcopy. Then we would like to add another one. So that will be f a s and f a check. And this should be add. Then we would like to change the color as well. So I'll say copy button style dot color will be this green one. So I'll say hash 48 doubleb 7 and it should be eight. Let's save. Take a look at it in this one. Okay. So for some reason this has been updated. Why this is the case? I'll refresh. I'm clicking to this one or this one. But the very first one has been updated. So this it is strange that we're going to take a look at it. I think it's because we didn't completed the else if case. We'll get into it just in a second. For now, let's move on with this method. So, what do we want to do once we copy it after 1. 5 seconds, we would like to go back to the previous state. And if you want to add some delays, you can use set time out method with the call back as well as your timeout. So, I'll go with this value which is equal to 1 second and half. I'll say copy button dot class list. Now we'll be doing remove but this time we're going to remove this one and I'll duplicate this. This will be add. So we are basically negating what we have just done a couple of seconds ago. I'll say copy button style dot color will be basically nothing so that it can go into the default color. Right? We're just reset resetting it. Sorry. Now, let's save and get started with the else if case. And I think it should be good to go. I'll say else if e. target list contains the color and this means if user clicked directly on a color box, right? So in this case we would like to run this block where I would like to get the hex value. We'll say const h value this will be e thetarget the next element sibling the query selector we would like to select the hex dash value and I'll just maximize this we'll say just get the text content now why this is the case why are we getting the next element sibling let's take a look at it pretty quickly under index. html. So if we click to the color element which is this one, we would like to go to the next sibling element which is this color info and from here we would like to get the hex value. So this is exactly what we are doing. We are just getting the text content and then we would like to do the exact same thing that we have just done right here. I'll copy this, paste it, save. We're just basically copying it to the clipboard. Let's put them side by side. Save this and take a look at the end result. I'll say, you know, just copy this one. But for some reason, it is getting the very first one. Let me copy this and put it into the URL. So, we are copying this value, but this UI has been updated. All right. So, the reason that this is happening is because of this copy button. Now when you say query selector of the copy button, we have five different buttons, but it'll always select the very first one. So instead of actually saying copy button, we would like to delete this and we would like to make it dynamic. So whichever we clicked, it should copy that one. And for this we can send an element to this method. So I'll say e. target in this one. And right here we will say e. target target. We would like to find the copy button because this is where we click to the box. Right? When you click to the box, you would like to select this element. target dot next element sibling query selector and we'll say dotcopy-bn. Once again, let me maximize this. Here we go. And in this method, we would like to get the element as an argument. Instead of using that copy button, I'll just say command D couple of times. I'll just say use that element. Now, it should be working out as expected. If I try to copy this one, it'll update it. And if I click to this one, this one will update it. Everything is working as expected, right? Okay. So, that was the entire project. I just try to go really slowly. I'm sorry if it is kind of boring, but I just try to make sure that we understand everything like the previous element sibling, the next element, so on and so forth. And we even made a mistake where we got the copy button with the query selector, but we just pretty quickly fixed it where we need to pass the actual copy button dynamically, right? we have added the event target or the copy button itself and then just handle it in the from the method. Okay, so I hope that makes sense. That's going to be it for this project. I'll see you in the next one.
Project 3: Kanban Board (HTML Drag & Drop API)
In this section, we're going to build a simple canon board. Now, if you have never heard of it, you can basically check it out and you can see a bunch of different examples, but I'd like to walk you through it within this example. So, we're going to have three different lists such as the to-do category, in progress, as well as done. And you can take these cards and change the category, right? So, I can take it, put it into this list or this one or even in this one. And I can even order them within the list itself. So, we have a buy groceries at the top if I wanted to. I can take it to the bottom. So, this is the end result. This is what we're going to be building. And there is an API which is the HTML drag and drop API. This is the documentation that you can take a look like if you want to learn everything about it. This is the article that you would like to go through. But basically I will simplify it and I'll just teach you the 90% of the things that you would need to get started with it. So this is the end result. Let's go ahead and jump into the code. I have an empty folder as always with three different files. Let's first get started with HTML. I'll just put them side by side. And by the way, the end result will be responsive as you can tell. Well, it is it's maybe not that responsive. I think here we cannot scroll to the top, but we can fix it within our code. And I just even went pretty quickly fix the end result. So here we can see it is responsive. we are able to scroll to the top to the bottom and we have our columns either like this or one at a time. Okay, now let's go ahead and have this index. html. Let's open this up with the live server that should be right here and we can close these warnings. Okay, so let's create our file. I'll say for the body we would like to have couple of different divs. So I'll just zoom in maybe and I'll say we would like to have a div that will be our container. So I'll say class name of container. We'll go ahead have this h1 which will be the simple canvan board text. So I'll go ahead paste this in. And then we're going to have the board itself. So it'll be this container that you can see. Oops. Okay. So it is this one that we have. So we'll just call this as a board. Let's say board just like that. And we'll go ahead have some lists. So I'll just say create a div with the list class. And this will take the id of list one. And we are going to duplicate this twice. But for now let's say this is the list one. And this will take the h2 which will be to-do. So this is what we have just built. And we're going to put two different cards. So I'll say card class that will have the wash dishes. Now the most important thing here it comes. It'll be dragable of true. Now let's see what this does. Um if I save, can I see anything on this file? No, I cannot. Okay, I just refreshed. Now we should be able to see it. Let's say dishes with double s. Okay, now it is working in live mode. Now what happens if you say dragable of true? Well, first let's delete it and try to see what happens if I try to drag this and drop it. I cannot, right? It is selectable. I'll just zoom in. So we can select it, but we cannot drag and drop it. But if you say dragable of true, now we can basically drag this and drop it any places. But we don't really have the functionality. So it is not going to work. But we're going to make that work just in a second. So this is that thing that we need and you can take a look at it from the documentation. It should be somewhere right here. Okay. So now that we have the dragable of true now that we know what this does, we'll go ahead add an ID. I'll say this will be our very first card. I'll say card one. And we can basically duplicate this one. This will be buy groceries, right? Let's type this out. So, it'll be dragable of true, but cart of two, right? We'll just update the ID. So, that's going to be for our very first list. Now, we'd like to add the other ones such as in progress and done. So, I have just zoomed out right after the list one. We'll go ahead add our list two which has the in progress because this is what you have when you refresh the page. You have one item here and nothing on the done list. So this is exactly what we have done. We have one card in progress and nothing in the list of three which is done. Okay. So that's going to for the HTML file. Now we would like to link our CSS file. I'll just say link CSS which is the style. CSS file. and let's say canon port because why not and then we would like to add the script source of script. js file and the very first thing we would like to do is just build the style CSS file. So as always we're going to add our basic reset and this is the end result that we have at the moment. So I'll just say select everything and we'll say padding of zero. Let's duplicate that. This will be margin of zero. And finally box sizing of border box. We'll go ahead select the body. The first thing I'd like to do update the font family. So I'll say font family will be equal to let's say sans serif. Now everything has been updated. Then we'll say let's update the background color. Instead of using white I'll go with a kind of like a gray color. I'll say f8, f9, and fc. Then we would like to say display of flex justify content of center and then align items of center. Now we would like to say minimum height of 100bh and it'll take put everything in into the middle of the screen. Then we would like to select our container and we would like to say text align of centered. Then we would like to say width of 100%. And finally let's give some paddings like 1. 2. tom. Okay, now that this is what we have, let's go ahead select H1. We would like to say color of the classic one that we use. We'll say margin bottom of 20 pixels and font size of 2mm. Okay, then we would like to change the board class, right? I'll go ahead select the board. Let's say display oops display of flex justify content. Now this will be spaced around and let me display it in the end result so that they are spaced out uh let's say spaced out evenly right well actually there is something called space evenly but this is kind of similar not exactly but it'll do this similar thing right okay and then we would like to say something like align items of start actually flex start just like this and we'll say width of 100% but we would like to give some maximum width which is going to be 1200 pixels and then we can say margin of zero as well as auto and finally we'll just give some gap like 20 pixels. All right, this is what we got. Still looks ugly but we're going to get there. I'll go ahead say select the list. We'd like to say background color will be updated to something like E3, E4 and E8. Then we'll say padding of let's say 1 RM. We can give a border radius of 8 pixels for the rounded corners. Width of let's say 30%. So it is kind of like 30 30 and we have some spaces. It'll be kind of like 100% in total. Okay. Then we would like to say minimum height. Let's just type this out. I'll say minimum height will be 400 pixels. And then we can say let's just give some box shadow. Right. I'll say zero and 4 pixels 8 pixels. And we'll say rgba. Oops. If I can't type correctly, we'll say rgba. We'll go with zero. Okay. Kind of annoying, but let's go ahead type this out. And for the color, you can go with something like 0. 4. But in this case, I'll just go with 0. 2. This should be good to go. If you increase it, what happens? Let's see our end result. Like kind of ugly. So like 1. 1 is even 0. 2. And then we can add something like list H2. We would like to update the heading. I'll say color of 555 and margin bottom of 1mm. And we can just increase the font size 1. 5 RM. This is what we got. Now we would like to select the card itself. Let's say dot cart. We would like to update the background color and bunch of different things. So let's just say start with this one. This could be white. Here we go. And we'll say color will be 333. And then padding will be let's say 1 RM. Then we could say margin bottom of 10 pixels. Now we have added the margin bottom. Let's say border radius of 8 pixels. Here we go. We'll say cursor of grab. Now this is kind of cool because once you hover over this, it has the grab. And there is also something called grabbing. when we click to it, this is how it'll look. So, let's actually try to see it. I'll just say by default this will be grabb. But if we say cardactive, it should be cursor of grabbing. Now, let's see this is grab and this is grabbing. Pretty cool, right? Then we would like to add one more thing which is going to be box shadow. I'll say zero 2 pixels 4 pixels and the same exact color I'd like to copy and paste. Now we would like to add some transition. First let's say here we'll have transform of scale that will be 0 sorry 1. 05 and box shadow. We would like to just update it a bit. I'll basically copy this entire thing but duplicate it. I mean uh increase it by two right I'll just say this will be four pixels we'll basically multiply it by two now let's say active this is what happens but there is no transition right it is happening immediately and we can go ahead add it by adding the transition field we'll say uh implement for the transform with 0. 2 2 seconds. And we can add a comma and we can say box shadow. This would be let's could also be 0. 2 seconds. Let's save. Now it's like a little bit more smooth. I'll delete this just to see like it is happening instantly. But once we have it, it's a lot more cleaner, right? And you can say something like all as well. Now it'll apply to everything but I just wanted to show this if you want to add some spec specific things sorry let's say for the transform you want this to be in 2 seconds like as you can tell it is just happening in 2 seconds which is kind of ugly but this is just an extreme example so I hope that makes sense and now that we have understanded we can save and move on with the next class I'll just say list dot over if we have this over class we would like to update the background color to be let's say D1 D3 D8 now why do we need this over class let me display if we go into the end result so if you take it and put it right here as you can tell the background changes right and this is what we are doing once we drag I mean once we enter into the container we will add that class and once we are out we're going to remove it I hope that makes sense Now let's go right here and finally just make it a little bit more responsive. I'll say at media. So I'll say media max width 768 pixels. We would like to change something which will be the board. I'll say flex direction will be column and we can say align items will be centered in this case. Then finally the list will be width of 80%. And margin bottom of 20 pixels. Okay. Why does this looks that ugly? Okay. This should be 80% not pixels. Here we go. Once you hit here, it's like completely responsive. So we have the entire UI. It is working as expected but we don't really have the functionality. We can just drag and drop or we could drag but we cannot drop it. So for this we will add the script. js file. So let's kill the left hand side and get started with it. And I think this will be easier than you think. But let's go ahead and see what we'll have. So the first thing I'd like to do just select all the cards and lists that we have in the UI. So I'll say con cards and maybe duplicate this. This will be lists and for the cards we'll say document dotquery selector all and I'll copy this name and then I'll say just select the card class. Then we'll go below we'll say document query selector all. This time we will select all the lists. Now what do we want to do first is to add some event listeners. Now notice how we have things like in the end result drag is started drag is entered right so like drag is entered drag is leave so on and so forth so we'll add all kinds of events that we would need for this project so the first thing I'd like to do is to create a for loop I'll say for const card of cards basically we will add an event listener for every single card and we can do it with a for loop. I'll say cart do add eventlist listener and we're going to listen for the drag start. Okay, this is how we can type this out. And once we have this event, we can run our method where we will handle this event. So I'll say drag start. This is something that we will create just in a second. Then we can say cart add event listener for the drag end event and we'll call our method to implement it which is going to be called as a drag end. And now we would like to add some events for the lists. Right? So we just added some events for the cards but we would like to add some events for the lists themselves. Right? I'll say for and do the exact same thing. const list of lists and we'll add four different event listeners. So I'll just say list add event listener and I'll just duplicate this three times. Here we will listen for drag over. We will have drag enter. We'll have drag leave and finally just drop event. Now all of these events are coming completely from the documentation. You can double check, but I'd like to simplify it and walk you through it within this project. Okay, so we are listening for these events. We would like to handle them within a function. So I'll just say drag over for this one. And we'll do the same thing for drag enter and these last two. I'll say drag leave. And finally drag drop. Now let's get started with the drag start function. Let's create it. So here is how I created it. And by default, this will take an argument which is going to be the event. So the first thing we would like to do is this one. We'll say e. at transfer just like this. And we'll say dot set data. Now this is exactly coming from the documentation. Let's type this out and then I'll explain what this does. So we'll say text slash plane and we'll just say this do id. So this basically will set the ID and I'll put a comment. This allows the drop location to know which element is being moved when you release it. So I hope this makes sense. You can take a look at the documentation. Let's just search for text plane. So this is exactly what we have I think at the top. Okay. So this is what they are doing. They say event. target id. We are using this id. It is kind of the similar thing. It is working in the same way. Okay. Now let's go ahead and complete this function. This is all we need for it to handle the drag start. Now we're going to add the drag end. I'll say function drag end. Now you can do anything that you wish within this function but for now I'll just say console log drag ended. Now I'm not implementing anything at the moment. So just to see this event is actually existed. This is why I am implementing it right here. Right? So we got the function. It's really simple. And now let's handle the drag over method. Once again will be super simple. Let's say function drag over and we'll just take the event and we'll say something like event. prevent default. Now why do we need this method? Why do we need to say event. prevent default? So if we have to explain it with a single sentence, this is what it would be. This line is important because by default browsers don't allow you to drop elements onto other elements. So this is exactly what we are doing. we will just prevent the default behavior. Now the other method that we would like to implement is the drag enter. If we take a look at the end result as I said previously when we enter into something we will just see this different background color with the help of this over class. So this is what we have added list dot over the background color will change. So this is exactly that method that we will handle. So let's say function brack enter now right and we'll take the event we'll say first let's prevent the default it's the same reason that we have above finally we'll just say this class list go ahead just add the over class now if we save hopefully it should be working as expected if I take this one okay why this does not work maybe we still didn't complete our code. That's the reason. But let's see how it'll happen. We just need to add one more method or maybe even two. I'll say function basically copy this, duplicate it. This will be drag over. And in this case, all we want to do just remove the over class. And one last function that will be drag drop. So I definitely understand this might be kind of complex or even overwhelming but everything that you have seen here are basically coming from the documentation and personally I didn't really memorize any of them. So if you delete this entire line or file and ask me to do it tomorrow again maybe I'll just forget some part which is completely fine right you don't need to memorize any of them but just know like this is something that has existed you can build your own version or you can use even some built-in packages so this is the point of this project in the first place just to make you aware that something like this existed within HTML And this is how we can build it pretty simply and quickly. Okay, with this explanation out of the way, let's go into the drag and drop method and say give me the id of the like ID of the element, right? I'll just say const id. We'll say event dot the exact same thing actually that we have done above. I'll copy this part event data transfer but this time we will say get data and this part will be the same which is text /plane then we would like to go ahead just find the card I'll say con card we can say document getelement by id and just pass the id within that and we'll say this dot append child because we are appending something Right? If I take this one and drop it, I just append this child into this parent. So that's why we need to call this method with the card itself. And finally, we'll just say this class list remove the over class. So that should be it. Hopefully everything should be working as expected. Let's go ahead and test this out. I'll refresh. Take this. Put it right here. Looks like it doesn't. Maybe we are missing something. Let's see why this is the case. So if we take a look at our terminal, we have an error that says drag leave is not defined. That's true because I forgot to call this as drag leave. Okay, that should be it. Now it should be working out as expected. I'll take this one, put it right here. And we can put it on this one. Everything is working as expected. So that's going to be it for this entire project. I hope you enjoyed it. Once again, the point of this project was to actually teach you that there is something called HTML drag and drop API. This is existed. This is something that you can use whenever you need it. Everything is coming from the documentation. It is kind of complicated, but you don't really need to memorize the entire syntax. All you have to do just come up to the documentation, learn it or try to copy and paste into your code. As long as it is working, I think that's completely fine. So with that, I'll see you in the next project.
Project 4: Expense Tracker with Local Storage
In this section, we're going to build an expense tracker. Now, this is the end result. Let's take a look at it and then we'll just jump into the code. So, we have a form where we can add a description like AirPods and then the amount. If it is an expense, we should put minus in front and then we would say something like $250. Now, if you say add a transaction, it'll be added to the list with a nice animation and your expenses will increase as well as your balance will be updated. Now, if you refresh your page, they will still be here because we will save them to the local storage. And then let's try to add something like salary. That will be an income. So, we don't really want to put minus just put the amount itself. So, let's say 2,000. I'll add this. Here we go. Now it is in the salary list. Everything has been updated. I mean it is in the transactions list. And if we wanted to, we can delete it. The UI will be updated immediately as we can tell. And we could refresh. Everything would stay here right there. And let's try to add something. Now, as you can tell, once we have couple of different items, at some point this will be scrollable. So this is something that we will learn as well. And if you wanted to have these screenshots, you can find the link in the description for the diagrams just like any other project that we have so far. Right? Okay. Now, with this in mind, let's go ahead jump into the code and try to build this end result. So, the first thing we would like to do just get started with the HTML file. As always, I'll put them side by side and we'll just take a look at the end result as we go. And here we can see it is responsive as well. So even if you are in the smaller screens, it'll just work properly. Here we have a little bit of flow, but I think that's fine. We could fix it in this uh like in this project. Okay. So let's go ahead get started with the HTML file. Let's put the title. I'll just say expense tracker. And we will link our CSS file. And let's go ahead use a font family just like we have done previously. I'll say command shiftp. I'll say Google fonts and I'll just select the insert link. And for the font family, you can choose anything. I'll go with popins. Here we go. We got the import. And we can go into the body. Create our container class. So I just fixed my typo. Let's say we'll have an H1 which will be this one. Let's say expense tracker and we can save. Let's say open with live server. We'll get some warnings. That's fine. Here we go. Now it is working as expected. Now the other thing we would like to add is the balance container. Right? So it is this one that we see. I'll go ahead say something like balance container. And we'll have some items like H2 of your balance. We can put the H1. This will be, let's say, ID. And this could even be H3. We can change it. I'll say balance. This will be the ID. When we first get started with it, it could be $0. So, this is what I'll have. And then we can basically have the summary as well, which is going to be the income as well as the expenses, right? I'll say summary class. This will have the income as well as the expenses. Let's first get started with the income div. This will be in H3. Let's say income. This is the text. And then the P tag. Initially, it'll be zero. But we will update it within our JavaScript code. And for the P tag, we can say something like ID income- amount. Let's do the exact same thing for this one. This will be age three of expenses. And we can basically duplicate this. Put it right here. This will be expense amount. Initially it'll be zero as well. So outside of the summary, right, go ahead find this one. And then outside of the balance container as well, we'll go ahead put the main container. Right? So this is what we have. Right below it, I'll say main dash content where we'd like to put the transaction container as well as the form itself. So here I'll go ahead say transaction dash container and then I'll duplicate this. This will be the form container. Let me show the end result. So we have built the header part, right? Now we're going to build the transaction container as well as the form container. Okay. So let's get started with the very first one. So this will have an H2 that will say transactions. Then we can go right here. We'll say we'll have a URL which stands for unordered lists. And we can give an ID. Let's say something like transaction dash list. And now for the content we are not going to have anything initially. This will be added with our JavaScript code. So I'll say transactions we will be inserted here right and then right after this ul as well as the div we'll go into the form container where we would like to have the h2 that says add transaction. Then we can have our form. Now this is not going to have any actions but it'll have an id of transaction form. Then we'll go within this form we'll have a div that will have the form group. So I'll say class form dash group where we'll have a label as well as an input. Now let's say this will be the description. This is the first input that we are building and we can give it a four that will be description and then we'll create the input. Let's say type will be text ID will be description. Placeholder it could be something like enter description and dot dot. Finally let's say this will be required. Now why did we put four? That is for the ID of description. Well, it's because if you click to the label, it should focus into the input. So, this is some best practice, one of the best practices that you should keep in mind. Okay. Now that we got the very first form group, we can duplicate this. I'll basically copy it and paste this right here. This will be for the amount for let's update it. That will be amount. Type will be not text but number this time. And this will be required as well. For the placeholder, we'll say enter amount dot dot. And after this div but still within the form, we'll have a button. Let's say type will be submit and we can say add transaction just like this. But I think we are missing one more thing which is this small element right below to the input I'll say small and we can say use negative for expenses. Okay. So with this that's going to for the entire HTML file. Let me show this from start to bottom. So we got the style. css length. We got the popins font import. We have the container with the balance container as well as the main content. Okay, so that's entire file. Let's go ahead link the JavaScript file as well. First, we will build the style. css and then we'll get into the JavaScript. So, I will kill this file and let's shrink this so that we can see them side by side. And by the way, this is the end result that we have. looks terrible, but we're gonna make it look nice. So, the first thing we would like to do, as always, just put the margin of zero at the padding of zero and box sizing of border box so that we just have our basic reset. Then we can say body and I'd like to put my background color which will be a linear gradient within this degree from this color to this one. Now, it is repeating itself. So we can say something like min height will be 100 ph. Here we go. Now it has been fixed. And I'd like to add the font family. Let's say it'll be poppins. And just follow it back with the sense serif. Then we can say display of flex. You can just say df aic and jcc. Now everything should be centered. We could give some padding such as 20 pixels and then just update the color that will be 2D 34 36. Okay, this is what we have at the beginning. Now we'll update the container. I'll say width of 100%. Here we go. I'll say maximum width will be 1200 pixels. Background color let's say will be white. You can either say white or use the hash value fff. Let's say padding will be 2mm. Let's give some border radiuses such as 24 pixels. And then some box shadow. Let's say box shadow. And maybe just before that we could save. This is what we got. Let's say box shadow 02 pixels. Duplicate it. RGBA. and we'll go with the uh let's say black color. But for the alpha, I'll say 0. 15. So we have this subtle uh box shadow. If you wanted to, you could increase it, but I think this doesn't really look nice. This is a lot more cleaner. And then we can move on with the H1 element. So I'll go ahead say H1. Select this. Let's say text align will be centered. Here we go. We'll say color will be updated to something like 1 a 200 2 and c. Then we'll say margin bottom of 35 pixels. Let's say font size will be not font style but equal to let's say 2. 2 2mm then we can say font weight will be 600 and let's just say letter spacing now we'll be using minus so we'll say 0. 5 pixels so notice how they are just squeezed if you say plus this is what'll happen let's say like 5 pixels too much wide but we would like to go with minus in this case then let's select the age two I'll say the color will be 2D be 37 and 48. Here we go. We'll say margin bottom of 1m. We could say font size will be 1. 25mm and font family sorry font weight of 500. Here we go. This is what we have. Now we would like to select the balance container and say something like text align will be centered. Then we could say margin bottom 35 pixels, padding will be 34 pixels and we would like to update the background color. Now this will be a linear gradient as well. Now, we would like to add some border radius such as 15 pixels or maybe let's just say 1 RM. Here we go. Then we could add some box shadow on top of it. So, say zero 4 pixels, 12 pixels and the let's say black color. And for the alpha value, we can go with even less than 1. 15 that we have done above. I'll just go with 0. 05. Super subtle, but why not, right? And then we can select the H1. I'll say balance container H1. Font size 3 RM. We could say margin will be 15 pixels to zero. And margin bottom specifically will be 20 pixels. And what happens if you delete this one? I think there isn't that much of a change, but and if you're wondering which H1 is it, it is this one. You could basically add this line to be able to see an element. This is a really nice trick that you could add in any place. Let's say you are wondering which one is the balance container. You could say let's add a border one pixel solid red. Here we can see this is that container that we have selected. So this is um kind of like a debugging tool that you should keep in mind. Now we can go ahead build the summary container. I'll say display will be grid and we'll have two columns. Right? Let's take a look at the end result. Here we go. We have two different columns. They will be side by side in large screens. But once we hit here, I think we could make them like um one column at a time in our media queries. But for now, let's focus on this UI. It'll say display grid. Grid template columns will be 1 FR 1 FR. Now they are side by side with the same size. Gap of let's say 24 pixels. And then we can say margin top of maybe we could just say something like 24 pixels. Then we can go below. We'll select the main content. I'll say display will be grid for this one as well. And we'll do the exact same thing that we have done above. So I'd like to copy this and put it right here. Now they are side by side. And we can give some gap like 24 pixels. And then we can select the income as well as the expenses. So we can just uh separate them with a comma. Then I'll say the background color will be white. So I can say white just like this. And we can say padding will be 24 pixels. Let's save. We would like to give some border radius of 1mm. And we can add some box shadow just like what we have done above. So I'll copy this. Okay. Now when we hover over this, we would like to do something which is to kind of like translate them in the Y direction in the minus direction specifically. So I'll say transition that will be on the transform let's say 0. 2 seconds and you can use a method like ease and then I'll say income hover state and let's select the same thing for expenses. What we would like to do is basically say transform. Okay. Why do I have a typo right here? Let's say transform will be translate Y minus let's say something like 2 pixels. So this is what'll happen in the end result. Now we can update the titles, right? I'll just say income age three. This will be color of kind of like a green color. Let's say it'll be 0596 69 like 9669 exactly like this. Then we can say font size will be 1. 1m and we can say font weight could be maybe like 600 just like this. I can go ahead duplicate this for the expenses but this time the color will be updated to something like DC let's say 26 it is this red color that we have then we can go ahead select the P tags and update them as well I'll basically do the exact same thing maybe this one put it right here this will be P tag and I will duplicate this but this will be for the expenses. Okay. So, we just basically selected the pag or both of them and we'll say the font size could be 1 75 RM. Here we can see they are just greater than the H3 and we can say font weight for this one let's say it'll be 500 and for this one it'll be 600. Then for the color, we are not going to put it right here, but we'll say something like margin top of let's say 8 pixels. Okay, because the colors will be different. I'll basically get this one. Say the color will be the exact same thing that we have right here. And we'll do the same thing for expenses. So I'll copy this and put the exact same color. Here we go. And the next thing that we would like to do select the transaction container and put them in the let's say the column direction right so I'll go ahead right here I'll say select the transaction container this should be class and I'll say something like height of 100 pixels sorry 100% let's save now this will be updated later in the video let's say display of flex X and the flex direction of column. Okay. Now we would like to go right below to it and we can select the transaction list. So I'll select it with the ID selector and I'll say the list style will be none. Now unfortunately we cannot see anything at the moment. Later in the video once we add it from JavaScript it'll be displayed right here. So this is the part that we are trying to build at the moment. Let's put the classes. We will see the end result a bit later in the video. So, we'll just get rid of the list style. We can say maximum height will be 500 pixels. And then we'll say overflow in the Y direction will be scroll or let's say auto. Now, what happens is this. Let me display pretty quickly. So the maximum height will be 500. As you can tell if we have more content they will overflow. And when they overflow we would like to say auto so that we can get this scroll bar. Right? I hope this makes sense. We have some let's just put something. Let's just add something more. All right. So we have a bunch of different elements and the maximum height is 500 pixels. Now they are overflowing. Right? In this case, we say overflow of Y direction will be auto so that we can get the scroll bar and nicely scroll within that. Okay, so this is exactly what we have done. We wanted to display it pretty quickly. Then we'll just say padding of right could be something like 8 pixels and we can say flex grow will be one. So it'll take the space as much as possible. Now I'd like to do something else which is this scroll bar. So as you can tell the color is a little bit different because we are going to style it manually. So we'll just customize it and let's see how we can make it work. So we will basically say something like transaction list. I'll copy this name and we'll say double columns and dash webkit. We can say scroll bar and we can update the width. So I'll say width will be 8 pixels. Now we can update the track as well as the thumb. Now what does that mean? So track is the background of the scroll bar. So what you have like what do you see here? I'll just zoom in. Okay. So this is the track and this is the thumb. Now we would like to select them and it'll say something like when we hover over the thumb just go ahead change the color. Now we'll see this in a second. Let's be patient and type this out. Right. I'll copy this entire thing. I'll say transaction list webkit scroll bar dash track. Let's duplicate this. And this time it'll be thumb and we'll just duplicate this once. Once again this will be thumb on the hover state. Let's build them. This will be the background color of let's say f1 f1 and we'll say border radius of four pixels. And I'll just add a to-do like to-do show this later in the video. So once we add our transactions, I'll just come right here in the code and try to change something so that you can see what we are doing right here. And I'll add a comment for the track. I'll say track is the background of the scroll bar and thumb is the dragable part of the scroll bar. Now I'd like to change the background color on this one as well. that will be let's say CB D5E and zero. Then we would like to say something like border radius of four pixels. Finally, we'll just update the background color on hover on the thumb. Okay. So, this is the color that I'll be going with. Now, that's going to be for the scroll bar uh styles. I'd like to put this to-do right here. We'll just come back to it later in the video. Now, the other thing that we would like to style will be the transaction itself. As you can tell, it looks really clean. And I'd like to just show you something. Now, I'll add an element. And once I say add transaction, notice how it'll be animated from the left hand side, right? So, I'll just slide in. Let's say add transaction. Here you can see it just slides in. And for this we'll be using an animation with key frames. So let's go ahead and build the transaction class. I'll say display of flex. We'll say space sorry just apply content of space between. We'll go ahead say align items of center. And we can give some padding such as 1mm and 1. 1 or let's say 1. 2mm. We'll go ahead say margin bottom of 12 pixels. Border radius of 12 pixels. Let's say background color of white. I'll say give some box shadow. It'll be subtle but still 0 like 0 2 pixels 8 pixels. And RGBA will go with this exact same value that we have previously. And I'll say transition will be all 0. 2 two seconds and we'll say ease. Finally, we'll just say border right because as you can tell we would like to add some borders, right? I'll say border right will be five pixels solid. We don't really want to give a color at the moment because it'll be dynamic depending on the type either income or expense. Okay. And one very last thing that will be the animation. And we can call this anything. I'll call it as slide in. Let's give something like 0. 3 seconds. And I'll say ease. Now let's build the slide in animation. We can build it with key frames. I'll say slide in. So whatever you put here, it should be right here as well. So if you said hello, this is the name of your key frame. So you would say here is my animation. I hope that makes sense. Now we would like to add two different props. We'll say go from this styles to this one. And now what is happening? Let's refresh. If you notice like it is happening pretty quickly, but we are going from opacity of zero. Say opacity of zero to opacity of one. And we are updating the transform on the x coordinate. So we'll go from left 20 pixels to the initial state now with the help of this one right. We are starting from here going to this one that will make it to slide in from the left hand side. Okay. So we're going to see this later in the video in action. And finally we can add some hover states update the transaction income expense etc. Now I know that we are going really slowly but I just want to explain every single thing in this style CSS file because we are learning a lot of different new concepts in this tutorial. Right? So let's just move on. Maybe we can split things a little bit up but let's go ahead and complete this entire file. Now what do we want to do is this. When we hover over the transaction we would like to change the box shadow and maybe take it to the right hand side. Right? So I'll just add this part where I say transaction. hover go ahead translate it on the X direction and add some box shadow and for the transaction income we will add this border color border right color specifically and for the expense we will add this one. So this is exactly what we have done and we will say now let's add this delete button. Now, initially it is not really visible. Once you hover over the element, you're able to see it. And once you hover over the icon itself, you'll be able to see this background color. Right? So to be able to implement that, I'll go ahead say transaction. delete button. Now we'll say the background will be null initially, no borders at all. This would be the color, cursor pointer, font size, and opacity of zero. That means it is not going to be visible initially but once we hover over it we would like to change the opacity and also we have like transition some paddings border radiuses and some margin on the left hand side. So I'll say once we hover over the transaction go ahead select the delete button and say opacity will be one that will give this exact same behavior. So it is not visible opacity of zero but once you hover over it is visible right now the other thing that we would like to implement is this when we hover over this it'll just scale a little bit right and we should be able to see the background so we'll go ahead say transaction select the delete button and when we hover over that change the background color and scale it a bit up now I'm just pasting copying and pasting but explaining every single line so I don't really I think this is counted as copy and paste because we are explaining every single line. Now we are going to go ahead and select the form container build this one and then we can jump into the JavaScript section. Okay. So once again on the form we have some linear gradients. We have some paddings, border radiuses, some box shadow as you can tell and the flex direction is column right? We're going in the vertical direction. So I'll basically add everything that I just said into the form container. And then we can select the form itself and make it to be in the flex direction column direction as well. Just like this. Then we can add some margin bottoms on every single element. Right? So we have this form group which is our description and enter description input. We're going to give some margin bottom right here. And same for this one. So this is what we are doing. Just adding some margin bottom on the form group class. Now we can select the label itself. Just change the color. Add some margin bottom display of blog and font weight of 500. So at this point we are just repeating ourselves right. We are just adding the same thing here in this file. That's why I'd like to copy and paste for the next items and just walk you through it. You can type this out or get it from the source code. So for the input elements, we are adding the width, padding, some borders, border radius, font size, background color, and some transitions. Now when we focus into the input, we're going to add some box shadow and we will update the border color. Now let's see if I click to this one. This is the end result by the way. But here is what happens. So this is that focus state that we have just added something in. Now we would like to say if we are on the hover state on the input we would like to change the border color and we can select the small element just add some really basic styling. Then we can select our button. Now this button is the type of submit. How do you select a button that is type of submit specifically? Well you can do something like button and then whatever the attribute that you would like to have. So the type is equal to submit go ahead select that button specifically. So if you had a button right below it and the type of this let's say something different like menu then this styles would not be implemented on this button. And we are just changing the background color, adding some different colors, right? Such as white, border radiuses, like everything that you have seen here. Super simple. I don't really want to go through it. So, we would like to add the hover state as well as the active state on the button. Right? On the active, we'll say translate Y of zero. So, first when you hover over it, it is a bit up and once you click to it, it'll just go down. Okay. So that's the entire CSS that we need. The only thing we left is the responsiveness here. I'd like to add my media queries pretty quickly. This is the first one that we'll add. And the other one is for even smaller screens like for the mobile phones. Here are the stylings that I just added. Super simple. These are the things that we have learned previously. So I'd like to just skip this pretty quickly. So 300 lines of CSS that's huge but we have learned lots of different new things in this project itself. Now in the next part we can build the script. js file to implement the actual functionality. And this is the end result. By the way the styles that we have written is working as expected. It is completely responsive up until here. So there is no issues at all. Okay. Now we can just jump into the script. js and get started with it. So the first thing we would like to do as always just go ahead get the DOM elements. Now I'll just paste this list because I don't want to type this out. And if you out as well, I have prepared a list for you. The link will be in the description. You can find the expense tracker. md file and go ahead copy this entire thing. Paste this in. So we are basically getting the balance element, income amount, expand amount, expense amount and everything that we would need. Now the first thing we would like to do just get the transactions and as I said previously the previous transactions will be stored in the local storage. So if you refresh this page like you will see the previous data and for this we can say something like let transactions initially this could be an empty array but we'll say or if we have something in the local storage go ahead and get that. I'll just say get item transactions. Okay. Now, since we are getting something from the local storage, we would like to wrap this with a JSON. parse so that we can get the structure data instead of a string. Okay, here we go. This is what we're going to have in a single line. And we would like to update these transactions list whenever we add something or whenever we delete something. Right? Let's take a look at this part. By the way, now the first thing I'd like to do get the transaction form element. Right on this one, we are going to listen for the submit event. So I'll say transaction form element do the add event listener listen for the submit event. And we would like to run a method called add transaction and this is what we would like to create. Now I'll copy the name. Let's say function paste this in. Okay. Now this will get the event by default. So for now if you just save this file and try to submit this form. So here I'll just say airpods and let's say 200. If I say add the transaction, notice how it'll refresh my page. So this is the default behavior on forms, right? When you submit something, it'll go ahead and re refresh your page. And what you'd like to do is just say event. prevent prevent default so that it doesn't really uh it doesn't really refresh the page. Now we can go ahead save this file and let's test this out once again. I'll put something let's say submit that. Now it doesn't really refresh my page. Right now we're going to go ahead and get some values such as the form values. Right? I'll just say get the form values. The very first one is the description. I'll say description element dot value let's say value just like this and we can say trim okay we just got the description now we can get the amount I'll say const amount let's say amount element dot value and what I'd like to do convert this to let's say uh integer I'll just say parse float here we go because by default the type of it would be string Let's actually try to see. I'll just say console log type of amount without doing this. Let's see what'll happen. What are we going to get from the terminal? I'll say like 200 at the transaction. Okay, it says description element is not a function. What do you mean? Okay, it should be value but without like it's not a method, it's property. Let's save and add something like 200 and put something. As you can tell that the type is string by default. But if you add the parse float here, I'll just wrap it up. Now let's try to submit the same thing. Okay, type is number now as we can tell. So this is what I'd like to do. And now we would like to create a transaction. I'll say transactions dopush. We're going to basically push an object into that list, right? I'll say ID could be date now because we're going to sort them, right? If you add something new, let's say 100, it will be added at the very top. So notice how it is right here. And this is how we can sort them depending on the type or we can reverse them. That's another thing. But I'd like to just add a unique ID. And this is what we can use. Then we can say description. Just add that. So you can say description. This is the key. And the value will be this one. But since it is the same thing on both sides, you can delete it and shorten this. And let's do the same thing for the amount. Okay. Now we have updated the transactions list. We would like to save this to the local storage as well. I'll say local storage set item set it into the transactions and we would like to say JSON stringify whenever you want to add something to the local storage you would like to stringify it first and then whatever that is in our case it is the transactions array now that we have saved to the local storage we can update the UI so let's say update transaction list call the method this is something that we're going to build and then let's say update summary as well. So this is another method that we're going to build. Once we have done this, we can basically reset the form. I'll say transaction form element dot reset. It should be reset just like this. Okay. So let's get started with this method. I'll say function update transaction list and we'll go inside. The first thing we would like to do just clear the previous list. So I'll say transaction element list element dot inner HTML will be nothing because basically we are just resetting it at the moment and then we're going to add whatever we have. Now I'd like to sort the transactions by the most recent first. So I can say something like const sorted transactions. Just get everything that we have under the transactions and we would like to reverse this. Here we go. You can also use the date, right? You can use the ID uh sorted depending on the ID, but this would also work without any issues. And now we would like to add each transaction to the list. I'll say sorted transactions do for each. Let's get the each transaction and run this method where we'd like to say create transaction element. which is going to be a method and we'll just say transaction pass it into it. Then we would like to build this method. This will give us the list item, right? It let's say transaction element and we would like to append this to the UI. I'll say transaction list element dot append child and it will be this child which is the transaction element. Now let's create this method. I know that at the moment it might not make too much sense but once we complete everything it should be pretty clear and crisp. So I'll go ahead and basically create this method. Here we go. This will take the transaction as the argument and we are going to create a list item. Now why this is the case here we said that the transactions will be inserted here which is a ul element. So we would like to basically put couple of different list items right here and those will be whatever you submit, right? Okay. So this is exactly what we're going to be doing right now. The first thing we would like to do just create a list element. I'll say document createelement which is going to be a list item. Then we'll say list item. class list class list dot add. And the thing that we would like to add will be the transaction class. Then we would like to add another thing that will be either income or expense. So I'll basically duplicate this. And here I'll say if transaction dot amount if it is greater than zero that means it is an income. So we're going to add the income class. But else if it is negative which means it is an expense. Now we can update the inner HTML which is the content. Let's say inner HTML and I'll put back text because we'll go make this multiple lines here. I'll have a span element and we need to type this out manually. Let's open this up. Close this off. And I would like to say here it'll take the transaction description. Then we would like to have another span. I'll duplicate that. This will take the transaction amount. Now, we'll like to format this. We're going to wrap it with a method, but I'll just leave it as a to-do in a second. Um, the other thing that I'd like to do still within this pen, I'll create a button, which is going to be this delete button, right? Okay. So, I'll say button and close this off. Okay. We're going to give the class name. Let's say class will be equal to delete dash button. And please be very careful. Just type it out exactly what I do. So do not forget the quotes. Anything that we have right here otherwise it's going to crash, right? So you should add the closing tags, opening tags, like everything it should be correctly. Okay, we have the class name on click. We're going to add. So once we click to this button, what do we want to do? just remove a transaction. Here I'll open up my uh quotes and I'll say remove transaction call this method with the transaction ID. Let's maximize this here. I'll say we will put the transaction ID. Once again, this will make a lot of sense just in a couple of minutes. And for the button content, it could be this X icon, right? The X character. Okay, so this is what we have. We have a to-do. We will fix in a little bit. If you wanted to, you can add a comment maybe right here. Let's say to-do update the let's say amount formatting. So this is what I do almost always adding a to-do so that I do not forget it in either case right in any case. Okay. So that's going to be for the inner HTML. Now we can basically return the list item which is the thing that we are getting and appending it to the UI. Okay. So that's going to be it for this update transaction list method. The other thing that we need to build is the update summary method. For now, I'll comment this out and just test it out just to make sure that everything is working as expected. Okay, let's go here. I'll refresh and we'll say enter description could be like let's say my salary and for the amount let's just go with 500 and I'll say add the transaction. As we can tell it has been added without any issues, right? If we click to it, nothing will happen because we haven't built the method. But this is a bit later in the video. Okay. Now we have updated this part but the summary has not been updated. This is something that we would like to do right now. I'll go ahead uncomment this one. Copy the name and create the method at the very bottom with a function. This will not get any arguments but we'll just go right here and try to calculate the total balance. Okay. So the first thing I'd like to do just say const balance. This will be the total balance. We'll say transactions and we can use the reduce method. Let's say reduce. And you can use this on arrays. This is an array method. And since the transactions is an array, we can safely use it. And here is how that work. So this will basically take a call back and then an accumulator, right? And we are going to start with zero and we'll add on top of it. Now let me give you an example. Let's say we have an expense or income of 100. We have an expense of minus 50. We have another income 200. And let's say something another expense with let's say minus 200. What this meth method will do it'll just get uh add these values on top of zero. So we're going to start with 0 + 100 + - 50 + 200 + - 200. So this will be equal to zero. 50. At the end the balance will be 50. And now let's see how this will work. I just need to explain it in really detail because maybe this is your very first time seeing this method. So we're going to get the accumulator, right? and then the transaction itself. So here we'll say accumulator plus this is what we would like to return transaction dot amount. Okay. So once again I'd like to walk you through it pretty quickly. So we're going to start with zero accumulator is equal to zero and the first transaction is equal to 100. So 0 + 100 this will be equal to 100. Right now this will be the new accumulator. So we have 100 at the moment as our accumulator. So 100 + min - 50. Right? 100 + - 50 will be 50. This is our new accumulator. So on and so forth. We'll just go through it until we complete this entire array. I genuinely wanted to explain this super slow so that it makes sense. Now we got the total balance. Let's try to calculate the income. So I'll say cost income transactions. Now this is an array. We would like to first filter out the let's say first we'd like to get the incomes, right? The positive numbers. So we'll say get every single transaction where the transaction amount is greater than zero. And then we'll do the same thing that we have done above. We would like to uh reduce it to a value. So we'll copy the entire thing. Paste this in. We'll get accumulator the transaction and we will add it on top of zero. But this will be the positive values only. We can do the exact same thing for the expenses. And we'll say if the amount is less than zero just grab them. and finally reduce it into a one single value. Now that we got all the values, we can update the UI. We'll say update UI. Let's say balance element. ext content will be equal to the balance. And we'll basically do the same thing for uh income amount element as well as the expense amount. So here I'll just say income. Let's duplicate it. This will be expenses. And then we would like to say expense amount element. Now I'll add another to-do right here. I'll say to-do fix the formatting. Again, we're going to create a method and wrap them with these arguments, but it'll just be in a couple of minutes. For now, let's save and actually test this out. So here, I'll go ahead take a look at the end result. I'll just refresh. We get rid of the previous state, but it'll just come back once we use the local storage. So for now, let's say my salary to this time. I'll add 500. Add the transaction here. We can see the balance has been updated, right? And we can say now uh something like AirPods it is expense. I'll say minus 200. At the transaction, everything is being updated. Now, as you can tell, this is not really formatted. We would like to see something like this and it is really easy to build thanks to the internalization method or the API. Basically, I will create a method called format uh format the currency. Let's say function format currency. This will take the number that we would like to format and we'll say return new internalization. So in NL dot number format we would like to use N US and then an object where we can say the style will be equal to currency and the currency itself will be let's say US dollars. And we'll just say dot format this number. Okay. Now we can go ahead wrap them with the format currency method. Just like this. Now we are able to see them. But this is actually coming from HTML, right? This is the previous state. It is not coming from here. But if we were to get the previous items. So, I'll just go ahead add something else. Let's say something and I'll say 1,000. Add the transactions. Uh, here we can see like it's been updated with the format currency method. Now, the thing is if we refresh this page, all the data is gone. It is actually in the local storage. So, how can we get that? Well, basically in the initial render, we would like to call the update summary as well as the update transaction list method. So, let's go ahead call both of them. And here we go. When you refresh, it'll just get you the data from the local storage. Okay. So, I think I have another to-do. Let's go scroll to the top here. I said we would like to format the amount right here. I'll go ahead wrap this transaction amount with the format currency method. Now if you save everything should be working as expected. This is the correct usage right? If you try to create a transaction element I'll just say like airports airpods 2 I'll say 500 and this should be an expense. As you can tell it has been formatted right here as well. Without this it wouldn't be okay. Now I think the very last thing that we need is the remove transaction method. When we click to this button it will run but we don't really have it. So let's go ahead and create it. I'll say function remove transaction and this will get the ID of the transaction so that we can identify which one is that we are trying to delete. So here I'll just say basically filter out the one we want to delete. Okay, we'll say the new transactions will be equal to transactions filter. We're going to get every single transaction but we would like to get the specific one and just filter that out, right? Like get rid of that. I'll say transaction ID. If it is not equal to this ID that we have just keep it in the array but if we have that get rid of it. So this is how that work and we'll say now that we have updated it let's save it to the local storage. So basically we will update our local storage which is the transactions and we'll say JSON stringify put the new transactions. Okay. Finally, we'll just update the UI, right? I'll say update transactions list. And finally, update summary. So, this is the beauty of having methods. So, we don't really need to write this entire logic again and again. Whenever we need it, we would just call it just like right here and even up here as you can tell. Okay. Now, we can delete this to-do, save this, and give it a go with the remove functionality. So, I'll delete the something. As we can tell, our income has been updated. The transaction list has been updated. And we can add more things. I'll basically go ahead and add some AirPods. Let's say minus 200. Let's add another thing like salary 500. Basically, anything. I'll just try to show something. I'll say, you know, some text. Okay, so I said we're going to have some to-dos in the style. CSS file when it comes to the WebKit scroll bar, right? Okay. Now, let's try to go over it once again. So, I just said that the scroll bar track would be the background. Let's say the background color will be red. As you can tell, the background of the scroll bar is red at the moment. So, this is something that you can play around with. I'll bring this back and the scroll bar thumb is the scrollable element itself. So let's say the background will be blue. As you can tell it's been updated, right? When we hover over this, it changes thanks to this line. Okay, so these are the some values that you could play and I wanted to add a to-do so that we can just go over it pretty quickly. Let's say you want to update the width. So this is how it'll look like. I think that this is a bit too much. So we can go with eight. Okay. So with that that's going to be it for this entire project where we have learned about bunch of different things when it comes to the CSS and for the very first time we have worked with the local storage in this series. So I hope you enjoyed the entire project. I'll see you in the next one.
Project 5: Bookmark Saver Application
So in this section we're going to build a bookmark saver application. So here's how that work. We can add a name as well as a URL. So let's go ahead and add something like, you know, I'll say Twitter and I can say https and I can zoom in. Let's say twitter. com. Add the bookmark. Now it's been added. If we click it, this is the page that we will be redirected. And if you wanted to, we can delete it. And everything that we have here will be saved to the local storage. So if you refresh the page, it'll still be here. All right. So you can see the screenshot within our diagrams. Now let's get into the application. The very first thing I'd like to do just build the HTML. Then we're going to get into the CSS and then the JavaScript file. Okay. So I'll maybe zoom in just like this. And this is the end result. By the way, let me update the title for that. I'll say end result. and we're going to build our own document now. Let's say bookmark saver. Okay, let's open this up within a new tab. Okay, here we go. This is what we have. Now, the very first thing I'd like to do is link my CSS file. Here we go. And then we can get started with the UI. So, I'll just have an app container. Then we will have a H1 element that will be this title that says bookmark saver. Okay. Then right below to it we'll have an input container. Right. I'll say input dash container. Here we go. And we're going to put two different inputs. Both of these. And then a button. So I'll say the very first one will be input which is a type of text. We can give it an ID like bookmark dash name and then a placeholder which can be bookmark name just like this one. Okay. Then I'll go ahead duplicate this one. The type for this will be URL. Let's say ID will be bookmark URL and update the placeholder within or I should say below to this input. We're going to have a button. Let's say button. give it an ID like add-bookmark and then we will say add bookmark. Okay, so that's the entire UI. The very last thing that we need is kind of like a list component where we can put these items as we add something right after this button and after this div. So outside of the input container we will have a ul with the id that will be bookmark- list. For the content we will not have anything. It'll be coming from the local storage or whenever we add something it'll just be updated. Okay. So that's entire HTML file. Let's go ahead uh sorry let's go ahead and add the script file. So we just linked our JavaScript file as well. Now it is time to move on with the CSS file. And by the way, this is what we have without any styling. Now let's go ahead and get started with the basic reset that we do every single time. So say margin of zero, padding of zero, and box sizing of border box. Now we can select the body. Let's say font family will be sense serif. We can change the background color. Instead of the white value, I'll just go kind of like grayish, which will be this value. And then let's say color will be like three couple of times and display of flex just by content center just like this. And then align item center. Now finally we'll say entire height will be equal to the entire screen. Now everything has been centered. Now we would like to select the app container. We can say background color will be fff just like this. And padding let's say 20 pixels from all directions. And let's give some rounded corners. I'll say border radius of 8 pixels. And some let's say box shadow that will be 0 to 4 pixels. Let's duplicate it 8 pixels or let's go even with 10 pixels. Then finally the color I'll say RGBA. We'll go with the black one. 1. Okay, this is what we have. Now we'd like to say maximum width will be 400 pixels and then the width will be 100%. Here we go. And then we can say text align will be centered. And instead of 100% width, I'll go with 90% so that it is not touching the corners. Here we go. Then I'll just say H1. Let's select the color and update it to be a green value like 2E C 71. Then we can say margin bottom of 20 pixels. This is what we got. Now we can select the input container itself. input dash container. We'll go ahead say display flex so that they are side by side. We can say flex direction of column because we want them to be in the column direction. Here we go. If you don't add this, by default they would be side by side. And then we would like to say gap of 10. Then finally we can say margin bottom of 20 pixels from the list item that we'll have later in the video. Then we can say the input that could be padding of 10 pixels. Then we can say give some border radiuses like four pixels. Then we can update the border itself. I'll say 1 pixel solid dd. Here we go. Then we can select the button. I'll say padding of 10 pixels. Then we can say background color will be this exact same value. Then we can say something like the color could be white. Then no borders. Let's say border of none. We'll say border radius of 4 pixels. We can say the cursor will be pointer. And on hover that let's say button do hover state. We would like to change the background color to be this value which will be 27 AE 60. Now we can add some transition right I'll say transition will be on the background color and we'll say 0. 3 seconds with the ease function okay now we can get started with the bookmark list even though we don't have it in the UI this will be a bit later in the video once we have these items right I'll say bookmark dash list then we'll say list style will be none And then we can say padding will be zero. Then we can select the list items itself. So I'll copy this thing. We'll say list item can change the background color which will be this value. Let me paste this in. Then we can have some paddings like 10 pixels. Can update the border which will be 1 pixel. Solid and ddd. We can say border radius will be 4 pixels. margin bottom of 10 pixels, display of flex. And then we would like to say like justify content will be space between let's say space between and then align items center. Here we go. Then we can select the A elements. We'll say bookmark dash list a element which is the link that will be color of this exact value. And we can say text decoration will be none. So that we get rid of the underlying text decoration which is coming by default. Then we can select the button element which is this one and give this kind of like a delete background color. Right? I'll say uh bookmark dash list. So like the button background color will be E74 C3C. And then we can say color could be white as well. We'll go ahead say no borders. Some border radiuses like four pixels. Padding of 5 pixels to 10 pixels from top and left like top, bottom and left and right. And then cursor will be pointer. Then we can finally say give some transition of let's say background color. Okay. So 0. 3 seconds with the ease function. Now we can select the exact same thing but change the hover state. Okay. I'll say background color will be equal to this value which is C 0392B. Okay, so that's going to be for the entire styling. Now we can jump into the JavaScript code. And just before we jump into the JavaScript, you might be asking what we have here is almost the exact same thing that we have on the button. So why do we need to add all of them? You are absolutely right. So we can go ahead and delete the parts that we don't really need. So this thing is exactly the same. We can delete it. These styles are The only difference will be the background color as well as the padding. So I'll go ahead save. Nothing should change. Right? This would be working as expected. Now this is not what we have. But this is what we have at the moment. But the end result will look like this. So what we have just done update the padding on this button as well as the background color. the everything by default would be coming from the regular button component that we have. Okay, with this in mind, let's go ahead open up the script. js file and get started with it. So the first thing we would like to do just get all the DOM elements that we would need such as the name input, URL input, the button as well as the list that we have right here. And I have prepared a GitHub gest that you can copy and paste all of them if you don't want to type this out. So the link will be in the description. Go ahead, find the bookmarks saver. md and copy this entire thing. So this is what I have done. right here. Right? So we are basically selecting every single element with their ids and assigning them into some variables. So the first thing we would like to do whenever we like whenever we visit this application we want the like bookmarks that we have in the local storage to be loaded immediately right. So they are going to be coming from the local storage. So I'll just say document addevent listener whenever the DOM content loaded basically whenever the website is loaded we would like to call a method called load bookmarks and this is something that we're going to build in a couple of minutes. For now let's just leave it as an empty function. Okay, so that's the first thing. The other thing we would like to say is the add bookmark button event listener. Right, we are going to add an event listener which is going to be click and we're going to call this anonymous function. So let's go ahead create it and just try to get started with it. So when you want to add something, the first thing we would like to do is get the name as well as the URL. So this is what I'll be doing. I'll just say const name bookmark name input do value. And we can just trim that down. Let's duplicate this. This time this will be for the bookmark URL input. So we're going to get that value and assign it to URL. Okay, we got both of these values. But now if one of them is not provided, it'll say please enter both of them. I'll just put something here and try to add. As you can tell, it just crashes, right? So I'll say if there is no name or URL we would like to alert something I'll say please enter both name and URL and we would like to just return out of it. So we don't really want to do anything else because they just failed. But in the else's case that means they have provided both of them. we can go through a quick validation check. Now, what does that mean? I'll add, let's say, YouTube, but for the bookmark, I'll just say YouTube. com without HTTP or HTTPS. Here, we'll get an alert that says, "Please put one of these at the beginning. " So, this is what we're going to be doing. I'll say if URL starts with, well, actually, not starts with. So if this is the case where it does not start with HTTP and we'll say if it does not starts with I'll basically copy this entire thing and I'll say https. If this is the case we can show an alert. Let's say please enter a valid URL starting with HTTP or HTTPS and we would like to return out of this method um if this is the case. But in else case we can just go right here call a method called add bookmark. This is something that we're going to create where we would like to add the name as well as the URL. And we also want to save this bookmark to local storage. So I'll say save bookmark. I'll say add the name as well as the URL. Then finally we would like to reset the form. Once we add something, it should update the UI. Right? Let's take a look at the end result. I'll say https at this form has been resetted. So we'll say bookmark name input do value will be equal to an empty string. Let's do the same thing for bookmark URL input do value. Okay. Now it is time to build these methods. So the first thing I'll be doing is to build the add bookmark not btn. This just should be add bookmark because it is a function that we are about to build. We're going to take the name as well as the URL and we'll go ahead create a uh list item. We'll say document createelement that will be a list item. And then we would like to create another element that will be a link. So here I'll say link and then we would like to say link. h will be whatever the URL is. Then we can say link. ext content will be whatever the name is. And when we click to the link. So notice how it'll open up in the new tab. And to be able to add this, we'll say link. target say target will be equal to underscore blank. If you do not add this line, it'll be opened in the current tab, right? It'll just replace the current URL. This is what we have just done. And then we would like to add the remove button. So I'll say con remove btn or let's just say button that will be equal to document. createelement which is going to be a button element. Then we can add the text content. So we'll say remove button dot text content will be equal to remove and then we can say remove button dot add event listener. So when we click to this button we would like to delete something right. So I'll say function and within this we will say first uh remove this from the UI right I'll say bookmark list dot remove child which is this list item that we just clicked. So we add the list item itself. It's because both of them are linked right. So if you click this button, it'll delete the li that you have just created which is this one that right here right and then once we have done this once we update the UI we would like to remove it from the local storage as well. I'll say remove bookmark from storage and this is a method that we're going to build just in a second. Let's say pass the name as well as the URL. Okay, so we have created the list item but we never added the link and the remove button into it, right? I'll just say alli append child where we'll append the link and then let's duplicate this. Within the alli, we're going to append the remove button. And finally, we will take the list item and append it to the UI. I'll say bookmark list append child. And we're going to basically append the list item itself. Okay, so let's move on. I'll just save. Now, the next function that I'd like to create is called get bookmarks from storage. So, this is a helper function that we'll be using a lot. And all this does, as the name suggests, it'll just go ahead get the bookmarks from the local storage. So, I'll say bookmarks, it'll be equal to local storage. get item. And we can give this key. I'll say bookmarks. And we would like to say just return the bookmarks. But now if this is undefined, right, we would like to return an empty array instead. So I'll just say if we have the bookmarks, go ahead say JSON. parse the bookmarks, but else just return an empty array. And let's move on with the next function which will be save bookmark. That will take the name as well as the URL. We'll go ahead and first get the bookmarks from the local storage. So this is why we have built this method in the first place. We'll just say get the bookmarks from the storage and we would like to add this new one on top of it. We'll say bookmarks dotpush where we would like to push a new object with the name as well as the URL that we just got. And then we can say local storage dot set item. So we'll just update it with the new value, right? I'll say set item that will be added into the bookmarks and we would like to add some value. So we so we'd like to say JSON stringify and whatever the value is which is the bookmarks. Okay. So that's going to be it for this method as well. Now let's build this one as well as the remove bookmarks method and that should be it. So if we want to load the bookmarks, we would like to say con bookmarks just like what we have done here. I'll copy it and paste it. Then I'll say for every single one of them just map through it and put it into the UI. So I'll say bookmarks dot for each and for every single one of them we would like to say add bookmark. Go ahead call this method with the name. I'll say name and the URL and that should be it. This is going to update the UI. And finally, this is the very last function I promise. We'll say remove bookmark from the storage that will take the name as well as the URL. And we'll go into within this function and let's grab every single bookmark that we have from the storage. And then we can filter this out, right? We're going to delete this one that we would like to like the user wants to delete. I'll say the new bookmarks will be equal to bookmarks filter and we're going to get the bookmark itself. Right? Every single one of them. But we would like to filter out only one of those. I'll say bookmark name is not equal to this name or let me maximize this. So we'll say or bookmark URL is not equal to the URL. So this will basically filter out the one that you would like to delete. And finally we can update the local storage once again as we have done above. Okay. So, I'll just save and give it a go. Test this out if it is working correctly or not. So, I'll just refresh and I'll just try to add a bookmark name. I'll say my GitHub profile. Let's add it. Uh, I'll say github. com and my username. Now, if I don't really add this field, I'll get an alert. If I don't add it with HTTP or HTTPS, I'll get an alert. But if I put it correctly, it should be added. And I'll refresh. It is still here. I can delete it. Here we go. And I can refresh it. Okay, it's still here. Why this is the case? So this is the case. It's because we say constant and we try to reassign it. If you take a look at the terminal, you're going to see that we have some errors. I'll try to say remove here. Here we can see we are just getting some errors. Our application breaks. So instead of cost, we should say alert. Now let's test this out. I'll go ahead delete this. Refresh. It is not there because it has been deleted. Okay, with this in mind, that's going to be for this entire project where we have built a bookmark saver. And I'll see you in the next project. In
Project 6: Registration Form Validator
this section, we're going to build a simple registration form where we have some form validations. So let me walk you through it. in the end result and then we'll just jump into the code. So if I do not fill anything and I say register, I'll get bunch of different errors. Let's go ahead and fill them in. I'll say this is the username such as John Doe. Let's give it an email atgmail. com. I'll say password from 1 2 3 and 1 2 3. Now here we can see it says these are valid but password must be at least six characters. So I'll go ahead and say 4 5 6. Now it says they do not match. And if I put everything correctly, but if I don't have a valid email, then it's going to crash as well. Email is not valid. Let's put this back and put something like just jo and run this. It says username must be at least three characters. And let's bring this back. Finally, let's say register. It says the, you know, registration is successful. And here we go. Form has been resetted. So this is the entire project that we're going to build and you can find the screenshots within the diagram that we have the link in the description completely for free. Okay, now let's jump into VS Code. I have three different files HTML, CSS and JavaScript. Let's put them side by side and first get started with HTML file. So I'll get my boiler plate and then I'll just add a title. Let's say form validator. I'll say link my CSS file. And at the very bottom of the body, I'll say script source script. js. Okay. Now let's get started with the container that we will have. And this will have a form. We are not going to have any actions, but we'll have an ID. Let's say it is called as registration dash form. Then we'll go ahead say H1. We're going to put this H1 the heading let's say register then we can go ahead get the username field right so we're going to build this one then the rest and finally the button so I'll say form dash group that will have the label input and another element that we will see so I'll say label this will be for username input and the text will be username Let's say input type of text and we can say ID of the username and then the placeholder it'll be enter username and we can run this file by the way. Okay. So this is what we have. If we click to the label it will focus because of the linking that we have. We say this label will be for the uh input that has ID of the username. So if I click it, it focuses. And then we're going to create a small element that will be empty. And we're going to fill this in whenever we have an error. Right? So this is that small element that will be hidden by default and it's not going to have any content. So we're going to like we're going to see this in a couple of minutes. All right. Now what we can do is basically duplicate this for the email. Let's say the uh four will be for the email. This will be email as well. Type will be email. ID will be email. And we'll say enter email. Okay. Let's duplicate this once again. This will be for the password. I'll basically select all of these and I'll say password. Okay. And one last time I'll duplicate this and let's say that was the password. And this is the confirm password. Okay. I'll select every single one of them. Let's say um confirm password and I'll give a space and let's say enter or let's just say for the placeholder it'll be confirm password. Okay, so this is the end result that we have. We would like to add a button and then jump into the CSS file. Let's say type will be submit and then the content will be register just like this. Now let's save and go back into the CSS file that we have and get started with it. The very first thing I'd like to do add my reset. So I'll say margin of zero padding of zero and box sizing of border box. I'll select the body element. I'll give the background color. Instead of white, I'll go with this hash value of F9 couple of times. Here we go. And then I'll say one family. We can go with sense serif. If you'd like to change it, definitely feel free to do so. Then I'll say display flex align item centered justify content centered and we'll say minimum height would be 100 VH. So we are basically setting up the height to be 100 VH and centering the entire content in the middle of the screen. Then we'll go ahead select the container element. We'll say background color will be white. Here we go. We'll say border radius will be 8 pixels. Maybe it is not really that visible but this is that container we just created. And then okay this should not be a background repeat but border dash radius and then we'll say box shadow I'll say 0 pixels 5 pixels to 15 pixels and then the rgba of the classic color that we use. So I'll go with black and for the alpha I'll say 0. 1. Here we go. Then I'll say width will be 100% but the maximum width will be 400 pixels and then we can say um give some paddings such as 30 pixels and then we could say overflow of hidden then I'll get the H1 and say text align will be centered then I can say color will be three bunch of times and then margin bottom of 20 pixels let's say here we go you can also use RM. I'll just go with 1. 2 RM. Then we can select the form group element. I'll go ahead say margin bottom will be 20 pixels. Now we also want to add the position of relative. And because like let me display we'll say position will be relative because on these small elements we will position them absolutely. So that's why we are saying this is the position of relative. Then we can go ahead update our labels. We'll say select every single label just say display of block. Then we would like to say something like margin bottom of 5 pixels. Then we can say color will be updated to 555. And font weight could be a little bit bold. Here we go. Then I'll select my inputs. I'll say border will be 2 pixels. It'll be solid. and then hash value of f0 bunch of times. All right. Then we can say the border radius will be four pixels. We could say display will be block. Here we go. Then we can say width will be 100%. Then padding of let's say 10 pixels. And on the input element I'll say font size will be 14 pixels. And finally the transition will be on the border color with 0. 3 seconds. Let's go ahead add the focus state. I'll say input. If it is focused go ahead say there is not going to be any outline but we would like to change the border color which is going to be 34 98 dB. Okay let's try to focus on it. As you can tell, the border color will change. And then I'd like to select the small element. So here I'll say small. The visibility will be hidden by default. And I'll explain just in a second or actually let me do it immediately. So when we have an error, so I'll refresh. So by default it is invisible, right? We don't have any content. But if we cut something, if we have some errors, it'll be visible. So this is exactly what we're doing. By default, it'll be uh not visible but then in a couple of minutes we will say visibility will be visible. I hope that makes sense. Then we can position this absolutely to uh let's say bottom minus 80 pixels or 18 pixels and the left of zero. Then finally we can decrement the font size to be 12 pixels. Now I'll just save this file. Let's take a look at the end result. I'll try to visit the index. html. And here on the very first input, I'll say on the first small element, I'll say username is required. Let's save. Now, it is not really visible because of this line. Let's delete it. It's right here as you can tell. Okay. And these errors will be added dynamically from our JavaScript code. And after the small element, we can select our button and style it. I'll say select the button. I'll say cursor will be pointer. Then we could say background color is going to be this exact same value that we had above. The primary blue button. We don't really want any borders. So I'll say border of none. Color could be white. Let's save. This is what we have. Now we're going to give the display of block. And then we'll say font size could be oops let's say font size will be 1 rm. Then we can give some margin top of let's say 20 pixels. And most importantly the padding of 12 pixels from all directions. And let's say border radius border dash radius will be let's say 4 pixels. If you wanted to you can increment it. And I'll say width will be 100%. It'll take the entire width. And finally, the transition will be added on the background dash color with 0. 3 seconds. Let's go ahead and say button if it is on the hover state. We'll update the background color to be this value which is going to be 2980 B9. Okay, it is this dark blue value. So the only thing we left is the error and success states. And let me once again demonstrate this pretty quickly. If we have an error on username, the error class will be added right here. Right? If we have an error on email, it'll be added right here. So just keep this in mind. But if it is successful, it would be success. Okay? With this in mind, let's see how we can update our states. I'll just say form group dot error without any spaces because it'll be in the same element. And then I'll say select the input element. Go ahead update the border color to be this error color which is E74 C3C. Okay. And maybe we can just duplicate this and update this to be form group but success case. We're going to give a green color like 2E c 71. And then finally on the error case. So I'll say form group dot error. We're going to select the small element and we'll say visibility will be visible and we would like to update the color to the exact same error color. Okay. So that's the entire CSS file that we would need. Now we're going to jump into the JavaScript file and get started with the functionalities. So the first thing we would like to do is get our DOM elements and for this I have prepared a GitHub gist that you can find the link in the description. So go ahead find the form validator MD and basically copy this entire elements that you have seen. We're going to get into this in a second. For now just ignore that. All right. So we got the form, we got the username, email, password, as well as the confirm password inputs. The first thing we would like to do is add an event listener on the form. So I'll say add event listener, which will be listening for the submit event and we'll say once we got that, go ahead and handle it within this function. So we're going to take the event as we have talked about it in a previous project. The very first thing you would like to do is say e. prevent prevent default, right? So, we don't really want this page to be refreshed. So, if you don't add this and if you say like submit this form, it is going to refresh the page. So, just notice how it's going to refresh it. But if you add this line, it's not going to refresh that, right? And then the very first thing you would like to check if all the fields have been filled in, right? So when you just say register developers check will be just to check if any of these fields are empty right. So let's say con is required valid you can call this anything but this is the name that I'll have and we're going to call a method called check required. And this is a method that we're going to create. Let's say function check required. Now this will take an array. Let's say we're going to put the username, email, basically all of our inputs, password, as well as the confirm password. So, we're going to pass this as an array so that it's a lot more comfortable to handle it. Can we just minimize this? It's already minimized. Oops. Okay, I'll just leave it here. All right. So, we just sent this array that we're going to check within the method in a really, really easy way. So I'll just say get the input array and we'll basically run a for each on this input on the input array. So first I'll say let is valid that will be equal to true. So by default we will think that it is valid but we will update it. Let's say input array for each for every single input we are going to run this method. So I'll say if input do value trim. So we're going to trim this down. And if it is equal to an empty string that means it is invalid. We would like to throw an error. So I'll say show error. And this is a method. Once again we are going to build and this will take two different arguments. So the first one is the input itself. So we need to say which input has an error. Let's say you filled this in. You filled this in but you did not fill these right. Okay. So the show error will be run on these inputs and this is exactly what we are passing. I'll say the input so that it knows which input to show the error and then we will say like the message here I'll say something like is required but what is required right? Is it password? Is it confirm password for this? We can say the input itself. But now if you put it like this, this will look kind of not formatted. So it will say something like password is required. But we want what we want to do is take the very first letter and capitalize it. So this is what we would like to have. So for this I will create a method that will format the input. I'll cut this for a second. I'll say get field name. Let's say input. This will basically format it. Let's create that method. And let's actually call this as a format field name so that our code is a lot more readable. And I'll paste this method. It's super simple. And I even added some comments. So if the input ID is equal to username, it'll take that and capitalize the very first letter. So this is how we do it. We'll say input do ID get the first character and uppercase it and then put the rest as it is. I hope this makes sense. Now this is working properly. Now that we got an error, we'll say is valid is equal to false. But in else case we can show a success message. Let's say show success. And this is another method that we're going to build. And of course we need to pass the input so that we know on which input we will display the success message. And at the very end we'll say return is valid because at the end of the day from this method we are expecting a boolean value that is either true or false. And just before we move on, let's build the other functions that we would need which is going to be the function of show error as well as the success. Okay. In the show error method, we'll get the input as well as the message as the argument. Then we would like to select the form group. Let's say form group that will be input. ment element. Now why are we selecting the parent element? Because if you have the input like you would like to go into the parent element which is the form group and as I said previously we're going to add the error class right here or the success class right so that's why we are selecting the parent element that will be equal to form group then we can add a class name I'll say uh class name that will be equal to form group plus it'll be the error, right? You cannot just say error only. This will delete the form group and add only the error. So, we'll add both of these. Then we can say con get the small element. I'll say form group query selector. we'll just get the small element and update the text content right I'll say small you can also say inner text is equal to this message so that's it for this method and let's hand handle the test case we'll get the input let's get the form group in the exact same way and for the class name we will say success instead of error okay so that's it because in the success case we don't really add any messages as you can tell. So with this maybe we can give it a go. Let's see if it'll work or not. As you can tell this is the demo application that we have and we are getting all these fields with some errors. Let's fill them in. Okay, it is valid. We display the success feedback but error on the other ones. Now that was the only the first help. We have other things to do. Let's just fill this in pretty quickly. I'll say gmail. com. Now this is also a valid email, right? So maybe this the provider isgm. com. So this is completely a fine email format. Then we can say from 1 to six and I'll just on this one. But let's just say only two letters. Okay. So this is one of the other checks that we need to keep in mind. Username must be at least three characters. And let's put this back. But now this is invalid. This is another check that we're going to have in our code. Now let's put three uh or maybe just one. It doesn't really matter. It'll say it should be at least six characters. And then we will finally check for the like if the passwords are matching or not. We have four additional checks that we need to add. I'll scroll to the top. So that was for the require required fields. We would like to create a variable for is form valid. This will be equal to is required valid initially but we will update this in a second. I'll say if is required valid we would like to check for the other things. I'll say const is username valid and we're going to call a method to check the length. So we'll say check the username. The minimum value could be three and the maximum could be 15. So if you try to add something more than 15 characters here, we can see this is another error that we have. And then we will have another check. Let's say cost is email valid. And we're going to call the check email function where we would like to check for the email that user just typed in. And then let's duplicate this one. It'll be is password valid. We will check for the length. Let's say check for the password. Minimum could be six and the maximum could be 25. Okay. Finally, we will duplicate this and we'll say check passwords match and we will check like we will compare both of these values which is the password as well as the confirm password and for the variable name we could say is passwords match. Okay, now we need to create all these methods one by one. So let's scroll to the bottom and try to build it. First I'll shrink every single function that we have so that it's easier to build. I'll say function check length where we'll take the input as well as the minimum and maximum values. So the very first if check will be this one if input dot value. length if it is less than the minimum value. In this case, we would like to show an error. Let's say show error call the method on this input, whatever that is. And then we'll say uh something like must be at least minimum characters. And let's put the money sign. And finally, whatever the input is, but we would like to format it just like what we have done previously. So we'll say format field name. And we're going to pass the input as the argument. Okay. And we're just going to return false from this method from this call. Now this will be equal to false if we hit this if check. And then else if we have the maximum case input do value length if it is greater than the maximum value I'll basically get the exact same thing but we'll say it must be let's say less than maximum characters and then return false but else that means everything went successfully. So we can say show success on this input and return true. Okay. So that's the very first method that we would need. The other one will be to check email. So here I'll just put it right here. Let's say function check email where we'll take the email and handle the method. Now we're going to be using a regular expression. If you don't know what that is, I can give you an example. So the first thing I'd like to do visit that GitHub gest and I'll copy this email regular expression. So let's go ahead and copy this and we're going to test this out right now. Okay, I'll just open up my terminal or the console I should say. I'll paste this in. So this is a regular expression that will check if an email is valid or not. So let's paste this in. We have this variable. Now we can say email regular expression. Okay, let's get this one and we'll say test and we can test anything. Let's say a. com. Is it an email or not? Obviously, it is not. So, it'll return false. Let's put something correct. I'll say gmail. com. But let's say john@gmail. com. Okay, this is equal to true. So here we can see this is not valid. It'll return false. And this is valid. it'll give you true. This is really easy to build with regular expressions. And just before we move on, if you delete this part and tell me to type this out, honestly, I cannot do it and I don't have to and you don't have to neither. So this is something that you would mostly get from you know online or you would get it with AI. So okay, just keep that in mind. If this looks complicated, maybe you are thinking how do I memorize this? How do I learn this? absolutely not needed. Then we'll go ahead say if basically what we have done in the terminal I'll say email reax test and we'll basically test the email. So I'll say email value trim if this is equal to like okay sorry this will return you either true or false. If this is true then we can show a success message. But if it is equal to false that means we need to show an error in the else case. Here I'll say show the error and here we'll just call the show success method and I'll pass the input and then here we'll pass the input as well as the message. Here we'll say email is not valid. Here we go. then we can return false from here and true within this if check. Okay, so that's going to be it for the check email method. The very last one that we need is the check passwords match function. That's going to be super simple. Let's go ahead and paste it. Um this will take the input one as well as the input two. Here I'll say if input one value is not equal to input two value. In this case we're going to show an error. This is the input two that we're going to show the error and we'll say passwords do not match. and then we can say return false. But if this is not the case, we'll just say return true. Okay, now that we got all these methods, we can move on with this uh if check where we need to just update this variable, right? I'll go ahead and say is form valid. And by the way, I have a typo. This should be valid at the end. I was just missing ad. So we'll say is form valid will be equal to if user name valid and we'll just basically chain all of these within and check. So if every one of them is equal to true form is valid otherwise we're going to get false. Okay, here we go. And then outside of this if, we'll say if is form valid, we would like to say alert registration successful. Okay, but uh not but and I was going to say we'll say form. reset. Okay, it should be reset like this. We'll basically delete the input elements. And finally, we can remove the success classes. I'll say document query selector all select every single form group and we'll say for each we can get every single group element let's say group and we'll say group class name will be equal to only form group right previously we had this success as well but we would like to delete it and have this one only. Now let's save. Everything should be working as expected. Let's go ahead and test this out. I'll leave everything empty. We got our errors. Let's put the correct values. Like I'll just say Joe at the end. I mean at the beginning I'll say John@gmail. com. I'll say 1 2 3 1 2 3. Okay. Why is this? Did we Okay. Let's see. Type should be password. Okay. Now, if you type in, it's not going to be visible. Let's type this out once again. I'll say Joe John@gmail. com. 1 2 3 1 2 3. So, we got an error which says username must be at least three characters. Let's say John and have another error. So, we should got an error, but looks like we didn't. What are we missing in our code? Let's take a look at it. So I just realized here in this method we are getting the email but I accidentally put the input. So this should be email and this should be also email. If you wanted to you can call this as input and make those input as well. But this is what I'll have. Let's try to test this out once again. I'll put the invalid one and 1 2 3. Now let's see. So email is not valid and this should be at least six characters. Let's put the correct one. Okay, now this is success. But this is not really success. Let's say 456. Now they do not match. Register. Now we got the alert and then everything has been resetted and we got rid of the success uh success classes. So with that that's going to be for this entire project where we have built a form validator with the register um register form and I have a typo. Let's fix it. Okay, this is what we should have. And that's going to be it for this project. I'll see you in the next one. All right
Project 7: Password Generator with Strength Meter
welcome back. In this section, we're going to build a password generator application. This is the end result. Let's take a look at it how that work and then we'll jump into the code. Now this is such a classic application but it's really helpful that will teach you a bunch of different concepts. Okay. So this is the end result. When you first refresh you will get a random password by default and if you wanted to you can create more. So I can update the length it'll be generated and as you can tell now it is completely strong. But if I wanted to not include the uppercase letters I can uncheck this. And now I will never have any uppercase letters in this password. And I can do it for the lowerase. And as I deselect them, the uh the strength will decrement. Now let's go with medium. As you can tell, now this is still medium, but it says you should select at least one of those, right? So let's go with this one. And I'll take the length to be six. So at minimum, we can go with six. And maximum could be 24. Now this is weak. Okay. And finally let's generate another one. I'll say copy this. It has been copied. Let's try to paste it. As you can tell this is exact same value that we have. If you wanted to have these screenshots, you can find the link in description for these diagrams. It's completely free. Um if you wanted to just challenge yourself and build it uh by yourself, these are the screenshots that you can take a look. All right. So I'll try to shrink this window. And as always, I have my second window, which is VS Code with an empty folder. We have three different empty files. First, we'll get started with the HTML file. Okay, let's go ahead and generate the boiler plate. I'll say uh put the title, password generator, and then I'd like to link my CSS file. And finally, I would like to get the fav icon. Uh I'm sorry, font awesome for these icons. So I'll go ahead to say cdnjs font awesome. Let's search for it and get the link. I think this would work. Let's copy it and then we will put it as the link tag under the head. Okay. Right here. Now we should be able to use the uh icons the yeah icons coming from font awesome. The very first thing I'd like to do create my container and then within this we are going to put the h1. Let's say password generator. Okay. Right after this h1 we would like to put the container which will be this one where we have the password itself and then the button. So I'll go ahead create a container called password dash container. So we're going to make this to be flex and then we will say justify content will be space between right. Okay here I'll say create an input that is type of text but this is only read only. Okay so you cannot really type anything in it is read only value and we can give it an ID like password. And finally we will have the icon. I'll say I and we can say class uh class will be f a r f a copy which is coming from font awesome okay then we can give it a title let's say copy-bn and then a title itself so that when you hover over this you would be able to see this title that says copy to clipboard now let's see what do we have I'll say open with live server and we'll get the warning as always. But here we go. This is what we have. Icons are working correctly. And you cannot type something in. I'm pressing some keys in my keyboard. It does not type. Okay. The other thing that we would like to build is our options. So right after the password container, I'll go ahead add a comment. Let's say options. And I can even say password container container. All right. So under the options I'll have the options class. Then we'll have the password length. At first I'll add comments. You don't really have to but this is really convenient if you are following along with the source code. I'll say dot option. So the very first option we'll have is the password length. So I'll add a label. Let's say this is for the length and let's say password length. So we just created the label. Now let's create the range container. Now this will be a container because we do not only have the input but also we have the value output. So I'll say range dash container and I'll say the very first one will be input that is a type of range right and then we can say id will be a length then finally we'll say minimum value maximum value and then the value itself so at minimum as I said we could have six maximum could be 24 and by default it'll be 12 so say minimum six 24 as the maximum imum and the default value will be 12. So whenever you move this around, this would be updated from our JavaScript code. This is a bit later in the video. And then we can have the span tag that will hold the value. By default, it is 12. And we can say ID length dash value. All right. So this is the very first option that we have. Right. After this one, we would like to create the include uppercase option. So I will add my comment and then we'll have the option class right within this div we will have the label that will be for the uppercase and text will be include uppercase we'll have the input this will be type of checkbox and then we can say ID will be uppercase finally we'll say this would be checked by default okay let's save. To get this formatting, I'd like to copy this entire thing. This would be for the include lowerase. So, I'll say command D couple of times and just say uh lower case. Here we go. Then let's copy this once again. Duplicate it. This would be for the include numbers and then symbols. Let's duplicate this twice. I'll say this would be numbers. So, I just paused the video and put them in. This is the numbers and then the symbols. It's the exact same thing that we have above, but basically we change the ID and then the text as well as the label for attribute. All right, let's save and take a look at the output. This is what we got. We're going to be changing the colors a bit later in the video, but now it is time to add the button as well as this container for the password strength. Okay, so let's move on. Now, what you would like to do, go ahead, scroll to the top, shrink the options container because we'll go outside. And we're going to create a button that will hold the text that says generate password. And just before this text, we'll like to add an icon. I'll say class will be equal to FAS FA- key. And we can give it a ID. And we can give it an ID to this button that will be generate dashbtn. And finally, we're going to put the strength meter. Right, I'll save to get this formatting. Right below to this button, I'll say strength dash container. And we're going to have a p tag that will say password strength. Okay. Now, as you can tell, this value will be dynamic, right? And the styling is a little bit different. I'm not really sure if you're if you can see it, but it is font weight of bold. So, we would like to select this with a span tag. So, I will say still within the P tag, but it will be under a span tag. I'll say medium. You can call this anything because we will update it. But let's go with medium. And then I'll add an ID. Let's say strength dash label. Okay, finally we're going to put the strength meter container that you can see. So this one is the container and this is the value itself. So still under this strength container div I will have strength dash meter this is the container that we have and then strength dashbar. Now this value will be updated from our JavaScript code. For now it'll be empty completely. Right? Let's take a look at the output. So this is what we have. We don't really see anything for the strength meter, but we will update it once again. Okay, so that's going to be for the HTML file. Just before we end this section, above the body, I'll put script source of script. js. Now we can close this file with command w and then just open up the style. css file and get started with it. Now, it's been a while since we haven't used any external phone families. So let's go ahead and install something. I'll say command shiftp and we're going to say insert CSS import and let's go with monerat at this case in this case. All right, we got the import. Now let's put our basic reset and like if this did not work in your case, you should visit the extensions tab and get the Google fonts as we have explained previously. So once you install this, then you should be able to search for it with command shiftp. All right. So, we're going to select everything and I'll say margin of zero, padding of zero, box sizing of border box and let's say font family will be monat that we have just imported and we can fold this back with sans serif. Now, what I'd like to do select body and just say minimum height will be 100 ph. We'll say display of flex let's say DF JCC right justify content centered align item centered color could be 333 and then we can say petting will be 20 pixels okay so everything has been let's say centered in the middle of the screen and I'm just too much zoomed in this is what we have now in this section I'd like to use what we call CSS variables You're going to see it's really cool and easy to get started with. Now I'll create it. This is how we would do it. We would say colon root and then you can create anything that you wish. So we're going to put primary color and let's add it to be 2B 58 76. Now why are we creating this? So let me just showcase it pretty quickly with an example. Now let's say you have really large CSS file. Basically you have a button. Let's say you are selecting select the label so on and so forth. You select your cards and in all of them you would say something like color and you would use this value. Let's say you got this value and you did the same thing for all of them. But now some of your friends told you that this color is not really good. go ahead and update it with this one. Now, what you'll like to do, copy this form here and update it on every single places, right? And if you imagine like you have 100 instances, you have to just scroll to the bottom and update every single one of them, which is not really acceptable, right? You definitely don't want to do something like this. So, instead, if you used, let's say, CSS variables, I'll do Ctrl + C. Get the exact same value. Okay, just imagine you are using the CSS variable. So instead of this you would say v and use the primary color. Now if you do the same thing for all of them. Let's put it. Okay. Now this is how your code looks like and your friend told you that this color doesn't look really nice. You should update it with this one. Now all you have to do only update this part because every single one of these are using the same color right it's been updated here and on this one and let's say on the next 100 instances I hope this makes sense this is why most of the time you would like to use CSS variables it is really useful all right now the first primary color that we'll have is this one as we just had now I'll put couple of different colors such as the secondary one. Let's say the weak color that's going to be this one. Okay. And like basically this is the primary color, the secondary color, weak, and we would like to add the medium as well as the strong colors. So I'll go ahead copy and paste. We can pause the video, type this out. Here we go. We got five different colors and we'll be using them a lot within this CSS file. So what I'd like to do just say background color will be linear grad gradient and just a quick correction if you're going to be using linear gradient it has to be background so if you put background dash color it's not going to work so this is something to keep in mind and then we're going to put the degree let's say 45° you can update it this is the one that I'll be using and then we'll be using our primary and secondary colors so just like we have used a couple of minutes ago I'll Save R. Get the primary color. We'll go from this one to the secondary one. Okay, now let's save. Take a look at it. This is the output. Now, if you wanted to change this secondary color, all you have to do visit this part and put something else and your document would be updated. Any place that you use the secondary color has now been updated to this value. Okay, I hope that makes sense. So, that's going to be it for the body. We're going to go ahead and update the container class. Let me just scroll down a little bit. Okay. So, we're going to put the background color. Let's say it'll be white. FF. Here we go. Then we can say padding will be 2. 5 RM. And then we can add some rounded corners. I'll say 1 RM. Can say box shadow. That will be 0 to 10 pixels to 30 pixels. and then RGBA of let's say like the black uh 15. Okay. So, it's subtle but I think it's looking nice. If you wanted to, you can increase it. This is the one. This is the value that I'll have. I'll say width will be 90%. And we'll say the maximum width could be 450 pixels. Now, let's select H1. I'll say text align would be centered. We can say margin bottom will be 1. 8 RM. Then we can say color will be the primary color. Here we go. Then we can say font size will be 1. 8 RM as we can tell. We'll say font weight will be 700. So it's bold. Um I'll say position will be relative. I'll tell you why. And then we'll say petting bottom will be 0. 5 RM. So this is what we got. We'll be using the position relative because right now we'll use uh the after sudo element to be able to give this underline. So here I'll go ahead say h1. Let's grab the after sudo element. As always you have the content as empty. Even if like if you want this to be displayed, this should be empty. Or like if you if you're going to put something, it'll be there, right? But if you're using it for only decoration purposes, just like what we have here, you would leave it empty. I hope that makes sense. Now, we'll say position will be absolute and the parent is relative. So, we're going to say the bottom will be zero. And then we can say from the left, it'll be 50%. Let's say if this is what we got nothing but if we add width we should be able to see something or maybe height as well. Okay. Why cannot we see anything? Maybe it doesn't have the background color. So currently it is right here but it is invisible. Let's say background color will be red. Here we go. By default the background color is white. So that's why you cannot see it. So, I'll go ahead at the background to be the same linear gradient that we have above. I'll copy this and paste it right here. Let's change the degree to be 90°. Okay. But now this is not centered. We would like to take it 50% back. I'll say after the left I'll say transform translate X will be equal to minus 50%. Here we go. So now it is centered completely and we can say border radius could be like 2 pixels. So this is one way of creating the underline. If you wanted to you can create a different element right after the h1 like you could create a div and then give it a class and then style it. But this is also a pretty valid option. Right of right after the h1 we will update the password container. I'll go ahead and select it and we'll say the margin bottom will be 2mm. Here we go. We'll say background color could be this which will be F8 FA FC. Then we'll say border radius will be 10 pixels. We can add the border itself one pixel solid and this value which will be E2 E8 F0. Here we go. And then let's say we will have the overflow of hidden. And then I'll add a tiny box shadow just like this one. If you don't want to, you can delete it. But this is what I'll have. And then let's say display flex align items would be centered. And as I said previously, the justify content will be spaced between. Here we go. Then we'll go ahead say petting. Let's say 0 1m and zero for both of the values. So what we have just done is to add some paddings to the right hand side. Right? So if you delete it, this is how that look. But if you add it, here we go. Now we would like to select the password itself and we'll say width will be 100%. Then we'll say petting will be 1. 1 RM. Here we go. We'll say heading right will be 50 pixels. Let's say no borders and the background could be transparent. Here we go. And then we'll say color will be this grayish color or a 5568. And then we can say the letter spacing will be one pixel. And then finally outline of none as well as the border radius of 10 pixels. Here we go. Now we don't have anything inside. That's why we cannot see it. But if we got the index. html, let's try to add something in like it is the input. Let's say value will be hello. Okay. This is how that look. Now we can move on with the copy button itself. Let's say select the copy button. It was copy-bn and we'll say cursor will be pointer. Then we'll say the color will be this one 71 80 96. Now, if you wanted to, you can create those as the CSS variables, but since this is a value that we don't really use too much, I'll leave it as a hard-coded color. But definitely, it is your choice if you wanted to add it right here or not. Okay. Right after the color, I'll have my font size to be 1. 1 RM. Then, we'll go ahead say background or for now, let's say width to be 35 pixels. I'll duplicate this. Height will be 35 pixels as well. Now we can say display flex. Oops. Let's try to fix it. Okay. I'll say display flex align item centered. And let's say justify content centered as well. Here we go. And then I'll say border radius will be 50%. Then we can add the hover state. I'll say copy button on the hover state. We could say color will be equal to the uh the primary variable the primary color. As you can tell it has been updated. Now we could also get into the options. I'll just scroll a little bit and then have the options selected. So I just selected the options. Now we'll say margin bottom will be tom. Here we go. We'll say background will be updated to be F8 FA FC to this grayish color. And then we'll say padding could be 1. 5 RM from all directions. Border radius will be let's say border radius will be 10 pixels. Here we go. And then we'll say box shadow. It'll be really tiny but still I'd like to add it. Here we go. Like it's really tiny. Maybe it is not visible from the video but I can definitely see it. Then we'll go ahead select every single option. So we'll say display will be flex justify content space between let's save. Here we go. We'll say align items centered. And finally margin bottom of 1 RM. Okay. Now the problem here is that the very last one also got some margin bottom. We don't really want to have it, right? It is not needed because there is no element right after this one. So we can remove that by saying option dot or sorry option colon last child. So we're going to select the last child and we'll say margin bottom will be zero. Here we can see it's been updated. So this is another trick that you can keep in mind for these situations. And then I'll say dot option where we'll get the label itself. And we're going to say font size could be something like 0. 9m it's been updated. We can say color will be let's say 4 a this value. So once again if you wanted to you can take this and make it a CSS variable. I'll just skip that. We'll say font weight will be 500. Here we go. Then we can select the range container itself. And then we're going to say display of flex align items would be centered and gap of 10 pixels. Let's save like I think we cannot see the difference for now because it is in these smaller screens. But now let's try to put it I'll just put that and I think I should put them side by side to be able to see it. Now I will save. Okay. So as you can tell there are some differences. If we delete the gap or if we add it, this is now a lot more visible. Now let's go ahead and change the width itself. I'll say this will be width of 60%. Here we go. Now let's say I'd like to select this input specifically which is type of range. How can I do it? I'll say input where the type is equal to range. Right? And then I'd like to change this color which is called the accent color. I'll say this will be the primary color that we have. Here we go. And then I can say the height could be something like 5 pixels. It's been updated. If you wanted to you can change it to be 50. I don't know what is the maximum value but let's go with one pixels. It's really tiny. I'll go with five pixels. Then you can say something like cursor will be pointer as well. And finally, I'll just say flex of one. Okay. Now, what I'll be doing is to select the checkbox itself. So, it's the exact same thing, but type will be different. Let's say checkbox. And on the checkbox, I'll say width will be 20 pixels. And same for the height. Let's save. Here we go. It's been incremented a little bit. Now, I'll say border will be 2 pixels. Solid. And I'd like to give the variable of primary color. Now it's not been updated. Right? And for this we can say appearance will be none now as you can tell it's just it got updated. If you delete that it will not but this is the like this is the style that make it work. Then we'll say border radius will be 4 pixels. Here we go. And I'll say cursor will be pointer and I'll say outline will be none. So for now that's going to be for the checkbox. We will update it just in a second. For now I'd like to select the exact same element and we're going to update the checked state. Okay. So if it is checked, what do we want this to happen? I'll say the background color will be equal to the primary color that we have. Now let's save and give it a go. Every one of them is checked, right? Because this is what we said in the default state. Let's see. Uh all of them are checked as you can tell. Alth they include uppercase. Now this is not checked by default but we would like to have this checked uh immediately. If you click it now it is unchecked. Right now we don't really want to have the background itself. We also check mark icon. Right? For this we'll go into the checked state and we will update the after pseudo element. So I'll say checked and get the after sud element where we would like to add the content. Now we'll be using a uni code character that will be back slash put it into a string back slash2714. Now let's save. What are we going to get? As you can tell this is what we have but it is not really centered. So I'll say position will be absolute but for this to work we should say the checkbox itself will be position relative and then I can say color will be white and then we can now center this correctly. I'll say from the left let's go 50%. From the top let's go 50%. And if you think this will center it I'm sorry it would not. You have to use this trick where you would say transform where the translate the x direction will be minus 50 and then from the let's say in the y direction we'll also do 50%. Minus 50% it should be. So we basically updated the x and y values. Now it has been centered correctly. Then I can update the font size. Let's say it'll be 12 pixels. Here we go. Now one more thing that I'd like to do which is there is no animation like no transition at all. It happens immediately. For this we can go right here under the checkbox. I'll say transition. Let's go a bit uh extreme. I'll say 1 second like it's happening really slowly but most of the time you would like to go with a value like 0. 3 seconds. I think this looks a lot more cleaner. All right. So that's going to be for the after element itself. Now we can get the length value. So I will select the length value. Let's go ahead say font weight will be 600. We can get the color that will be primary color. Here we go. And then we'll say width will be 30 pixels. Then we would like to say the text align would be centered. Then we can update the background color that will be equal to this value as you can tell. Then I'll just say border radius will be 4 pixels. Here we go. It's a little bit rounded. Now I'd like to add some paddings. Finally, we'll say petting 2 pixels to 5 pixels. All right. Now we're going to go ahead and select our button that we would like to update. So I'll say width will be 100%. Then we would like to say petting will be 1 RM from all directions. And then I'll add a background that will be linear gradient just like what we have done above. It's the exact same thing. Let's save. Here we go. I'll say color will be equal to white. We can say border will be none. Border radius will be 10 pixels. Then we can say font size will be updated to 1 RM. Then we can say font weight will be 600. Here we go. It's a little bit more bold. Then we'll say cursor will be pointer. Now I'll give some transitions. So I'll just say all 0. 3 seconds so that we can have the hover state happening a bit more smoothly. Then margin bottom of 1. 5 RM. Finally, finally I'll just give some box shadow that is tiny but it'll just give this kind of effect. I think it looks a lot more cleaner if we have the box shadow. Now we're going to go ahead and update the hover state. I'll say button on hover. We would like to basically have a transform field. I'll say translate of Y will be minus 2 pixels. And then I think that could be it for the hover state. All right. So this is the output that we have. And then after the hover state, we will add the active state where we will update the translate Y to be resetted. All right. Now we would like to get the strength container and I'll say margin top will be 0. 8 RM. Then we would like to select the P tag within this strength container. So I will update the font size to be 0. 9 RM. And then we can update the color to be this value that you see on the screen. And then we'll say margin bottom of 0. 6 RM. Here we go. And then I'll say display of flex. Then finally we'll say justify content space between just like this so that they have some spacing uh between them. And lastly I'd like to say font to weight to be 500. So it's a little bit more bold. All right. Now, we're going to go ahead and get the strength dash label. And I have a typo. Let's say strength label. I'd like to say the color will be primary color. So, we'll say variable. Here we go. Now, there isn't that much of a change, but it is this element. So, if you say red. So, this is the one that we have actually updated. And then I'll say font weight will be 600. Now it's a little bit more even bolder than this one. Now I'll select the strength meter. Then we'll say height will be 10 pixels. Then I'd like to say the background color will be updated to EDF 27 sorry 2F7. It should be like this. Then I'll say border radius is going to be 5 pixels. Then we would like to say margin bottom will be margin top actually will be 0. 5 RM and I'll say overflow would be hidden. Finally we can give some box shadows. I'd like to copy and paste. Here we go. Now we just said insert and as you can tell it is like inwards right? It is insert. If you delete that it would be outside. But now it is set into the container itself. Now we will get the strength bar itself. So I'll say bar and height could be 100%. It'll take the entire container. We'll say width will be zero initially. Right? And then we can say minimum width will be 5%. Now we can add a background color. I'll say variable. You can use any color. I'll go with the weak one. I'll say weak color. Here we go. And then we'll say transition is going to be all 0. 3 seconds. And we'll say ease. Now transition is needed to have this effect. Now this will be strong. Notice how it'll transition smoothly. Here we go. Just take a look at it now. Okay. So this is happening thanks to this transition that we have. And we can add some border radiuses. So I'll say border radius that will be equal to 5 pixels. Okay, now it is rounded. And at the very end of this file, I'll have my media query that's around 10 lines of code. We will update the container H1 and option label when we hit this uh this pixels and below. Okay, let's save. Now it's been updated, right? So there's like a subtle change once you hit that break point. Okay, so that's going to be for the entire CSS file that we have. Next, we're going to build the JavaScript. So the very first thing we would like to do is get all the DOM elements such as these checkboxes, the button, the copy button, the string meter, so on and so forth. Now we could type them out like const password input. We would get the document dot getelement by ID and then we put the ID. But instead of typing them out, I have prepared a file. You can find the GitHub gist link in the description, just find the password generator file. Go ahead, copy everything that you have seen here. This is what I'll be doing. And I'll just delete this. Paste this in. Now, these are all the elements that we'll be using. And then we have the character sets that we're going to be using to be able to include the uppercase letters, lowerase numbers, and symbols. So these are those variables that you don't really need to type them out. All right. So the first thing I'd like to do is this. If I update this input, I want this value to be updated. Right? Currently the value is 12. Let's open up the HTML file. Um search for the value. All right. So it is 12 by default. And here is the text. We want this to be updated whenever the value changes. Right? So this is how we can make that work. I'll say select the length slider. We're going to add an event listener which is the input and then we can run this function. I'll create an uh I'll create an arrow function and I'll say length display. ext content will be equal to the value of this. I'll say slider do value. Now let's see if I update it the value will be like it'll be updated with this one right at maximum it could be 24 and at minimum it could be six so that's the very first thing that we have done the other thing that we would like to do is to create a password right if I click to this button I want to generate a password so I'll say generate button add event listener which is going to be click once we clicked it we would like to call a function called make password and this is something that we'll create. So I'll go ahead say function paste this in and get into the logic. So the first thing I'd like to do is get all these variables. So what is the length that user wants to have? If user wants to include the uppercase, lowerase, so on and so forth. So let's get the length. I'll say it'll be length slider dot value. Now this is a type of string. So I'd like to wrap this with the number class. Now this is going to be type of number, right? And then I'll say conclude uppercase. This will be uppercase checkbox checked. So either true or false. Here we go. We're going to duplicate this and this will be for the lowerase checkbox and we'll say include lowerase. So let's go ahead and update it and let's duplicate this. This time it'll be include numbers and I'll say number um checkbox. Then finally this will be for the symbols include symbols. Okay. Now the first check we would like to have is this one. If user does not select any of those we're going to get an alert, right? Let's go ahead and type this out. I'll say if uh like if not include password sorry if not include uppercase and if not include lowerase and the rest too. So I'll just say if this is equal to false and this is also equal to false which means it is not checked. In this case we would like to say alert please uh select at least one character type and then we can just return out of this function. Don't do anything else. Let's test this out. I deselected every single one of them. Looks like it did not work. Why this is the case? This should be not now. Let's see. Okay, it is working as expected. But if we have at least one of them selected, we can go ahead and create a new password. So I'll say const new password. And I want to put the logic into a into another function. I'll say create random password. So this is a function that will create and I have a typo. Let's say random. Now, this will take the length, right? Let's say this is the length that we would like to have in our password. We would like to give you some couple of different booleans such as the include uppercase, let's say include lowerase, include numbers, and then finally the symbols. Okay, once we got the new password, we would like to say password input do value will be equal to this newly created password. So we will update this input that we currently don't really see, right? Okay, let's save. Now we'll go ahead create this function. Okay, let's go here. Let's say the first thing we'll take is the length and then we will get those uh variables, right? You can say something like use uppercase. But I think I'll just go with the same name like incode uppercase which is equal to true or false for the numbers lowerase symbols. Just make sure they are all in the exact order that as I have okay now we'll go ahead and create a variable called all characters. Initially this will be equal to an empty string. Depending on these selections, we are going to update this characters. Now, let's say if user wants to include the uppercase letters, we would like to go ahead and just say all characters will be equal to or it would be updated with the uppercase letters. And then we'll say if they want to include the lowercase letters, we would like to do the exact same thing with the lowerase letters, right? Okay. Now, since these are just oneliners, I can delete the curl braces. This is completely fine. And I think this looks a lot more cleaner. Now, let's add the if check for the last two. I'll say if include numbers. go ahead and update the all characters variable with it and then we'll add the symbols. Now if all of them is equal to true, right? are true, if they are checked, what'll happen in this characters string? Basically, it'll be equal to this one where we have the first uppercase letters, right? It has been added and on top of it, we have added the lowerase letters, then numbers, and then finally the symbols. Now everything is selected. We're going to go ahead and select something randomly, right? So we're going to get one uppercase letter. lowerase number symbol. And this will happen randomly, right? But if user had let's say only uppercase letters, this would be the all characters variable, right? And then we would select some values randomly. Now we'll create a variable. Let's say let password that will be equal to an empty string but we'll go ahead and update it. So I'll say for let I is equal to zero while I is less than the length. We could say just increment it by one. Okay. So we will say password plus equal to something right and for this we need to create a random index. So in every single iteration we're going to get a random value right and to be able to select those values we need to get a random index. So we'll say const random index and this should be a variable name. We'll say math do floor we'll say math random call the method and we're going to multiply it by all characters length. Right? Depending on this length, we're going to get a different random number and floor this down so that it is a valid index and we'll say password now will be equal to all characters random index. So here we go. The password will be updated with the length whatever that is and finally we can return the password. Go ahead try to update this. I'll include everything. Here we go. This is the output that we got. It just works without any issues. Now I'll just say only include symbols. This is exactly what we got. Let's say only lowerase and some uppercase maybe. Here we go. So that's going to be for this method as well. Once we update the UI, we will like to update the strength meter as well. And I'll put the logic into a function. I'll say update strength meter call this with the new password. Now let's build this method or the function however you'd like to call it. I'll say this will take the new password. Now to be able to decide the strength of the password if it is medium, weak or strong, we'll be using some numbers depending on these checkboxes. So if uppercase included, let's say we will add additional 15 points. So on and so forth. Now instead of calling this as new password, I'll just call it as password. So it's a little bit more easier to type out. So the first thing I'd like to get is the password length. So we can say it'll be equal to the password. length. Then we can check if it has uppercase letters. Right? I'll say has uppercase. We are going to say we would like to use a regular expression. So this is how we can do it. We'll say if it has any of these characters from uppercase A all the way up to Z. In this case, we're going to go ahead and test this out. Test out the password. If this includes like if this returns true, this will be equal to true, right? No brainer. Now we'll go ahead duplicate this. This will be equal to has lower case. We'll just say A to Z but lowered. And then let's duplicate it. This time it'll be numbers. Let's say from zero all the way up to 9. And we can say has numbers. Duplicate it. And I'll say has symbols. And instead of typing every single symbol, I think I can just scroll to the top, copy this entire string, and paste this in. Okay, so we got all of these. Now we'll say let's calc let's calculate a score for the password strength, right? I'll say let strength score. Initially, it'll be equal to zero and we will increment it as we go. So let's say first we'll get started with 40 points, right? I'll say strength score plus equal to I'll say math dominimum. We'll say password length* 2 and 40. So basically we are going to have two different values. Let's say this is equal to 30. We're going to get the minimum of them. Now if this is equal to 300, we're going to get 40, right? So at maximum it could be 40 right if it doesn't really matter if this is like 3 million we are going to always get the minimum value which is 40. So that's why I say at maximum it'll be 40. Right? So this is something to keep in mind not only to specific to this project but if you want to get a value that is like at maximum right here at maximum we would like to get 40. That's why we use the minimum method. So maybe this is kind of like a quick note that you can take. If you want to get a maximum value you would use the minimum. Right? So I can feel like it sounds a little bit complicated. That's why I just put a comment that you can have in the source code here. The domin method will get the minimum value from these right but this will be this will make sure that at the maximum you would get 40. I hope this really makes sense. And then we'll go ahead just add couple of different if checks. I'll say if has uppercase we would like to increment this strength score. Let's say strength score plus equal to 15. I'll duplicate this three times and I'll say if we have some symbols if has numbers. I think this should be numbers. Okay. And then I'll say has lowerase. So we'll just add additional 15 points for every single one of these options. And then we can enforce the minimum score for very short passwords. I'll say if password length is less than eight. I'd like to run this if check. I'll say strength score will be equal to math dominimum. Strength score and 40. Right? We're just going to get the 40 depending on this like thanks to this minimum method. If this is equal to 100, we would still get the 40 because length is less than eight. We want to just enforce the user, right? I'll say enforce minimum score for every short password. All right. Now, we'll go right below to this if check and I'll get some variable called save score and I'd like to add a comment. Now, why do we need this? So, basically I would like to ensure the width of the strength bar is a valid percentage. So, we don't really want to have something like minus 50 or 1,000, right? It doesn't really matter what that is. I'd like to just make sure it is valid, right? So, I'll say math dot maximum. We'll add either five or we'll say math dot minimum that will be 100 and strength score. Now, let's say this is equal to 1,000, right? We are going to get the minimum value. So this part will be equal to 100. Now as you can tell this safe score will be either five or 100, right? It will be always within this spectrum. Now here we are using maximum. So we're going to get 100. Okay. Now that we have this variable, we can say strength bar. Let's select it. We'll say style. And finally, we'll just update the width. So I'll say style do width will be equal to save score whatever that is and we'll just add the percent at the end because this is some CSS we would like to calculate the width as a percentage and finally I would like to update this text as well as give a color right this would be either medium weak or something like strong so I'll create two different variables I'll say strength label text that will be equal to an empty string and then let bar color will be equal to an empty string as well. We'll go ahead say if this is equal to sorry if strength score equal to or if it is less than 40 this will be equal to a weak password. So I'll go ahead and say something like bar color will be this red color that will be a hash f c 8181 and then we'll say strength label text will be equal to weak right and then let's add the other cases instead of typing this out I'd like to copy and paste I just said else if strength score is less than 70 this will be a medium password the yellow color as well as the medium text. Finally, the strong password. I'll paste this in. Here we go. And now that we got all these variables, I'll just go ahead update the strength bar and then the color. I'll say strength barstyle dot background color will be equal to this bar color that we have. And the same for the text. Do I have a typo? Now it seems like we don't really have this selector. I'll go ahead scroll to the top and get this element. So strength label will be this value that we have. I'll refresh this page. Let's say generate a password. Here we can see this is medium. Let's go all the way up to 24. Now it is strong. It is working as expected. Let's go with this value. Okay, it's medium. Now it is weak but I think we have kind of like an error. If we select everything at maximum it doesn't really fill this in completely right. So let's see what we are missing in our code. So I have just paused the video and find the solution. Now this has symbols regular expression is not really correct. Notice how we have the opening and closing brackets. We are missing it right here. So first I would like to add the opening brackets and then let's go ahead close this off right here. But still this is not really valid because here we would like to add a backslash. Now this should be completely working out. Again really weird really complex but this is what we would like to use with a regular expression. Right? So I'll go ahead and save. Now let's give it a go. I'll maximize this. Select everything. Now it is 100% as we wish. So I hope that makes sense. The very last functionality we left is this copy button. If we click to it, we want this value to be copied. Update the UI and after 1. 5 seconds like we have some delays and then it'll go back to this icon. Right? Let's go ahead and add it. And just before to it, I would like to add one more thing. So if you reload this page, when this page loads, we don't really get a new password. So we would like to have this behavior. Every single time we refresh, we're going to get a different value. So it's really easy to build. All we have to do add an event listener. I'll say window dot add event listener that is DOM content loaded. We'll call our method which is to make a password. Now let's refresh. Every single time by default we're going to get a new password. And then if we wanted to we can create more and more. Now I'll create that copy functionality. So I will go at the very bottom of this file and I'll say copy button add event listener which will be the click event. We would like to call this function. Now you can create a different function but I'll just put it in line. So I'll say first let's add an like optimization check. I'll say if password input does not have any values we could just return don't do anything right? But if we have something we can go ahead select the clipboard and say write text into it and the text that we would like to copy will be password input do value. Now this will take some time right this is asynchronous. So we can say then once this is completed successfully we would like to show copy success. Let's call this method. We are going to create it in a second and if we got any errors we're going to catch it with the catch block. So I'll say catch um you can do anything like displaying an alert. I'll go with a console log. Let's say could not copy. And then we can put the error message into the terminal. Okay, let's save and now create this function. I'll go ahead create that. It'll be really simple, really basic. All we have to do just change the icon first. I'll say copy button class list dot remove. We're going to remove the classes coming from font awesome which is this one as well as fa copy. Now I'll duplicate this and we would like to add another one. So we just remove this right we are going to remove this and add this check mark which will be fas and fa check also I'd like to change the color to be this green one so I'll say copy button dost style dot color will be equal to this hash value which will be 48b78 okay now let's save and give it a I'll click to it. But now this will stay just like this forever. Instead, we would like to update it after some time. And if you want to add some delays, you should remember the set timeout method. So we got our callback as well as the timeout. Let's say after 1. 5 seconds, we'll say copy button class list. Now remove the check mark, right? And then I'll duplicate this. Instead, we'll click to add the copy button itself, this icon. And then let's update the color. This will be the default color. I'll just leave it as an empty string. Okay, let's save and try to see. I'll click to it. It's been updated. And let's see if we got this value. I'll just paste. Here we go. Let's generate another thing. Copy it. Okay, so it's the exact same value. All right, so that's going to be it for this entire project. I hope you enjoyed it and learn something new from it. I'll
Project 8: Functional To-Do App with Filtering
see you in the next one. So in this section, we are going to build a 2D app. This is the end result. Let's take a look at it how that work and we'll jump into the code to build it from scratch. So we have an input element where we can add things, right? I'll say learn Python. I can either add this by pressing enter or clicking into this button. It should be added to the list. I can delete them and check them as completed. And we can have some filters. So I'll just say only show me the ones that are active and completed ones. If I say clear the completed, it'll go ahead to delete all of them. And now we only have these active ones. Right? And the best thing about this app is that this data will be saved to the local storage. So if you go ahead and refresh this page, it'll still be there no matter what, right? All right. And you can have these screenshots from the diagrams. The link will be in the description just like any other application that we have. Okay. So this is the end result. Now let's go ahead create an empty folder called to-do app and have our three different files. They are empty at the moment, but we're going to build them one by one. So, let's put them side by side. So, grab this and put it just like this. Let's get an empty HTML file. I'll say this is the to-do app. And let's put the link CSS, which will be style. css. And let's link the script file. I'll say script. js. And we can put a div that. Let's say class name of app. You can call this anything. This is the name that I'll be going with. Now we're going to have the header section which will be this my tasks as well as today's the date. Now this is correct. This is not something hardcoded and I'll show you how we can build it to be dynamic. Right? So if I open this up tomorrow, this will say May 6 and also it'll say Tuesday. So with this in mind, let's go ahead and put H1. We'll say my tasks. Now the other thing that we need to add is this icon. For this, we'll be using font awesome. So first I'd like to say just open this up with live server. We got some warnings, but that's fine. Here we go. And let's grab the CDN link. So I'll say cdnjs cdnjs. com libraries and font awesome. Go ahead, copy the very first one and then put the link right here. Now we should be able to use those icons. So I'll put the I element. Let's say class will be fas check- circle and then I'll save. Here we go. We got that circle. And after this H1 we'll say P. Now this content will be empty for now. We'll say id will be date. Later in the video once we get into the javascript part we will make this text to be inside right within this p tag but it'll be dynamic. All right after the header component we'll say div that will take the class name of to-do input. We'll go within this dev. We'll say create an input that is type of text and we can add an ID like task dash input and then placeholder. Oops. So this should be task input and then placeholder it'll be what do you need to do just like this and then right after this input I'll put a button that will be id of let's say add dash task and I'll put the i element the i tag let's say class fas a plus okay so this is the end result that we have at the moment right after this div which is the to-do input we'll go ahead and add our filters so these three filters I'll say dot filters and we're going to create a span let's say the class will be filter and this will be active initially which is going to be the all filter right and I'd like to add a data dash filter attribute I'll say this will be Now we'll be using these later in the video. For now, just go ahead duplicate this twice. This will be filter but not active. This will not be active as well. This will be for the active one. Let's say active and this will be for the completed. Okay, let's save. Take a look at the output. This is what we have at the moment. Right after this div, after the filters, we will add the to-dos container. Okay. So, the first thing I'd like to have is a ul that will have the ID of to-dos list and content will be empty. As we add more and more things, we are going to add it right here within this UL. Right? So you can add a comment such as the list items will be inserted right here later in the video. Okay, after this ul I would like to put a div. Now this will be the case if we don't have anything. We're going to get this icon and then no tasks here yet. So I'll say this div will have the class name of empty dash state and this will be hidden by default. Let's go ahead say I. This will be the icon fasa-clipipboard list. Then we can say something like no tasks yet but this will be within a tag. So I am too lazy to type this out. I'll copy and paste. Here we go. So currently this is visible but we're going to make it to be hidden unless we have nothing right if we have something we're going to see the input or the list item but else this is going to be the output and then after this to-dos container so I'll just delete this comment shrink this right after the to-dos container I'll have a footer element which is going to be this part right I'll say get a p tag this will be id of the items dash left and we're going to put something like zero items left and again this will be dynamic later in the video so if you add more and more things this will be updated and if you check them it'll be decremented so this will be uh updated from our JavaScript code later in the video so I just need to mention them couple of times so that it doesn't really feel any complicated I hope it's not really annoying So I'll say button id clear dash completed and let's say clear completed. So it is this button as you can tell. So this is our output. Looks terrible but we're going to fix it in a couple of minutes. Okay. So we got the styling linked into the HTML. We can go ahead and get started with it. So let's get into the style. css file. The first thing I'd like to do just add my reset. So I'll select everything and I'll say margin of zero, padding of zero and then box sizing will be equal to border box. Now let's create some CSS variables just like what we have done previously so that it's a lot more convenient to work with the colors and like CSS variables in general. So I'll have my primary color. I'll just say it'll be 7749 F8. Okay, it'll be this primary purple color that we have right here. And then I'll have the primary light. Let me just go ahead put them one by one. If you wanted to type this out, you can just pause the video and do so. This is what I'll be doing just to not waste any time. We'll have dark, light, gray, we'll have danger, success, and finally the border color. Okay, so I hope these make sense. We'll be using them in a couple of seconds. Now, let's say we're going to select the body. I'll say font family will be sensif. I'll say background color is going to be it'll be F1, F3, F5. Now, if you wanted to, you can take this and put it as a CSS variable, or you can still use the hash values if this is something that we'll be using only once. And I think this is one of those cases where we'll be using this value only once. So, I'll just put it right here instead of creating a CSS variable. So, it's completely optional. Now, let's try to take a look at the output. I'll save background has changed output. And then I'll say the minimum height will be equal to 100 VH. And then we would like to center everything. I'll say display flex justify content centered and align items to be centered. Here we go. Then I'd like to add some paddings. I'll say petting of 20 pixels. And let's say color will be our dark color. Right? So I'll say variable dash dark. Here we go. Then I would like to select the app class and I'll say width will be 100%. But the maximum width is going to be 500 pixels. Then we can say background color is going to be let's say white. Here we go. And I'll say border radius will be something like 12 pixels. And we can say overflow will be hidden. And finally, we can add some box shadow so that it is looking kind of like box shadowed, right? I don't really know what to say. Let's go ahead copy paste this. Okay. So, if you wanted to, you can increase the value, but I think this is a bit too much and extreme. We can go with something like 0. 1. I think it looks pretty clean. Now, the other thing that I'd like to do just get the header component. So I'll say select the header element. I'll say background color will be the primary color. So I'll say variable dash primary. Okay. Now I'd like to say color will be white and padding could be something like 20 pixels to 25 pixels. Here we go. And this is a bit zoomed in I believe. Let's see if this is the case. No, it's not. It's in 100%. So it is the normal level that you should have and then we can get the H1. So I'll say header go ahead select the H1 element font size could be incremented to be 24 pixels or I think this has been decremented right now if you delete this it's a little bit larger. So I'll say 24 pixels. Let's say margin bottom of 5 pixels. And then I'll say font weight of 600. And then I'll go ahead get the P tag. So I'll say header P. Now currently we cannot see it but it'll be this date that we have. So this styles will be visible later in the video. I'll say the font size will be something like 14 pixels. And let's say opacity is going to be 0. 9. Okay. Now let's go ahead get the to-do input. So we'll say to-do input. Let's say padding will be 20 pixels to 25 pixels. Here we go. I'll say display will be flex. Gap will be 10 pixels. And then we can say background color will be light. border bottom is going to be one pixels. Solid variable of border. Here we go. Then we can go ahead get the input within this to-do input. So we'll say flex will be one which means it'll take the entire space that is left. So we'll say padding will be 12 pixels to 15 pixels. Here we go. We'll select the border let's say it'll be 1 pixels. Solid D E like D E 2 E and six. Then we can get the font size. Let's say it'll be 1 RM. Then we can finally get the transition to be all 0. 2 seconds. Now I'll go ahead and get the focus state within this input. So here we would like to say no outline. So outline will be none. Let's say border color will be updated to the primary color. And then we can add some box shadow when we focus into this input. Okay, just like this. This is what we have. Now I think we also want to add some border radiuses. So I'll say border radius could be 6 pixels. Here we go. And then after the focus state, we can get the to input button this time. So we're going to update this button on the right hand side. So I will say background color will be equal to the primary color that we have. And then we'll update the color to be white. Here we go. We can give some paddings or maybe instead of pettings I'll go ahead and give the width to be 40 pixels. And same for the height. Okay. So this is what we have. Now let's say we don't want to have any borders. And then we'll say border radius again. It'll be 6 pixels. so that it is consistent and we can say cursor will be pointer and finally I'll say transition will be all 0. 2 seconds. Let's update the hover state. I'll say to-do input. We're going to get the oops let's say get the button hover state background color will be primary light this time. Okay. And then right after this selection we can get the filters. So I'll say display of flex. We can give a bit gap of 15 pixels. Let's say border bottom will be equal to 1 pixel solid and the border color that we had. Finally I'll say padding will be 15 pixels to 25 pixels. Okay. So this is what we got. And now on every single filter we would like to do something. So I'll say filter go ahead get them. We'll say petting will be five pixels to three pixels. And then we would like to say cursor will be pointer so that it feels like as a button. I'll say color will be gray but it should be wrapped with it wrapped with variable. I'll say gray. Here we go. And then I'll say border bottom. I'll say two pixels solid and transparent. Now we would like to go ahead get the transition. I'll say all 0 2 seconds. Then we can go ahead get the filter hover state. We will update the color just like in the end result. So when we hover over them, it'll be updated. So I'll say hover um I think we can say color is going to be the primary color. Okay. And then after this one I'll say if filter is active we would like to say color is going to be primary one then we can say border bottom is going to be 2 pixels solid and we'll say variable of d- primary. So this one is active as you can tell. So it will uh it'll apply these styles. Then we can also say font weight is going to be 500. Maybe we should go with 600. I don't really know. Okay, I'll go with 500. Then we can go ahead get the to-do container, right? I'll say to-dos container where I'd like to add some paddings. So I'll say instead of auto, it'll be 15 pixels to zero. Then I would like to get some maximum height of 300 pixels. Then I'll give I think overflow dashy it'll be auto. Now why this is the case? Let's see if I add bunch of different things. This is what I'll be doing. Okay. At some point this content will overflow because the maximum height is 300 pixels. Let's say this is 300 pixels. the rest content will overflow. So we say in the overflow case go ahead add a scroll bar. Right? This is how we can do it. Just give a maximum height but also add the overflow of auto and specifically in the y direction. Right? Because it is in the vertical direction in this case. I hope that makes sense. Now we cannot see anything because we don't really have any items yet. But later in the video, it should be it should make sense, right? So after the to-dos container, I'll go ahead get the to-dos list. This is going to be a selector with the ID. I'll say list style type is going to be none because this is an unordered lists. I mean, it's an unordered list and we don't really want to see those kind of like bullet points, right? I'll say to-do item. I'll get some paddings such as 12 pixels to 15 pixels. Again, we cannot see the styling yet. This will be a bit later in the video once we have those. So, this is basically what we are building at the moment. So, I'll move on and I'll say display will be flex. Align items will be centered and let's give the transition on the background color and then I'll say it'll be 0. 2 seconds. Now we can say if to-do item is hovered what'll happen? Let's see. So the background changes right. We'll say background color is going to be the light color that we have. Okay. Now we can say the checkbox container dash container. Now you might be asking we don't really have this class in index. html right? If you take a look at it, we don't really have it, but it will be added once we add some list items. Okay, for now, let's add the styling. I'll say the checkbox container will have the margin right of 15 pixels as you can tell. And then we'll say the to-do checkbox will have the opacity of zero and position will be absolute. Let's save. Again, we cannot see anything. We don't really have any items, but we'll get there. Then we can go ahead get the check mark itself. So at this point I'd like to copy and paste and walk you through it line by line. So we'll say display of inline block with and height of 20 pixels some borders border radiuses position will be relative cursor pointer and some transitions. And just before we move on I'd like to update the index. html file with some hardcoded data so that we can see something on the UI as we go. Right. So, I'll go ahead add a list item that has the class name of to-do item. And just make sure that this is under the ul element. So, we have a label with the input as well as the span. Then, we have another span that says buy groceries and then a button with this icon. Now, let's save. This is the output. Now, we're going to add some classes to make that look nice. So, without this, let's see what would happen. You cannot really see the check mark, right? So this class is updating check mark. Let's see which one is this. Okay, it is the span that we have. Now let's move on. I'll say right after this I'll say to-do dash checkbox. If this is checked, we would like to say plus dot check mark. Now what does that mean? So we just said if to-do checkbox is checked, right? If this input is checked, go ahead select the very next spin that has the check mark class. So I hope that makes sense. Now we are going to select this one and we will update the background color that will be let's say variable of success and then we'll say border color will also be success. And let's see this in output right here. Okay. So the background is success as well as the border color. Let's see if we can see this in action. Here we go. Now if you don't add the border color, let's see what would happen. So only the content itself is green. So this is the check mark that we just updated. But now I'd like to draw this check kind of div, right? So here I'll go ahead say to-do checkbox if it is checked we would like to select the check mark and we are going to add the after element. So I'll say content will be nothing. It'll be position of absolute. Let's say position will be absolute. Then we'll say left will be 6 pixels. Top will be 2 pixels. Width will be 5 pixels. height could be 10 pixels. Now let's save. Basically nothing. But let's go ahead and move on. I think on the check mark I was going to say did we forgot the position of relative? No, we don't. So that's great. We'll go ahead say border will be solid and white. Okay. Now this is what we have. We can update it and make it look like a check mark. So I'll say border width is going to be zero 2 pixels and zero. Here we go. This is what we got. Now we're going to just rotate it. I'll say transform will be rotated with 45°. And now this is a check mark. So this is kind of like an advanced CSS or I wouldn't really say advanced CSS but this is something that you should be a little bit clever, right? We just drew a rectangular and then we deleted some borders such as these left and top border and then we rotated it. And this is the output. Okay. Now we'll go ahead add the to-do item text which is going to be this one. So to-do item dash text. Let's say flex will be one. So it'll take the entire space or as much as possible. We'll say font size could be 1mm and then transition is going to be all 0. 2 seconds. Then we can go and say to-do item. If it is completed, we'll select the to-do item text and then we'll say text decoration will be line through and then the color is going to be variable of gray. Okay, so for some reason this did not work because we don't really have the completed class. If I go ahead and add this completed class on the to-do item. Let's see where is the to-do item. I'll say completed. It should be like uh it should be changed. Here we go. And then we'll just move on with the delete button. So instead of typing this out, I think I am a bit lazy. Paste this in. Let's save. Now we cannot really see it. It says opacity zero but let's say one for now. Okay, this is how that look. For now it'll be opacity of zero but later in the video we will update it. Right? So we'll say if todo item is hovered the delete button opacity will be one just like this. And then we can even change the color itself. I'll say if delete button itself hovered the cover will be danger. So here it will it would not but here it should. Okay. So that's why we don't really put the color right here. And finally we are going to update the empty state. So if we delete everything uh or let's just take a look at the completed filter. This is the output that we have. This is the empty state and let's try to update it. Right. Okay. First I'll go ahead delete this. Maybe comment this out. I'll say dot empty state. Let's say display will be flex. Flex direction will be column. I'll say align items would be centered. Justify content would be centered as well. Here we go. I'll say padding is going to be 40 pixels to zero. And then color is going to be equal to gray. Now I'll select the empty state of icon right the icon of the empty state. I'll say font size is going to be incremented to be 40 pixels and margin bottom of 10 pixels. Finally opacity is going to be 0. 7. Here we go. And let's say the hidden class is going to have this style which is display of none. Finally, we'll add the footer element. So what I'd like to do just copy and paste because this is super simple that we have done millions of times at the moment right so far. So display flex so that they are side by side. Justify content space between align items of centered some padding. Change the border top background color and font size. Okay. Now let's get the items on the left. Let's say items left. The color would be updated. Then the clear completed button. We'll say cursor will be pointer color will be updated and the rest. So this is how that look. And on the hover state we will update the color to be this red color. Right? Okay, so with that, that's going to be for the entire CSS file. In the next section, or maybe just in a second, we're going to get into the script. js file. Okay, so now let's get started with the JavaScript file. Now, we would like to get all of our DOM elements so we can type them out or the better option, I have prepared a GitHub gist that you can find the link in the description. Go ahead and find the to-do app. md file and select everything that you have seen here. Copy it and paste it right here. So we got couple of different items, couple of different elements that we'll be using. All right. So the first thing I'd like to do is create some variables. I'll say let to-dos. This will be an empty array initially. And then we'll say let current filter is going to be equal to all. So this is the default value that we'll start with. And then I'd like to add some event listeners. So I'll say add task button add event listener which will be the click event. Once we click it, we're going to run this arrow function where we would like to call the add to-do method with the task input value. So whatever you put here it would be sent to this method. And I also want to add another method or sorry I would like to add another event listener that will be for the enter right. So we can either add something by pressing to this button or we can press enter. So they are right here. I'll say task input dot add eventlister. This will be key down where we would like to get the event. I'll say if event key is equal to enter, we would like to go ahead and run this add to-do method with the task input value. Now, since this is only a one line, I can go ahead delete it and just put it side by side. This is what I'd like to do most of the time. If I just have an if check with a single line, I just put it next to it. Rather than creating curly braces. Okay. Now, I'd like to create one more event listener. I'll say clear completed button. We'll listen for the click event. So, when we click to this, we would like to call this method called clear completed. For now, I'll just have it as an empty function. Later in the video, we're going to build it. So, the first function that we would like to get started with is the add to-do, right? Add to-do function, which will take the text and we would like to just check if this is empty. So, if you do not add anything and press this, nothing should happen, right? I'll say if text dot trim if this is equal to an empty string. Now, we are using trim. That's because if user wants to add an empty string, still nothing should happen. We'll say if this is the case, it just return don't do anything. But else we can go ahead create a to-do. Let's say to-do which will be an object. And here we'll be having an ID. I'd like to make this to be unique. So I'll just say date dot now. And then we'll add the text. This will be equal to the text that we have. Now since they are the same, we can shorten this. And here we should have a comma. Then I'll say by default the completed will be false. Now that we got the to-do object, we would like to say to-dosp. So we're going to push this to-do into this array that we have above. Right? So we just updated the array. Now we would like to update the local storage as well. So I'll say save to-dos call this method and then we'll say render to-dos as well. For now I'll comment this out. This will update the UI but local storage. So I'll say function save todos. I'll say local storage set item. We'll update the to-dos key. You can call this anything really such as hello, but it should be something that makes sense. In this case, it'll be todos. We'll say JSON. Stringify these to-dos that we are adding. And then I'd like to update the item items count. This is another function that we'll create. And then we'll say check empty state state. So this will check if user should see this kind of a UI or if they AUI I was going to say but let's say this kind of AI right so if they don't have anything this is what they see but if they have something this is what the user will see now let's try to create these functions I'll say function let's create this one first and duplicate it now we're going to add this function So first let's get started with this one. I'll say con uncompleted to-dos. We'll say todos do filter where we'll get the to-do and I'll say if it is not completed right I'll say to-do is not completed. So this should be todos by the way we got the list the array and I'll say items left text content will be updated. Now this will be dynamic. So I'll put back text and I'll say uncompleted to-dos. Length. So whatever the length is and then items left. But now notice how so I'll try to just delete some stuff. So I'll just leave only one. If it is only one you will see item. But if it is multiple it would be items. So we are going to even check for this. So I'll say length and we'll say item and here it should be dynamic. So we will say maybe I'll give out this space uncompleted to-dos. If it is not equal to one that means it'll be plural but else we can leave it as an empty string. And finally we will say left. Okay. Now let's see. It says zero items left which is what we'd like to have for the zero. It should be items but this is currently not coming from this method. It is coming from the HTML file. Oops. Let's go ahead and check the HTML. So if you say five, this is what you would see. But just in a couple of minutes we are going to update it dynamically. So this is just the function we have defined it. We are not using it yet. And then we can I think go ahead and build the render to-dos function which is going to be the longest one. But this is the actual function that will make our application work right and I think we can build this one as well which will be pretty simple. So I'll say con filtered to-dos. Now we would like to filter the to-dos. I'll say filter to-dos. We would like to pass the current filter, right? So it either it is all active or completed. Let's create this function. So I know that this might look a little bit complicated at the moment, but this is really how we can move forward. We'll just build one function at a time and at the end it should work and it should all make sense. Once we complete it, I can walk you through it pretty quickly. So we're going to get the filter, right? This is the current filter that we just passed. And we'll have a switch statement. I'll say switch. We'll say add the filter. We'll say if case is equal to active, we would like to say return the active to-dos. So I'll say to-dos filter where the to-do is not completed. So I'll say to-do. completed is equal to false. And then we're going to go ahead and say if case is equal to completed in this case I'll duplicate this I'll say where the to-do is completed but in the else case so here I'll say in the default case we'll just return all the to-dos without filtering anything. Okay so we got those to-dos I'll say if filter todos. length length is equal to zero. We can say empty statecl class list dot remove hidden and if you just read this line it should make sense right if we don't have any to-dos we are going to see this on the UI we're going to remove the hidden class so that it is visible but in the else case so here I'll say else empty state doclass list we're going to add the hidden class and I just realized this should be filtered to-dos right not filter this is a method this is the variable that we have okay now I think we can go ahead and get started with the render to-dos so I'll say function render to-dos this is not going to take any arguments so we can just get started with it so first what I'd like to do just get rid of the entire UI I'll say to-dos list dot inner html will be equal to nothing because we're going to update it, right? This is kind of like a reset. I'll say const filtered to-dos. We're going to say filter to-dos call it with the current filter. Okay. Then we would like to say filter to-dos for each. We'll get every single to-do and I'll I will run this function. So the first thing we would like to do is create a list item. And that list item is going to be looking like this that we have. So we're going to create the list item that's going to have this class name. It'll have a label with the input span, another span, and a button. Right? So this will be a little bit long, but we're going to go step by step. Let's say con to-do item. I'll say document. createelement. create element create a list element and then I'll say to-do item doclass list dot add it'll be equal to to-do dash item then we'll say if to-do is completed in this case we would like to say to-do item class list at the completed class okay we would like to go below to it right I'll Say let's create a custom checkbox. I'll say con checkbox container. Let's create it. I'll say document dot create element. This will be equal to a label element. And then we'll say add a uh let's say class list. Add a class that called the checkbox dash container. So we just created the container. Now it's time to create the checkbox itself. I'll say this will be equal to document. createelement which is going to be an input and the type of this input type of this checkbox is going to be equal to checkbox. Let's say checkbox. Here we go. And then I'll add a class list that is going to be equal to to-do checkbox. And I'll say checkbox dot checked. So either it'll be true or false which is going to be coming from to-do. comp completed field and then we can say checkbox dot add event listener. We're going to listen for the change event. In this case, we are going to call this function called toggle to-do with the to-do id. We're going to pass the ID so that we know which to-do that we're updating. Right? So, we're going to toggle the state whenever we click to it. And let's create this function as well. I'll duplicate this. Let's say toggle to-do. This will take an ID. We're going to build it in a bit later in the video. And now let's create the check mark itself. So we created the checkbox. Now let's create the check mark which is this one. Right? I'll say con check mark that will be equal to document dot createelement of span. We'll go ahead to say let's add a class list. So we are going to add a new class name that will be equal to check mark. And then now we are going to update the UI, right? I'll say checkbox container. app child checkbox and then I'll duplicate this. We're going to also append the check mark. Okay. Now we would like to create a text element. I'll say const todo text. We are going to create a span element. I'll say to-do text dot class list dot add to-do item text and then we would like to update the text content. I'll say text content will be equal to to-do. ext. So whatever the value is and then we can create a delete button. Now at this point I think we can move a little bit faster. I'll add a class name called delete button and the content will be this which is this exact um icon. If you take a look at the index html this is what we have used previously as well. Okay. So this is the exact same thing and then when we click to it we would like to call a function right that is called delete to-do. I'll duplicate this call the delete to-do. Um we will implement it in al bit later in the video. Okay. So we created everything. Now let's add this elements to the to-do item. We'll say to-do item dot append child checkbox container. Duplicate it. That will be the to-do text. Duplicate it. And then delete button. And then finally we'll say to-dos list append child to-do item. So what we are doing here is this basically so we created all these elements one by one right at the end of the day we would like to take all of them right all of them and put it under the list item and then take the list item put it under the ul so that it is visible on the UI okay so this is what we are doing now let's try to save this which we already did and give it a go I'll say learn HTML and CSS. Let's add. Okay, something has been updated. Not the UI. We'll take a look at it why, but definitely something is working. I'll go ahead and just say learn Python. Add this. Now, two items left. So, it so looks like something is working right now. Let's try to scroll to the top and see if we have called the render to-dos method. Looks like we didn't. So, let's save. Okay, I'll try to add something else. I'll say learn JavaScript this time and add this. Okay, so once again it did not work. Let's open up the terminal. Okay, it says cannot read the length on the check empty state. So, I'll just say length uncompleted to-dos. This is the only thing that we have. Okay. So, why this is the case? Maybe it's because we don't really have any uncompleted to-dos. So, to-do is not completed. Now, to be able to get rid of this, you can add question marks, right? The optional chaining. I'll try to add something else once again. I'll just say something random. Let's just say frr three times. Okay, once again, we got an error, but let's try to fix it. I don't really want to cut this out from the tutorial. So, again, it is coming from the check empty state. Add save to-dos and add to-dos. Now, the length is causing this, right? I'll just search for. length. We have another one right here. So whatever the current filter is, it is all. I'll add question mark right here as well. Okay. Once again, let's give it a go. I'll say learn something else. And then it says we cannot read the for each method. Now let's see why this is the case. Why did we encounter this much of errors? I'll just search for each. So this function is not really working as expected. Okay, I think here we should say return to-dos instead of just to-dos, right? Okay, that was the issue. Now if you don't say return, it doesn't return anything. And this is equal to undefined. So that was something that we have and I didn't deleted this part from the video so that you can see my entire thought process. Um okay let's save and try to add one last thing. Here we go. UI has been updated. We can see it right here. But what happened to the previous items? Now they are definitely in the local storage. I can open up my application local storage. So here it should be application not cookies but local storage. All right. So we have bunch of different values. Here we have some to-dos. Okay. So maybe the previous ones have been deleted. Why this is the case? If I refresh this page. So it is right here. Let's add something else. Okay. So what happens is this. Whenever you add something new, it is going to update this one instead of adding on top of it. Okay. Kind of strange. When you refresh add something new, it's going to replace it. But if you don't refresh the page and add something, it's going to add on top of it. So we're going to get into this functionality. But first, we would like to get everything from the local storage and display it on the UI whenever we load our page. So, let's add an event listener for that. So, I will go right here at the bottom of the file and I'll say window addvent listener. Let's listen for DOM content loaded. And then we would like to run this function where we'll just say call the render to-dos or let's say load to-dos. Let's create this function as well. Let's say function load to-dos. So this will get the stored to-dos from the local storage. I'll say local storage. get item. where we have this to-dos and then I'll say if we have some value we would like to say to-dos array will be equal to that value I'll say JSON. parse parse the stored to-dos and then just go ahead render it on the UI. Okay, now let's refresh. Looks like we don't really have anything. Okay, so of course it is not going to work if you don't call this function. Let's go ahead call this and save. Here we go. These are the values that we are getting from the local storage. Right. Let's try to delete them manually. Here I'll go ahead get the application. Let's get the to-dos and I'll just delete them. I'll press delete. They are gone. Now, if we refresh, they are not going to be there. Right now, let's add something like learn Python. Add this. Refresh. It should still be here. That means this is working as expected. Now, let's scroll to the top. I'd like to add more things. when we say add to-do. So we are going to render the to-dos but also we would like to reset the form. Right? Currently if I say learn JavaScript it has been added but this is not getting updated. So I'll say task input do value will be equal to an empty string. Let's add something. It'll just reset itself without redoing anything. And now we can add the function where we would like to delete the to-do itself. So here we'll get the to-do ID. I'll go ahead say this to-dos will be equal to todos do filter. So we're going to filter out the one that has just been deleted. We'll say get every single to-do and check if to-do ID is not equal to this ID and include it. But else go ahead and delete that. Then we'll just save the to-dos to the local storage and then we'll say render the to-dos. Okay, let's go ahead and give it a go. I'll try to delete this one. Now it is not here and the local storage has been updated. Let's refresh. As you can tell, it is not here. Now the other method could be to toggle the state which is this one, right? Let's give all the space. I'll say we're going to say the to-dos will be equal to to-dos. m mapap. We're going to get every single to-do and then run this function here. I'll say if to-do ID is equal to this ID. We're going to go ahead and update the completed field. So I'll say return all the previous fields of the to-do and update the completed state right we'll say it will be equal to to-do completed but we are going to negate it so if it is equal to true it'll be false false it'll be true right and if this is not the case we'll just return the to-do as itself okay and then we'll say save this to the local storage and then update D1. Okay, now let's give it a go. I'll say complete it. Refresh. It is still this value. I can complete this one. Uncompleted. Refresh. And this is what we got. Now the other functionality that I'd like to add is this button. Let's just search for it. Here we have the clear button. Clear completed button. We have added this function which is this one. So when we click it, it's going to delete the completed ones, right? So let's say this one is completed. If I click it, this should be deleted. I'll go ahead and say maybe to-dos. It'll be equal to to-dos dot filter. Right? We're going to get every single to-do. So with this, we only have the uncompleted to-dos, right? We'll say save to-dos. Go ahead, call this and render to-dos. Okay, I'll click it. Now UI has been updated. And then we have one more thing. Let's try to refresh. Now when we refresh, it says zero items left. But we actually one item left. So we would like to fix this as well. And to be able to update it once after we get the to-dos from the local storage, we'll just say update the UI with the update items count. Right, let's refresh. Here we go. We have one item left. When we refresh it, this is what we got. Let's add more things. Okay, now I'll just say this one and this one is completed. If we take a look at the active looks like UI is not being updated. Okay, we're going to take a look at it. These does not work. And to be able to make them work, we can add an event listener, which will be click, right? We're going to add a click uh event listener to this one, this, and then the completed one. So let's go ahead and try to do so. I'll say get the filters for every single one of them. We would like to run this function where we'll say filter dot add event listener of click and then we are going to run this function. So I'll say set active filter. And how do we get the filter on all of them? Right? How do we know if this is the all, if this is active and this is completed? So, we have added some attributes like data-filter. Right? And they have all these values. This should be a lower case by the way. I don't know why I put it as uppercased, but it should be a lowercase like this one. Here we go. So, just update that. Now, we'll say um set active filter. We'll say get the filter get the attribute which is called as data dash filter. So this will give you the value and then we can build this method which will be easier than you think. We'll say function where we'll get the filter as the argument and then we can say first let's grab the current filter which is this one and then we'll say filters. So filters do for each every single filter we will run this method. And I'd like to maybe just call this as item so that it's not really confusing. I'll say if item get attribute get the attribute of data-filter. If this is equal to the filter that we have in this case, we'll just say item doclass list dot add the active class. In the else case, we'll just say remove it. Okay, so this will just make sure that only one of them is active at a time. And then once we have done this, we would like to update the to-dos. And now it should be working out. I'll say active. So we only see the active ones. If I say completed. Here we go. And then all of them. And one more thing that we are missing is to set our date. Right? We would like to get the today's date and format it in this format. So I will create a function for this. I'll say function that is called as set date. And we would like to call this function whenever we load this page. We'll just say set date. Now let's get into it. So we'll say con today which will be equal to the new date. And now we would like to create some options so that we can update it properly. So that we can format it properly. Right? I'll say options where the weekday will be in the long format. Month will be short let's say and then day will be numeric. So we'll go ahead and just say date element. ext text content it'll be equal to today dot to local dates date string we can use n us and then put the options okay so here we can see today's date is right here as expected if you wanted to you can change the options which is going to update the formatting but this is the one that I'd like to have in my code so let's go ahead and save this file and I think that's kind of it for this entire project, right? Let's just try to test this out for the very last time. I'll try to add something else. Let's just say something else. We can add it with either enter key or we can press to this button. It'll be added. We can toggle the state delete. Refresh. Everything should be here. Can say clear the completed ones. We can change the filter, right? and we can delete it manually. So that's going to be it for this project and hopefully I'll see you in
Project 9: Professional Contact Form (HTML/CSS)
the next one. All right, so welcome back to this section. We're going to build an entire contact form. This project only includes HTML and CSS. There is no JavaScript at all. So this is one of those projects where you can practice your design skills with CSS. Okay, so we have some cool animations with box shadows and nicely designed inputs. And finally, we have some info section. And this entire form will be animated from the bottom of the screen when you refresh the page. Right? So we have this slide in effect. If you would like to get the end result screenshot, it'll be right here in the diagrams and the link will be in the description. With this in mind, let's go ahead and get started with it. So for these icons, I'll be using Font Awesome. So I'll just visit cdjs. com and then search for font awesome. Okay. So I'll click it and I'll get the very first link that we have. Okay. Now we have three empty files. First let's get started with HTML. I'll get the boiler plate. let's say contact form link our CSS file and then paste the font awesome link. Now we can get started with the body element. So, first I'd like to put those side by side. And this is completely responsive, by the way. As you can tell, once we hit a certain break point, it's going to be in the column direction, right? Okay. So, I'll say open with live server. It should be right here. But we don't really have any content. Okay. So, I'll go ahead and get started with it. So first I'll have a div with the class name of container and then I'll have one more container but this time it'll be called as form container and then we'll have an H1 that will be this text that says get in touch and then we can have a P tag. It's going to be this one. Let's say fill out the form below to contact us. And right after this P, we'll go ahead create a form element. It's not going to have any actions. So let's delete it. We'll have a div that will be input group. Input dash group. Then we'll go ahead create one more div that will be for the input field. So we'll say class input dash field. And then we'll have an I element where we will hold the icon. So it's going to be this icon. Let's say fasa-ash user. And then right below to it, we'll have an input which is going to be type of text. We can give it a placeholder like name. And then we'll say this is going to be required. Okay, let's save. This is the end result that we have. And then we can duplicate this. I'll basically duplicate this and give one space. This will be FA uh like FAS and FA envelope. Okay. For the type, this is going to be email and placeholder will be equal to email. Okay. And now let's try to duplicate this once again. Here we go. The icon will be phone. Type will be tell. And then let's say phone, we could say something like optional. Since this is optional, we can delete the required field. Right? Okay. So this is exactly what we're building at the moment. We can duplicate this once again. And this time it'll be icon of FA tag. Let's say type of text. And then this will be the subject. and required. Okay, let's save. So this is the output. Now this time instead of an input field, we will create a message field because this is a bit different, right? I'll say dot message dash field. We'll go ahead get an icon. This time it'll be fa message. And we can delete this empty space. And then I'll have a text area component or the element. So I'll delete the ID and then the name. Let's say placeholder will be your message. And then I'll say it'll be required. Okay. Right after this div I'll have a button. Let's say type will be submit. We'll go ahead have a div with the class name of btn dashc content. We can have a span that will be sent message. And then finally the icon which is going to be class of fas fa- paper plane. Okay. So that's going to be it for the entire form. At the very bottom we would like to have this info. So after the form we'll say div that will have the class of contact dash info. We can say get the info item and we are going to be having this three times. So we can say multiply this by three. Right here within the very first one we'll get an icon that will be class of fasa map marker alt. Okay. So it is this icon that we just got. Then after this I I'll say span and just get this content. You can put anything that you wish. Okay. Right after this I'll get a different icon that is called FAS FA envelope. And then for the content we can get the exact same thing that we have here. I'll put a span and put it inside. Now finally here we'll have another icon that will be for phone and then for the span I'll get this text. Okay. So this is the entire UI that we have built only the markup. Now we'll go ahead and get started with the CSS file that we have already linked and we are not going to have any JavaScript so we can delete it. Okay. So let's get into the CSS file and get started with it. So the first thing that we always do is to add some basic resets, right? I'll say get the padding of zero from all directions. Margin of zero and then box sizing will be border box. And we can add a different font family. This is optional. I'll go with sens. Okay. And then I would like to add some CSS variables. So I'll just get my root element and I'll say dash the primary color will be equal to this one which is going to be 4 a de e 80. I'll duplicate this. I'll have primary dark and let's not forget to turn this off or add the semicolon at the end. Now this will be 22 C 55 Ne. I'll duplicate this. This is going to be BG dark and the value is going to be 1 A three times. Let's duplicate this. This will be text light F uh 3 F4 F6. Let's say text light and I'll have text gray. Let's say we will have card BG. Then we can have input BG as well. And finally the border radius. border radius. Okay, let's just put these values. This is going to be 10 pixels. We'll have the input BG as 333 and then we'll have cart BG as 25 three times just like this. And then the text array will be 9 C A3 AF. And then this value I think this is something that we have already put correctly. Okay. So we'll be using these variables just in a second. We'll go ahead and get the body element. Now we'll say the background color is going to be equal to bar d-b dark. Okay. Then we'll go ahead and change the color. That will be text light. Okay. Then we'll say minimum height is going to be 100 ph. So we'll say display flex justify content centered and align items will be centered. Then we can say padding will be 30 pixels to 15 pixels. Then we'll go ahead get the container itself. I'll say the width is going to be 100% and the maximum width will be 800 pixels. Here we go. Then we'll go ahead select the form container and we'll update the background color. So I'll say background color will be card bg. Okay. And then we'll get the border radius value. I'll say variable dash border radius which is going to be equal to 10 pixels. And then we can get a padding value such as 40 pixels from all directions. And then we can add a box shadow. So say box shadow will be equal to zero 10 pixels 30 pixels and then rgba let's say it'll be 0. 3 okay then we'll go ahead add an animation now this animation will be let me demonstrate pretty quickly it'll be this slide in effect from the bottom of the screen right so we will add this animation called fade in let's say 0. 5 seconds and it can be ease out. Now we don't have this fade in animation, right? We can create it with a key frame. So I'll say key frames and the name should be fade in. We'll say go from this styles to this one. And here from will be opacity of zero. And then we'll say transform translate Y of let's say 20 pixels because we'll be coming from the bottom, right? And now two which is the end result will be opacity of one and transform of let's say just reset it which is going to be 0 pixels in the Y direction. Right now let's save and take a look at it. Okay. Whenever I refresh it'll be like fade in from the bottom of the screen now. We can add more things but I think this is already looking pretty nice. So I'll just leave it as it is. Then I'd like to select the H1. Let's give a little bit space. I'll say the color is going to be primary color that we have. Here we go. And then I'll say font size will be 2. 2 RM. Then we'll go ahead say margin bottom will be 10 pixels. And then we can select the P tag. I'll say margin bottom will be 30 pixels. And then color is going to be text gray. Okay. Then we can get the input group class if I can type correctly. Here we go. We'll say display will be grid. Now hear me out. Let me demonstrate this pretty quickly. So it'll be display of grid, right? But once we hit a certain break point, it's going to be in the column direction. So let's see how we can make that work. I'll say display will be grid and then we'll have the grid template columns that will be repeat of let's say auto-ash fit and then min max 240 pixels to one fraction. Let's see the end result. Okay. So this is how that work at the moment. Now let's move on. Right after this, I'd like to add some gap such as 20 pixels. And then we can say margin bottom will be 25 pixels. Now we'll get the input field. This will be position of relative because we'll you'll use position absolute on the like on these icons. And we'll select the message field as well. and it'll be also position of relative so that we can nicely position this icon. Let's do it immediately. I'll say input field and we'll say message field. Now we would like to select the icon within the message field as well as input field. Right? So I'll select both of them and I'll say position will be absolute. It'll be top of 50%. From the left we can say 15 pixels. Transform on the translate Y is going to be minus 50% so that it is centered vertically. Now let's save and let's see what we're going to get. Okay. So it is overflowed within this and we'll say color is going to be primary color and then finally font size of 1. 1 RM. So this is what we have now. Currently, it looks not really good, but once we format the input as well as the text area, it'll look nice. Okay. So, here I'll go ahead and get the message field icon. And I'll change the top position to be 25 pixels. Okay. Now, we'll go ahead and get the input as well as the text area. So, I'll say This will have the width of 100%. Here we go. We'll say padding is going to be 15 pixels from all directions but at the very end will be 45 pixels which is going to be from the left hand side. And then we'll say background color is going to be input bg. Okay. Then we'll say border is going to be 2 pixels solid and transparent. Then we would like to add the border radius. And then the color is going to be text light. Here we go. And then I'll say font size will be 1 RM. And finally the transition from everything. Let's say 0. 3 seconds in ease. Okay. Now let's add the text area itself. We are going to update it a bit. I'll say the height is going to be 150 pixels. Let's save. And then I'll say the resize is going to be equal to none because currently I can't resize it, right? And since we have some transitions, it is happening really slowly. But we are going to get rid of this resize property. And I just realized this should be text area. I had a typo. Let's save. Now we don't really have this resize option. I'll say margin bottom will be 35 or 25 pixels. Okay. Now we'll go ahead and get the focus state on both input as well as the text area. And we'll say the border color will be updated. Let's say border color not the background. It's going to be primary color that we have. And then outline is going to be none. And finally, I'd like to add some box shadow. So if we don't have if we don't add the box shadow, this is how it'll look like. It's still looking pretty nice, but I'd like to have this effect as well. So I don't really know if it is visible from the video, but there is definitely a subtle change which is happening thanks to box shadow. So let's go ahead and add it. I'll say box shadow and I'd like to just provide the value box shadow everything zero but then 3 pixels and then we have this green color. Now let's see the end result. Okay. So this is what we have at the very outside layer. Then we can get the placeholder styling. I'll say input placeholder element and duplicate it. This will be for the text area. I'd like to change the color to be text gray. All right. So, it's been updated. A subtle change, but I think it's looking pretty nice. Then, we'll go ahead and get the button itself and say the background color will be updated to primary color that we have. Then, we can get the color itself. It's going to be black. And then I'll say font weight of 500. or let's go even with 600. Here we go. We can give some border of none. We'll just get rid of that. And then border radius of border radius variable that we have. Headings will be 16 pixels to 30 pixels. Then we can say cursor is going to be pointer. And then I'll say width will be 100% no matter what happens. And then the transition will be for everything 0. 3 seconds. And we can say ease. Okay. Now on the hover state, let's try to update something which is going to be the background color itself. It'll be primary dark. And then we'll update the transform. So I'd like to say translate Y of minus 2 pixels. so that it would go up a little bit. But then I'd like to add this bug shadow, right? Kind of like neon effect. I think it looks pretty nice. And let's see how we can add it. I'll basically grab the same value. Okay, so it's the exact same color I believe. Let's see. Okay, it's the same thing but 0. 3 and we update these values. Okay. So this is how that look. This is how we can give the hover effect with the box shadow. And then I would like to add the active property. So say button on the active state. We would like to take the transform of translate Y and bring it to the previous state. Okay. So I'll hover over this and click to it. It just goes to the previous state. Now we can get the button content. So I'll say dot btn content and I'll say display of flex so that we can say gap of 10 pixels but without display flex I think it's not going to have any gap right it does not work really properly we'll say 100 pixels of gap but if you delete the display flex you cannot really see it and now let's say it'll be 10 pixels let's say justify content will be centered otherwise as it is on the left hand side and then we can say align items will be centered as well. Here we go. Then I'll go ahead get the contact info. Contact dash info. I'd like to get the margin top of 40 pixels. I'll get padding top of 30 pixels. Border top let's say will be 1 pixels. Solid RGBA of white which is going to be 25. Sorry 255 three times. And then we'll say 0. 1. Let's save. Here we go. And then I'll say display of flex but in the vertical direction. Right? I'll say flex direction is going to be colum. Then we can give the gap of 15 pixels so that they are nicely separated. I'll say info item. We would like to say display of flex. Let's say df. And then I'll say align items to be centered so that this text as well as the icon is nicely centered. And then we'll say gap of 15 pixels. Here we go. And I'll get the info item icon. And I'll say color is going to be let's say primary color that we have. Then I'd like to update the font size. Let's say 1. 2mm. Okay. If you don't add this align items like I think we cannot see it yet but let's just be extreme. I'll say 2 RM. Okay. As you can tell now it is not really centered nicely. If you say align item centered and accept this. Okay. Now it is centered as you can tell. But now we'll go with 1. 2 RM. Okay. Then we can give a width such as 20 pixels. Okay, let's say 20 pixels. Okay, then we'll get the info item span. Say info item span elements that we have where we'll update the color itself to be text gray. Okay. And finally, we can add some media queries. I'll say media uh let's say maximum width, but we need to wrap this with brackets. Let's say 600 pixels. And below we would like to add the form container to be padding of 25 pixels. Let's see now. Okay. What the hell? This button is not really looking correct. We're going to fix it. Okay. So, I think all we have to do just say input group is going to be grid template columns, right? I'll just say one fr. Let's see now. Okay, this doesn't really fix it. We're going to take a look at it. Um, but we can say something like H1 font size is going to be equal to 1 RM 1. 8 RM. Right now, let's see why this is causing it. Right? I think let's see in the index. html HTML this button should be outside of this indiv. Okay, now it is working correctly just like in the end result. But this is not width of 100. We can take a look at that. And to be able to make this text area 100% width, we can basically take this entire message field. So just cut it from here and put it right after this step. Now this should be working correctly. Okay, so with this that's going to it for this entire project. We had two different small issues where we had to get this button put it outside of this div and then the same thing for the text area which is this message field. Just go ahead take it and put it outside of this div. Previously it was right here but we took it and put it outside. So that's the entire project. We have learned bunch of different things with the grid to let's say box shadow to animations. Now if you want to change the entire theme, all you have to do visit the style CSS file. You don't really need to change anything here in these styles. Just change the root uh CSS variables. Let's say we would like to go with a blue theme. I'll go ahead change them. Let's say we're going to have this one. And if you save, now everything is in the blue theme. So this is the beauty of using CSS variables. So I just bring back the previous colors. I hope you enjoyed the entire project. I'll see you
Project 10: Modern Modern Pricing Cards
in the next one. All right. So welcome back. In this section, we're going to build these pricing cards that you can see on the screen. This is a really popular component that almost every single company use nowadays. And if you ever wondered how to build one of those, this is what we're going to be doing in this video. And at the very bottom of this page, we have this testimonial component which is also pretty popular, right? And this entire website, this entire UI is completely responsive. So once you hit a certain break point, this is what you're going to get. And then finally, one card at a time and you can scroll to the bottom. Everything is working without breaking anything. All right. So if you would like to get the screenshot here, I have it. The link will be in the description for this diagram. And then for the icons, we'll be using Font Awesome. So head over to cdnjs. com and search for Font Awesome. I'll copy the link, kill this website, and put them side by side. So I have the two different empty files. We're going to get started with the HTML. So let's get the boiler plate. I'll say the title will be equal to something like pricing cards. And I'd like to link my CSS file. and then just paste this link that we have just copied. Okay, we can go into the body and create a container. Let's say something like hello. I'll save and open this with the live server that we have. Okay, so this is the end result. Now let's go ahead and get started with it. So I'd like to show you the actual end result as we go so that I can reference it and I said currently we are building this. I can say something like we're currently building this button so on and so forth. So under the container we're going to have a header component where we can put the title as well as the P tag. So I will say H1 choose your plan and let's try to capitalize them. Okay. Then we're going to go ahead create a P tag where I'll say select the perfect and you know what I'll just copy and paste because why not? Here we go. I just got the P tag. Right after this header, I will create the pricing cards uh container. And then we're going to have the basic plan. So, this will be our card and it'll have the card header initially where we can store the icon, this rocket icon, the basic um the basic text, whatever the plan is, right? and then the price and finally the description. Okay, so under the cart header I'll say plan- icon where I'd like to put the I element with the class name of FAS FA bracket and then after this div I'll create H3. I'll say basic and then after the H3 I'll say price because we're going to have three different elements. So, we're going to have a span with the currency um currency class. And then I'll duplicate this twice. This will be amount and then the period. So, either it is monthly or yearly, right? I'll just say slash month and then we're going to put the amount for the basic plan which is nine and then the currency which will be dollars. Okay. And then after this price, we'll put the P tag with the class name of description. Okay, I'll copy this entire thing. Paste this in. This is what we have at the moment. So, right after the P tag as well as this div which is for the cart header, right? Just go ahead shrink this. Right after this one, we'll have the cart dash body. And then this will get some features under the ul element. So I'll say features. Let's put all of them one by one. We'll have the list item with the icon that will be for the check mark. So I'll say class name of fas a check. And next to it we'll put let's say we'll put a space and I'll say five projects. Okay, let's save. So this is what we have at the moment. Now I will go ahead and duplicate this couple of different times. So we're going to have for the 20 GB storage, basic support, email notifications, advanced analytics, and then finally the custom domain. But these two will have different icons. So I'll just say FA times for both of these and they will be disabled. So I'll just say class name of disabled. Let's copy this and put it right here. Right. Let's update the content. The very end one will be custom domain and this one will be advanced analytics. Okay. Now we're going to build these three. So this will be 20 GB, right? I'll say 20 GB projects, sorry, storage. Here we go. If I can type it correctly. And then we'll say basic support. And finally the email notifications. And let's capitalize this correctly. Okay. So that's going to be for the card body. I'll shrink this. And finally we'll have the card footer which will get this button. So I'll go right below it. Card dash footer. That will get the button. Let's say class name will be btn and we can say get started. Okay, so that's going to be it for the basic plan. Let's go ahead shrink this entire cart. And this is the end result, but we're going to make that look a lot much a lot more better, right? So I will have my pro plan. This is basically the same thing, but we'll have different content as well as a different let's say class names. So I'll say it'll get the cart as well as the popular class name so that we can have different styles on it. And then we'll put the let's say popular dash batch which is going to be this one. We can say most popular right we will position this absolutely to the top right corner. And then we can have the card header component that will get the icon. So it's the exact same thing. I'd like to copy and paste. If you want to, you can pause the video and type this out. So under the cart header, we got the exact same content, right? We just change the icon. And then we have the price. This is the pro plan. We got the currency amount and period as well as the description. And then right after the cart header, let's go ahead and shrink this. I'll have the features. Sorry, we'll have the card body. Now, what I'd like to do, just go into the basic plan, copy the entire card body, and then paste this in. We will just change the content. Okay, so this will be the same. Everything will be the same, but the advanced analytics will not be disabled. Let's go ahead delete that. And this will be a check mark as well. So I'll just say check. Here we go. And there is nothing difference like nothing is different than this one. We can leave this as it is. And then at the very bottom of this card body, we will create a card footer. We'll just say this will have a button with the class name of btn and also btn dash accent. And I'll just say get started. Okay, so that's going to be for this plan as well. Let's go ahead and shrink this. Finally, we're going to put the enterprise plan. And by the way, this is the output that we have. So, right after this one, I'll say enterprise plan. And then we'll create the cart class. This will get the cart dash header thing. And I'd like to give you the content. So this will get the plan icon with this building icon. Then we'll get the text. So right after the plan icon, go ahead put the enterprise text. Then we'll get the price as well as the currency amount and period. Okay. Right after this one, we are going to put the description. So after the price, go ahead get a P tag with the description class. And this is the content. And then after the cart header, we can put the dashcart body. Sorry, cart-body. And then we'll put the features. Instead of typing this out, I'd like to get everything that we have here uh under the ul. So that was the pro plan. Now we're going to put it right here under the card body. And this will not be disabled. It'll also be a check mark. Okay. And then right after the card body, we will put the card footer component or the div I should say. We'll say this will get the button class of btn and then the content will be get started. Okay. And then at the very bottom we would like to put the testimonial component. So let's go ahead and scroll to the top. I would like to find the pricing cards. shrink this and then we'll go ahead create the testimonial div and then I'd like to have the quote as the class name I'll have an icon which will be class of fas a quote dash left then we would like to put a p tag right after this I'll say p tag you can change the content this is what I'll have I'll copy this entire thing paste this in and Then right after this p tag I will create the author class that will get an avatar as the div with the class name and then we would like to put an image. Now we can use the random user me. So let me provide this to you and I'll copy this entire URL. Paste this in into my URL into my browser and this is the output that we got. If you wanted to you can change it change this value. Sorry we can put something like 14. you'll get bunch of different results and this is the one that I'd like to go with. Let's add an old tag. I'll say this is the customer that we have and then after the avatar I'll say the info which is going to be this part. We'll just say H4 put the name and then we'll have a P tag that will be their title. Let's see. Marketing director. Okay, so that's going to be it for the entire markup. Next, we would like to build the CSS file. So, let's go ahead open this up and get started with it. So, the first thing I'd like to do, as always, get our base styles. I'll say margin of zero. This is the basic reset that we always do. Then, padding of zero, box sizing of border box, and then I'd like to change the font family. Let's say it'll be equal to sense surf. You can use anything that you wish. Now I'd like to get some CSS variables so that we are consistent in our code. And now this CSS variables will be really helpful if at the end of this project you want to change the entire color. All you have to do just update these CSS variables, right? So let's say at the end of this section you would like to go with a yellow theme or a blue theme. All you have to do just update couple of different values right here. And now instead of typing everything, I'll just type out the very first one. Let's say primary dash color. We can put this value. I'll say 4 A D E 80. Now we'll have bunch of different values. And instead of typing them out, I have prepared an entire GitHub gest that you can find the link in the description. Go ahead, scroll and somewhere in at the bottom, you should find something like pricing. md. So copy this entire file and paste this in. Here we go. We got the primary color, the dark one, light, and couple of different values as well as some shadow values. Right, for the box shadow, we'll be using all of them. Now let's scroll to bottom. I'll have the body selector and I'll say the background color is going to be this bg dark. Okay. Now we'll use the color. It will be text height and if you want to use a CSS variable you should wrap them with the variable as you might already know and then I'll say minimum height is going to be 100 VH here we go we'll just say display of flex justify content centered and then align items will be centered then we'll say padding will be 40 pixels to 15 pixels and we can change the align height could be something like 1. 6 six. Okay. Now, after this, I'd like to select my container. I'll say container. That will be width of 100 pixels. Sorry, 100%. But the maximum width is going to be 1200 pixels. And then I'll say margin is going to be 0 to auto. Then we can get the header styles. I'll say header. It'll be text align of centered. Now it's been centered. And then we'll say margin bottom of 50 pixels. Then I'd like to get the header H1. Now there is something different here. This is not just a regular color. I'm not really sure if it is visible from the video, but we have a linear gradient from left to right. So this color is a lot different than this one. Let's see how we can make something like this. So the first thing I'd like to do before we get into the colors, I'll say font size will be 2. 5 RM. And then I'll say margin bottom will be 10 pixels. Okay. Now we're going to get into the colors. So I'll say background and not background color. Notice how it should be background because we'll be using linear gradient. So I'll say two, right? will be going from this color which is the primary color that we have and to this color which will be primary light that we have. Okay. So if you save this is what we got. But we don't really want to have this on the background. We text. So we would like to first just say display inline block. So it only takes the space that it needs. And then we'll say background clip is going to be equal to text. Now the background is gone, right? We would like to say color will be equal to text. Sorry, it'll be equal to transparent. Let's go ahead update it. Here we go. Now it works. And if you want this to work on every single browser such as Safari as well, you can add the fallback with WebKit. say get the exact same thing and just paste this without any spaces. Okay, so I'll just put a comment. Let's say this is for Safari. Okay, so this is how we can get this kind of an output. If you want to change the colors now, we can basically go scroll to the top. Let's say you would like to get a blue theme. Update the primary one. And which one did we used? It is primary color and then the light one. Can go ahead update it as well. Okay. Now the entire theme has changed but I'd like to go with these ones. Okay. Now let's scroll to the bottom after the H1. We're going to get the P element. So I'll say header P tag. I'll say color will be text gray that we have. And then we'll say font size is going to be 1. 1 rm. I can change the max width. Let's say it'll be 600 pixels and margin is going to be 0 to auto. Then I'd like to say get the pricing cards container. Right? I'll say pricing dash cards. And then I'll say display will be a grid. We'll say grid template columns is going to be a repeat to auto fit. We'll say min max that will be 300 pixels to one fraction. Right? And then we'll say gap of 30 pixels. Now we would like to say margin bottom will be 60 pixels as well. Now currently we cannot see the effect but if you put it like this it'll be responsive out of the box. Okay, after the pricing cards, I would like to get the card itself. I'll say the background color is going to be the card background color that we have. And then we'll say border radius is going to be the border radius variable that we have. I think it is 10 pixels. Okay, so it's 12 pixels that we're using. If you wanted to, you can update that value as you wish. Then I'll say overflow is going to be hidden. Then we can say um position is going to be relative and you're going to see why. We'll say box shadow will be this shadow medium that we have. And then I'll say let's give some transitions on everything 0. 3 seconds as is. Okay. So that's it. Let's also add the height of 100%. Now we'll go ahead and get the card hover state. We will update the transform property. Let's say transform will be translate Y of - 10 pixels. And I'd like to get the box shadow. We'll say it'll be equal to the large box shadow that we have. And then finally the background color can change to card hover state. Okay, let's take a look at it. As we hover, I think it is changing but this should be background color. Okay, now the background color changes as we wish. Then I'd like to get the card header component. Say card dash header. I always say component is because I'm using React a lot. But this is basically a class. I should say I'd like to get the cart header class, right? Okay. Let's say padding will be 30 pixels. I'd like to get the text align to be centered. And finally, let's add some border bottom. I'd like to copy this value and paste this in. This is the output that we got. Now, I would like to get the plan icon as well. I'll say width will be 70 pixels. Same for the height 70 pixels. And we can add a background gradient. Now, let's try to paste this in. and then I'll walk you through it. Okay. So, there's nothing to walk you through it basically, but we have added some degrees. You can also say something like to right or to left to bottom whatever you wish. I'll go with 135°. We're going to go from this color to this one. And we're updating the alpha value, right? So that we can get this kind of an output. And then I'd like to change the border radius to be 50%, so that it's a complete circle. And then I'll say display flex. And then so that we can center this icon within that. Right? I'll say display flex align items to be centered. And now let's say justify content centered as well. And we can say something like margin of zero to auto. And I'll give some something like 20 pixels. Okay. so that it's centered within this container. And then I would like to select the plan icon itself right the icon element not the container I'll say font size will be 1. 8 8 RM it's been incremented and we can say the color is going to be primary color that we have now it is looking a lot more cleaner then we can get the H3 I'll say font size will be 1. 5 RM we can give margin bottom of 15 pixels okay then I'll get the price itself I'll say margin bottom will be 15 pixels as well then we can get the currency so I'll go ahead say currency Okay, it'll be equal to font size of 1. 5 RM. And then I'll say margin right is going to be 2 pixels. It's very tiny, but if you had 20 pixels, this is what would happen. I'll just give two pixels. Then I'll say color is going to be a variable of primary color that we have. Here we go. Now the other thing that I'd like to do just align this to the top. So I'll say vertical align will be equal to top. Now in this case the text has gone to the top but what I want to happen is this right the currency will go to the top. Now currently this is not really how that work but once we make this larger it'll work as expected. Okay. So I hope we're going to see what that means just in a second. Let's say amount select this and we'll say font size will be equal to 3. 5 RM. Here we go. This is what we got. If you delete this part, they would be side by side. But now this is the output that we would like to have. And I'll say font weight is going to be equal to 700. And then I'll say line height could be one. And then I'll say color is going to be a variable of primary color. Okay. Now we'll go ahead and get the period itself. I'll say font size will be 1mm and I'll say color is going to be text gray. And after this we can select the description itself. I'll say dot description. Let's say font size can be decremented a bit such as 0 95mm. And then the color is going to be text gray as well. And then I'll select the cart body. Let's say this will get the padding of 30 pixels. And then let's say uh flex grow of one. Now why this did not grow card body if we delete it. I'll just bring this back. Even though we cannot see the difference, I think it'll be clear in a couple of minutes. I'll say features will be equal to list style of none. So we can get rid of those bullet points that we have. And then I'll say the features let's say dot features get the list items. We'll say margin bottom will be 15 pixels. Then we'll say the display will be flex. So that we can align items in the center right in vertically they are centered. Now we'll get the same thing but the icon itself I'll say margin right will be 10 pixels and we can say font size will be 0. 9 RM and then I'll select the uh the check marks specifically and then we'll get the this cross icon. So I'll say features LA I so list item I and then actually the FA check specifically right we'll say color is going to be variable of primary color that we have and I can duplicate this will be for the FA times and this would be a color such as the danger color I'll go with E F444 four right 44 double times. If you'd like to take this and make it a CSS variable, you can definitely do it. So, you would just come here and you would say dash, let's say danger color or whatever you would like to call and then paste the value then use it in your CSS variables, right? I mean right here, but I'll just use it as a hard-coded value because it's not really that important at the moment. Now, we can select the disabled state as well. I'll copy this. I'll say if list item is disabled. So, let's say li is disabled. We'll say the opacity is going to be 0. 7. And then the color is going to be text of gray. as you can tell. Then I'd like to get the card footer itself. I'll add some paddings such as 20 pixels to 30 pixels as well as the 30 pixels as well. Then we're going to get the button itself because currently it looks terrible. I'll get the button. Let's say display of block. Then I'll say width is going to be 100%. I'll get the padding itself. Let's say 14 pixels. And then font size could be just one. I'll get the font weight to be 600. Text align is going to be centered. I'll say color can be text light. And then I'll get the background color which is going to be RGBA value of okay, this is kind of annoying, but let's type this out. We'll get the white color and we'll just change the alpha value. And then I'll duplicate this. Do the same thing for the border itself. This will be 2 pixels solid. And then this exact same value. And I'll say border radius is going to be border radius value that we have which is 12 pixels. And then I'll say cursor is going to be pointer. Finally, the transition is going to be all 0. 3 seconds in ease. Okay. Now, let's get the hover state. I'll say btn. If we are in the hover state, we will update the border color to be primary color that we have. And then the background color. I'd like to copy and paste this value. And like why this did not update? This should be btn. Okay. Working as expected. Now this button is the accent, right? This is how we called it. I'll say btn dash accent. We'll select this and I'll say the background color is going to be variable of primary color that we have. And then the border color also going to be the primary color. And finally the color itself will be black. Okay. So this is output that we would like to have. Now on the hover state I'll update some stuff. Let me copy and paste. Super simple. We'll change the background color as well as the border color itself. Now the other thing we would like to do is take the popular cart and scale it a little bit. Right? It's larger than these two. So how can we make that work? I'll go ahead and just say get the popular cart. I'll say transform will be scale of 1. 0. 5. So it is just tiny bit but it definitely has the effect. I'll say border will be 2 pixels solid and the variable of primary color that we have. Okay. Right. Let me just put them side by side. Okay. Now, right after the border, I'll just say Zindex is going to be two. So that is always in front. Then I'd like to get the hover state. I'll say popular. If it is on the hover state, we can change the transform. I'll say translate Y is going to be minus 10 pixels. And scale could be still 0 1. 0. 5. 0. 5. Let's see this in action. Okay. So, if you don't add this, let's see what would happen in the hover state. It goes like, can you see like it's still going up, but it also scales down. So, you have to say the scale should be still the same. And then you will let me save. take it to translate y of um minus 10 pixels. I hope that makes sense. I'll just put them side by side. Okay. Right after this hover state, we'll say popular dashbatch. And as I said previously, we're going to position this absolutely to the top of 15 pixels and let's say right of 15 pixels as well. Now we would like to say the background color is going to be the primary color that we have. And then I'll say and it is this one by the way that we're building. The color is going to be black. We'll get the font size to be 0. 8 RM. Font weight let's say 600. Let's say padding is going to be 5 pixels to 12 pixels. And then border radius will be 20 pixels. Okay. And if you want this to be always in front just to make sure you can add the zindex such as three. So what we have done is to set the popular zindex to be two and then this is larger than this. Right? If you don't add them, let's see what would happen. Maybe nothing would change. But you just want to make sure that this batch is in front of the cart itself. Right? You don't want this to be like back of this card because it would be invisible. So what you would like to do is just add this double check where you would put the Z-index on the popular to be something like two and then this would be larger than this. Okay. So that's going to be for the cards. Now we can build the testimonial component itself. I'll go ahead just get the testimonial. I'll say margin top is going to be 60 pixels. Does that work? Let's say 600 pixels. Okay, it's working. Um, I'd like to get the display of flex and justify content to be centered. Now, I'll go ahead and get the code. I'd like to say maximum width is going to be 700 pixels. Background color could be the card BG that we have. Let's save. Like, is it updating? I don't really see background color. Let's say it'll be red. Okay, it seems like we have a typo. Let's visit the code. Okay, so it's actually correct. That's strange. Now, let's say the border color is going to be one pixel solid red. Okay, so it is not working because I have a typo. This should be code correctly. Now, let's save. we can see the output but this should be the variable of card background then right after this background color I'll have the border radius value under the border dash radius and I think I'm missing the semicolon and also I am missing this variable at the like in front right after the border radius we'll add the padding of 40 pixels from all directions and I'll say position is going to be relative and finally let's give some box shadow which will be the shadow medium okay this is what we have now let's go ahead get the code icon I'll say color is going to be the variable of d- primary color then we would like to get the font size to be 2mm I'll say opacity will be decremented we'll say 0. 3 this is looking a lot more cleaner I If you wanted to, you can increase it or even delete the opacity itself. This is what I'll have. And then I'll say the position is going to be absolute to the let's say top of 20 pixels and left of 20 pixels. Okay. Then I'll go ahead and get the code P tag. I'll say font size can be 1. 1 RM. I'll say margin bottom 20 pixels. line height and just make sure to put the semicolon. I'll say line height will be 1. 7 and let's say position will be relative. I'll say the padding left is going to be 15 pixels. Then we can get the author itself. So just say dot author this will be width of 50 pixels. Same for the height. Then we can get the border radius to be rounded which is going to be 50 pixels. I mean it's going to be 50%. But this did not work because this has to be the avatar itself. Right. I'll select the author and just change it to be display of flex and we'll say align items to be centered. Okay. Now this is what we have but still not working correctly. Let's go ahead and say overflow will be hidden. Now what is happening is this the image overflows the container. So that's why you cannot wrap it. So we say if there is an overflow just go ahead and hide it right just hide that overflow. Now we'll just say margin right is going to be 15 pixels to have this spacing. And I'll say border could be 2 pixels solid and the primary color that we have. Okay. Still we cannot see this but we'll just see this in a second I believe. Let's see. Okay. So we're going to get this kind of an output. Let's say right after the avatar I'll get the avatar image itself. Now let's say the width will be 100%. And we'll do the same thing for the height. And just to center this correctly, I'll say object fit will be cover. And I just realized this should be border. That's why it did not work. Okay, now it's working as expected. After the image, we can select the info H4 where we had the font size to be 1. 1 RM and then margin bottom of let's say 3 pixels and then I'll get the info p tag. I'll say padding will be zero. Let's see it's going to fix this spacing. I'll say margin will be zero as well. And let's say font size can be 0. 9 RM. And then finally the primary color will be used. Now this is the entire UI. I'd like to make this a little bit more responsive. So I'll go ahead select the media queries. I'll say maximum width 768 pixels. We would like to get the body and just change some padding some paddings right. I'll say petting will be equal to 30 pixels to 15 pixels. And then I'd like to get the header component. I'll say margin bottom will be 30 pixels. I'll get the header H1. This will be font size of 2 RM. And then I'd like to get the pricing cards. I'll change the grid template column to be one fraction. And then I'll say maximum width is going to be 400 pixels. Margin will be zero. Auto and 40 pixels as well. Then I'll go ahead and get the cart as well as the popular and I'll just say transform is going to be none. Okay. And then on the hover state I'll just change the transform al to be minus 5 pixels instead of 10 pixels. That would be a bit too much for mobile devices. And then I'll get the testimonial. I'll say margin top will be 40 pixels. And finally for the code we'll say 30 pixels. Okay. So this is the entire application that we have built. We are just missing one thing which is this animation that we have on the button. Right? We want this to be infinitely working. So I'll go ahead put them side by side and get started with it. So we would like to create a key frame right so that it is like it is going infinitely. I'll just say add key frames. I'll say the name could be anything. I'll go with the pulse because this is what we call this animation. And we'll have three different states. So from the 0% we'll add something. At 70% we'll do something. And finally we'll do something else which is the 100%. Now, if you want to use them, we'll just select the button accent and we'll say the animation is going to be pulse and then 2 seconds. Let's say infinite. Here we would like to change the box shadow. So, I'll say box shadow will be four different times zeros and then we'll say rgba of this color. So, instead of typing this out, let me please copy and paste and you can pause the video, type this out. I have already done this. Now, initially this will be the value. And then we are going to change this to 10 pixels. So it's the exact same value with a different opacity. And then finally at 100% we will add this value. Again we don't really have any pixels but also no opacity at all. Okay. Now this is how that work. for a split second we are able to see the box shadow and then it's going to disappear. Okay, so with that that's going to be it for the entire project. Now if you wanted to change the theme all you have to do just scroll to the top find your primary color right let's say I want to have kind of like a pink theme. I'll go ahead select this value and change it to this one. And let's have one more. I'll go with this light theme. Now, as you can tell, the entire application has changed. All you have to do maybe just update this background color, but you get the point. This is the video of using CSS variables. I'll do Ctrl + C to go to the previous state. Okay, so that's the entire project. I hope you enjoyed it. I'll see you in the next
Project 11: Team Members Showcase Section
one. Okay, so welcome back to the section. This is what we're going to build. This is what we call the team members showcase, which is something really popular and really common where the companies put their team members on a separate section. And this is exactly what we're going to be building with the avatar, the full name, title, as well as the biography. And we can even add some social links. And this will be completely responsive. So we're going to have three different columns in large screens. And then medium will have two columns at a time. and then just one column this section at the very bottom, this is what we call the CTA, which stands for call to action. So there is no JavaScript at all. It is HTML CSS only. And I think this is a great project to practice your CSS skills. And if you want to get the screenshot and build it by yourself, here I have it. And the link will be in the description for completely free. Now the first thing that I'd like to do get the icons and for this we'll be using font awesome. So I'll visit cdnjs. com. Let's search for font awesome. You can use any other alternatives but this is the one that I'll be using font awesome. Right. I'll go ahead get the link. Let's copy it and then paste it into our HTML file. Speaking of which, we'll create that and then let's say style CSS. First let's get started with the markup. So we'll get the boilerplate code. Let's say this is the team members showcase link our CSS file and then I'll put the link that we have just copied for font awesome. I'll just say hello save and let's say open with live server and then we're going to put them side by side. Here we go. Now I'd like to open up the end result. This is what we have here. You can see the title says end result. so that we can do some references here. I'll just create a header component and I'll get started with this H1 that says meet our team and then I'll create a P tag. This will be the description and I am too lazy to type this out. I'll copy and paste. If you wanted to, you can pause the video and type this out. Then we would like to have this team grid. Now we'll have six different team members. Let's say team member one and the content will go into the card div. Now this will have a card dash top. Let's duplicate it and it'll have card bottom. Let's first get started with the top section. Now what you have seen here this is the background and we will create this as a separate div. So I'll say profile-bg. It's not going to have any content like it'll be empty and we're going to position this and then give it a width and height and then we'll have the profile- image. This will get the image component or the image element and for the source we will be using the random users. I'd like to copy the URL paste this in. So you can type this out random user. mme api portraitsman32. jpeg. And if you paste this in, you will be able to see different results depending on the value. So I'll go with 12. This is what we have. So on and so forth. Okay, let's put them side by side. Once again, let's save. Let's put an alt such as team member on this image. And after this image and then after this div, I'll go ahead create the H3 which is going to hold the username. So I'll say Alex Morgan right after this H3 I'll put P the P tag I'll say class will be RO uh let's say it's founder and CEO okay right after this div I think my mouse died I was going to say now it is working so right after the card top will go under the card bottom and I'll put a P tag let's say this will get the class name of bio And I am too lazy to type this out as well. I'll paste this in. You can change this and put it anything that you wish. And then um after the P tag, I will create a div with social links class. Now we'll have three different links. This is not going to take us to any website. I'll just leave it as a hashtag, right? A hash. And I'll say class name. Let's say this will be social- icon. Now let's put the actual icon. Let's say class name of FAB FA LinkedIn- okay let's save now uh let's duplicate this twice one and two this will be Twitter right and then the very last one will be GitHub let's save and take a look at the end result this is what we have now we don't really want to type this out six different times right it's the exact same thing all you have to do copy it, paste it and then change the value. Now there is no need to waste any time. So I have prepared an entire GitHub just let me get this. Here we go. Um okay so you should be able to find this link in the description. Go ahead find the team members showcase. So, copy the entire markup and we have some CSS code that we're going to get into in a bit. But basically, this is the entire team grid that we have. Okay, so this has no logic at all. Just pure markup. That's why I'd like to copy and paste. I'll delete this entire team grid and paste this in. Let's save and take a look at the output. Okay, so this is the exact same data that we have right here. And now we would like to put the CTA section. So I'd like to scroll to the top. I'll shrink the team grid component. So we have this div. Let's shrink this. And we'll create this team dash CTA which is going to take an H2 that says want to join our team question mark and then P tag. Let's say we are always and copy and paste. We are all always copying and pasting. Here we go. And then we'll just put a button or a link that will take us to nowhere. But the class name should be CTA button. And CTA stands for call to action. I'll say view open positions. Okay. So this is the entire markup. Next we are going to build the CSS. So I'll go into this file, shrink the left hand side and get into this file. Okay. Okay, so the first thing we would like to do is to get our basic resets. Now, I know that this is kind of repetitive and it might sound a little bit annoying, but we have to do it if you want to get rid of all the default paddings, margins, and add this box sizing of border box. We have explained this in the previous sections, so I'll not go over it once again in this project. Let's save. This is what we got. And I'd like to update the phone family to be, let's say, Sans serif. As always, if you wanted to, you can change this and make something completely different if you wish. Now, I would like to get some CSS variables. I'll get my root element. And instead of typing them out, I don't really want to waste any time. So, that's why I have prepared this entire list. So, just go ahead find the team members showcase. Um, this is the HTML that we have copied. But I have a complete CSS code around 10 lines of code. Let's paste this in. So we have bunch of different colors for primary for the text and we have some values for border radius. We have some box shadow values and then couple of different values as well. So we'll be using all of them in the incoming minutes. So we'll kill all these websites. Okay. Now let's get started with the body element. I'll say body let's say background color will be equal to variable of bg dark. I'd like to get the color that will be text light. And I'll say min height is going to be 100 ph. And then I'd like to get the display flex. Let's say justify content centered. Align items to be centered. Let's give some paddings. I'll say 50 pixels to 15 pixels. Finally, line height of 1. 6. Okay. Now, we would like to get the header element. I'll say text align will be centered. Then I'd like to say margin bottom of 60 pixels. Okay. So, we'll go ahead get the header H1. Let's say font size is going to be 2. 7 RM, which is this one H1. Now I can see that everything is side by side. I think we forgot to wrap everything with the container component. So I will visit index. html. Okay. Right after the body, I'll create the container dev. Let's copy this and just put it right before the body closing tag. Now I'd like to go into the style. CSS and I'll select the container itself. Let's say the width is going to be 100%. And the maximum width could be something like 1,200 pixels. Now, if we go into the larger screens, this is the maximum width it'll take. So, if you wanted to, you can inspect it. Let's find the container. Right? So, here we can see, just notice here at the top, just take a look at it. We have the 1200 pixels of width. So this is the maximum val maximum value that it can take. Okay. So with this in mind, let's put them side by side once again and just move forward. And I'd like to add one more thing. I'll just say margin of zero from top and bottom but auto from left and right so that it is centered. Then I'll get the H1 that we already have. It is this element. Let's say margin bottom will be 15 pixels. Okay, I'll say background. Now, it should be background, not background color because we will give this linear gradient. I am not really sure if it is visible from the video, but this color and this one is completely different. So, we'll go to the right from this one to this color. Okay, let's see. I'll say background will be linear gradient. You can either say 90° or you can say to right and I'll say go with this color like from the primary color to this one and say variable of primary light. Okay. Now if you save you're going to see that the background has been updated. So we can fix this. I'll say background clip is going to be text. That's the first thing. Now we'll just say color should be transparent. Okay, now this has been fixed. Now we would like to add the support for the Safari as well. I'll say webkit and I'll just get this exact same value. Paste this in. Let's say it'll be text and I'll just add a comment. Let's say for safari as well, right? Okay, after the color I'll say display should be inline block and then I'll say position will be relative. Okay, now I'll go ahead get the after element so that I can put this underline in the middle of the H1. So I'll say header H1 and let's get the after element. content will be nothing which is an empty string and we'll say position is going to be absolute to the let's first say width of we can go with any value I'll go with 60 pixels let's say height will be 4 pixels and then I'll say background can be variable of primary gradient now it is at the top right I'll just say bottom will be minus 10 pixels and then we'll I'd like to center this. So I'll say left 50%. Okay. Now this is still not centered. It is starting from the 50%. I'd like to take this 50% to the left. So I'll say transform translate X is going to be minus 50%. Here we go. Now it is centered. Let's add some border radiuses. I'll go with 2 pixels. Okay. So that's going to be for the after element. Now we can get the header P tag. I'll say color is going to be text gray. We'll be using the CSS variable. I'll say font size will be 1 1. 1 RM. Then we'll get the maximum width to be 600 pixels. Let's say margin will be zero to auto. So if we do not add this, what would happen? I think it would not be centered correctly. But let's bring this back. Save. Okay, now it is centered. and then I'll say margin top of something like 20 pixels. Okay, so that's going to be for the header P tag. Now I'd like to select the team grid. Team dash grid. I'll say display will be as you can tell it'll be grid. We'll say grid template columns. I'll use repeat of auto fill and minmax 280 pixels to 1 FR and then I'll say gap of let's say 30 pixels margin bottom of 60 pixel 60 pixels. Now let's see if this is responsive already. Let's select the correct one. Okay, so it's already responsive as you can tell thanks to this minmax method. Okay, now we'll get the team dashcard. Let's say the background color will be card bg and then we'll get the border radius which will be the border radius value that we have. So it is 12 pixels but if you wanted to let's say you want to make this to be 20 pixels. So we can go right here and update it. Okay, but this is the value that I'll be using which is 12 pixels. Now I'll say overflow will be hidden. Then now why is this the case? So if you delete this now here you can see image is overflowing the card. So we say if there is any overflows right if there are any overflows just get rid of that and hide it. Now we cannot really see that overflow. I hope that makes sense. Now we can add some transition. I'll add it on everything. 0. 3 seconds and ease then I'll say box shadow will be variable of shadow MD which is going to be this value let's say shadow MD okay so is this one and we're using a CSS variable so that our code is consistent right if we wanted to use shadow MD we can copy it paste it here if we wanted to use it in this component okay right after this one I'll say height will be 100% and let's say display will be relative sorry position should be relative right on display we don't really have relative okay I'll say position is going to be relative and then I'll say display will be flex and flex direction is going to be column now I would like to add a hover state on the card so that it can be translated to the top and there are a little bit of box shadow. I don't really know if it is visible from the video, but there is definitely a box shadow going on. So, let's shrink this and go into the team cart hover state. Transform could be translate Y of - 8 pixels. And then I'll say box shadow is going to be shadow large. Okay. And then I'll get the team cart on hover state. We would like to get the profile background. I'll say profile-bg. And we are going to scale this up. I'll say transform scale 1. 1 because if you take a look at the end result, if you hover over this background also scales. So this is something that we would like to do. Okay. Let's save and move forward. And by the way, let's open up our own version. Currently, it's been like translated, but we cannot see the background. So, we're going to get into it. First, I'd like to say select the card top element. Position is going to be relative. Let's say petting top is going to be 70 pixels. Petting bottom could be 30 pixels. Pix align could be centered. Okay. So, this is what we have. And I'd like to add the zindex of one. Then I'll say profile-bg. Position is going to be absolute. Let's say top of zero. Left of zero. And then I'll say right of zero as well. And then I'll get the height. Let's say 120 pixels. We can add the background color as well. So I'll use the primary gradient. Let's save. we cannot see anything. Um, why this is the case? It is profile dashbg. Is it because maybe we don't have the z index yet? Let's test this out. I'll say minus one or maybe 10. Okay. So, for some reason we cannot see this. Um, profile-bg. Let's see. Do we have this element on team grid? we have profile-bg so I think we are using a gradient and we are saying background color that's why is it doesn't work let's say just background here we go it is working as expected now if we wanted to take this back of the image right I'll say z index of minus one okay so if you do not add this it will um how do we call it like it would overflow the image itself but it will just take it to the one level behind. Okay, so we got the Z-index and let's give the transition to be on the transform because we are scaling this up, right? I'll say transform 0. 4 seconds and ease. Now, if you hover over this, as you can tell, the background is scaling up a little bit. Okay, then I'll get the profile image. Let's say width is going to be 100 pixels, height will be 100 pixels and we'll say border radius to be 50%. So that it can be rounded. Um currently it doesn't maybe because we have the overflow of hidden. I was going to say maybe we are missing overflow of hidden. Now with this added it is working as expected. Then we can add some margins. I'll say margin from the top, right, and left and from the bottom. Okay, now it's been centered. And then we can say border is going to be four pixels solid and it'll take this card the background. Okay, then we can say something like position will be relative on the image container itself. Now we're going to select the image. I'll say profile image because I don't really know if you remember but this is the container that we have. This is the actual image. Okay. I'll say width is going to be 100%. Same for the height and I'll say object fit of cover. Okay. So this is nicely centered and we can add some transition on the transform. Let's say 0. 3 seconds and ease. Okay, I'll go ahead get the team cart on hover state profile dash image and I'll select the image. We would like to just say transform will be scaled up 1. 1. Okay. So this is how the effect happens. Basically when we hover over the card the profile image is being scaled up and we have this beautiful effect. Then we would like to select the H3 on the card top. So I'll say card dash top. Let's select the H3. I'll say font size will be 1. 4 RM. Margin bottom of 5 pixels. And then font weight could be 600 just like this. And then I'll get the roll update the color to be a variable of primary color. Here we go. And I'll get the font size to be 0 uh 0. 95 RM. And then font weight could be 500. I'll get the card. The bottom class. Let's see. padding is going to be 20 pixels from the top, 25 pixels right and left and 25 pixels from the bottom. Okay. Then we would like to add the flex row of one. And then I'll get the display of flex direction of column. Let's save. And I'll say justify content to be spaced between. And then finally I'll say border top is going to be 1 pixels solid variable of border light. Okay. Now I'll go ahead and get the bio. We'll say color will be text gray. The font size let's update it to be 0. 95 RM. We can say the margin bottom will be 25 pixels. Flex grow is going to be one. And finally the line height could be 1. 6. Okay. And then I'd like to scroll a bit. I will select the social length. I'll say display of flex so that we can give some gap of 15 pixels. And I'll just say justify content will be centered. Okay. And then I'll select the social icon itself. Let's say display of flex justify content centered. align item centered I'll say width will be 36 pixels. Same for the height and then we can get the border radius to be 50%. Okay. Then I'll say um text decoration is going to be none so that we can get rid of this underline. Okay. I'll update the let's say background color that will be equal to background overlay. Okay. So this is the background that we are building. That's why we said give some height and width and height. Otherwise, this is how it would look like. And if you do not add the border radius, it's going to be a square. Okay. After the background color, we can add the color to be text light just like this one. And finally, I'll just add some transitions to be on everything 0. 3 seconds. And let's use ease. And then I'd like to update the hover state. So I'll say social icon on hover. We would like to get the background color to be updated to the primary color that we have. Then I'll say the color is going to be text gray. And finally we can give the transform of translate Y. That's going to be 3 minus 3 pixels. Let's save and give it a go. When we hover over this, this is what we got. Now I think color is not really visible. So we can update it on the hover state. But say this will be dark. Okay. Now this is a lot more readable and accessible. Okay. Now let's move on with the CTA section because at the moment we have built all of our cards working properly. Okay. Now we're going to build this section. So I will select the team-cta class and I'll say text align would be centered and let's scroll to the bottom so that we can see it in action. I'll say margin top is going to be 30 pixels. Let's say padding will be 40 pixels as well just like this. And then I would like to update the background color to be variable of background overlay. Then I'll get the border radius value that I already have just like this one. And finally, let's say not finally but couple of different things. So we would like to say position will be relative, overflow is going to be hidden and then box shadow will be shadow MD. Okay, now we are good to go. Then I'd like to add this kind of like UI where we have the how do we call it like kind of like border top but I'll be doing this with the after element or like we have used after element a lot. Let's go ahead use the before element. Let's say teama let's get the before sudo element. We can add the content of nothing. If you add something let's see what'll happen. It'll just add it'll be added before to this component itself. Now we don't really want to have any content. This will have the position of absolute top of zero left of zero. We can add the background not background color but background because we'll say variable of primary gradient and then we can get the width of 100 pixels sorry 100% height of let's say height will be 5 pixels. Okay, this is what we got. It's working as expected. I would like to get team CTA H2 update the font size to be 1. 8 8 RM and then I would like to get the margin bottom of 15 pixels. Let's say color is going to be variable of primary light. Okay. Then I'll get the team CTA P tag where I'd like to say color is going to be text gray. Here we go. I would like to get the maximum width. Let's say maximum width will be 500 pixels. And let's try to center this. Let's say margin zero auto and 25 pixels. Then I'd like to go into the CTA button. Let's say display is going to be inline block. I'd like to get the padding that will be 12 pixels to 35 pixels. Pixels it should be. Okay. and we'll say the background will be updated again. Background not background color because we'll use the primary gradient. Now I'd like to get rid of this text decoration of underline. I'll just say none. Let's update the color itself. This will be variable of text dark. Right after the color, I'll say font weight is going to be 600. So that is bold. And I'll say font size could be 1 RM. Then I'll go ahead add the border radius of 30 pixels. And then let's say transition will be on everything 0. 3 seconds. And let's use ease in and out this time because why not? I'll add the box shadow to be 0ero to 5 pixels 15 pixels and then variable of shadow color primary. Then I would like to add the hover state on this CTA button. Let's go ahead select it. I'll say on the hover state as always I'll say transform of translate Y of minus 3 pixels and then box shadow will be updated. Let's say 0 to 8 pixels. 20 pixels variable will be shadow color primary hover. Okay. So this is how that look. I think pretty clean and sick. And with this we are pretty much done with the entire project. But I'd like to add some media queries just to make this completely responsive. I'll say maximum width of 768 pixels. We would like to add some additional styling. I'll say header is going to be margin bottom of 40 pixels. I would like to select the header H1 and update the font size to be 2. 2mm and then I'll get the team grid gap will be updated. let's say 20 pixels and I'll say team CTA padding is going to be 30 pixels to 20 pixels and let's say team CTA age 2 that's going to be equal to font size of 1. 5 RM and then we'll be even more responsive I'll say media get the max width 480 pixels so below to it and like this value and below this value we would like to say body we'll have the padding of 30 pixels to 15 pixels we can get the header H1 I'll copy this value and even document it more that's going to be equal to 1. 9 RM and let's get the profile image let's say width is going to be 90 pixels same for the height And I'll say cart top of age three. Font size will be 1. 3 RM. And finally the team CTA get the padding of 2. 5 pixels to 15 pixels. Okay. So these are definitely optional. You don't have to add it, but I'll just leave it here in case you want to have this working completely responsive. Okay. So this is how that work. This is the entire project that we have built. Now let's say you want to change the color theme. All you have to do just scroll to the top and change these values to anything that you wish. Right? If you want to go with a green color, you could update all these values with some green colors. But I'll use this beautiful purple theme that we already have. Okay. So that's the entire project. I hope you enjoyed it. Okay, so welcome back. In this section, we're going to build a recipe
Project 12: Recipe Finder (MealDB API Integration)
finder application. I'd like to give you a quick demo before we get started with it. So, I'll say let's search for chicken. We got different results. Here we can see. Let's click to one of them. You'll even get more details such as the instructions, the ingredients, and even a YouTube video link. For a split second, I'll open this up. I think we'll get some ads. Okay. So, but this is the actual video that is working as expected. Then you can click to the other recipes and UI will be updated. And then we can scroll to the top, search for anything that we wish. So, I'll just say egg. Okay. Now, all these recipes are coming from a service. It has both a free plan and premium plan. We'll be using the free plan, right? This is what we call an API. If you don't know what that means, I'll explain it pretty quickly on a diagram. But basically, you can use the free plan if you are building this during development or if it is for educational use. This is exactly what we'll have in this video. So, we don't really need to pay anything. Okay. So, they have a bunch of different endpoints. If you don't know what that means, once again, I'll explain. But basically when you put chicken and click to this button we got some results right but what is actually happening behind the scenes let's see so they have search meal by name I'll copy this URL copy this endpoint now when you say chicken right you are sending a request to this endpoint but the search query is equal to chicken okay so this is the output this is the results that you get and then we are displaying it on UI. So here we have chicken hendy chicken kangi right I don't know how you pronounce it but this is the exact same data. So chicken kangi chicken I don't know how do you read it but as you can tell it is the exact same data. So we are sending a request to this endpoint and we are getting a response. So we are displaying it right here and we'll see how to do it in code. And then we have another request to a different endpoint where we do a lookup, right? I'll click this. We got the details. So this is another request. Let's see. They have this lookup. Um like there is the lookup endpoint. So what you do, you pass the ID of that meal. Let's do it pretty quickly. So here I'll go ahead add the ID of chicken. I don't know, car. uh paste this in. Okay, so this is the exact same meal, but we got even more details about uh let's say like the uh ingredients like we got the instructions so on and so forth and even a YouTube video. Okay, so I hope all that makes sense. We'll be using them. Now, if you don't know what is an API, let's see it pretty quickly. Um and then we'll just jump into code. So what is an API in the first place? It stands for application programming interface which sounds absolutely complicated but in simple terms an API lets two programs to talk to each other right and here is exactly what we have. We have our own program where we would like to talk with another program with another service. So it allows you to get or send data between your app and another service. And this is exactly what we have from our service. We would like to like uh we would like to send a request and get some data from a different service. And this will be possible thanks to an API. Okay. And this API is built by the ML DB. So you don't really build it. All we have to do just use it. Okay. So I hope all that makes sense. Now we can talk about API support for hours. But if we have to keep it simple, this is what it is in its core. Okay. But now this will take a bit time to get into the API, right? It'll take us some time because first we have to build the HTML and then CSS and then finally get into JavaScript where we can send requests to this API. Okay, so I have an empty folder. The first thing I'd like to do just get the cdnjs. com and grab the font awesome link because we will use some icons in our application like this one um for the ingredients so on and so forth. Okay, I'll just even put them side by side. Let's get started with the HTML. I'll zoom in. Get the boiler plate. Then I'll say recipe finder app. And then let's link our CSS file. Get the recipe finder URL. Sorry, this is the font awesome URL, not recipe finder. And then we can create a container right here within the body. And then I'll get my header component, which is going to be this part. And as you can tell our application is completely responsive. So we'll even make this app to be completely responsive. Right? So this is the part that we are building which is the header component itself. So I'll have each one and I'll say get an icon where we would like to say fasa utin sales. So this will give you this icon and then right next to it I'll give one space and I'll say recipe finder. Now let's try to run this um with a live server. I think I'll get a warning but it is working as expected. Okay. Right after this H1 I'll have a P tag. Let's say find delicious recipes from around the world. And then right after the header component, I'll get this p tag with the link. Let's say API-link. I'd like to add this data from the mail API. We'll say data from and this will be a link so that we can take them to this URL. I'll copy it, paste it. This is what we have. For the text, I'll say the meal DB. And I'd like to add an emoji. So, let's say cook. Here we go. Okay. So, this is the output that we have at the moment. And right after this P tag, we'll go ahead and just say search dash container where we'll have the input that will be type of text. Let's say the ID will be search dash input. And then I'll say placeholder is going to be search for meals or keywords. Okay. So after this input I'll put a button where we can add the id that will be search-b and then let's say search will be the text. Right after this search container we will put the error container itself. Now this will be hidden by default. Let's say class. Sorry, this should be ID by the way, not class. This is going to be ID. And then the class will be um hidden by default. Now, we are going to get errors if we search for something that does not exist. Right? So, we got an error. And by the way, let's say back to recipes. So, I'll just refresh and search for something that does not exist. This is the output that we're going to get. And this container will be hidden by default. Once we have an error only, then we will display it. So this is what we have for the content. We can say P tag of this no meals found try another search term. Now we can actually like leave this content completely empty but this is what I'll have by default and then we can change this within our JavaScript code. Now finally we can add another thing which will be the result heading. So let's search for something like egg which is existed. So we're going to get this title right. I'll say um have a dev with the ID of result heading and the content will be empty at the moment. Then we'll have the meals ID which is going to be the meals container. Okay. And then finally the details, right? If you click to one of them, it'll open this up where we have the details. So I'll say it'll be meal dash details. Let's give the class name. By default, it'll be hidden. But if we click to one of them, it will it'll be visible, right? And then I'll get a button. Let's say id will be back dashbtn which is this button and then we can give it a let's say we'll give the icon which will be class name of fas f a arrow- leftft and for the content I'll say back to recipes okay right after the button we'll have the div with the class name of meal details content. Okay, this will be empty as well. So that's going to be for the entire markup. This is how that look at the moment. Um, we'll just make it look a lot more cleaner. Just before we get into the CSS part, I'd like to get the script file length. Let's say script. js. Okay, so now that we have this seted up, we can go into the style. cs. CSS and get started with it. So the very first thing that I'd like to add is my basic reset. I'll go ahead paste this in and then I'd like to get my color palette. I'll put them under the root that will be my CSS variables. Now instead of typing them out, I have prepared an entire GitHub just that you can find the link in the description. Just go ahead and scroll and find the recipefinder. md file and copy this color palette and paste this in right here. Okay, so we have a primary color, dark, light, and couple of different values as well. Then I'll get the body element. I'd like to say um font family will be updated to sense serif. You can use something else. Then we can get the background color that will be background light. And then color is going to be text dark. And then I'll say color is sorry the line height is going to be 1. 6. Okay. So that's going to be for the very first selector. And then we can get the container itself. Let's say the width is going to be 100%. And then the maximum width. Okay, let's try to put them correctly. Max width could be something like 1,000 pixels. And then I'll say margin will be 0 to auto. And the padding is going to be 2mm to 1m. Okay. Then we'll go ahead get the header itself. that will be text align of centered and I'll say margin bottom of 2 RM then we can get the H1 that will be font size of 2. 2 2M and then the color is going to be primary color that we have and then I'll say margin bottom will be 0. 5 RM here we go and I'll get the icon itself I'll say margin right could be something like 10 pixels okay then I'll get the header P tag let's say header get the P tag that will have the opacity of let's say 0. 7 if you want you can delete that but this is what I'll have and then I will also update the color to be text dark okay then I'll get the search container let's say display will be flex then I'll say margin bottom will be 2mm here we go and I'll say gap will be 10 pixels max width is going to be 500 pixels and we can say margin is going to be from the left of zero and from the right zero as well. And let's actually say auto instead of zero. It'll be centered correctly in a second. So I'll save and let's move on. We'll get the input that is type of text specifically. So I'll say where the type is equal to a text. We would like to select that input and I'll say flex is going to be equal to one. Okay. Now it is taking the entire space. And then I'll say padding is going to be 10 pixels to 16 pixels. Let's say 16 pixels. And I'll say font size will be 1m. Then we can say border radius is going to be the border radius value that we have. Then right after this I'll add a border that is 1 pixel solid and this color that is ddd. And I'll say background color will be the background that we have. And then color will be text dark. And I can say outline will be none. Okay. So this is the output and I'm really happy with it. Now I'd like to select the focus state on this input. I'll say if it is focused go ahead update the border color to be primary color. Okay. And then we can select the button and try to update it. I'll say the background color will be updated to the primary color that we have. And then we can add the color to be white. Let's say border will be none. Okay, this is what we have. And then I'll add some border radiuses. let's say variable of border radius value that we have and I think it is either 10 pixels um or is it even 8 pixels okay after the border radius I'll say padding is going to be equal to 0 to 20 pixels then we can add some font size of 1mm let's say font weight is going to be 600 so it's a little bit more bold and then I'll Say cursor is going to be pointer. And then finally some transition. I'll say it'll be equal to the v variable that we have. Let's say transition. Okay. Now we'll add the hover state where we would like to change the background color which is going to be equal to primary dark. Okay. So this is how that work. Now we would like to get the result heading. And let me grab this value. Paste this in and we'll go through it. So we have the result heading, the text is centered, we have the margin, bottom, font size, and then the color. Then right after the result heading, I'll select the meals dash container. And I'll say display will be grid. Let's say display grid. Grid template columns will be repeat of let's say auto dash fill. And we'll say minmax of 250 pixels to one fraction. And then let's give it a gap like 1. 5 RM. And then we can get started with the meal itself. I'll say the background color will be equal to cart bg. And then the border radius value. Let's say box shadow is going to be equal to shadow variable that we have. And then overflow will be hidden. Then we can get the transition cursor is going to be equal to pointer and then the position will be equal to relative. Now on the hover state, I'd like to transform this. Now let's see the end result. When you hover over these items, they are just translating to the top by minus 5 pixels. And we have some box shadow going on as well. Right here we can set it on hover state. So this is exactly what we have just added. Then we can select the meal image. We'll say width is going to be 100%. The height is going to be 180 pixels and then the object fit will be equal to cover. Okay. So we can save this and then I'll say dash sorry dot meal dash info that will be getting petting of 1mm and then we'll get the meal title. Let's say font size is going to be equal to 1. 1m. We'll get the margin bottom of 0. 5mm and then color is going to be text dark. So this is the mail title that we have just built, right? It is this uh component that we have in our code. And then after the mail title, we can get the mail category which will be this one that you have seen. So I'll go ahead paste this in instead of typing this out. It is super simple. We just have the display of inline block. We have a background color which is this primary light and then we have the color, some paddings, font size, border radius. so that it is rounded and then some margin bottom. Okay. And then we can get the meal details which is going to be this component. Right? This is what we call the meal details container itself. Right? I'd like to select that one where we had the ID of meal details. So we'll give this background some border radiuses so that it is rounded. some box shadow padding and margin from top and bottom with two RM and then we can update the back button. So I'll go ahead paste this in and walk you through it. We'll give some margin bottom. We'll add the background color so that it is transparent. We'll add the color itself, some borders and then some paddings. Then on hover state we are going to update the color as well as the background color. So this is exactly what we have. And then we can get the details content. Now we would like to center everything right but we want them to be in the colum direction. So as you can tell we have one at a time that is going on in the column direction. So I'd like to put this code. I'll say meal details content flex direction will be column and it'll be centered. Then we can get the image itself. So this will be maximum width of 400 pixels. Okay, I'll just paste this in. Some border radiuses and some margin bottom. Now let's get the title which is this one. That will take the color of primary, some font size, margin bottom and text align. So I am just copying and pasting these styles because they are super simple and we don't really want to waste that much of time, right? So I'd like to get the category as well. We'll say margin bottom and text would be centered. Now we can get the span itself. This is what we'll have. And if you remember, we had the span or do we have it? Let's see the category. Okay. So I think we don't really have this span at the moment. But once we take this data from the API and once we display it within this div we will just have the content within a span right so for the category specifically so it'll make sense once we get into the JavaScript part okay so these are just some basic styling and let's get the class for the instructions as well we'll get the H3 where we update the margin bottom only and then we'll say the ingredients list which is going to be this list that we have and then we can get the list items as well as their icons. So you can pause the video, type them out. Really there is nothing complex other than background colors, border radiuses, margin bottoms, paddings, so on and so forth. I don't really want to waste that much of time where I'd like to give you these classes. And if you even want to, you can copy the entire style. css CSS file from the source code and just jump into the JavaScript section and then we would like to get the YouTube link which will have this background color of red and then we will update the icon where we would like to give some margin right of 8 pixels. Okay. And then we can get the error container itself updated as well. Right? Because let's take a look at it. If you put something that does not exist, this error container will be shown. And we would like to have these classes. And then I the API link as well, which is this container, right? We would like to style this. So I'll paste this in. Let's save. Let's get the link within the API link, the a tag. Okay. So it's been updated. Now we would like to add the hidden class which is going to be display of none. And some elements have the hidden class such as this one. If you get rid of that, it'll be visible. But by default, we don't really want this to be visible, right? Okay. So now everything is done. All we have to do just add some responsive styling, some responsive design thanks to the media queries. So we have the search container has been updated, the search button and some of these classes. Okay, let's save. This is the entire uh the entire CSS file that we had to build. Now we'll get into the JavaScript file and actually interact with this API. So the first thing we would like to do is to get our DOM elements. So let's say search input and we can say document dot getelement by id and then we'll pass the id which is going to be equal to search dash input. Now instead of typing out every single element I have prepared an entire list that you can find it from the github gest. So just go ahead copy these elements under the recipefinder. m and then paste this in. Okay. Now the other thing that we would like to do is to create some uh variables. So I'll say con base URL and I'll explain what that means and why do we need this in the first place. So whenever we send a request let's see the documentation. as you can tell this part is exactly the same right? If you want to source something, list all the meals, if you want to, you know, get a random meal, so on and so forth, every single time you need to type this part, which is our base URL. So, let's create it under a variable. Um, I think I'll go ahead copy this, paste this in. And just notice how we have a slash at the very end. And then we will need two different URLs which is going to be let's say search URL and then we're going to need another one that will be lookup URL. So we are going to use this search URL whenever we need to search for something. Let's say chicken. So we are just sending a search request and then if you want to get the details we are sending a lookup request. So they both have different endpoints. That's why we need to create two different URLs here. This will get the base URL. Let's say um this will take the search php question mark s equal to and that's it. Right? So I am not memorizing these. Right? I don't know them like top of my head. Everything is coming from the documentation. This is for the search mail by name endpoint. Right. So here they have Arabia. What does that mean? I don't know. But looks like it is this food. Okay, it is this one. And if you search for something like chicken, this part would be updated. So this is exactly what we are trying to do. And then for the lookup, this is what they have. Lookup. php question mark i and equal to. So let's go ahead just copy this. Paste this in. But this should be lookup. php i and equal to. Okay. We'll be using them just in a second. And then we can add some event listeners. We'll say search button dot add event listener which will be click event and we're going to call it the search meals function and then we can add another more another event listener instead of clicking when we press enter it should also search right so I'll say uh meals sorry search input dot add event listener let's say key press in this case we would like to get the event and we'll just check if this event do key is equal to enter right I'll say if it just go ahead search for the meal I'll say search meals and we don't have this function so let's create it I'll say function search meals but now since we'll be using the fetch request API This needs to be let's say async function so that we can use a weight. Okay. So I'll say const let's first grab the search term. So whatever user types in I'll say search term we'll say search input do value and we would like to trim this down. Let's say value dot trim. Now what happens if they don't put anything? I'll just search. They say please enter a search term. Let's try to handle this case. I'll say if um search term is equal to an empty string or you can say if it is not valid right if it is a falsy value. In this case we'll say error container. ext content will be equal to please let's type it correctly. Please enter a search term and then we can say error container. class list dot remove the hidden class so that it can be visible and then we don't want to do anything else from this function. We'll just say return out of it. Let's save and take a look at this actual application that we are building. I'll say don't put anything and search for it. Here we go. This is what we got. And I'll do the same thing with enter key. I just press enter. This is the UI that we got. Okay. So this is the edge case that we just handled. Let's say handled the edge case. And then now we would like to actually fetch the data. So I'll say try and catch block. We'll try to do something successfully. And if it fails, it'll hit the catch block where we can handle the error itself. So in the try we would like to first show some kind of a loading message. So notice how if I send a request to chicken we are going to see something like loading for a split second. Okay. So it says searching for chicken. Let's do it in the try. I'll say result heading. ext text content can be equal to this dynamic value that will be searching for let's put the actual search term and then we can even add three dots at the end and then we can say meals container inner HTML is going to be equal to nothing and then we'll say the error containerclass list dot add hidden. Now, since we are just starting to search, we're going to get rid of the error container, right? We're going to just hide it. But if we have some errors, then we can display it under the catch block. Okay, now it is time to actually fetch the meals, right? I'll say fetch meals from API. And to be able to fetch something, we can use the fetch API. We'll say await fetch and we'll put our search URL, right? I'll just say search URL because we are trying to search for a meal. And then we'll put the search term. I'll say search term. And now if you just scroll to the top a little bit, if you're wondering what the hell does this even mean, right? What is this equal to? Now the base URL is this one and search URL is base URL plus this value right. So if you delete this part and put the base URL so this is what the search URL is. I'll copy this and just do Ctrl C. Okay. So this is the search URL itself that we have and then at the very bottom we have the search term. If user put something like chicken this will be equal to chicken. I hope that makes sense. So this is the URL that we just put to get the correct value, the correct details and this will give you a response, right? Let's say response and then we can get the data out of it. I'll say con data again await response. json. Then we can let's just say console log the data itself. Let's say data is here. And also we can do something like if okay I'll just leave it so that it's not really confusing. I'll do it in a second. For now let's go ahead open the terminal the console and send a request to chicken. Okay. So it says this could not be found. Do I have a typo? Let's see why this is the case. Um for some reason this is what they put in front. So I just pause the video and debug this a bit. Just make sure to add https and double like double forward slashes. Now this should be working out. Let's go ahead search for chicken. Okay. So we have this loading state and then we got the data itself and it is under an object called meals. So we'll say data do meals and then we can get the actual results. So if we search for something that does not exist, the meals will be null. And let's handle this with the if check. So this is what I was going to add. I'll say if data do meals is equal to null or we can say if it is not existed by doing this. This is the same thing. I'll just be a bit more explicit and I'll say if it is equal to null. In this case, I'd like to do something right. I'll say the result heading text content for now is going to be nothing. And then we'll say the meals container inner HTML is going to be equal to nothing as well. We're just res resetting it. And then we can say error container. ext content can be something like no recipes found for this search term. And I'll wrap this with quotes. Let's say search term itself. And then let's say try another search term. And then we would like to see this on the UI. That's why we're going to say error container. class list remove the hidden class so that it is visible on the UI. Right? But in the else case that means we found something right. So this is the case where we like where we found no meals. I'll say no meals found but here we found something we would like to update the UI. Okay. So I'll just say result heading is going to be equal to the text content will be equal to search results. So I just said search results for the search term. And notice how this should be back tick so that we can put the actual dynamic value and then we can display the meals. So I'll just say to display the meals for a second. But for now let's save and give it a go. Just test this out. I'll put something that does not exist. We are going to hit the if check where the meals is not found and we're going to get this UI. Right. No recipes found for this search term. Try another one. Let's try something else such as chicken. We got the loading state. And then it says search results for chicken, but we don't have the function. So, we need to go ahead and build it right here. So, I'll say call the display meals method with the data meals. So, we'll basically take this meals object, right? We have the meals. We're going to send this array so that we can display all of them one by one and every single one of them. Let me demonstrate this. Now I'll just refresh for a second. I'll say chicken. So we got data meals which is an array of 25 items. So every single one of these objects has the ID meal, right? The ID of the meal, the name, uh let's see, we got the instructions, so on and so forth. and we would like to grab this data nicely display on the UI. Okay, so let's see how we can make that work. And once we search for it, once we display the results, maybe we can get rid of the search input, right? I'll just say once you display them, you can say search input value is going to be equal to nothing. And then in the catch case, let's handle that one as well. where we can say error container. ext content is going to be equal to something like something went wrong, right? Like anything can go wrong. So, we're going to hit the catch block and we would like to put a general message and then we would like to see this on UI. So, we're going to get rid of the hidden class. Okay, I hope all that makes sense. Now, we can get started with this function where we will display the meals. Okay. So I'll just scroll to the bottom. I'll say function. This is our function that we have of the function name. And then we'll get the meals as the argument. Now I'll say meals container inner HTML will be reseted initially and then we'll go ahead map through every single meal and display something for them. So I'll say meals do for each. We can use this method because it is an array. We're going to get every single meal and return something. So here I'll say meals container inner html is going to be updated. So we'll say just concatenate it with this value. So every single time we will update this container, right? And what do we want to add? So we'll say we'd like to have a div. Now you need to be really careful and type this out correctly. So we'll open this up and then turn this off. Now if you don't want to type this out once again I have prepared the GitHub gist. I'll copy this entire thing. Paste it and I'll walk you through it. So we are basically looping through meals and creating a card for every single one of them. So we got the meal and we will put this div for every single one of them which is this output that you have seen. So it has the class name of meal and we added this data meal ID. We'll be using it in a second and it'll get the ID meal field. Then we have the image. This is coming from the API. We got the name and then the category. Okay, let's save and take a look at it. I'll say chicken search. Okay, so it is working as expected already. We got the name uh the image the category and it is just working as expected. Now what happens if we click to one of them? Currently nothing happens. But what we want to happen is this one we would like to get the details. But now how do we know we click to this one or this one. Right? How does this happening? Well it is possible thanks to this field. we have the data mail ID. So this is the data set that we are going to add on every single card just like what we have done at the moment. And when we click to them, we'll be using this ID field. If not, it'll do just in a second. For now, let's put them side by side and get started with this functionality where when we click to a cart, we would like to have this UI updated. So let's go ahead and get started with it. So the first thing you should notice is that we have a click event, right? So let's scroll to the top and add one more event listener. I'll just say the meals container dot add event listener of click event. And then in this case we would like to run the handle meal click. Okay. So this is the function that we are going to create right now. And then one more thing when we click to this button what happens the meal details is going to removed right it'll be hidden so I'd like to add that one as well I'll say if back button is clicked in this case we would like to run this function here we can say meal details dotclasses do add we would like to add the hidden class okay so this is something that we'll just in a second when we click to the back button it'll be hidden. Okay, now let's create this function at the very bottom of this page. Okay, so I just created the function and this page is refreshed. So I didn't really change anything in the code. I promise this is exactly where we left. Um I'll go ahead create this variable called meal element. And this will be the closest element that we clicked. Let's say e. target dot closest mail. Let's say meal. So this will give you the meal element that we clicked. And then we'll say con meal id. We'll say meal element dot get attribute where we would like to get this data meal id. So this is the attribute that we have passed. So we'd like to get that one. So it'll give you the value which is the meal ID. Right? And here I can say if this meal element does not exist just return out of this function. Don't do anything. Okay. Now we have the meal ID. We can do a lookup. Right? I'll say try and catch. We'll be using the response that is coming from a weight fetch of the lookup URL. Let's put this. let's say lookup URL that we have created above and then we'll add the mail ID. Okay, so I just added the mail ID but we have an error. If you're using a weight the function should be marked with async. Okay, now we'll get the data out of this response call. I'll say response JSON. Okay, now we can just console log the data just to see what are we getting as the data. I'll open the actual application that we are building. I'll say search for chicken and see the output. Okay, so we got the data is here. This is the previous console log. If we click to this one, it says E is not defined. Okay, this should be event. Let's take this as the argument and do it once again. I'll click to this one. Okay. Now, this console log is coming from here, right? It is the line 90 as you can tell. Now, what do we have? We have an array with only one item. So, we would like to select that one specifically. All right? Because this is the one that we clicked. If you click to this one, still you would get this one object. We'll select this and then it has the like the area category. It has the instructions and it has all the ingredients. Now it says the ingredient one is chicken and here is the measure 1. 2 kilograms and then onion it's going to be five thin thinly sliced and then tomatoes two finely chopped so on and so forth. So it is going in this order but we don't really want to add any ingredients that is not existed. Right? If it is an empty value, we don't really want to put it here on the UI. Let's just demonstrate this pretty quickly. Okay. So, if a ingredient is equal to an empty string, we don't really want to see it here on the UI. So, this is something that you would like to keep in mind. And this is exactly what we're going to be doing in our code. Let's put them side by side. Right after this console log, I'll say if data do meals and if data meals of zero. So we just selected that object. If this is existed then we would like to get the mail itself. I'll say data dot meals of that object which has all the data that we need. Now I will create a I'll create an array called ingredients. And this array will take at most 20 different ingredients because if you take a look at the console log let's open this up once again. Okay. So we have at most oops let's say at most we have 20 different ingredients that is starting from one all the way up to 20. And we would like to get rid of the empty ones. Right? So this is what we're going to be doing. I'll say have a for loop that starts from one and it goes all the way up to 20 included. And we'll say just increment it one by one. Now I'll say if and I'll paste this in. So we basically say if string ingredient 7 or six or five whatever the i is if it is existed and if it is not equal to an empty string. So just read this please. We say if this is existed and if it is not equal to an empty string only then go ahead select that and in this case we'll say ingredients push we'll push an object with the ingredient itself. Let's say ingredient and this will be meal. Okay so we'll basically get the value itself right. I'll copy this thing and then we are going to put the index. I'll say meal. Let's say this will be back. And then whatever the index is here, I'll say put the I. So it'll be 1 2 3 all the way up to 20. Now I feel like I have to explain this really slowly if it is kind of annoying. Please uh feel free to speed this up. But we're just going to go ahead put the measure now. So we'll have the ingredient as well as the measure itself. Once again, I'll say meal back and string measure or strr measure value and whatever the index is. We're going to select all of them. And if this is equal to an empty string or if it is something like null, let's see, do we have any that kind of a value? We don't really have for the measures itself, it is also an empty string. So what we can do is just fall back this with a with an empty string or we can even leave it empty. Okay. So now that we got the ingredient and measure all we want to do just display them on UI. Now I'll go ahead right after the for loop I'll say mail uh meal details content dot inner HTML will be equal to this thing that we have. Now we'll do the same thing or a similar thing what we have done above. We'll just put some content and instead of typing this out it'll be really annoying. We would like to copy it from the GitHub just so let me copy and paste and I'll walk you through it. Okay, I just paste it. We got the meal itself which we have copied or which we have grabbed previously. We are getting the thumbnail and put it under the image. We are getting the H2. Put the name of it. Put the category. If it is empty, we'll say uncatate. Uncatategorized. Then we have the instructions. And we are getting the ingredients array. For every single one of them, we are putting the measure and then whatever the ingredient is. So if you take a look at the end result, we have the measure first and then the ingredient name. So we have like five thinly sliced onion. So on and so forth. And since this will be an array, we would like to convert this to a string. We use the dot join method. So pretty basic JavaScript knowledge that you should have in mind. Whenever you use map, this will be an array. You would like to take this and convert it to a string. And then uh we say if there is a YouTube video, just go ahead put the link otherwise leave it empty. Okay. So that's going to be for the markup. I'll shrink this and I'll say meal details dot class list. We'll say remove the hidden class so that we can see it on the UI. And one more thing we would like to scroll into view. I'll say mail details dot scroll into view and I'll just say the behavior is going to be smooth. Okay. Now let's put them side by side and give it a go. Okay, let's just even like try it like this, not side by side. I'll say search for chicken and click to this one. Okay, we got the actual details and we are scrolled into it smoothly, right? It is not happening instantly. It is going smoothly all the way up to the bottom. We have the image, the instructions, ingredients, and the link itself. Let's try to open this up for a split second. Okay, so we actually have the UI or the link I should say. And then let's handle the catch case and that's going to add for this project I believe. So we'll say could not load the recipe details. Try again. And now let's get rid of the hidden class so that we can see it on the UI. Okay. So let's try this out for one last time and see if it is working as expected. So I'll search for chicken. We got the loading state and then the title. We got the actual results. We can click to any of them. We got the details and we can say back to recipes. It'll be hidden because we are adding that hidden class. And then let's try to search without putting anything. Okay, let's search for something that does not exist. Okay, so it looks like everything is working as expected and this should be responsive as well. So this is what we have on large screens, smaller ones and in the tiny screens. Okay, so I'd like to get rid of the console logs that we have. This is the first one and this is the second one. Okay, so with that that's going to be it for the entire project. I hope you enjoyed it. I'll see you in the next one. Okay, so
Project 13: Real-Time Currency Converter
welcome back. In this section, we're going to build a currency converter application. This is the end result. Let's see how that work and we'll build it from scratch. So we can put any kind of amount. Let's say 150. And we will convert US dollars to something like euros. And all these currencies are coming from an API, a free service that we'll see just in a second. Okay, let's say convert. This is the equation that we have. And we can even double check this with a different application. So in my Mac, I have raycast. So I'll say $150 to Okay, so this is more or less the same thing. Maybe this one is using a different API that's why there is a slight difference but basically it is the same thing and it is working correctly in real time. Okay, if you would like to get the screenshots, I'll leave the link in description. So if you would like to maybe build it by yourself, this is the uh let's say the starter point. Once you convert, this will be the output. And you have all kinds of currencies. And all of them are coming from an API. So you don't really need to type this out at all. Okay. Now, let's go and get started with the HTML. I'll say index. html style. css and a JavaScript file plus a script. js. First, let's get started with the markup. I'll put them side by side. And let's say start this with the live server. Okay. So, I just got a warning as always. Um, this is something that I'll delete later in the video once we complete it. But this will basically update the port. So, if this looks like something that you didn't get or kind of confusing, just ignore it completely. It has nothing to do with this project. Okay. So I'll say get the title as currency converter app and let's put a title like H1. Hey okay just refresh now it should be working out in real time. As you save it'll be updated. So the first thing I'd like to do just link my CSS file as well as the JavaScript file. I'll say script source that will be script. js JS file and then the other thing that we would like to do is to create a container where we would like to put the H1 and let's actually take a look at the end result and go over it. So I'll say it'll take the currency converter as our title and then right after this I'll have the form. Let's say form it'll get the ID of converter- form. Now we don't really need any actions. So I'll go ahead and delete this. We have the ID where we can get started with the very first form group element. Okay. So we're going to have a label that will be this label amount. Right? I'll say poor will be for amount and then content can be amount. Right? After the label we'll have the input that is going to be type of number. Let's put that and give it an ID. Let's say it'll be amount. and then a placeholder. Let's see if I refresh. This is the placeholder that we have. So I'll say enter amount. And let's say this will be required. So if we don't put an amount and try to convert this, we're going to get a warning. Okay. Right after this very first form group, we're going to have another one. Let's say group just like this. And then this will be the select element. Now here we can see we have a select with bunch of different options. So let's say first just get the label itself. I'll copy this paste that let's say this will be for from dash currency and amount could be from. Sorry the content could be from and then we'll have the select element. Let's delete the name. We'll put an ID uh let's say from oops from dash currency. Now the content will be empty at the moment. So we cannot really just go ahead and say option and then add every single option. So we have I think more than 100. I didn't really count it. I don't know how much we have. But we cannot really type this out, right? Technically we could spend the ne next one hour and put all of them. But this is not really something that you should be doing. This is not really how you build real world applications, right? This data will be coming from our API. So let's say currency options will be inserted from our API. Okay. So that's going to be it for the very first one. I'd like to duplicate this and let's say this is going to be the form group. This will be two currency, right? Let's do the same thing. And then the content can be two. Okay. Once again the options will be dis will be displayed and then finally we can put the result. So once we put an amount let's say from USD to this one. Okay. So this will be the result text. So we would like to put that um after this select and after this div. I think I forgot to add the button. So go right after the form group and still within the form we'll have the button. Let's say the type is going to be submit. And then we can say button, we'll say convert. Okay. And then we can go outside of the form. I'll say let's create a result div. And this will take the content later in the video. Right? Once we calculate it, it'll be coming from our API. So that's it for the entire markup. I'll just go ahead get a uh get a phone family. And we can do it by using this extension as we have done previously. So let's say Google fonts. You need to install it. I have already done this. Once you install it, you can say commandshiftp or control shiftp and then just search for Google fonts. Now you can insert it with the link to the HTML file and you can yeah like you can select any font family that you wish. I'll go with popins. Okay. Let's put it right after the style. CSS import. So that's going to be for the HTML file. Now let's get started with the style. css file. So as always, the first thing you would like to do is to add your resets. So I'll say margin of zero, padding of zero. Just get rid of them. Get rid of the default margins and paddings. And also add the box sizing of border box. Now we'll be using some CSS variables that I'd like to copy and paste. and I'll provide them if you don't want to type them out. So, I have just prepared a GitHub gist that you can find the link in the description. Go ahead, copy this and paste it. It should be under the currency-con converter MD file. So, this is the exact same value that I have. Once you have done this, we can get started with the body element. So, I'll say body, let's say the background color will be equal to variable of bg primary. And then we can get started with the uh centering right I'll just center everything in the middle of the screen I'll say display all of flex justify content will be centered let's say align items will be centered as well and we'll say minimum height could be 100 ph here we go and then I'll say padding is going to be 20 pixels from all directions and then we can update the font family so we have imported the popins I'll use this one Just in case if this is not available, we can say use the default sans serif for sans serif uh font family and then we can get the container right I think I have a typole let's say container I'll say width is going to be 100% the max width could be 400 pixels and then we can select the background color let's say it'll be variable of bg secondary three and then we can say petting will be 30 pixels not auto okay then we can add some border radiuses to be 15 pixels and then I'll add some box shadow let's say 0 to 40 pixels 20 pixels and then rgba value let's say use the black value. 3 okay now I'll select a different element which is going to be h1 let's say text align line could be centered and then we'll say color is going to be text primary and finally margin bottom of 20 pixels. Okay. Now we're going to get the form group itself that will take the margin bottom of 15 pixels. Okay. And then we'll get the label element. Let's say display will be block so that it is taking the entire line. Right. It'll be a block element. By default, it is inline or inline block. What is it? I don't really remember. Let's just type this out. What is label element display um by default? I think it is inline, but let's double check. I'll just search for something like inline. Okay, they are in line by default. Right after the label of display block, we'll say margin bottom of five pixels and then color is going to be text secondary. Okay. Then we can get the input element. Let's say input as well as the select selector right I'll say width will be 100%. So it is taking the entire width. We can give some padding such as 10 pixels. And then I'll say um background color will be BG input. Then we can say border will be one pixel solid let's say border color. Okay. And if you wanted to update all these values all you have to do just scroll to the top and change them and make them whatever you wish. Right after the border I'd like to say border radius is going to be 5 pixels. Font size will be 1 RM. and then update the color to be text primary. Okay, I'll get the input focus state and let's duplicate this. Say select focus. Let's say outline is going to be none. Border color could be updated to be let's say accent primary. And then finally, we can give some box shadow that I'd like to copy and paste instead of typing this out. Okay, so this is what we have as the output. Now we'll go ahead get the button element so that we can style it. I'll say button is going to be width of 100%. Then we can say padding is going to be 12 pixels. I'll say background color is going to be accent primary. And then we can say color will be white. Let's say fff. And then I'll say border is going to be none. You can say border radius 5 pixels. Here we go. And I'll add some font size of 1 RM. Let's say cursor is going to be pointer. And when we hover over this, we'll take to update the background. So I can say just transition will be 0. 3 seconds from all directions. And I'll just say e is right. And then I'll just say button select the hover state where I'd like to say the background color will be equal to accent um accent hover and then I also want to say transform of um sorry transform is going to be translate of y minus 3 pixels so that when you hover over this it is just going up a bit. Okay maybe I can go with two pixels. Okay, then finally we'll just get the result and I'll say margin top is going to be let's say margin top will be 20 pixels text align centered I'll say font size is going to be 1. 2 to RM and then color is going to be let's say text primary. Now even though we cannot see it, we can test this out. I'll say something like 500 USD. And this is the output that we got. Okay, but for now it'll be empty. That's the entire CSS file. Now we can get started with the JavaScript file. So the first thing I'd like to do is to select all of my elements. Let's get started with the converter form. So I'll say const converter form. We'll say document. getelement by ID. And our ID is converter- form. Let's duplicate it. This will be from currency. And let's go ahead update the variable name. I'll say from currency. Let's duplicate it. This will be to currency. and then we'll get the amount input and then we'll get the result div. Now let's update the values itself. I'll say this is the two currency and then this will be the amount and then finally this is going to be result. Okay, we'll go ahead and add an event listener. So the first thing we would like to do whenever we visit this page whenever it's been reloaded we would like to select all these options. Currently we don't have anything but here we'll like to have all of them. And for this we'll be using an API. This will be a free API. And if you don't know what an API is pretty quickly explain it even though we have done this in the previous projects but I'd like to go over it once again. Now it sounds complicated such as now first this stands for application programming interface but basically an API lets two programs talk to each other and this is exactly what we have. We want our application to talk with a different service so that it can get some data. So it allows you to get or send data between your application and another service. I hope that makes sense. So this is how we can explain it in simple terms. Okay. So we would like to whenever we load this page we want to send a request to get the data where we have all these options. Right. Let's see how we can make that work. Okay. I'll say window. adde eventlister. Whenever we load our page, we would like to say fetch currencies. And this is a function that we are going to create. I'll say create this function for now. Let's leave it empty. And then I'd like to add one more event listener. I'll say converter form where we would like to listen for the submit event. Once this is happening, we would like to convert the currency. I'll say convert currency. And this is a function that we will create here at the bottom. I'll say function and leave it empty for now. First, let's get started with this one. So, the API that we're going to use will be this one. So, I'll just leave it as a comment. You can type this out. I'll copy this and paste it right here in my uh in my URL bar. Right. Okay. So we are just sending a request to the latest version and our base currency is USD and it'll give you all the rates in real time. Okay. So here uh this is today's date. It has been just updated and we have all kinds of currencies. So it is like1 US is equal to1 AED so on and so forth. It is equal to 138 Canadian and all the currencies. Now we would like to select all of them and display it in our UI. Okay. So I'll just leave it open and let's see how we can make that work. I'll copy this value. I'll say const response. When we send a request with the fetch API to this URL to this endpoint, we'll get a response. And to be able to use a weight, we would like to mark this async. And then we'll say const data await response. json. JSON. So if you have ever worked with fetch, this is how you would use it. First you would get the data and then grab the uh like you would get the response and grab the data out of it. So this is how we can extract it and then we'll say const currency options. Now before we do so, I'd like to just say console log data. Okay, let's see what we're going to get. If you open up the terminal, you should be able to get this data. Okay. So, first they say you can up upgrade this to version six. I think this is the latest version, but this is also working. Um, we can use it. And now under the rates, we have every single rate that this API providing, right? We would like to get the keys, right? on every single rate we would like to get the key so that we can nicely display it. Okay, so this is exactly what we're going to be doing. We'll get every single key and display it as a currency option. So I'll say currency options will be equal to object keys where we would like to get the keys from data. rates. So data is the object. We went into the rates and get the keys. So if you now say console log the currency options you will see an array of currencies. So since this is an array we can use the for each method. I'll say currency options dot for each get every single currency and do something with it where we would like to create an option. So I'll say cost option and specifically option one I'll tell you why document. createelement create element. Let's create an option element. Then we can say option one dot value will be equal to currency. And then we'll say option one dot text content will be equal to currency as well. Then finally we'll append this to UI. So first we would like to pass this value to the from element and then we would like to create the same option for the two element right for the two select here I'll say from currency dot append child append the option one and then let's do the exact same thing for option two oops let's say duplicated this is going to be equal to option two value and then append this one. Okay, so that's going to be it for this entire function. As you can tell, we got all these currencies as an option. I think this does not work because this should be two currency. Okay, now we got the exact same values here on this one. Now that we have this function is working properly, we can get started with this one. So first if you put a value and try to submit it. Notice how it'll refresh the page because this is inside a form right? This is a form element. So we would like to just say first get the event and say event. prevent default so that it doesn't really refresh the page. Once we have done this we can grab the amount that user typed in. So if they put 120, we'd like to grab that. We say amount will be equal to amount input value. This will be a string because it is coming from an input. So we can take this and convert this to be a to number. Right? I'll say parse load and we can get this value and then I'd like to get the currency that will be from. So if they selected this one, we would like to get this value and then get the get this value as well. So it is super easy to build. We'll say const currency value that will be equal to from currency dot value and then I'll duplicate this. Let's say to currency value and do the exact same thing as the variable name. Now what happens if user put something like minus 5? We would like to give some alerts, right? I'll say if amount is less than zero, we don't really want to calculate it. Instead, I'll say alert. And if you wanted to, you can put it under the curly braces as well. I'll say alert, please enter a valid amount. And then we can return out of this function. We don't really want to do anything else, right? So I'll go ahead put something like minus 50 and convert this. We got an alert that it says please enter a valid amount and then if this is not the case that means we can actually convert it. So we'll send a request to our endpoint which is this one but instead of typing out as USD we will say something else. So we'll say fetch make this to be a back tick. Paste this in. Instead of USD we will say whatever the chrome value is right I'll say ch from currency value because we don't really know what user will select right and then we'll say get the response. I would like to make this an async function. Okay, we'll get the data and this should take the await in front. Okay, now we can get the rate itself. Let's say const rate and we'll say data dot rates just like what we have done previously but this time we would like to get the selected rate. So we'll say to currency uh value this will give you the rate and we can convert this. I'll say cost converted amount we'll say whatever the amount is multiply this by rate. So this is how we can calculate it super basic math and then I would like to I'd like to get something. So what is that? It'll be this two like two floating numbers, right? If you don't add it, maybe it'll be longer than this. But I'd like to get this and just say to fix to fixed to only two values, right? Only two floating numbers. And then we can finally update the result. ext content. Let's say this will be back where we'll take the first put the amount and then the from currency equal to two currency and then the uh the currency name. So say amount one space and then from currency value will be equal to let's say converted amount and then whatever the two currency is. Okay. Now let's save and take a look at the output. This is what we have built. I'll say 150 USD to let's say euros. I'll search for it and let's say convert. This is the value that we got. Let's double check. I'll say $150 to euros. Okay, more or less it is the same, right? It is working properly. Okay, so with that, that's going to be for the entire application. I hope you enjoyed it. Okay, so in this section, we're going to build a GitHub user finder. Now, by default, I put my own name. So when you refresh the page, it'll go ahead get my own GitHub profile. But at the end of this video, I'll show you how you can put your own name. And then you can search for anyone. Let's put something like Brad. It'll go ahead get this profile with the latest repositories. Okay. So this is the application. This is how that work. It is completely responsive by the way. Let's go ahead try to shrink the screen. So everything will be in the column direction without breaking anything. And to be able to build this application, we'll be using the GitHub API. So there is a free API where you can fetch uh GitHub profiles. So here's the entire link api. github. com/ users/ whatever your username is. In my case, this is what I have. You can put your own username and it should be able to fetch your profile. Now this only gives you the profile. You cannot get the repos, right? But they have this repos URL. If you send a request, it'll give you the repositories that you have. Right? So this is what we'll be doing. We'll send one request to fetch the profile and then another repositories. So I hope that makes sense. If not, we'll see it in action just in a second. And if you'd like to get the screenshot, maybe you would like to build it uh without watching the video here. You can find the link in the description completely free. So the first thing I'd like to do is get the uh let's say font awesome so that we can use these icons. Okay. So I'll visit cdnjs. com. Let's search for font awesome and I'll copy the link. Now let's get started with the HTML. So I have an empty folder and three empty files. Let's get started with the markup. So, I'll put them side by side and let's say just have this title as a GitHub user finder. Let's say I'll put an H1 that says hey for now. Let's say open
Project 14: GitHub User Finder (GitHub API)
this up. Okay, so we have it. Now, let's link our CSS file and then put the font awesome link. And at the very bottom, just before the body closing tag, I'll say script source. We'll go ahead uh link our script. js file. Okay. Now, let's get started with the actual content. So, we'll have the container and I'd like to just take a look at the end result as we build it so that I can reference to this markup as we go. So, I'll say container and then we'll have the header component, the header element which will have the H1. So, the first thing I'd like to have is this GitHub icon. So, I'll say use the I element. We'll say class of fab fa-gop. So this is coming from font awesome as you might know already. And next to this icon we'll put the text which is GitHub. Let's say user finder and I'll capitalize the age as well because why not? Okay. So right after the H1 I'll put the P tag where we'll say search for any GitHub user profile. Okay. So I'll just put this P tag right after the header element we would like to put the search container let's say create this div and I'll have an input element which is this one and next to it we'll put a button so I'll say input this will be type of text let's say it'll have the ID of search it'll have the placeholder of let's say enter so if you delete that this is the placeholder that we have let's say enter a GitHub username and then right after the placeholder I'd like to say something like autocomplete will be off so that it doesn't really get annoying with the auto completions and then I'd like to put the button let's say id will be equal to search dashbt and then the content will be search okay right after the search container we'll go ahead and create the profile container itself let's say profile file dash container but I think this will be an id. So let's say this will be a hash at the beginning. Okay. And then I'd like to put the class of hidden by default because if you refresh this when you first visit this page it'll be invisible. Right? We'll have a loading state. Once we fetch the profile then this profile header will be visible. So we'll just have the hidden by default and then we can get the profile header itself. Let's say profile dash header class that will have the image. Let's say source will be empty for now because we don't really know the user profile image, right? This will be updated later in the video. And then for the alt, we can say profile avatar and then I'd like to put the id which will be avatar. Okay. Right after the image, I'll have a div that will have the class name of profile dash info. And within this div, we'll have the h2 that will store the username, right? The full name and then the username. Then we'll have the bio, location, date, so on and so forth. So let's say H2, we'll get the ID of name. The content will be empty initially. Let's say P ID will be username. Then we'll have another p tag which will be for the bio. Okay. Right after this I'll have a div with the class name of location dash date. So both the location and date I'll put a p tag. Let's say it'll get this icon which will be for the marker icon right for the location. Let's say class is going to be fas marker and finally alt. Okay, right after this I element, let me give all the space. Right after this, I'll have a span which will be ID of location. And you can leave the content empty or you can put something like not specified by default. And if user has location, we are going to update that value with that actual location. Right? So I'd like to duplicate this P tag. This will get another icon. Let's say F A R. I'll say FA. This will be calendar this time. Calendar alt. And then right after this icon, we would like to put this joint text. And then whatever the date is, right? So here we'll say joint. But this part is going to be dynamic. So for now, I'll leave it empty. And I'll say this is not going to be a location, but instead joint dash date. Okay. So that's going to be for the second P tag as well. Let's go outside of this div which is the location and date. I'll have an A. Oops, I think I have made a mistake. Okay, let's go outside of this location date. And then I'll put the A tag with the ID of let's say profile dash link and href is going to be empty for now. We can even delete it because that href will be added once we fetch the profile. So this is going to be the ID. Let's say target is going to be underscore blank. So that when we click to it, it'll open up uh sorry it'll open up with a new tab and then after the target we can say class name is going to be button here. I'll say view profile. That's going to be it for the content. So right after the a tag we're going to go outside of this div which is like which is the profile header right. So just shrink this go outside of it and we would like to create another one for the stats. So these are the stats elements that we have the followers following and the repositories. But uh let's say we'll have three different stat. I'll duplicate this. Let's say stat times three. The very first one is going to take this icon. Let's say class name of f a s f a- users which is this one and next to it we can put a span that will get the id of followers and like this content will be updated but next to it will have the followers text okay so we'll do the same thing for the following and repositories what I'd like to do copy this paste this inside and same for this one but we will update the icon let's Say this will be FAS FA- user-friends and let's say following this will be repositories and then the icon and also this should be following by the way let's fix it the ID will be updated and this ID will be repost let's say and then icon will be fa uh sorry fasa code dash branch now if you save you should be able to see the output we are going correct Exactly. Right. All we have to do just build the entire markup. Then we'll jump into the CSS. Okay. So, right after the stats, let's shrink this. We'll go outside of it and we'll create the additional info such as these ones. Right. I'll say dot additional dash info. And I think I have a typo. Let's say it'll be additional just like this. So we'll have three different items. The first one will be let's say info- item and we can duplicate this twice. This will get the ID of let's say company container and then we'll create for the blog container or the website and then the Twitter container. Right? So now I'd like to have an I element. Let's say class will be fasa- building which is this one. And then next to it we can have a span that will be ID of company. Um here I'll say not specified by default and then we would like to build the rest of it. So I'll get this ID. Paste this in. This is going to be blog container. I'll get the content. Paste this in. The icon will be f a link and then let's say id. So the id is going to be blog but this is going to be a link. So I'll say a element, right? When we clicked it, it'll take us to that website whatever that is. And then we'll say open this up with a new tab. We'll say target blank. And you can say something like no website by default. So I'll do the exact same thing for the very last one. Let's say it'll be Twitter container. And for the content, let's try to copy this. Paste this in. We'll update the icon. That will be F A Twitter. And this should be F A B by the way, not FAS. And then we'll still have the link ID will be Twitter as well. Target_lank. And let's say no Twitter. Just like this. Okay. Okay, so let's save and take a look at the output. Everything is right here on markup on HTML, right? So, right after the A element, go outside of these two divs, right after the additional info, right? We'll shrink this and we're going to put the repos container or let's say repos section. And then I'll have an H3 that says latest repositories. Let's go ahead paste this in. And then I'll have a div that will be the id of repose- container. Let's say class will also be reposer. And then we can put the actual div. Now this will be for the loading state. I don't really know if you can see it but for a split second. Now this is too fast but like there is a loading there's a loading state. Let's try to actually see it. I'll go ahead slow down my internet connection. So, let's say it'll be slow 4G. I think we should be able to see it. Maybe let's say 3G. Okay, it's incredibly fast. Let's try to copy this and try to open this up in incognito window and I'll try to do the same thing. Okay, it's incredibly fast because it is coming from the cache. Can we just disable the cache? Okay, let's say disable the cache and run this all over again. Now, this is super slow, but let's try to see. Okay, here we can see we have this loading repositories for a split second. So, we'd like to build it. Okay, I'll just put this to previous state. Okay, so let's put them side by side. Uh, we'll have this div that will say the loading repositories. So I just put this text that says loading repositories and I put this class. Now I'd like to add a comment where the repositories will be inserted here dynamically. Right? Once we fetch the profile, they will be like the repositories will also be fetched and we are going to put it into here from our JavaScript code. Okay, so that's going to be for the repos section as well. Now, right after this div and these three. Okay, so just go outside. So right after these three divs, which is going to be basically the profile container, just shrink that. And outside of it, we would like to put the error container. So if we have an error, let's try to put a user profile that does not exist. I hope this doesn't really exist. Let's search for it. Okay, so we're going to put this error container. By default it would be hidden but once we hit the error case we are going to display it which says no user found please try another username. Okay so with that that's going to be for the entire markup. This is what we have. We would like to now we jump into the CSS file and get started with it. So the first thing we would like to do as always it'll be our basic resets. Let's say petting will be preseted. Same for the margin and then box sizing will be equal to border box. Now I'd like to add some CSS variables and instead of typing them out I have prepared an entire list that you can find the link in the description find the GitHub finder MD and then copy this root object. Just go ahead paste this in. So we have bunch of different values so that we can use them to get this beautiful purple theme. Okay. Now I'd like to select the body element. Let's say background color will be updated to BG dark. We would like to update the color as well. That will be text light. And since we are using a CSS variable, we have to wrap them with this variable uh function. Right? And then I'd like to say display will be flex. And then we would like to say justify content will be centered. Align items will be centered. And let's make the minimum height to be 100 ph. So that our entire content is centered in the middle of the screen. And then I'll get the padding to be 30 pixels to 15 pixels. And then we can save. Let's take a look at the output as we go. Then I'd like to finally add the font family to be sense serif. And maybe we can even update the line height to be 1. 6 so that everything is just a bit more spaced out. Now we can get the container itself and just give it a maximum width. So I'll say the container will be selected. width will be 100% but the maximum width is going to be not height but let's say 800 pixels okay and then we can get the header element let's select it I'll say header will be selected we can say text align will be centered and then margin bottom will be 30 pixels okay then we can get the H1 let's say font size will be equal to 2. 2 to RM and then margin bottom will be 10 pixels. Finally, update the color to be primary color. Okay, then we can get the header of uh I was going to say get the P tag in the header and then I'll say color will be text gray and let's say font size can be one area and then I'll get the search container which is a class. Let's get this one. I'll say display will be flex margin bottom of 30 pixels and then gap of 10 pixels. Here we go. And I'll say let's select the input but specifically the type of text. So we'll say type is equal to text. We would like to select this input and just say flex will be one so that it is taking the entire space. Padding will be 12 pixels to 16 pixels. Let's say font size will be 1 RM. And then we can update the border radius value. Let's see what is this. If you scroll to the top, it is equal to 10 pixels. Okay. I'll say border will be none like this. And I'll say background color could be the card bg value that we have. And then we can get the color of text light. Finally, outline will be none as well. Then I'd like to get the focus state. So if we click to it once it is focused we would like to get this kind of like a box shadow value and I'll just paste this in. We'll say on the focus state go ahead update this box shadow. Okay. And then we can get the button itself and try to update it. I'll say background color is going to be primary color that we have and then we can get the color let's go with black and then we can select the border that will be equal to none let's say border radius will be updated padding could be 0 to 20 pixels then we can add like font size of 1 RM font weight could be let's say 600 it and then I'll get the cursor to be pointer. And finally, we can give the transition. We'll say background color and 0. 3 seconds. So when we hover over it, we'd like to update the background color to be this primary color that we have. And then right after the button, we can select the profile dash container, which is going to be the ID. We'll say background color get this car card bg um I'll get the border radius let's say variable of this value padding let's say 25 pixels from all directions add some box shadow which is going to be shadow medium and then margin bottom of 20 pixels and then we can get the profile header class I'll say display will be flex align line items will be flex start and then gap of 25 pixels margin bottom 25 pixels as well. Now this align items of flex start will make them to be u align in the start right it's pretty self-explanatory but if you were to put them side by side right this is how they start uh at the beginning if this was something like centered then image would be in between so it would be in the middle of that container let's actually try to see if I say this is going to be center it should be updated okay Okay. So here we can see it is now centered. But I think this looks a lot more cleaner. Um just like what we have right here. Okay. So this is something that I wanted to mention. Right after this one we can get the avatar itself and we'll say width is going to be 90 pixels. Same for the height. And then we would like to let's fix this. We would like to say border radius will be 50%, so that it is a like um it is a circle. Let's say object fit will be cover. And then I'd like to update the border value to be 3 pixels to solid and primary color that we have. Okay. Then we'll get the profile info. Let's say profile- info flex is going to be one. So that it is taking the entire space that is remaining. And then we can get the name element. We'll say font size will be this. And then margin bottom will be updated. Let's do the same thing for the username. So currently we cannot see those but they will be added once we get into the JavaScript um JavaScript section. And then let's select the bio. These are super simple styles. That's why I'd like to copy and paste instead of typing them out. We have the bio where we have this color as well as the margin bottom. Let's do the same thing for the location date. We'll say display flex and let's save. Now they are side by side. Um the location as well as the date. We have some gap margin bottom color has been updated and then the font size. Now we can get the location date icons and we can say color will be the primary color that we have. Now it's been updated and we can say margin right could be something like five pixels. And then we can get the btn class and try to update it. I'll say display will be inline blog. And then I'll add some paddings. Let's say something like 6 pixels to 16 pixels. Sorry, 8 pixels to 16 pixels. I'll say background color will be updated to be primary color. And then we can update the color itself. Let's go ahead say color will be black. And then I'd like to just copy the rest of it. We will update the text decoration, border radius, font weight, font size, and then the transition because when we hover over it, we would like to update the background color to be this value. And I think this should be equal to background color. Okay, so this is the output that we have at the moment. The next thing that I'd like to do is to update my stats. So here I'll put my comment and then the stats so that they are side by side where we set display of flex gap of 15 pixels and just space between. Now we can select every single stat. I'll just put them one by one. Now these have been updated but I think we are missing the stat on this class or on this element. Let's visit the index. html under the stats. Um where do we have it? Okay, we have stat. Okay, so I think I have double stats right here. Let's try to delete them. And this should also be deleted. Okay, so we have one stats parent and then one stat, second, and then the third one. Now they all have been updated. So right after the stat, we can get the icon, update the color as well as the margin. Right. So this is what we have at the moment. Okay. Then we can get the error container and try to update the background color as well as the color itself so that we can get this output. And then I'd like to add this hidden utility class. Let's say display will be none. So that is not really visible on the screen. So if you save now they should be invisible, right? Because we have added this hidden class by default. And then we can get the additional info. Let's select this class. Additional dash info. Let's say margin top will be 25 pixels. Let's say display will be grid. And then we'll say grid template columns is going to be repeat of auto-ash fill. And then I think I have an extra brackets. Let's delete them. autofill of let's say minmax of 20 pixels to one fraction and then we can get the gap of 15 pixels. Then we'll give the border top let's type this out. Border top will be one pixel solid and let's use this value. I'll say 255 couple of times and we'll just get this value. So even though we cannot see it on the screen but basically this is the place that we are trying to build the additional info right we have added this border top and let's say the padding top is going to be equal to 20 pixels. Okay now we can get the info item. I'd like to copy and paste because it is such a simple style. We have display flex align items of centered. We have some gap color has been updated as well as the font size itself. Now we would like to select the icon and try to update the color. So I'll say info item I color width and text would be centered. Now let's get the link itself. So I'd like to copy and paste. Here we go. So that they can look like this. And on hover state. So if I hover over the link, we would like to update the text decoration as well as the color itself. So I'll add the hover state just like what I have just mentioned. Okay. So let's save. That's the styles that we have. The other thing we would need is the repos dash section where we would like to add some margin top of 30 pixels. Then we can get the H3. I'll say select the H3 and update the font size to be 1. 2. tom let's say margin bottom will be 15 pixels we can add some colors such as text light and then we can add the padding bottom to be 10 pixels and then we can add this border bottom so instead of typing this out I'll go ahead copy and paste with this value so that's going to be for the age three now we can get the repos container itself and make them to be responsive with the display grid okay Now let's save. Of course, we cannot see the output because we don't really have any UI at the moment. Uh but yeah, so this is the output that we are building at the moment. So these are the styles that we would need. And then let's say repo-cart, we would like to update the background color to be this value. And then I'd like to update the border radius with this 10 pixels that we have. And then we can give some paddings from all directions. Right? I'll say petting will be 15 pixels. And then we can say the border itself is going to be this value that you can type this out. And then I'll add the transition. Now when you hover over them, they will be translated, right? So we'll say add the transition on the transform as well as on the background color because the background color is also getting updated. Now let's add the hover state where we can say translate Y will be minus pixels minus 3 pixels so that it can go up and then the background color will be updated. Now let's get the repoint name itself. So font weight will be updated margin bottom color text decoration will be none because it is a link by default. Then the display will be block so that it can take the entire width. So since we are doing the exact same thing over and over again, we can just speed this up a bit. I'll say repo. name on the hover state, the text decoration would be updated so that we can have this underline and then the description is going to take all these values. We can get the meta data which is going to be this container that we have. So we will say display of flex so that they are side by side. Add some gap in between which is 15 pixels. update the color as well as the font size. Then we can get each item. So this is one item. So on and so forth. We'll say repo meta- item. And then we can get the icon and try to update it as well. Then for the loading um for the loading container that we had, we can select it, update the color and add all these styles. This will basically make it to take the entire width, right? We say grid column, it'll start from the very first one until the last one. So it'll basically make it to be the entire width. And if there are no repos, we would like to add this class. So that was a lot of copying and pasting. Sorry if it is kind of like confusing or annoying, but we haven't done anything complex. So these are all the styles that we have written above, right? We have done this over and over again. So I just wanted to copy and paste the last styles. So the very last thing that I'll be copying and pasting will be the responsive styles for the mobile devices. Okay? So I'll add all of them. If you don't want to type them out, you can grab everything from the source code. Right? Just find the style. css, CSS. Copy the entire file and paste this in. And with that, that's going to be for the style. CSS file. Now we are going to build the most exciting part, which is the JavaScript file. Okay. So the first thing we need is to get our DOM elements. Now we can type them out, but we'll have more than 20 elements. So there is no need to type them out. I have prepared the entire list that you can find under the GitHub finder. just go ahead copy every single one of them and just paste this in. So we have 20 different elements. Um so we'll just use all of them to display the UI nicely here on this application. Right? Okay. Now that we have all the elements, we can add some event listeners. So when we click to this button, uh we would like to search or if we press enter, we also want to search. So let's add both of those event listeners. So I'll say search button dot add event listener. This will be click where we would like to call the search user function. And let's duplicate it. This time we will listen for key press but we would like to add this onto the search input element. So we'll add the key press event. Um we would like to do a quick check. So I'll get the event and I'll say if event key is equal to enter right only if it then we would like to search for the user I'll say if e key is equal to enter we would like to just say search the user okay now we need to create this function let's go ahead create it this will be a function search user but now this will be an async function fun because we'll be using a weight within this function and first let's try to get the value and we would like to check if it is an empty value or actual input right so let's see what I mean I'll say con username we would like to say search input do value and we would like to trim this down I'll say dot trim call the method and then we'll say if there is not username if this is a false value we can say just return out of this function and return an alert where we can say please enter a username. Now I'll just try to click to it without typing anything. We got the alert and if you put an empty space so just put bunch of different spaces still we're going to get the exact same um output. If you don't add the trim if and if you try to add some spaces it'll try to search. So that's why we're using the trim uh right here. Okay. So after this check, we would like to actually send the request. Now I'll have the try and catch block. In the catch, we will get the error and handle it. But here in the try, we would like to send the request, right? And let me type out the entire URL. So it is api. github and just try to put the https in front. github. com github. com and then / users slash whatever the username is. So in this case I'll put my own but actually this value will be coming from the input. So just go ahead copy this and we'll be using it. I'll say const response. We would like to say await fetch where we would like to send a get request to this endpoint. I'll make it to be back and then here instead of my username this will be coming from the search input. So I'll say this will be equal to the username value that we have right whatever user has and just before we send the request I'd like to just reset the UI. So I'll say profile container dot class list dot add. We would like to hide this. So I'll say add the hidden class and then same for the error container. This will basically reset the UI whenever you send a request and then in a bit will make it to be visible. So we got the response. Now let's say if it is not okay, I'll say if response is not okay, we can just throw a new error and then we can put something like user not found. We can put anything. I'll just say user not found. And then after this if check we can get the user data. Let's say const and try to format this. Okay. I'll say const um user data. We'll say await response. json. Okay. So response. json and let's try to say console log user data is here and try to put this next to it. I'll save and take a look at it. I'll try to search for my name. I'll say put my username and search for it. Okay, user data is right here. We just got this data. We have all these fields that we can display and then we'll be using the repos URL to be able to fetch the repositories of this user. Right? Okay. So now that we know we got the actual data, it is working correctly, we can go ahead call this function. I'll say display user data and we'll pass the user data into this function. In the catch case, I'll say just show an error and let's create this function. It'll be really basic. Let's say show error. Um this will not take any arguments. I'll just basically say error container. class list dot remove. We'll say remove the hidden class so that it is visible and then go ahead add the hidden class onto the profile container so that we don't really see the profile container right here. Um for now let's try to create this function as well. I'll say function put this name. We'll take the user data and for now I'll just leave this empty. So let's try to put a username that does not exist. I'll say I think I need to save this file as well. By the way, let's try to search for a user. Okay, user not found. That means this function is working correctly. Now we can get started with the actual function that we have. So I'll just call this as user because why not? It is shorter. And before we get into it, once again, I'd like to put my own name right here by default. So you can put your own as well. Uh basically just scroll to the very bottom outside of any functions. I'll say search input value and you can put your own username. I'll put mine. This is my GitHub username and I'll say go ahead call this search user function. Now if you save by default this will be the value uh within the input and it'll actually call this function. So if you take a look at the terminal and refresh, you should be able to see this console log where it is fetching the user data. Now we would like to take this user and try to display it. I'll say avatar. source. Let's get started with the image. I'll say it'll be equal to user avatar URL. So it has to be called like this because this is how GitHub returns us, right? Avatar. URL. If you want to get the bio, you would say bio so on and so forth. Okay, now that we know this, we can move forward with the name element. We'll say text content will be equal to user. name or if this is undefined, we can put the username. I'll say user. lo. So this is how GitHub calls it. For the username, it is under the login field. I'll say username element. ext text content will be equal to back text. I'd like to put the add symbol and then I'll say user. lo and then we can put the bio element. Let's say text content will be equal to user. bio. If this is undefined, we can say no bio available. So that's going to be for the basic info. Now we can update the location and date. I'll say location element. ext text content will be equal to user. loation. Let's try to type this out. But if this is not really specified, we can say not specified. And then let's try to put the joint date. I'll say joint date element. ext content will be equal to user. created uh created_. So this is the field how user sorry how GitHub stores so created add but now this date is not really formatted right it is kind of like ugly so we would like to make it look nice so that we can put this like December one and then the year we are going to build a function where we can format it for now I'll just leave this as a to-do I'll say to-do format the date. Okay. So, right after this one, we can add the stats. Instead of typing them out, I'll copy and paste four lines of code. We will update the profile link which is coming from this field. Same for the followers following and then the repos. Now, for the additional info, we can put this if else statement. I'll say if user company existed, we can update that. But else we can say not specified. So you can either wrap them with curly braces or if it is an like if it is a single line you can put them as a oneliner and then I'll do the same thing for the user blog if user has it or not. So I'd like to just paste this value and let's maximize this entire screen. Okay. So if user has the blog we are going to update the text content as well as the href. Now if it starts with HTTP we'll just use it but if not we will put that so that it is an actual link right and then in the else case we'll leave the href empty and we'll say no website okay now we can actually display this because by default it would be hidden and then let's do the same thing for the Twitter username so I'll go ahead paste this in and by the way all these fields once again are coming from GitHub. So they have like Twitter username, we use the blog, right? User. blog. As you can tell, this is not something that I am just making up, right? All of them are coming from the actual API. So let's try to use the display flex as well. And then finally, we will add the sorry, we will remove the hidden class so that it is actually visible. Right? I'll just say show the profile. Now let's save. And here we go. It'll be updated. We got all this info by default. And now, as you can tell, this is not really formatted. We would like to fix it. And then we are going to get the repositories because currently it just says loading repositories, but we don't really have that function. So, the first thing I'd like to do just scroll to the top and wrap this with the format date function and delete this to-do. Now, let's try to create this function. I'll go ahead scroll to the bottom. Uh, let's say function is going to be format date where we would like to get the date string and try to return the formatted date. So I'll use new date pass the date string and I'll say to local date string first option will be n / us and then we can add our options so I'll say year is going to be numeric and then I will duplicate this twice here we would like to select the month this is going to be short and then finally uh year sorry the day is going to be numeric as well. Okay, let's try to save. Now, as you can tell, it's been updated. So, here I think our gap is not really working. Let's try to find it within the style. CSS file. So, just scroll to the top and find the profile header. This should be gap instead of grid area. Let's say gap is going to be 25 pixels. Now, we have that gap working properly. So that's it for the profile info. Next, we are going to build the latest repositories. So I just killed the CSS file and here I am in the search user function. Once we display the user data, we would like to fetch the repositories. So I will call this function that we will create in a second. And this will take an argument which is going to be user data repos. Okay. Now let's try to create this function. I'd like to shrink every one of those so that it's not really confusing and I'll just put it right here. Let's say function uh I think I have a typo. Put the name that will take the repos URL and let's try to make this function to be an async function. Okay. So I'll go within this function and the first thing I'd like to do is just clear the previous repos and show some kind of loading state. even though we have it. But if we try to fetch another profile, we'd like to just reset the state. So I'll say repos container. in html is going to be this. Let's say uh string value where we'll put a div. And be really careful to type this out. You don't really want to have any uh any typos here, right? So I'll say div. It will take the class. Let's open up our codes and I'll put the loading dash repos as the class name. And then we can put the loading repo. I'll just copy this entire thing. I don't want to put any typos. And I'll put three dots at the end. Okay. So that's going to be for the inner HTML. Now we can create the try and catch block where we would like to send a request to this repos URL. So I'll say response URL and then I'll put the let's say data and instead of data let's just actually call it as repos and I'll say await response JSON and then now that we have now that we fetched the repos we can display it. So I'll create a function instead of display user data we'll say display repos and then we can pass this as the argument and in the catch we can handle this I'll say repos container dot inner html will be equal to this value which is the error dossage and we're going to pass the class okay so let's try to create this function and then I think the entire application will be completed So first I'll check for an H case. So I'll say if repos let's say if repos. length if it is equal to zero that means no repos found right. So I'll say just put the u inner html to be this div where it says no repository is found and then we'll return out of this function. But if there are some repos, we can basically try to display it, right? We'll just put these cards one by one. Okay. So, first I'd like to clear the container. I'll say repos container. HTML will be reseted. And then we can add every single repository one by one. So I'll say repos. Because it'll be an array and every repo we'll just get them and try to run this function. So first let's say const repo card we would like to create a div. Let's say document. createelement it's going to be a div element and then we can add the class name. So say repo cardart doclass name will be equal to repo-card and then we can uh format the date. So here we have a date. Once again we'll be using this function to be able to format it. I'd like to say const updated at and we will call this function where we would like to pass the repo. Updated add field. So this is going to update that. that date. And now once again I have prepared something for you that you can copy and paste because this is really annoying to type this out otherwise. Um here I'll go ahead and just say paste this in. The only thing that we do is to update the inner HTML where we add a link tag uh a p tag a div you know everything that you have seen here where we like to basically get the data and display it. Now I don't really want to type this out because probably I'll make some mistakes some typos that's why I have prepared this where you can copy and paste uh with me. Okay. So just after this semicolon we would like to say repos. container appentis child into it right which is going to be the repo card. Okay. So if you scroll to the top you will see that we have the link we have the description uh we have the name language we have the star count force count and then finally the updated date. Okay. So if we save I think this should be good to go. I'd like to make this a little bit larger. We got all the repositories. But now in the end result, we only have six, right? How does that work that we got 30 in this case? So we can update this. Basically, it's super easy. We can scroll to the top when we send the fetch request. Okay, it is right here. We can add a query. So I'll say whatever the repos URL is, right? Whatever that is. Just go ahead add this per page and let's say it'll be equal to something like six. Let's save and take a look at the output. I think this should be underscore per page. Okay, now we got only six values, right? Six repositories. Let's say make this to be 10. You would get only 10 different repositories. So this is something that you can add uh to make that work. But what happens if you accidentally break this so let's put something random. Now this is not a correct URL. Let's save. So we got this error where it says fail to fetch. So this is something that we have even handled right under the catch. This is what is happening. But let's get rid of this fetch error. Now it is working correctly. And I'll put this as six. Let's refresh. Okay, so we only have six repositories in this application. Okay, so believe it or not, this is the entire application that we have built. It's completely responsive. You can search for anything, right? Let's just put Brad. This is what we got. You can search for John. You'll just get bunch of different user profiles. And by default, you can put your own. Okay, so that's going to be it for this entire project. I hope you enjoyed it. I'll see you in the next one. Okay, so
Project 15: Custom 404 "Page Not Found" Design
in this section, we're going to build a custom 404 page. There is no JavaScript at all. This is only HTML and CSS. Now, this is actually not about the project itself, but it's about a website that I'd like to mention. So, how do you find these kind of beautiful uh illustrations? So there's a free website called storieset. com uh which is something that I'm using for my personal projects and even some of my tutorials. So you can search for something like not found or even 404. I think I searched for 404 previously to be able to get this image which is this one. So you can use any of them. This is the one that I'll be using with. And if you want to change the color, all you have to do just go ahead visit here and you can even put your own color as well. Okay. So I'll just refresh and get this default image. Now I already have installed it. So I would like to copy and paste from my file. Okay. So it is this image. Once you have installed it, just put it under the um under this folder. We will not have any JavaScript. I'd like to delete that file. and let's get started with the UI. Okay, let's say this is our custom 404 page. Let's try to link our CSS file which is this one. And then we can get started with the markup. That will be really simple. So let's put them side by side. Okay. So I'll just Here we can see we have an image, then H1, P tag, and then a link. So, let's try to type this out. I'll have the image, which is going to be the 404. png. Let's add an alt like 404 illustration. I think I have a typo, but let's say illustration. And then we'll have the H1. Let's say oops, page not found. And I'd like to add this emoji just to make it a little bit more fun. and then I'll put the P tag. Let's try to copy and paste this value. And then finally, we'll have a link. Now, this will not take us to any other pages because we don't really have it. I'll leave the href empty. And let's say back to home. Okay. So, that's going to be for the markup. Let's say open this up with the live server. Okay. Now let's try to add the CSS file. So I will get the base styles. Let's say margin of zero and then the padding of zero as well. Box sizing will be border box. Then we can get the body element. Let's say the background color will be 1 one one. So it is kind of like a dark color. So it's not completely black like 0 but it's a bit different. And then we'll get a color. Let's say it'll be white. Then we can say display will be flex. But now everything should be side by side. Let's see. So everything is side by side. But we want them to be in the vertical direction. So I'll say flight direction is going to be column. And then we can say justify content will be centered. Same for the align items. height could be let's say height will be 100 VH okay so I just said height is going to be 100 VH and phone family could be sense serif then let's select the image and try to update the width to be 100% and then the maximum width could be 550 pixels okay so now it's looking a lot more cleaner right I'll say margin bottom will be 1. 5 5mm and then we can get the H1 let's say font size will be 2M and then margin bottom could be one just like this and then I'll get the P tag let's say font size is going to be updated the color could be this gray color and then finally the margin bottom let's say 2 RM let's update the length So I'll say background color is going to be this green value which is hash 3 EC F8E. And then we can update the color itself. Then let's say text decoration is going to be none. Let's save. It's been updated. Let's try to add some paddings. Let's say 0. 75mm to double it. Okay. Let's say border radius will be 8 pixels. Font weight could be bold. And let's try to add some transition on the background color. I'll say 0. 3 seconds. Let's say a on the hover state. We can update it. So I'll say background color will be equal to this value which is 04. Let's say FC8D. Okay. Now let's save. This is what we have. We can make this a little bit more responsive. Let's put them side by side. I'll add a media query. Let's say media max- width is going to be 600 pixels. So below uh 600 pixels and below we would like to implement these styles. Let's say max width could be 400 pixels on the image. H1 could be font size of 1. 5 RM and then the P tag could be font size of 0. 9 RM. Okay, so once we hit 600 pixels, the UI will be updated. Okay. So with that that's going to it for this project as well where we have learned about this website called story set so that you can get free illustrations with a different bunch of different options. Okay. So I hope you enjoyed it. Okay. So in this section let's
Project 16: Newsletter Signup UI
one. Okay. So in this section let's build this newsletter signup UI which is something really popular and common. I'm sure you have seen one of those where you put your email and submit it. then weekly you would get some tips or whatever the content is, right? And you can find the diagrams in the description. So for these icons, I would like to use the font awesome. So I'll head over to CDNJS and search for font awesome and then get the very first link and then we'll get started with the UI. So I have an empty folder with two different files which is the HTML as well as the style. css. CSS. This does not contain any JavaScript at all. Okay. So, let's try to put them side by side. This is the end result and this is the one that we're going to be building now. Okay. So, let's just say H1. Hey, save. We got the output. So let's say newsletter app or you know let's say UI and then I'll put the link of my style. css file as well as the font awesome link that I have just copied. Okay. So before we build the CSS file, let's first get started with the markup. So here the first thing we'd like to do is the signup container, right? We would like to create this one and then I will create the icon container as well which is going to take the icon of envelope. So I'll say f a r f a envelope dash open. It is that icon that we have and then I'll put the h2. This is going to be the content I'd like to copy and paste. And then let's get the p tag as well which is the description. Okay. Then right after this signup container, sorry, within this container, we will create a form. We don't really need any actions. So let's delete it. Within this form, we can create the div element. Class will be input dash group. And then within this div, we can create this icon. Let's say class name is going to be fa- envelope. but not open. And then next to it, we can put an input that is a type of email. Okay, we don't really need a name or ID. So let's try to delete them. Let's say this will be required. And then the placeholder could be enter your email. Okay, so that's going to be for this div. And then right after this, we'll add a button which is going to say subscribe. And we can put the icon. So I'll say put the I element f a s f a d- arrow dash right. So that's the content. Right after the form we can put the benefits. So say dot benefits and then we'll put two different p tags. Let's say they will take the class name of benefit dash item and then as content it'll take the I element fasa dash check right next to it we can put this text that says weekly coding tips and let's try to replace this and I'll say fa check but the content is going to be this one okay so I just copied and paste it here we go this is the output that we have at the moment. Now let's jump into the CSS file and get started with it. So as always I will add my reset at the very top and then I would like to get my CSS variables. So for this once again I have prepared the GitHub chest under the newsletter signup. md. So go ahead get these colors. We'll be using them. So now we can select the body element. Let's say body where we would like to update couple of different things. So I'll say font family will be sense serif. The background color could be the bg color that we have and then height 100ph display will be flex justify content would be centered align item centered and then finally the color is going to be text primary. Okay. Now we can get the signup container here. We would like to say background color will be updated to be equal to container dashbg. And then we'll give some paddings from all directions. Let's say 2. 5 rm. And then let's say border radius could be 16 pixels or you can just say 1m. And then we can say box shadow will be updated. So I'd like to provide this 0 to 10 pixels 30 pixels and then the shadow color that we have and then I'll say text align would be centered. Let's save. This is the output. Let's say maximum width is going to be 400 pixels and the 90%. Okay. Then we can say border will be one pixel solid and then the border color. Then we can get started with the icon container itself. I'll say margin bottom will be 1. 5 RM. So that is just pushed the content is pushed down. We'll say font size will be 2. 5 RM. And then the color is going to be primary color that we have. So we'll say primary color. Go ahead get that value. Let's update the H2. that will be margin bottom of 0. 75 RM can give the color that will be text primary and then we'll update the font weight as well as the font size let's get the P tag itself let's say font size is going to be 0. 95 RM and then we can get the color that will be text secondary let's say line height will be 1. 5 so it is a bit more space out margin bottom could be updated as well to be let's say 1. 5 RM and then we can get the input group itself say get this class so first I'll say margin bottom will be 1. 5 RM or let's go with 1 RM itself and then I'd like to say position will be relative because I will position this icon absolutely within this input group. Okay. So, I'll say input group get the icon. Let's say position will be equal to absolute. Let's say from the left it'll be 12 pixels. From the top, we'll say 50%. And to be able to center this correctly, we'll say transform translate Y of minus 50%. And let's update the color to be text secondary. Okay, now it's been updated. But we would like to take the input and just say width is going to be 100%. So it is taking the entire space just like this. And we'll give a bit of petting. We'll say petting will be 0. 85 RM from all directions. But we will update the very last one which is the left. I'll say 2. 5 RM. Okay. Then we can get the background color and update it to be input bg and then get rid of the border or even update it. I'll say one pixel solid and get the border color itself. And then I'd like to update the color that will be text primary and then font size to be 1 RM. And let's give the transition on everything 0. 3 seconds and ease. And then we can get the focus state. So say input once it is focused, we would like to update something which will be the let's say outline is going to be none. The border color could be updated. Let's say it'll be primary color. And then I'll say box shadow. Instead of typing this out, I'll just provide. Okay. Okay, it'll be equal to this value. So that when you focus like this is how that would look like. And I think I forgot to add some border radiuses. So say border radius will be 8 pixels. So that it is looking a lot more cleaner. And then how do you update the placeholder itself? So you can say input and get the placeholder element. Let's update the color. I'll say text secondary and opacity could be 0. 7. Okay. So here we can see it's been updated. So if you say red, this will be the output. Okay. Now let's select the button itself. I'll say get the button where we can say the width is going to be 100%. It is taking the entire space. And then I'll say padding will be 0 uh let's say 85 RM. And then we can give the background color to be primary one. It's been updated. Let's say color could be black. And then we can say font size of 1 RM, font weight 500. I'll say no borders at all. Um let's say border radius to be 8 pixels. Cursor could be updated to be a pointer. And then let's say display of flex so that these are side by side. But we also want to give some spacing. So let me save. Okay. I'll say justify content will be centered. And then let's say align item centered. And then finally let's say gap of something like 10 pixels or maybe eight pixels. Okay, I think it's a subtle change but it is looking a lot more cleaner. Then I'll say add the transition on background color with 0. 3 seconds and let's use the ease function. And then on hover state on the button we can say background color will be updated. You can use any of these. Um I'll just use this one. Let's see. Okay. So it is the exact same color. So instead let's use something like a66 AEN9. Okay. So this is kind of like the dark color. If you wanted to you can create this as a let's say as a CSS variable. But I'll just leave it as hard-coded value. And then we can say transform will be translate of Y minus 2 pixels. So when you hover over that, it'll just go up. And let's say this will be added on everything. Now this is happening smoothly. Now I will select this icon within the button. So I'll say button get the I element. I'll say font size is going to be 0. 9 RM. And let's say the transition will be on transform 0. 3 seconds in ease because when we hover over that let's say button once button is hovered we will take the I element and we'll say transform translate x of 3 pixels. So when you hover over this icon will be pushed to the right by 3 pixels and then we can get the benefits. Let's say margin top could be 1. 5 RM and then we can say text align is going to be equal to left so that they are pushed to the left. I'll say border top is going to be updated. Let's say it'll be one pixel solid. The border color itself. Here we go. Then we can say padding top could be 1. 5 RM. Then we can get the benefit item itself. I'll say display flex items centered gap of 8 pixels and I'll say margin bottom of 0. 5 RM. Let's update the font size itself to be 0. 9 RM. Okay. So this is the output. Now we can update the color on these icons. I'll say benefit item. get the I element say color will be equal to variable of secondary color and font size can be 0. 8 8 RM. Okay. Finally, I'll just add a media query. Let's say media max width 500 pixels and below we can update the signup containers heading values. So I'll say 2 RM to 1. 5 RM. Okay, let's try to hit that drag point. So we are at 500 pixels. It is a subtle change but I think it is looking a lot more cleaner. All right. So in this
Project 17: "Coming Soon" Page with Countdown Timer
section we're going to build this nicel lookinging coming soon UI. So we have a logo, one badge title and description. Then we have the countdown which is updating every single second. Then we have an input where we can put our email. Let's say we would like to be in the weight list. I'll say notify me. We have the loading spinner and then the success message. It says you're on the list. We are going to notify you when you launch. And then we have some social links that is nicely animated. And this is completely responsive. As you can tell, it is working in the larger screens and smaller screens. As usual, you can get these diagrams in the description. I'm going to include the link for completely free. Okay. So, with this in mind, now let's go into VS Code. As usual, I have an empty folder, right? You can call this anything. I just open this up in VS Code and then we are going to create three different files. So the index. html style. css and we are going to need a bit of JavaScript. So I will have script js file. So as usual we're going to get started with the index. html file. I will get the like quick snippet. Let's add a title something like coming soon UI. And then I'm going to link my CSS file. So I'll say link CSS which is the style CSS file. And then we can also link our JavaScript file. So normally we would go at the like just above the body. We would say script source and add the script. js file. Now this is completely fine but there is a better option. So you would cut this from here and put it under the head. Then you would add the defer attribute. So this is a better practice right this is the modern practice and it makes loading script. js faster than you know putting it here without the defer attribute. Okay so keep this in mind. Now I would like to import two more things. The first one is a you know a font and I'm assuming that you have this extension called Google fonts. Okay. If you don't have it go ahead and install it. It's free. Um here we will put commandshiftp or control shiftp then type google fonts insert link. Okay go into an empty line and type this out. Then you're going to get this kind of like drop down and you can type space grotesque and this is the phone family that we're going to be using. Once you press it's going to import that phone family. Very convenient. And one more thing, we're going to be using some icons in this project, right? So, we have this one, that one, and like these social icons. For this, we can visit cdnjs, and we're going to get the font awesome link. So, I just refreshed. Now, I'm going to type this again. Font awesome. Go ahead, get the link, and then paste it right here. So, maybe I will put it right after the style. CSS. And let's take this, put it above the script. js. JS. So this is a bit more organized. We have our CSS imports and then the JavaScript import. Okay. So with this now we can go ahead and get started with the markup. So the first thing that I'm going to build is these kind of like blobs, right? So as you can tell it is animated. Like just take a look at it closely. It moves to the left and to the right. Same for this blue one and that pink one. Right. Okay. So, let me actually first run this with the live server, right? We don't have anything. Let's put them side by side. Okay. So, under the body, I'll just add a comment. Let's say animated background. And within this, we're going to have a bg class. Then, three different blobs, right? So, I'll say blob, and this is going to be blob dash one. And again one blob is basically one of these right blob another one and then the third one. So I will duplicate it. Let's say second one and the third one. They are not going to have any content. We're going to build it with CSS. Okay. So that was the animated background. Now we're going to have the main content. And for this I will have a main element. This will get the class name of let's say container. Within this we're going to have our logo. So I will have the logo class on the div. Then I will have logo dash icon. Let's say icon. Within this we are going to have the I element which is going to hold the you know um the logo and we'll say fa solid and fa it should be bold which is this icon that you can see. Okay I I'll just zoom in. This is the bold icon coming from font awesome. And then right next to it, we're going to put the name. So go right after this logo icon div, we're going to have a span. I will just say flux. You can call this anything, but that's the name that I'll be using. So right after the logo, we're going to have a section. Let's say class name is going to be hero. And within this we're going to have a batch which is this one. So this is the batch. We are going to have the pulse animation as you can tell. And then we're going to have the text that says coming soon. So within the batch I will have a span with the class name of pulse. It's not going to have any content. Um we will say coming soon. And then right after this step I will have H1 which will say something like something awesome is brewing. And notice how this is outside of the batch right still within the hero but outside of the batch. And then we're going to have a P tag. Let me provide this. So it's basically this text as you can tell. Okay. So that was the hero section. Now let's go below. We're going to have the countdown section as well. We'll have section element. Let me give the class name. Within this section, we're going to have a div. Let's say class name of time dash block. And let me again show you. So every single one of these rectangles is a time block. Okay. So this is time block separator. and so on. Within the time block, we're going to have a let's say value and then the label. Okay, so let's go within this time block. I will say we're going to have a span with the class name being time dash value. Duplicate it. We're going to have time label for now. Let's say this will be days and this is going to be something like0. And I'll give an ID for this. Let's say it's equal to days. Save this. Right after this time block, we are going to have a separator. So I will say span and it's going to get this class called separator. And for the content we're going to put colon. Okay. Now we can copy this and basically paste this in. This time it's going to be let's see hours then minutes. Okay. So we're going to get the hours. Let's type this in. I'm going to select both of them with Ctrl D and I'll say ours. And then once again we're going to put a separator. So now we can copy this paste this once again right um this is going to be this time minutes let's say and let's do it once again finally it's going to be seconds. Okay, so let's take a look at the end result. This is what we have at the moment, but of course we are going to update it with CSS. So that was the countdown section. Let's go ahead and shrink this. And then next we're going to have the email form. So I will have a form element. We don't really need any actions. Um I will have the class name called email dash form and we're going to have one id again let's say email dash form. So we're going to be using this for styling and this to be able to select element with the javascript. Then I will have a div. Let's say this will be class name of input dash group. And within this we're going to have one icon. Let me show you it is this one. Right? And then we're going to have the input itself. So I will get the I element. Let's say FA- solid FA- envelope. And right after the I element, we're going to have input type will be email. Let's say it's going to be required. You can add a placeholder something like enter your email. Okay. So I think that's entire form. But we need to add a button as well. Right after the input group, just say a button. Type could be submit. And for the text, we're going to say notify me. And I will have one more icon. Let's say class name FA solid. And it's going to be FA arrow, right? Which is this one, as you can tell. Then at the very end, we're going to put three social links. So go outside of the form and we are going to add let's say social links I will have a div let's say class name of socials and then I will have one a element let's say href you can put your own you know social media uh but I will leave as an empty link and I'll say class name could be sorry we're not going to have any class names Right within the a tag element, I will say get an icon. And this is going to get the class name. Let's say FA- brands. And we're going to have FAX Twitter, right? So, um, go ahead and save this. Then we're going to duplicate it twice. This time it's going to be, I think, Instagram. And then this is going to be, let's say, Discord. So I think that's the entire UI but we are just missing one element which is the success message right we didn't add this UI so let's go ahead add that one as well but initially we are going to hide it right once user submits and then only then we're going to display it so go above the social links right let me say social links just above that I will have the success message like this. Um here dash message class as well as hidden. Okay, so by default it would be hidden. Let's say id would be equal to success. And as for the content, we are going to have one icon which is a check circle. And then here is the text that you can pause the video and type out. Okay, so that's the entire markup. You can take a look at it. We got the icons, we have the input elements, everything. But of course, we don't have any styling. So, let's try to build it step by step. I'm going to put it side by side with VS Code. Okay. So, they are side by side. Now, it's time to jump into the style. CSS and build the entire styling. Once we are done with it, we will get into the JavaScript file. All right. So, first off, I will have some CSS variables. I will grab them from the source code. You can do the same thing if you don't want to type this out. Just go ahead find this folder under the source code and find the style. CSS then get this value. Now here as usual we're going to add our resets. So let's say select everything margin of zero heading of zero and box sizing will be equal to let's say border box. And we have already explained what this does in the past. So I'm just going to move on. Then we're going to get the body element. Let's select it. I will be using the phone family that we just imported. So I will say space rotesque. That was the name. And we can add a fallback value as well right next to it. Then for the background, let's say we're going to have this bg color. Then for the text color, we'll be using let's say variable called text, which is the white color, right? Then we can say minimum height is going to be 100 VH. So it'll take the entire screen. Let's say display flex align item centered and just apply content centered as well. This will take everything and put it in the middle of the screen. Right? So it is centered nicely. And then finally I will say overflow should be equal to let's say hidden. Okay. So that's the entire styling for the body element. Let's scroll to the bottom. I will get the bg and I'll say something like position of absolute I will say insert of let's say insert of zero and zindex is going to be let's say minus one. Now, if you save, you're not going to see any change. Here, I'll add a comment. I'll say explain this later so that I don't forget about it. And let me even say like to-do later in the video. You're going to see what this does, but unfortunately not now. Let's try to build the rest of the UI. This is going to make sense. Um, I will display it. Now, here I will select the blob class and we will say position is going to be equal to absolute. We would like to have this as a circle. So I will say border radius is going to be 50%. Then we will say something like filter of blur let's say 80 pixels. Um then I will have the opacity let's say 0. 6. And then the animation. So I will call this as float. And we will create it in a second. Let's say it's going to take around 15 seconds. Let's say ease in and out. And then I will say infinite. So it's going to be infinitely animated. And now we can select the blob one. Let's say blob dash one, which will be basically this one. Okay. So I believe that's the blob one. Then we have two and then three, right? Okay. So, we're going to get this one and let's put it side by side. Let's say this is going to get width of 500 pixels. Same for the height. And then this is going to get a background color. So, I'll say background. Just make sure to select background, not the background color. Okay? Because we're going to be using the linear gradient method. And then this is going to take 135°. It's going to go from this color to that one. So here is the first value. It'll be let's say 6 3 66 F1. Then this is going to be 8 B 5 C F6. Okay. So as you can tell it is already here. And if you delete the you know filter of blur you can see that this is just a circle. If you delete this it would be a rectangular or a square because they are the same values. And if you delete this one, it would be a bit more shining. So these are all the styles that you can always pause the video and delete them one by one to see the effect. Right now I would like to position this to the top like a little bit more. Right? So here I will say top will be equal to let's say minus 15%. And then I'll say left should be equal to minus 10%. And finally I'll say this is not going to have any animation delay. So we can just say 0 seconds. But I think if it is equal to zero you can just delete it completely. Okay. Now as you can tell it is a bit more pushed to the left and top. So top left. So that's the blob one. Now in the same way I will get the blob two and three. So I'll paste this in. I would say go ahead and get this from the source code. This is the exact same thing but we put the you know bottom right of 10 right it is right here. And then I add some animation delay like minus 7 seconds. And then let's do the same thing for blob three. Go ahead paste this in. As you can tell, these are only three blobs. But now they are not animated, right? Because we don't have this animation called float. So we need to create this. So just scroll to the bottom. We will have the key frames. The name is going to be equal to float. This is how we call it. And we're going to have a couple of different states. So at the beginning, which is 0% and at the end, which is 100%, we would like to have these styles. So we're going to say transform translate of zero and zero which is the initial position right and we'll say scale will be equal to one but in the middle like 33% we're going to do something and else on the 66% as well. Here I will duplicate this and here for the values let's delete them. This will be 50 pixels and minus 50 pixels. Scale could be something like 1. 1. Let's duplicate it. Put it here. This time it would be 0. 9. And for the values I will say 30 pixels to minus 30 pixels. Okay, let's save. Now hopefully they should be animated like as you can tell. And I will even delete the blur so that we can see it clearly. So I'm going to comment this. Like as you can tell they're like scaling down, scaling up, moving to the right, to the left. And I think it looks pretty clean. And you can add the filter so that it's like even better. All right. Now you might be asking, hey, we have some animation delays. I get it. But why is it minus? Right? Shouldn't it be like shouldn't it be something like 7 seconds instead of minus? Now that's a very good question and I have some comments that explain this right. So I'll paste it right here. Okay, let me maximize the screen. So animation delay can be positive or negative, right? And they do different things. So here in this example, let's say we have positive 2 seconds. What this does, this is going to wait 2 seconds and then start the animation, right? But if you have something like - 10 or - 7, it's going to start immediately but 7 seconds into the animation. So if you have a 20 second animation in total, like in our case, we have 15. And if the animation delay is minus 7, animation starts right away, but it begins at the 7second mark, right? It skips the first 7 seconds. So if you don't add these delays, they will all start from the same position. So let's actually delete them. And I will delete the blur as well. Like I'll refresh. As you can tell, they all do the same movement, right? They go to the right, they come back, they scale down. But if we add the delays, so I'm going to add the delay. I'm just doing Ctrl + Z. You don't have to do it. I will delete the blur so that we can see it. Now, if you refresh, like as you can tell, this is already into the animation. And this one as well, like they're doing different things. So, I think this looks a bit more cleaner. That's why we do in that way. Okay. Now I'll bring them back and leave this comment for your reference. Okay, so that was the key frame. I hope it wasn't that confusing. We're going to get a container element. I will say display flex. We're going to say justify content centered align items centered as well. Let me put them side by side. Okay, once I save everything should be side by side. And here I will say maximum width is going to be 650 pixels and let's say 100%. But I think that's not the behavior that we would like to have, right? We don't want everything to be side by side. So I did a mistake. I will delete them. We don't really need it under the container. Instead, like let's save. I will say instead text align would be centered right and then I think I'll just say let's give some paddings like two RM from all directions so that it's not really like stick sticky to the screen. Okay, that was the container. Now let's get our logo. I will say display flex so that these two are side by side logo and then the text. So they are side by side. Now let's say justify content centered align item centered as well. Then I'll give some gap between them. Let's say 0. 75 RM. And then I'll say something like margin bottom of 3 RM. Okay. Now we will select the logo dash icon and I will go inside. Now this is going to get width of 48 pixels. It's going to get the same height as well. Now I will say border radius should be 14 pixels and we would like to give a background. So I'll say background will be linear gradient. We're going to have this degree and we're going to get two different values. Let's say variable we're going to use the d- accent from this color to that one which is you know accent light. Okay. So we can see the background. Now I would like to center this icon. I'll say display flex align item centered and justify content centered as well. Now icon is in the middle of the container. And finally we can say font size could be something like 125 RM. Okay. So that was the logo icon. Now let's select the span within the logo itself. I will say font size could be something like 2M and I will say text transform is going to be uppercase. So it's like uppercase and we'll say letter spacing could be 0. 1 you could use or em right in this like in this case let's use em and then I think I'll say font weight should be 700 so it is a bit more bold um then we can go here select the hero element this will just have margin bottom of 3mm so that we have some extra space then we can select the batch which is this coming soon text. So I will say get the badge and add some classes. Let's say display inline flex. Right after this I will say align items should be centered gap of 0. 5 RM. Then I will have background. Let me grab this value. Okay. So you can pause the video, type this out. Let's do the same thing for the border. and I will get some paddings. Okay, so that's the background color and then the border color. Now I will say border radius will be 100 pixels. So we can you know make this circle as much as possible. And then I will get let me paste this in. We're going to have font size, font weight, a different color, and then the margin bottom of 1. 5 RM. Now you might be asking why do we use inline flex instead of flex. So go ahead and type this out. You're going to see that flex is taking the entire space. But inline flex is like only take the space that you need, right? Don't try to you know like row only take whatever you need. So that's why we are using inline flex. And then we would like to get this kind of like pulse element. Let's try to see how we can build it. First I'll select the pulse class. This is going to get some width and height. Let's say 8 pixels. Height of 8 pixels as well. We're going to say border radius to be 50% so that it is like a circle. And then we'll say background um yeah background is going to be equal to accent white and some animation. Right? I'll say animation. It will be the pulse. It's going to take 2 seconds. And then we're going to say e is in out and in infinite. Now let's build the key frame which is equal to pulse. We are going to have the initial state which is 0%. At the end 100% and also in the middle we're going to do something. So let's say 50%. So at the start and at the end it's going to have the box shadow of basically nothing. So we'll say 0 0 and variable is going to be the glow color. But here in the middle we're going to say just duplicate this value here. It should have 10 pixels. Now as soon as you save this you're going to see the end result. But here is the thing. Instead of having this color at the end this should be equal to transparent so that it would be like invisible at the end. Right? So in the middle like it is invisible. If you put this value back, you're going to see that it just grows and shrinks without ever disappearing. So that's why we're going to say transparent. Okay. So that's the pulse animation. Now we can select the H1 and add some stylings. So this is like very simple. That's why I would like to copy and paste and walk you through it line by line. Okay. So we have H1 selector. We use phone size with the clamp method. So this basically says it cannot get smaller than 2M. This is the preferred size and phone size cannot get larger than this value. So this is going to make it responsive. Here you can see if we got a larger screen this is larger but it never gets larger than 3. 5 RM. And normally it is like six V port right? This is what we have. And at minimum it could be two area, right? It cannot go lower than this value. So we have the funk weight. It's a bit bolder. We have line height, letter spacing, and margin bottom. Super easy classes or styling. That's why I don't want to type this out so that we don't waste any time. Right? Then we're going to get the P element. We basically want to update the color. Okay. So we have a different font size, a different color, line height, maximum width and margin of zero and auto so that it is centered. So at maximum it can get 450 pixels otherwise it would be taking the entire space right and you can always like delete them and see what that does. So I don't want this to be this large. That's why I add this class or this styling and it is a bit shrinkedked. Okay. Now let's try to get the countdown and try to put them side by side. You already know what to do. We will use display flex, right? I will basically copy it. Let me paste this in. So we have countdown selector. We will say display flex justify content centered. you know, align items, gap of one, and some margin from the bottom. And within the countdown, we can get the time block element. And I just realized at the very end, we have an extra separator. So, I'm going to go ahead select that from this file and delete it. So, we don't really need this last separator. Okay. So within the time block we are going to have the background color. Let me get this. It has this RGBA value. We're going to add a border color as well. Then we will have some border radiuses. Maybe some paddings. Let's save. Okay. So that's the end result. I will say minimum width could be 90 pixels. And then I will add some blur. Right. So we'll say backdrop filter blur of 10 pixels. Then we can select the time value. Now again I will provide this to you because it's like nothing complicated at this point and you can always grab this just like what I do from source code or if you want to type this out pause the video and you know do so try to put them in this way. Okay. So we say display block which is you know for this element time value we have font size it is a bit larger than usual font weight line height some margin bottom and then the background color right so we go from this color to that one which is from text to accent light now if you don't add these let's see what's going to happen this background is under the text but what we want to do is basically like clip it with the text, right? We don't really want to see this as background, but instead on the text. So that's why we add these props and it just works. Okay, so this is something that you don't need to memorize. You can always Google this, but just know that something like this existed. And so yeah, that's the time value props or the styles. Now, we would like to select the label, which is this one. And we would like to do four different things. I will grab it from the source code. We have a different font size, color, text transform to uppercase, and then some letter spacing of 0. 1. Then we can select the separator and make it a bit larger. Right. So I will get that. As you can tell, this is looking a bit more cleaner. Um, just like what we have here. Okay. Now let's go at the very end. Right. We would like to update the email form. So I will select it. Let's say display of flex so that they are side by side. And then we will say gap of 0 65 RM or 75 RM. And then we'll get maximum width of 450 pixels. Now let's try to center this with margin zero and auto. So as you already know this is the vertical value. We don't really want to add any vertical margins but from the horizontal direction we will say auto so that it is centered. Now we are going to get let's say the input group element and I think I'll just provide this right. I'll paste this in which is the input group element the parent element that contains you know both the icon as well as the input. Now we say flex of one so that it is taking the entire space. If you delete that they would be like almost the same size. Okay. So we have display flex align items would be centered. We have some gap between them, a different background color, a border color, right? Border radius padding and we have the transition. Now, right after the input group, we can select the focus state. So, if you focus this, what happens? I will say input group and we're going to say focus within. So, here basically we would like to update the border color. It's going to be this variable called accent. And notice how it's going to update the uh you know the border color. And also I will say add some box shadow. It's going to be three pole zeros 3 pixels and then the value let's say rgba. Um here I think I'll just provide this instead of typing this out. I'm too lazy to do so. Okay. So once we are in the focus as you can tell it has this small box shadow. I don't know if it is visible from the video but I can definitely see it live here with my own eyes. Okay. So that was the focus with an state. Now we can select the icon. Okay. And update the color. As you can tell it is text them. Then we're going to get the input element. It looks very ugly now. We would like to update it. So we are going to add deflex of one so that it is taking the entire space. Background will be transparent. We don't really want to have this white color right. Then we have border of none. Petting um some font like font family would be inherit. If you delete this like it's different right? So we're going to say just inherit this from the body element. Then we have font size color and outline of none. If you look like this, like as you can tell, it has this outline on the focus state, but we don't really want to have it. So, we're going to say get rid of the outline. And we can update the placeholder color as well. This is how you would do it. You would say input, select the placeholder, and update the color here. Let's say something like red. As you can tell, it's been updated, right? Okay. Now, what else are we missing? It's the button. Let me grab this. Like it's super easy. That's why I copy and paste. I hope you don't mind it. So these are all the things that we have already learned, right? So we say display flex so that these are side by side. If you delete this like would they be side by side? I think they're already side by side but we say flex so that we can align them. Then we have some gap between them. Let's say if we had five like the gap is huge. Then we have the background color going from accent to this one. No borders, some paddings, border radiuses and you can see the rest like nothing is complicated at this point. And now let's select the hover state. Whenever we hover over it, something should happen, right? So I will say button hover state. We would like to, you know, just take this a little bit above. And this is how we do it. Translate Y with minus 2 pixels. If you want this to be go down, you would say 2 pixels. And we also add this glow with the box shadow. Then I will select the let me actually copy this. Paste this in. Instead of button this time, we will say the eye element which is this icon. Right? In this case, what do we want to do? Let's say transition. It's going to be transform and we'll say 0. 2 seconds in ease. And here I will say email form. We'll say button. When we are on the hover state on the button, we want to select the icon and do something with it. So we'll say transform translate X or pixels. So now when you hover over this as you can tell icon also goes to the right hand side right. So this is how we do it. We say email form where we have the button once we hover over it. Select the icon and add this transition. All right. So that's it. Now let's try to update the success message. I will go ahead select it. We're going to say you know display flex align items would be centered justify centered some backgrounds. Um I think like I have a typo here. Success message. It should be with double s. So I was wondering why it did not work because this was not matching. Okay. So we have like a background color, a different border color and you can see the rest. Nothing complicated. Now we would like to select the icon, right? So I will say success message. Select the icon and update the phone size. The other thing that I would like to do is adding an animation. So I will say animation. The name will be fade in. You can call this anything but this is the name that I'll be going with. It's going to take 0. 4 seconds. And let's say ease. And let's try to get that key frame. So I'll say key frames. This is the name called fade in. We'll say from let's say opacity of zero to let's say transform translate Y of minus 10 pixels. We're going to say two. And as you can imagine opacity is going to be one and this would be the initial state. So it's going to be 0 pixels. Let's save. Like as you can tell let me see when we refresh it is like nicely animated. If you make this like 100 pixels, it would be coming from even like more above. And if you want this to be coming from the bottom, you would say plus 100 pixels, right? Let's try to refresh. As you can tell, like this is how that work. Let me explain. Let's say we have an element, right? This is the initial state which is like let's say 0 pixels. Okay. If you say something like minus 10 pixels, it would be here, right? it would be above. But if you say like plus p plus 10 pixels, it would be 10 pixels below. And what we have done is this. We say it should start, let me bring this back. We say it should start from minus 10 pixels and it should come back to the initial state. So that's why it is animated from here to down here. So I hope that makes sense. Just always remember top is minus, okay? And bottom is plus. And if you're doing horizontally, let me just put it in this way. Let's say we have zero pixels. This part would be plus and here would be minus. Okay. So let's try to delete this and go back to VS Code. Put them side by side. So now we're going to build the socials. Right? This is exactly what we have done. Um right after the success message icon selector I will get the socials we say display flex so that they are side by side we say justify content to be centered so that it is in the middle of the screen right if you bring this back it's been centered we have some gap and margin top of 2mm for some reason I cannot see my icons let me refresh okay now we have the icons and we select the A element element, right? We have some width and height. If you delete it, you cannot see that. So, we're going to bring this back. We have the background color. Let me refresh. We have a background color, a border, you know, it is circle, so border radius. The rest is super easy. Now, let's add the hover state. What do we want to do is basically, you know, animate them to uh, you know, in the up direction. So, we're going to use a translate Y with the minus value like I need to refresh. Okay, as you can tell, this is nicely animated. And as you can tell, we have some, you know, like a line at the bottom. To be able to get rid of this, I think we should visit the link element, which is a tag. And we would say something like text. Um, was it transform? Not really. Was it decoration? Yeah. Um I think it is like underlined by default but I'll just say none. Now it is gone. So in the demo application I have this but I think it doesn't look clean. So I will try to get rid of it by saying text decoration is equal to none. The other thing that I want to add is a bit margin for the success message. Let's try to find it. Um here we say like maybe this should be 1 RM. Okay, this looks a bit more cleaner. And let's scroll to the bottom. By default, we don't really want to see this. So, we had the hidden class. We're going to say display of none. Okay, now it is not visible. But once we submit it from the JavaScript, we're going to make it to be visible. So, I believe that's the entire classes, right? The entire styling. We just want to make this responsive. And here this is something that I'll copy and paste. Super easy. I'll walk you through it. So we will say media maximum width 600 pixels. Right? So 600 pixels and below we are going to have different padding for the container. We will update the logo countdown time block. You can get these values from the source code like super easy. Nothing complicated. And now this should be responsive as you can tell. So these are all the styling. Now we will jump into the JavaScript file and build the logic. So the very first thing that we need is a launch date, right? Is it 4 days later, 10 days or is it already passed? Right? How do we know? Let me maximize entire screen and type this out. So first off I'll say con launch date and this will be equal to new date and here this will take a couple of different values. So I would like to make my launch date to be let's say 1st let's say January 1st 2026 and let's say at 12 p. m. right in the afternoon. Okay. So here's how we can do it. First off we're going to pass the year and then the month. Now you might think, okay, we're going to pass one because January is the first month, but not really. This is zero indexed. Okay, so here maybe I can type this out. I will say here's a quick note for you. Month is zero indexed. So that means 0 is equal to January and 11 is equal to December. Okay. So just keep that in mind and I will format this. Okay. So this is going to be zero and the day is one, right? So we'll say 1st of January and you know the hour which is 12 and then the minutes I believe. So here I will put another comment. Let me actually paste this in. Okay. So first off you put the year right? We put 2026 month is January. It is zero indexed. We put the day which is the first of the month. Um we put the hour and minute. So that's the launch date. Now we need to get some DOM elements. Okay. So I will get the days element and we'll say qu uh sorry document do query. Okay. What am I doing? I'll just say get element by id. So if you remember in index. html under the time let's find it. So we have things like ID for days, hours, minutes and seconds. So we're going to select them one by one. We're going to get the days element. Let's say this will be equal to hours. And actually if you don't want to type this out, I have prepared the GitHub just you can find it in the description. Find the coming soon UI. md. You can do Ctrl+ F and find it. Then copy everything that you see here. So these are the DOM elements, right? I will paste this in. We got the days, hours, minutes, seconds, and then we have the email form as well as the success message. So this is how we select all of them. Then we will create a method. Let's say function update countdown. Let's say countdown maybe like this. Okay. So this is a method that we need to call every single second, right? As you can tell it just updates after each second. Here we will go ahead and say first off let's call it. This is the initial call. And then we will set an interval. So we're going to say call this method in every single second. Right? We're going to put 1,00 milliseconds. So here I'll say initialize the call and then update every second. And now the question is what are we going to do within this method? Well, first off we need to get the difference. So I'll say now say new date. This will give you like exact time and then we'll say const the difference is equal to launch date minus now. Now if the difference is already less than zero that means we already get to this date right. So we're going to say if difference is less than or equal to zero. In this case we're just going to put zeros right. We're going to say 0 days 0 hours minutes and seconds. So here I will say something like days element text content will be equal to double zeros. Right? We're going to do the same thing for the hours, minutes and seconds element. Okay. And at the end we'll just say return don't do anything else. But if this is not the case then we have to calculate every single one of these items. Right? So here I'll say const base and this is going to include a bit of math. So let's say math the floor and we're going to call the depth you know the difference divided by in here we go 1,00 * 60 * 24. So that's the math behind it. It's not really that important for you to completely memorize it but just understand how that work. So this is basically 1 second you know we are going to multiply it by 60. So this is minute and then by 60 this is an hour and then 24 which is 24 days. Right? This is how we calculate the days. Then we're going to do the similar thing for hours, minutes and seconds. Now if you don't want to type this out once again you can grab it from the gist. I have prepared all of them. Just go ahead copy it and paste it here. You should be good to go. Now we got all these values. We would like to update it, right? We would like to update the UI and this is how we're going to be doing it. I will say days element text content will be whatever the days is. So this is basically a an integer, right? So let's say it's a value like four. We would like to convert it to be a string to be something like this. So we're going to wrap it with the string class and then we'll say pad start to and then we're going to pass zero. Now this means if we have only 4 days left we would like to add one zero at the beginning so that it can look like this right so this is basically what we do we always make sure that this is equal to two digits right um like we don't really want to see something like this let me show you okay like just imagine if we don't have the zero at the beginning right I don't need to show that so this is what we do we say at maximum it could be two elements and make sure to add zero if it is like if it is only one digit. But if it is something like let's say already 15 days, you don't need to add a zero at the beginning. So we do the exact same thing for hours, minutes, and seconds. Okay, this is an example. Just keep that in mind. And let's actually take a look at the end result. So today I'm recording this video at like December 27th of 2025, which means we have around 4 days, right? So let's take a look at the end result. This is our own UI here. You can see it's been updated. Now I will add maybe six more days on top of it. Let's say something like instead of one, let's say six or seven. Like as you can tell, it is getting updated. Let's say seven. Now this should be 10 days, right? If I go and do something like 2027 and first like this is going to be more than 365, right? So we have 369 20 hours. So you get the point. Now let's imagine if it is less than today. So let's say it was a year ago, it'll just be zero, right? Because we have this if check. Okay, so I hope that makes sense. Let's bring this back. Now that's the entire thing for the updating the countdown. Now on top of it, we would like to have this functionality. Once we click to it, we should update the UI. Currently, you know, let's put an email. Nothing happens. And actually there is something happening which is it refreshed the page right. So if you put something let's say. com when you say notify me it refresh the page and we don't want this to happen. So we will go here create an event listener. So say email form add event listener when we submit this right in this case we are going to have this method let's call it we're going to get the event. So we can say event default. This is going to let's say this will make sure to not reload the page. Right. And then we can get the button. So I'll say con button email form query selector. We're going to get the button element. And we'll say something like button inner HTML. And we are going to add a loading spinner. So I'm going to say get an I element. Let's open this up and close this off. This will get the class. Let's say FA- solid. Um here this should be maybe single quotes. Okay, this will also get FA spinner and also FA- spin. Okay, so this is going to give that spinner um icon. And then we can say button should be disabled because we are in the loading state. Let's say that's equal to true. And now I'd like to add some delay, right? I will say simulate an API call, right? So as if we have a back end and we are waiting for a response. So I will say set time out call this method after 1 second right and here basically we will say email form class list we're going to add the hidden so that would be you know we are going to remove the like the form let me actually show this I'll put something atgmail. com this is the end result we have the loading state and then form is gone But now we have the success message. So we're going to hide the form and I will duplicate this. This time it'll be success message. And we're going to remove the hidden class so that we can actually see the success message. Okay, let's save and take a look at the actual app. I'll put my name. Once we submit it, we're going to get the loading spinner for 1 second. And then this has been animated nicely. All right. So that was the entire project. I hope you enjoyed it. Just take a look at the codebase. The JavaScript part is not really confusing. 60 lines of code and like 10 lines of it where we just get the launch date and the DOM elements. Then we have some calculations. Don't worry if you cannot really keep this in mind. That's completely fine. This is something that you would get from Google or AI. Uh you know like it's not really that important. Just know how that work, right? How do we update the text content? What the pad start does uh in the first place and the rest is just syntax. You don't need to memorize any of them. Okay, so hopefully I'll see you in the next section. All right, so in this section, this is what we're going to build. We have a contact page UI
Project 18: Contact Page UI with Form Validations
design with a form and some information on the left hand side. Now, let's go ahead and fill this in. I'm going to put some hardcoded value. Let's say John do. put an email and we're going to select a subject. Let's say partnership. Put some messages, right? We can type anything and then go ahead send the message. We have the loading state and then maybe like 2 seconds later, we got the, you know, the feedback that is nicely animated. And if we wanted to, we can send another message. So this is one of the components that you would see on every single company's page. So in this section, we are going to learn how to build it, right? And as usual, you can get the diagrams with the link in the description. Now, let's jump into VS Code. Go ahead and create an empty folder. You can call this anything. This is the name that I came up with. Then, we are going to create three different files as usual. Let's say index. html style. css and script. js because we are going to need a bit of JavaScript for that logic. Okay, first off, let's build the markup. I will get my boilerplate code. Let's add a title something like coming soon UI and we can link our CSS file should be CSS. Then we're going to link um I think it should be script source the script file and we're going to add the defer so that it can load in parallel. Right? So this is one of the best practices that we have told in the past. Um, then I think we can get some fonts here. Right after the style. CSS, I will press command shiftp and I'll say Google fonts insert link. And the font family that I'll be using will be enter. Right? So I'm going to install that or import it. Then I would like to also get the font awesome as usual. Let's visit CDNJS. We're going to search for font awesome. copy the link and just paste this in. Okay, because we're going to need some icons. As you can tell, we're using a lot of them and they will be coming from also. Now, with this, let's say something like H1, hey, and run this with live server. Okay. Now, we're going to have the markup, right? So, we have basically two different panels, one on the left and one on the right. So let's try to build it. Under the body, I'm going to delete the H1. So I will have a main element with the class name of container. So we're going to have the left side. Let's say this is the info section. And then I will duplicate this. Let's say this is the form section and that's going to be the right side. So let's build this one first. I will say section and give a class name like info dash section and let's duplicate it. Put it right here. This is going to be let's say form dash section. And let's get started with this one first. So we're going to have a div with the info dashcontent. Within this we are going to have the span element with the badge class. And this is going to say contact, right? So this will say contact. Right after this fan, I will have H1. So we are building this part. Let me show you. We just built the badge. We're going to have the title and then a description. I'll just copy this. So paste it right here. That's the H1. Um I'm sorry. Like this is the H1 where we say let's work together. And then we're going to have a P tag. And that's the description. You can get it from the source code or just pause the video, type this in however you wish. So right after the P tag, we're going to have contact dash carts. And then cart, right? We're going to have this three different times. So I'm going to duplicate it. Or maybe let's just build the very first one. So contact card is going to have the card dash icon. And here this is going to be an i element. Let's say class fa solid. And I'll say fa dash n below. Right. Right after this, we will have another div. So right after the cart icon, we will have div with the class name card dash info. And this is going to get the span. And before I build it, so this is what we're trying to build. This is the first card. Second and third, we have one icon and then like a information section, right? Okay. So that's the first spin. Let's say class name card dash label. This will get the email as the text and for the value I will get in a tag. So href, it's a mail. So, we're going to say mail to and then whatever the mail address is, right? So, that's how you build a contact card. So, go ahead, copy this, okay? And duplicate it twice. So, that's the first one. And then the second one. Now, we're going to update the values. So, first off, update the icon. This is going to be phone. And let's say something like phone. And here you can add a value. In this case, I'll just put something test like this. And since this is a phone, we'll just say tell um and then put the value. And then we're going to have another one for the contact card. This will be fa let me update it. Um location dash dot and then we are going to say something like address or I'll say office and then I'll put a test address once again. So it'll be a span element right here. Okay. So go right after the span. We have three different divs, right? Go below to it. And I think this is the container. Okay. You can shrink this. Go below to that. And we are going to have I think the social links. So we just built the cards. Now we're going to have the socials. And you can use your own social links, but in this case, I will leave it empty. Okay. So we have the socials parent and then we have like Twitter, LinkedIn, Instagram and GitHub. You might be asking what this does. Well, this is for only you know um accessibility. This is for the like screen readers. You can I think click to this and see what that does. Okay. So the purpose of aerial label is the same as that aerial label. What does that mean? It provides the user with a recognizable name of the object. Like this is for accessibility, right? It is for the screen readers and in this case we are including it because why not? That's one of the best practices, right? Okay. So that's the very first section. Let's go ahead shrink this. That was the info section. Now we're going to have the form section. This will be a form. We're not going to have any actions. Let's say class will be form and actually like contact- form. And I will give an ID as well. Say contact dash form. Within the form, we're going to have an H2 that says send a message. I'll paste this in. And let me show you. It is this part. Now, we're going to have a row, right? we have two different items right next to it and every single one of these is called a form group right so we have form group for the first name then we have for the last name for the email so on and so forth okay so right after the H2 I will have form dash row and within this we're going to have two different form groups so the first one will look like this so this is what I just pasted we have a label and then one input that is type of text. Now we say four and it indicates the ID of that. So here if you put the first name 1 2 3 you would like to update it. You update it here as well. And this is because if you click to the label it will activate that input. Right? So if you click to the label right? Okay. So that's the reason when you click to the label we basically um attach them to the input and then we have a placeholder as well as the required field. Now I'm going to duplicate this. Let's say this time that would be equal to last name. And for the placeholder we can say something like do right. Okay. So that's the form row element. We can shrink this and go right below Ted. We are going to have the email. So you can actually pause the video and try to build it by yourself. But it is very similar. We have the label that says email type. We have an input type of email and a placeholder. Right? So this is what we have at the moment. Of course, no styling at all, but we're going to get there. And then we have a select element. Right? So let's go here. Right after this one, I will have another form dash group. I will get the label. Let's paste this in. Or is going to be subject and uh instead of email, we're going to say subject or topic. And this is going to have a select element. We don't really need a name, but we're going to have an ID. Let's say it's going to be equal to subject. And we're going to have couple of different options. So the first option is not going to have any values but it'll say something like you know select a topic and we can say this is going to be the default value. So we're going to say selected and let's say it is disabled. So users cannot select that one. Right? You cannot select this first option but you can select the others. Okay. Now we are going to have the other options one by one. We have the general, we have the technical support and I will get the rest. So we have sales partnership and the other. All right. So that's it for this form group as well. I will go ahead have another one. This time this will be a text area element. As you can tell this is for the message. So let's say class name form dash group. Once again we're going to have a label let's say for let's say message and with the text this will be a text area element. We don't really need a name but let's say ID will be message. And we can add some other props like a placeholder. Let's say tell us about your projects or opinions whatever you would like to say and then I think I will have required as true and I will say rows of five by default. Okay. So that's it for the form group. Now we're going to have a button. So go outside of this have the submit button. This will say send message but it's going to be under a span element. And we would like to have an icon right next to it. So I will say I give the class name FA- solid FA- paper plane. I think this should be it. I will give the class name of submit bn. All right. So that's the button. Now outside of the form, we would like to have a success message, right? I will say success message or state. Here we'll have a div. And the class name is going to be success dash state. By default, this is going to be hidden. And we're going to have an ID. Let's say success. Then within this, I'll have a div. And let me show you, by the way, what we are building pretty quickly. put something in. Okay, so we have the icon, a title, description, and then another button. Okay, so um here I will say class name, success dash icon and this will get the I element. Let's say class name will be FA- solid and FA check. And go outside of this success icon and create the H2 that says message sent. And then finally a P tag that says thanks for reaching out. I'm going to paste this in. And then I think just a button. Let's say this is the reset button. Here is the ID. and send another message as the content. Okay, so that's the entire HTML file. We have around 140 lines of code and it is just markup, right? We don't have any styling yet. So next, we can add our CSS file. So as usual, we are going to get our CSS variables. I will just grab it from the source code. If you don't want to type this out, you can do the same thing. Go ahead, find the source code in the description. Find this folder, right? And grab the style. CSS file. So, get the CSS variables. We just have some colors and variables like the border radius. If you want to update it, of course, you can do so. Now, I will add my reset. As usual, we'll say margin of zero, padding of zero, and border box. I'm sorry, box sizing of border box. Now, right after this, I will get the body element. If you remember, we have imported a on family, right? That is called enter. Now, we're going to be using it. Okay. So, I'll say enter and we can add the sens as the fallback. Then I'll say the background is going to be let's say variable d-b. Then we're going to get the I think color let's say variable that's going to be text. And then we can get the minimum height of 100 VH, right? And then I will have the blank element. I'm going to add the reset for this as well. So we will say color should be inherited from the parent element. And then I'll say text declaration is going to be none. So that we don't really have that underline. Right? By default this is equal to underline value but we're going to make it to be none. Okay. Then I will select my container element. So here is what we're going to be doing. We will have two different elements, right? So I will be using grid for this. So I will say display of grid and I will say grid template columns. We will say one fraction to one fraction. So it's like 50/50, right? And we will say minimum height for this could be 100 VH as well. Then we are going to build the info section which is the left hand side. So I will say info dash section and then we're going to say the background is going to be a linear gradient value. We're going to have 135°. Let's say we're going to go from the accent color to this color. I think it'll be accent dark. Okay. Make sure that this is equal to background and not background color because we are using linear gradient. Then we'll say petting of 4 RM and maybe something like display of flex align item centered and I will say position will be relative. Let's say overflow is going to be hidden and I think we can put them side by side as we type out. So this is what we just built. Um let's try to get them side by side maybe like this. Okay, so that was the info section. Now we're going to get the info content. So I'll say dash sorry dot info-content and I will say something like maximum width could be 450 pixels. Okay, it cannot get larger than that. And then um sorry I think this should be maximum right not minimum maximum width. Okay. Now I will get my badge. Let's select it. I will say display will be inline block. And then for the background, let's say we're going to get RGBA. I'll give 255 three times, but at the end it's going to be 0. 1 or let's say even two. Okay. So, as you can tell, we have a slight like slightly white background. It is kind of like a gray, right? We update the opacity from one to all the way up to two 0. 2. Okay, so that was the background. Now let's add padding. Let's say 0. 4 RM and 1 RM. And then I will add some border radiuses, right? I'll say border radius could be 100 pixels. And then maybe something like font size, let's say 0. 85 RM. Then we will go ahead and say font weight is going to be 500. And then margin bottom 1. 5 area. Okay. So that was the batch. Now let's try to get the info section H1 element. Right. So maybe I will copy this. Select the H1 and I'll say font size. Again we're going to be using the clamp method. Um let's say clamp. We're going to put two RM which is the minimum value. the preferred size which is for view port. Um and then finally we'll say 2 RM. This is the maximum size. I think like minimum and maximum should not be the same here. Let's say 1. 5 or maybe should this be like four. Okay, that's too large. Maybe let's say three. Okay, like this is the maximum size. Um but I think I'll just go with two. Three is a bit too large. Okay. So these are the values that I will have. If you wanted to, you can update it of course. Um here let's say font weight is going to be 700. Then I will have the let's say line height to be equal to 115. And then margin bottom of one area. Okay. Now we can get started with the P tag right. So here I will say get the info section and here we will do something different. Let's say from the info section go ahead find the direct child. So we can say info dash content and again we can use this selector. We will say find the direct pac right and I will leave a comment. Let me maximize the screen. Okay. So this uh character is the direct child combinator. Okay. So this is how we call it the direct child combinator. It selects only elements that are immediate children not nested deeper. Okay. Hopefully that makes sense and I can show you this in index. html file. Let's find the info section. Okay. So we say like under the info content find the direct P element. Right? So imagine if we had another P tag that is within the H1 that would not select this one. It would only select that one. Okay. Because this is the direct child. This is not this is nested under the H1. Right? Okay. I hope that makes sense. This is what we are doing. This is what that means. Within this P tag, we are going to say font size of 101 RM or 1 1. 1 RM. We're going to say opacity could be a bit decreased like 0. 9 and I think this should be T by the way. Content. Now we can see the difference. Let's say something like 0. 1. Okay, it is working. So we got the opacity. We're going to have the line height. let's say 1. 7 so it's a bit more spaced out and then maybe I will have let's say margin bottom of 2. 5 area okay so that was the description now we would like to get the contact cards right select all of them put them side by side so I will say something like contact dashcards we're going to say display of flex we're going to say flex direction to be colum And then we're going to give some gap. Let's say gap 1m. Okay. So they have some gap as you can tell. Then I will also say margin bottom will be 2. 5 RM. So that it is spaced out from the social icons. Now we're going to select every single content card specifically. Let's say content dashcart. And this will also have display of flex so that they are side by side. I was going to say um why this is not the case like not content but it should be contact right. Okay as you can tell the logo and the text are side by side. So we will have display flex align items will be centered let's say gap of 1 RM and then I will say something like background again I'll be using this value let's say RGBA and I'll be using 0. 1 so they have some background then we can give the padding let's say 1 RM to 125 RM right let's say border radius we can use the variable for this called d- radius that is equal to 12 pixels and then we can say something like transition all 0. 2 seconds because on the hover state I will copy this. So we would like to animate them to the right hand side. So that's your challenge. Pause the video and try to do it by yourself. Okay. So we'll be using trans transform translate x. Since we would like to go to the right hand side, what should we do? Should it be positive or negative? The answer is positive. So we'll say 5 pixels. Now if you hover over it, right? As you can tell, it goes to the right side. So to simulate this even better, I'll say 50 pixels as you can tell. And if you said minus 50, it would go to the left hand side. Let's bring this back. I also want to update the background color, right? So, it's going to go from this to that one. As you can tell, maybe it is not really visible from the video, but there is definitely a change. It is tiny, but still, um, it's better than not having at all. So, that was the hover state. Now, we're going to select the card dash icon, and we will say width is going to be 44 pixels. We're going to do the same thing for the height. Um it should be like this. Now you might be asking we update the value right but nothing has updated. Well it's actually this like kind of like the background parent element. Okay. So once you add the background it should be visible. And let me actually give you the background color. So it's going to be this rgba value. As you can tell we have the background but we need to center this right. So I'm going to say display flex item centered. Let's say align item centered. Justify content centered. Okay. So this is one of the options. Or you could say display grid and you could say place items centered like center. So this is another option. You would either do this or that one. Okay. So I will leave it as a comment. Let's say option one. using grid and that's the option two using flex to center the items right okay so we have these I think I will also update the font size let's say 1. 1 RM and maybe let's add some border radiuses um let's say border radius I'll be using my variable let's say dash radius okay so this is looking very good at this point. If you wanted to, you can change this value maybe like 10 pixels but I will leave it in this way. Okay. Now we can get the card info and here is what I'll be doing. I'll say card info display flex but the flex direction should be colum. Now do we really need this? Let me see. If you delete this part, what happens? Yeah. So, we have email text and then the value, right? They are side by side. But if we say flex direction would be column. As you can tell, now they are in the vertical direction, right? And we can even add a gap. Let me add them side by side. Here I'll say gap of maybe like 1 RM would be too much. Yes. Let's say 0. 5. Okay, I think even like four should be good to go. So that was the card info. Now let's get the card label. And you know what? I'll just provide this to you so that we don't waste any time. It's very simple. We're going to have font size. The opacity would be updated. Text uh transform would be uppercased as you can tell. And then we're going to have the letter spacing adjusted. Now we would like to get the a element and span element which is within the card info and we are going to update the font weight. Okay. So that's the first thing. Now on uh on hover state again I will provide this super easy. We will just say text decoration should be underline. Then we can get the socials. So here I will say display flex and give some gap between them. Now let's get the socials the A elements right we are going to select each of them let's say width 42 pixels and same for the height now we can give a background color that I'll copy and paste so you could probably make this to be a CSS variable as well because we have used it multiple times at this point okay let's say border radius should be 50%. So if the size if the width and height is the same and you say border radius 50% it's always going to be a circle. Right now we can center this by saying display grid and place items to be center. Okay. Then I think we can give the font size of 101 rm or 1. 1. Then I'll give the transition let's say all um maybe like 0. 2 seconds. Okay. If you refresh you can see the icons. Now let's add a hover state where we would like to update the background color as well as the position. Okay. They are animated. They are going in the vertical direction to the upside. Right? Because we are using minus. So with this we have written all the styles for the left hand side right it is looking almost the exact same thing as you know the end result. So here I think we just have gap and here we don't if you wanted to you can delete it but honestly I will leave it. Maybe we can shrink this a little bit. Let's see where is that gap. Um under the info it should be card info let's say 0. 2m twom maybe one yeah I think two should be fine now let's try to build the right hand side which is our form right so I'm going to get this let's say dash sorry dot form dash section then we'll have the background let's say it's going to be variable of d-bing of 4mm from all directions then we're going to give the display of grid and place items not content but let's say items to be centered. So it's going to center the entire content. Now let's just try to add our hidden class right. So you can add hidden display of none. Once you save this should disappear because we have the hidden class in the success uh success message. Right? For now, let's leave it uh without having it because we need to see this. Um yeah, let's actually have it here and once we need to build this part and we can comment this out. Okay, so for now have the hidden class at the very end of this file. All right. Now let's try to select the contact dash form and here I'll say something like maximum width of 480 pixels and then we're going to say the width will be 100%. So this will make that you know the maximum width could be this and not larger than this value. And if you wanted to you can update it but this is what I'll be using. Let's say contact form. We're going to select the H2 which is this send a message text. And I'll say font size could be let's say font size 1. 5 RM. Wait, did we select it? So I didn't see really a difference. Let me say like 5 RM. Okay, so it is actually working. This is the value that I will have 1. 5 RM. Then we're going to have the font weight as 500. Let's actually use 700. Then maybe I'll say something like margin bottom of two area. Okay. Then we're going to get the form dash row class. I'll say display should be grid. And we're going to say grid template columns 1 fr and 1 fr. So again 50/50, right? So we have the first name and last name side by side just like in the end result. Okay. And we can give a gap. Let's say one rm between them. Then we're going to get the form group element. And I'll say something like margin bottom 1. 25 RM. So we have a bit more space. But do I have a typo? Yes, this should be form. Okay. Now, right after this, I will again get this. Let's say we're going to select the label and we're going to add some styles like display of block let's say. Then we're going to have font size 0. 9m. We're going to have font weight let's say 500. Color is going to be this variable called text dim and margin bottom of 0. 5 RM. Okay. So that's what we have at the moment. Now we would like to select the input the select element as well as the text area right so text area select as well as the inputs and this is what I'll be doing I will say under the form group get the input select as well as the text area and give all these styles right so width of 100% and let's actually try to delete them and add one by one okay so this is what we had at the beginning, right? So, we said width of 100. This is what we're getting. We said update the background color. Then we said add a border. Give some rounded corners, right? Then we said add some paddings. Then we said add, you know, get the font family from the parent. So, we will just inherit it. And then we're going to say here's the color transition. And yeah, so these are all the styles. And then I would like to update the you know placeholder text color. So I will say get the placeholder and update the color if you wanted to like we can say red and it would update. But of course we would like to use this value. Then I will get the focus state for these elements. Right? So on focus again we can delete them and see the end result one by one. So first off when you focus you see that we have an outline right we get rid of that first now we don't have it then we added the border color right this is what we have on focus and then we add a box shadow so I don't know if it is visible from the video but it's definitely here right it has like a slight box shadow now the other thing that I will add is a cursor pointer on the select element Okay. So here as you can tell cursor is not pointer. Let's try to have it. You can say you know just get my select element and say cursor would be pointer. And now as you can tell the cursor is pointer. If you want it to be specific again you can add this part. And honestly this is what I will have. Then we can get the options. So here you can see we have couple of different options right. I don't know if we can change the background color. So here like let's say background will be equal to red. Does that update? I think not really. Um so this is like native to your operating system, right? If you're on Mac, this is what you're going to see. If you're on Windows, it would be a little bit different. I don't know if you can like fully customize it. Um here I will delete that. But if you are interested you can of course do a quick research. Well I'm not really interested in this. So I'm going to delete that part. Okay. Now we can get the text area. And here I will just paste this in. We're going to say this is the minimum height. Okay. It cannot get smaller than this. And we're going to say it should be resizable. Um let me put this in this way. So it is resizable only vertically. Okay. So you cannot try to resize it horizontally. And we have other options like I think none right you cannot resize it at all. We can horizontal vertical um yeah in this case we're going to be using the vertical value. Now we can also get the submit button. Again I will get the entire styles and I'll just walk you through it. So let me delete everything one by one. And I'll just apply each so that we can see the difference. Okay. So this is what we had at the beginning, right? Let's put this back. Width is 100. Then we got the display flex and we said align items would be centered and justify content to be centered as well. So they are side by side and the content is in the middle of the button. Right? Then we have the gap between them. We added a background color. We need to get rid of this ugly border. So, we just add border of none. We're going to add padding from all directions. Give some rounded corners, font family, and all the font styles would be inherited. Then, we can get the font weight, color, cursor, and I think some transitions. Now, we're going to add the hover state because currently when you hover over this, nothing happens. So I'll say submit button on hover update the background color as well as the transform where we update the translate and then we add the box shadow. Okay. So that was the hover state. Now I will get couple of different styles as well. We're going to have submit button hover state but for the icon. So when you hover over it as you can tell icon goes to the right side by four pixels. And it also like nicely animates. Then what we will have, let's see, we're going to have the reset button. And let's try to delete this for now. Okay. So this is the reset button. And we need to style that as well. Again, I will provide this to you. And let's try to delete these lines one by one so that I can walk you through it. So this is what we had at the beginning. Now we're going to say background color would be transparent and then we are going to add the border some paddings border radius on weight. Let's add a color cursor would be pointer and some transitions. Again we will have the hover state or the reset button. Right? Once you hover over it this is what happens. border and color updates. Now we can get the success state. I'm going to select it. We will say text would be aligned right to the center as we can tell. Maximum width and then the animation called fade in. This is something that we're going to build in a second. And let's actually do it. Let's say key frames name would be fade in. So this is going to have two different states. We're going to go from opacity of zero and let's say transform translate Y of let's say 20 pixels and we'll say two. Let's duplicate it. As you can imagine opacity is going to be one and transform translate will be equal to 0 pixels which is the initial position. Right? So once we save let's try to reload. As you can tell, this has been animated from the bottom of the screen. If you put minus, that would be animated from the top of the screen. In this case, I'll go with positive 20 pixels. So here again, I will go ahead paste some styles and walk you through it. So this is the success icon, but let's try to see how that work step by step like as if we are typing this out. Okay, so this is what we had initially. We're going to give a width and height and background. Right? So this is linear gradient. This is the degrees from this color to that one. And we're going to give border radius so that it is a circle. Display grid and place item center so that this can be centered. And then I think we will update the font size. And we can say margin horizontally is going to be equal to auto so that it is in the middle of the screen. So this is top, this is horizontally, right, right and left. And this is from the bottom. As you can tell, we have some spacing. Then I will get the age two. Again, we have margin, bottom, and own size has been updated. We can get the P tag. Paste this in. Okay. So that's the entire UI. Let's get this hidden class as well. so that the success message is not visible at the beginning and then finally to make this responsive I will add some media queries. Okay. So we basically say if we are in the 900 pixels or below make this to be like not side by side right just have one fraction at a time. So we have one and then the other grid element. So previously it was 1 FR right 50/50 but now it is 100%. Then we update the paddings on these sections and then you can pause the video this once we get into the 600 pixels and below this is what'll happen. Now with this our UI is completely responsive as you can tell. And here actually let me shrink this even more. Right? So this is like completely responsive looking very nice. Now we would like to write some JavaScript so that we can actually submit this form. Right. I will maximize my screens. Let's go under the script. js. And first off let's try to get our elements. So I would like to you know just type this out. It is only three elements. So we're going to get the form. Let's say document. getelement by ID. And here is our ID that's called contact dash form. I will duplicate it. This time that's going to be the success. Duplicate it. This time it'll be reset-bn. I'll just go here. I'll say reset btn. And this is going to be let's say success state. Okay. So these are all the elements. Now we're going to have form add event listener. We will listen for the submit event and we're going to run this call back. Now we already know what to do, right? This is something that we have done in the past. First off, we are going to prevent the default behavior which is going to let's say um it will prevent let's say this will prevent reloading the page right and then I'll get the submit button. So I'll say con submit btn I'll say form the query selector we will get the dots submit dashbtn now we could have get this from the top as well but this is just a different way so that's why I'm including this um here let's say first off we would like to show a loading state so we'll say submit button dot inner error HTML will be equal to this part. So I'll have single quotes let's say an I element. So make sure you type this out correctly. And looks like I made it like I made a mistake. It should be in this way. We're going to have the class name. Let's say class will be equal to FA- solid FA spinner and FA spin. We can add a text as well like right next to this we'll say sending dot dot. The other thing is that we're going to get the submit button and say disabled. Say disabled will be equal to true because like if we are submitting button should be disabled right and then we can simulate an API call. So as if we are in the loading state and for this we can say set time out we're going to call a method but this will run after 1 second right you can even make like two seconds if you wanted to so here I'll say form class list dot add we will hide this so we'll add the hidden class and from the let's say success state we're going to remove the hidden class okay let's save and give it a go I'll go here. This is the like this is the one that we have built. Okay, this is not the demo. Demo is right here. It is almost identical. I just put John. Let's fill this in. Okay. So, I'll say send the message. We have the loading state for 2 seconds. And then, as you can tell, this is what we have. Now, when you click it, nothing happens because we are not listening for an event. So, this could be your challenge. You can go ahead pause the video and try to build it by yourself and then come back to my solution. So I will get the reset button. I will say add event listener on click. We are going to do something which is this method. So here we'll say first off reset the form. Let's say formreset. Then we'll say form. class class list dot remove hidden because we would like to see this now it should be visible and on the success state we will say class list add the hidden class right we are going to hide it then we can also say on let's get the submit button once again I'll copy this paste this in we would like to update the button state because in the past if you remember we had the loading state we would like to update it because if you save now and take a look at the end result. Let me fill this in. So if I say send another message like we can still see that it says sending we need to reset it. So here we'll go ahead and say submit button and I'll basically provide this to you. We'll say inner HTML. This is what we had in the past. And we'll say button should not be disabled. So, believe it or not, that's the entire JavaScript that we would need. Only 30 lines of code, right? Okay. You can take a look at it. I'll just try to scroll from start until the end. And let's give it a go one last time. We'll say ch let's say fill this in pretty quickly. And if you wanted to like we can add more and more lines and this would be scrollable. So we just send it success message and let's say send another one and it is getting reseted. So that was the entire project. I hope you enjoyed it and learn something new from it. With that hopefully I'll see you in the next
Project 19: Scroll Progress Indicator
project. All right. So in today's project we are going to build a scroll progress indicator. So notice how as soon as I scroll, we have an indicator at the top. It says how many% we scroll and we can see it actually right here at the bottom. And if I go up, it's going to also update the UI. Right? And once I reach the end, it says completed now. This is a component that you would see in blog applications. And in this like in today's project, we're going to learn how to build it. So if you're ready, let's jump into VS Code and get started with it. All right. So I am right here under the index. html file. First off, I'll have my title. I'll say something like scroll progress. And let's try to link our CSS file. And we are going to need a little bit of JavaScript. So we would like to link our script. js file as well. Now first off, let's build the markup. Here I will have a div with the class name being progress bar. And I'll give it an ID. Let's say progress bar as well. I think I have a typo. Let me fix it. Progress bar. Yeah. Okay. That's the very first div. And then we're going to have one more div. This will like this is going to be the batch that we have at the very bottom. Right. So here I'll say class name. It'll be badge. And let me give the ID as well. And like initial value is going to be equal to 0%. And here we are not going to have any value at all. Now we can create an article element within this like I'll have a class name. Let's say content and then I'll have one H1 and you can grab the entire content from the source code. This is what I'll be doing. I'll just get this pastes in and then we're going to have couple of different P tags, right? So the very first one is going to be this and then that one so on and so forth. So I will paste this one and actually I'll grab everything from the source code. So here from my second screen I'm copying everything and I'll just paste it right here within the article. Just paste this in. At the very end we're going to have a P tag. So this is going to let me delete this. This is not correct. We're going to have a P tag. This is going to determine if we are at the end or not. So I'll just say end. Well, actually this is not going to determine if we are at the end or not. This is just going to be this text. Let me display. It says the end, right? We are going to calculate if we are at the end or not by using JavaScript. Okay. So this is just a P tag with a class so that we can make it different than the rest of the elements. Okay. So here I'll just say the end and let me copy it from the source code and just paste this in. Okay, so that's the entire markup. Now let's jump into CSS file. All right, so I just put them side by side. By the way, I'm running the index. html with the live server. Okay, now I'll just try to walk you through it. This is going to be around 80 lines of code and it's going to be super simple. So first off, we're going to have our resets, right? And then we're going to select the body element. I'll update the font family. This is the one that I'll be using. You can get anything that you wish. Then we'll get the background. Update the text color as well as the line height. And then I'll select the progress bar which is going to be this thing that you see at the very top. Right? So first off, we position this to the top. We say fixed from the top left. Right? It starts from here. And then the height will be 3 pixels. So if you wanted you can make it larger or even thinner but I'll go with 3 pixels. Then the background will go from this color to that one. So notice how we have a like a tiny gradient right. Then initially the width is equal to zero and zindex is equal to 100. So it is at the top of every single component. And we are going to transition like we're going to add a transition to the width. Right? So it is happening smoothly. So that's the progress bar component. Let's save. Okay. Then I'll just get the badge which will be this thing that you see at the bottom. Right. So what we say is that position should be fixed to the bottom right is going to be 24 pixels. Update the background. The border color add some padding. You know update the border radius, font family, font size, so on and so forth. And again we say zindex will be 100 so that it is on top of the elements right. Okay. Then what else? We're going to get the complete class on the badge. So if it is completed the background will update the color will update as well as the border color. Right? Okay. What else? We're going to have the content. So we will basically give it a maximum width. center it and add some paddings from the horizontal and vertical directions. Then we'll update the H1 which is this element. H2. I think all of these are H2 elements. And then we'll update the P tag as well as the end element. So as you can tell the color is different. It is centered. It has some margin from the top and font style is equal to itallic or italic however you read it. So with this we are completely done with the CSS file. Now we just need to build the logic within the JavaScript file. So head over to script. js file and get these two elements. So we're going to get the progress bar as well as the badge. And then we're going to add an event listener to the document. So I'll say window. adde eventlister. Whenever user scrolls, we would like to call this method which is called update progress. You can call this anything but this is the name that I'll be going with. So I'll copy the name and I'll go right here create a function. Now this is not going to take any arguments but within this first off we would like to calculate couple of different values. So the first one is how many pixels we have scrolled from the top. Right? So here I'll say const scroll top and I'll just add a comment. I'll say how many pixels we have scrolled from the top and this is how we can calculate it. We'll just say window dot scroll y. So this is going to give that value. And then we would like to calculate the total scrollable height. Right? So full page minus the visible area. Let me just say const document height. And here I'll maximize the screen. Just leave a comment so that you don't really confused or have it in the source code. So we're going to say document dot document element which is HTML and then we'll say scroll height. We'll say minus window dot inner height. So this is going to give us you know this value that I just said the total scrollable height and then finally we're going to get the progress. So here is the basic math behind it. We'll just say scroll top divided by document height and I'd like to wrap this. So first off we're going to multiply it by 100 so we can get the percent and then we are going to wrap this with let's say math round meth uh round method. Okay then we'll just say progress bar which is this element. We'll say style and we would like to update the width. So I'm going to say give me the width element. We would like to say whatever the progress is. So this is going to be some pixels right either zero 100 50 whatever that is at the end we'll just add the percent sign and then we'll say badge dot text content this will be equal to progress once again plus um the percent sign one empty space and I'll just say red because if you take a look at the end result whenever you scroll it says you know like 29% red and then we can check if progress is equal to or greater than 100. In this case, we would like to add the complete class to the batch. So, I'll just copy and paste and we would like to update the content as well. But in the else case, we are going to remove the complete class. Okay, let's actually save and test this out. Here, I'll go to the one that we just built. At the beginning, it says 0%. And if you scroll, notice how it updates this part as well as the progress bar itself. Once we hit the end, it is completed and this is filled 100%. Okay, just one thing that I'll update. Let's just add the red at the very end. Okay. All right. So with that I think we completed the entire project. I hope you enjoyed it. This is a very common component and the logic behind it is pretty simple. Like it's completely fine if you cannot come up with this idea but at least now you know how to build it. So with this hopefully I'll see you in the next project.