Learn Next.js by building a full-stack CRUD app | Nextjs + Firebase (Auth & Firestore) + TailwindCSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome my friends on the internet to today's next.js tutorial where we're going to learn nexjs by building a full stack application with tailwind firebase next.js and some other cool little features here and there that's just going to make a great learning experience for anyone who isn't really too familiar with next.js we're going to be looking at like apis and how you can fetch them into your front end and all the kind of specificities that come with it so it's going to be a great tutorial if you enjoy it please like and subscribe super appreciate it and let's first start off by looking at a demo of what we'll be building today so for this tutorial we're going to be building a super nice and neat and responsive uh to-do list app uh for all the data persistence is going to be in firestore and the crud functionality you know you can swap it for anything that you like so we've got a neat little login screen uh where you can register and if you submit you get nothing let's say we register an account which is monkey at live.com put in a password submit it logs us in uh we get a nice little menu where you can log out and in here we could add a to-do which is like buy groceries or whatever add that it pops up here you know go for a run once again it all looks great on mobile and we could edit a to-do so you know don't forget apples save that and let's say we deleted this one and then refresh the page and all of our to-do is get pulled back in so it's a pretty great application we've got some nice little icons here it's super responsive and everything let's get into it cool so that all looks good now let's see how we build it and we're going to start that process by coming into our terminal and here i'm just into my document so the first thing we'll do is cd into our project folder so github and i'm going to type the command mpx create next app and i'm going to call it next js to do app now to do our apps are great because if we just type enter we can go yes and that's going to build our next.js app now to do apps are great because they teach you all the fundamentals of like crud implementation and how you can work that into your system so once you finish this project i highly recommend you adapt it into something that you want added to your portfolio project or whatever you like but yeah should be dope cool so now that that is all installed we're going to cd into that file so that's next js to do and in here the first thing we're going to do is install a tailwind for a design library and for that we're going to type npm install dash d tailwind css post css and auto prefixer and once we've done that come on we're going to type mpx tailwind tailwind css and that dash p that's going to make us a nice little file and now i'm going to type code dot to open up my code editor now the link to the github repository for this code is in the description so check that out if you want but now that we've opened it up we are first just going to come into this tailwind config file that we just made and i'm going to swap out content here for this code just there so now we can save that and the last thing we have to do is create is coming to this file just here and we can remove all of this code and we want to copy and these three lines just here and for this particular tutorial we're not going to need any of this information in home.module.css so we can just delete that file cool so now we've initialized tailwind and we're going to start building our project but the first thing we're going to do is actually just take a look at what next.js provides us with so in here we have some a package.json file which is just standard for all react projects we have a readme and then you know i get ignored some not so significant files don't really have to do anything with these but the three folders that are significant are the pages directory the public directory and the styles so next.js works by basically by using this pages layout as like your folder directory full of all your pages and so when you navigate to a different url or a different suffix or a different route from your website it will navigate to the relevant directory in here so we'll look at that a bit more later and so essentially the entry point for our whole app is in this app.js file and from here everything kind of gets rendered within and so we can come into our terminal and if we just start this up npm run develop we can see that it starts up a server here on localhost 3000 for us and if i just move that to the side just like that nice and neat uh we can see that we're getting an issue and that's just because of the home module file that i removed and so if we just kind of remove that for a second then we get none of this and that's all good but we actually don't need any of this content so we can come in here and just gut everything cool so now if i refresh that page we still get an issue and that's because styles is not defined and so we just have to remove that from this just here and so now when i refresh the page we get it totally blank uh we have this entry point which we don't have to touch but essentially the actual content that gets rendered within that entry point is within this index file here so if i type james james pops up on the screen and so this is going to be the folder where we start typing out all of our sub componentry and stuff like that now if i wanted to add a new file and let's just call it henry.javascript and we can use rfc to render out henry we can see how this pages directory works by going henry and now we can see that this component here gets rendered and so if i change that to james james that will fully refresh that page just like that so it's absolutely magic equally if i wanted a folder called subfolder i could make that and in here i could have a new file called index.js rfc that so i'm going to say that this is the sub folder page uh you want to make sure that all of your index pages have capitals and in here we can just say this is the index page and so if we go to a subfolder we can see that this component gets rendered and then if i had a new file in here called banana.javascript rfc that banana just change that to an uppercase well actually more specifically the a good practice i like to do is banana page for all pages that will say banana and so now i can come into subfolder slash banana and banana gets rendered because it's within subfolder so you can kind of see how that routing works with these pages but anyway we actually don't need any of this so i'm just going to delete it for the second and we'll see how it works a bit more later for the minute we're just going to come back into localhost 3000 and we render out james now we have a couple of things to set up afterwards we're going to start off with a components folder so in our components you know we're going to need one called login.javascript so i'm just going to make that so in here what i would probably do is just say uh render login right just like that and so now we can auto import that that shows up at the top and now login is rendered and we have our first component uh rendering within our page and we can kind of see how we would build a login form to our to-do app now for this project i want to use some google fonts and so we're going to come into google fonts for a second and so the fonts that we're going to be using for this particular project is mont ceret and so if we just click on this font we can add a few styles in so just like that pretty simple we're going to take all of the bold ones none of the italicized fonts and we can copy this link tag here to import it into our folder to import it into our application but the one thing we're going to have to add if we want to add links into our document we come into our pages and we create a new file called underscore document.javascript and so this is just a next.js specific component and it has a very like particular format but essentially what it's going to do i'm just going to copy it in is as much as we might have head tags in here they're only for these essential other tags or links if we want to add other links we have to use this document component and add them into here and so in this particular case what i'm going to do is copy all of these link tags just into the head of this document here and that should work nicely now we're gonna have to just quickly close some of these tags like that i have to do this top one so now that should be all happy and the other thing we're going to have to do is change cross origin just there to this and so now that should compile correctly and we can in this particular case apply that font family to our entire document by coming into our global css and in here we can just select everything and apply that font family just like that so that's nice and easy and now if i come back into my document we can see that monsterart font is indeed applied so that's cool so now we have fonts configured into our document the last thing we're going to use is font awesome icons so in here if we just type in font awesome icon cdn we can select this top package here as version 6.1.1 for me and once again come back into this document file and copy in that additional link tag just like that update any of these comments here so it says no referral policy and we'll probably also have to change the cross origin but the cool thing about that is that now we're going to be able to use font awesome icons and just say dragon for example and so now we can copy this dragon we can paste it in here underneath our login form and now if we come back into our document we can see uh that we do indeed get that little dragon rendering so that's super neat uh one other thing to note in xjs is that class is a reserved word so when you are using these icons you will just have to update it to say class name but that's pretty straightforward so now that we've finished most of the configuration and the imports for our project the next thing we're going to do is come into our components document and make a layout.javascript component and so in here we're just going to do rfc to create that component and essentially how this component is going to work is it's going to receive props and in here we're just going to destructure children search here chil if i can spell it correctly out from props and inside of this div here this is where we're going to initialize our page layout and so essentially what that's going to be is we're going to have our children being rendered out here but this overarching component we're just going to say class name is equal to flex and flex column this is all tailwind styling we're going to say min height of the screen we're going to give it a position of rel relative just like that and now we can see if that's working by just changing the background to a background of site 900 and now obviously nothing changes because we haven't rendered this component anywhere but if i comment back into our app we can uh wrap this component just in here with our layout i enter that down onto a new line and paste that down below oops that should actually say layout just like that and now we can see that our whole screen goes the color we would expect it to go which is perfect so now we have our layout wrapping our entire document so that's super neat so logically the next thing to do would probably be to make uh header and footer components so in here i'm just going to say footer.javascript rfc and rfc just like that and so for the moment i'm just going to say this one's going to yeah just say header and i'm going to give it a class name of fixed we're going to say top of zero width is going to be full left is zero our background is just going to be green 300 for the moment so that we can see that working and for our footer we actually don't have to do too much because what we can do is if we come into our layout component we can render out our header just here have that auto import and now we can have a main component and render our children within that main component and we can give this a class of flex 1 and so what that means is that this component is going to occupy most of the space and we can see that working if i type background yellow 300 it takes up all that space so that's super cool and naturally that will just push our footer component to sit always at the bottom and so we can see it just down there and so now we have a nice neat responsive layout and as we fill out our component our header will stay fixed so it's going to be excellent and so with that all done the first thing we're actually going to start styling out is our header but i actually just quickly decided that i would prefer to change the font real quick so what i'm just going to do is uh quickly click on that one remove all of this and instead i'm just going to take this just fond because i think it just looks slightly cooler so if we just grab all these styles just like that uh refresh the page so that little thing comes up we can swap out those link tags that we just had before really quickly so it's just going to be these three here just like that and once again we'll just have to make sure that we close all of these and update this term just here so now we can save that and then we will just have to come back into our style sheet and just swap that font over just like that cool so that's all done once again we are working on our header so if we come back into our header here what we're going to do is we're going to just call it uh we're going to just make an h1 tag called to-do list just like that now obviously the text is quite dark so in this component just up here since we're having a dark theme i'm actually just going to say text white and so that should change everything just like that and now in our header we can remove that background just like that so that is all good and we can see that that is overlapping like that but if we change this from fixed to sticky we can see that now it will push it below and it will still stick to the top so that's super good from there what we're going to do is we're going to give this a class of text uh 3 xl so that should be a little bit bigger and we're quickly just going to start off by designing for a mobile and then later what we'll do is we'll move up to a full screen device and so just here we can see that that's actually not too bad considering that we're going to have a profile icon over the other side and so when we go to a larger screen i can add that breakpoint by just saying small and in tailwind it's way easier to go from small to big and so i'm just going to say when we go bigger than a small screen i want the text to be like 6 xl and so how that's going to work is it'll be that size and then when we come on to a bigger screen it gets way larger which is you know just what we're looking for so now that we've added that in the next thing we're going to do is add a profile icon and so for that we're just going to say uh flex items santa justify between and have a padding of four all around so if i save that that will push the to-do list in a little bit and we can come in here and just say ike profile and we can just take this user icon just like that and paste it just below just here swap out class for class name and now we can see that we have that little user icon showing up on the other side which is just what we want if anything we could probably just make the padding x a little bit bigger so we can say padding x is maybe six push it inwards a bit and once again when it comes to a bigger screen we're going to want to upgrade these sizes because currently only the text is working and so we can actually achieve that effect by copying that from there and pasting it in here although that's actually much too large so maybe i will keep them independent and to do that we'll just add the classes in here so i'm going to say text extra large and small maybe text 3xl uh which i three just like that so that's a bit smaller there and a bit bigger there so that's beautiful the last thing we could probably just do is say uh background of slate 900 because otherwise when we scroll we'll be able to see things behind it so we can equally just say background inherit and lastly we're just going to say border bottom border is going to be solid and we're going to have a border of white and so that would just put a nice little white border underneath out the top of our page so that actually looks fairly reasonable uh we can continue to build on that so if i just bring this down to the side yeah that'll do currently we can select all of this so on this particular font what i'm just going to say is select none so that we can't get that select effect uh and this icon is going to be interacting so for it what we're going to have to do is add some hover effect so we're going to say duration 300 so that all uh transition effects take 300 milliseconds so it's not an instantaneous transition and we're just going to say hover opacity 40. so now we can see that when i hover it goes dark and the last thing we probably want to add is just a cursor pointer so that's just going to be a nice little profile icon for us later so the next thing we're going to have to do for our to-do list is do our login screen and so that's going to be relatively straightforward and here what we're just going to do is add flex and flex column for our main display and also give it a padding of four and i might actually just try keep that consistent with the header so i might just remove that padding x of six so that everything lines up nicely and now i'm going to come back into our login screen remove our document and so now in here where we're rendering out our login i'm actually just going to remove these to set them back to fragments so that our main is the primary like container for that and what that means is that we can come into our login component and in here we can just say it's going to have a class name of flex 1 and so now if i said background green 300 it will once again occupy all of that space so that's super neat so in here we can say flex flex column justify center items center so that everything is centered and this is where we're going to have our login form so obviously the first thing we're going to need is an h1 tag and so that is going to say login and so we can see that pop up just down there now for that we're just going to say font is extra bold and we're also going to say that the text on this page is going to be small but on a smaller or bigger screen the text is going to be actually we'll make that small make this extra small just like that now for this we can change the login so that it sizes up so that just sets the default for everything else but for this login we'll make it bigger so we're going to say text to excel so that looks pretty good and then on a smaller or bigger screen we can say maybe text for excel so just like that so once again when i come out bigger it's just going to grow a bit larger so that is good beneath that well actually first i should probably just get rid of that background color because we don't really need it we have login next what we're going to do [Music] is have an input the type is going to be text just like that and so that's going to show up here and now for that we're going to give it a class of outline none because currently what you'll notice is that if i click on it it gets a weird outline and so now when i click on it we don't get that weird outline we're also going to have to say text is slate 900. so that we can actually see it we're going to say padding let's just see what padding 2 looks like honestly that doesn't even look too bad i think what i'm also going to do is just say width is full so that it occupies the full width but i'm going to say max width is maybe 30 characters just like that so we can set a maximum width so now what will happen is as we expand the screen it's going to reach a maximum width of 30 characters and we can see that that would change if i went 65 it would grow way bigger but we don't need that so 30 characters just like that and then we're also going to set a placeholder as equal to email address so now i can remove that we have email address just there i might just capitalize that and remove these bullet points so that's a nice little component we're also just going to have one for password just in here so i can change this to say password uh and for our flex container i can say a gap of four and on a smaller burger page i can have a gap of maybe eight and so now when we are on a big page that's probably too much to be honest so four looks actually pretty reasonable and then if we come down we could possibly even make that like two on small screens and get four in a bigger screen so that looks pretty good for a login screen to be honest uh once again for this h1 i'm just going to say select none because i really don't like being able to select that text and the last thing i'm just going to do is just set a duration to 300 because we just want to add some focus effects for when they focus on the login screen so in here what i'm going to do is say border bottom uh border solid border white but on focus i want the border to be cyan 300 and so what that should do is we can see that when i focus we get a little border but we can actually make that a bit thicker so i could say two so now you can really see it that when we select it we get that little border down the bottom which is kind of neat and we will consequently just want to copy that to this bottom component just here just like that magic so now depending on which one you select on you get that tiny little bottom border effect and so finally we're going to have a button uh and so this is going to have a class name of width full max width uh 30 characters to keep it consistent with the others we're going to say border is going to be one pixel white and border solid just like that and so in here we can just say submit and you know instead of doing that we could just do upper case for example that would work too so now we have a cute little submit button we also just want to add a py of maybe one uh honestly you could possibly make that two and so now we just have a really cute little login screen that looks actually pretty dope um i might however just change this from 30 to 40 so that we get a tiny bit more width magic and now we have a good looking login screen obviously the one thing we're going to need is that this button needs to be more interactive so for that what we're going to do is once again say duration 300 we're also going to say relative and in here we're going to add an after effect so after is going to have a position of absolute after is going to have a top of zero after it's going to have a right of full which is like 100 pushing away from the right we're also going to say after is going to be background white after z10 after width is going to be full and after uh height is also going to be full and so how this is going to work is that when we do this we can see out here so we're just going to have to set overflow hidden on the main component but now what we can do is we can say on hover we want after to minus translate x full and that didn't work because i was pushing it the other direction but we can see that now that it comes in but it can't really see it because it's happening too quickly so if we just add and after duration 300 to that we can see that now we get that nice little slider however submit is gone and we can fix that just by putting the submit inside of an h2 giving that a class name of relative and a z of 20 and in here on hover we can also just change the text color so the text is going to have to be slate 900 and so if i just wrap that submit inside of this h2 like that now when i swap we can see that the submit stays the same and we just get that super neat little hover effect that looks excellent so if i made to my own horn i actually think it's a pretty cool little login screen obviously the next thing we're going to have to do is actually wire it up but i can't stop playing with that button but essentially now to wire it up what we're going to need is some state so in here i'm just going to import use state from react and now inside of my component here i can just say const email set email is equal to use state uh and we're just going to have an empty string and i can do the exact same thing for password and do the same thing here password and now in these inputs what we can do is we can set the value is equal to password for the password and we can say on change is equal to pass a function take the event and just say set password equal to e dot target dot value uh and likewise we will want to do the exact same thing for this one just here the last thing we want to do is just change this to a password so that when we type it it goes like that which is cool we can actually see that it's changing the top one because i haven't switched the logic over but this will be set email uh sorry wrong way around this will be email and set email so now all of those states are working nicely uh the next thing we're going to do is just say function submit handler just like this and in here we're just going to say if not email or not password uh return so nothing happens uh but equally what we could even do is just add a little error statement and so we could add some error logic in here so we could just say arrow and set error and that can just be null for the minute and just underneath the login screen we could have a div that just displays the error like that but we can conditionally render it so if we just wrap it we can say if error is true and that then render this particular component and so in here uh we can say never but basically what we're doing here is instead of just having this return statement we can set some state so we could say set error please enter username and password uh we'll change that to email and so now what we can do is just quickly make this look a little bit pretty by just saying once again class width full max width is going to be 40 characters uh border rows for 300 i think we'll go text rows 300 padding y of 2 and so now if we have nothing in here and nothing in here and i click submit nothing happens and that's because we have to wire up this button so we just have to say on click is equal to handle submit handler and now when i click here we can see that we get this little text showing up however it doesn't have the border showing up and that's because we have to just add the rest of the border settings so border and border solid so border just sets the thickness but now that that works it's all good we can also just say text center uh and the last thing i'm going to do is change that to a 400 just so it's a little bit more intense so just like that please enter username and password so that will only appear if they enter it incorrectly cool so that's all good the actual one other thing that we might want to just enter is an h2 just here and this just says uh login uh if login is true then it's going to say login otherwise it's going to say register and close that and the reason i've done this is just because i want to have i want to provide the user the ability to switch between a login and a registration state and so in here we can just say const is logging in and set is logging in equal to use state and it's true initially so if it's true that means it's going to render it should actually render the register button because we actually want to allow the user to switch to a registration page and so we can just have that down here and we can say on click is equal to function and it's just going to be set is logging in to not is logging in and i think i might have just made a spelling error so i'll just make that like that is logging in perfect and so that's just going to say register down there i actually don't mind not having in all uppercase so maybe i'll just go log in like that uh we also just want to give it some quick little styles so we're going to say class is equal to duration 300 and we're just going to say hover scale uh 110 so like that and so now when you hover over like that it will pop up and the last thing we probably want to add is a cursor pointer cool so now when you click register it will switch to the login page and consequently we also want to change that text up here so where this says login i'm just going to say uppercase and i'm going to use a similar thing to below so is logging in question mark if it's true then they say login otherwise it says register so now on the registration page then if we click login that will change too so that's pretty neat so now that we have a fully fledged login page and registration page i think it's just about time that we set up our firebase product so for that what i'm going to do is go to firebase and head over to their console and so now that i'm logged in it takes us to this project page and we're going to want to add a project and so i'm just going to call this next to do we click continue we don't need any of the analytics we're going to let it create a project for us snap my fingers and it's done magic click continue and now we come into here and the first thing we're going to want to do is come into authentication and click get started so while that provisions us an authentication system uh we're just going to click email and password we're going to want to enable that uh you can optionally do an email link we're just going to stick with the email password and so that is now enabled and that's pretty much it so we have no users just yet but we can go ahead and start using that and the way that we will initialize that is by coming into firestore we're also just going to create a database while we're here and we will start in test mode actually now we're going to start in production mode you can use either and switch them around later it doesn't really matter and that's going to set us up a database for our project and now that we have a database we're just going to come into the rules section really quickly and just remove this logic just here so it's just allow read and write and so that's just going to be a totally open uh public database so as long as no one gets your credentials you're all good so now that we have done that we're going to have to initialize firebase into our project and we can do that by coming into the firebase documentation which will be linked in the description below and we can just go add firebase to your project and so we're going to follow this instruction just here and so the first one is going to be to go npm install firebase so if we come into our code stop that and click npm install firebase that should be good and while we're doing that we're just going to create a file called firebase.javascript where all of our magic is going to happen so now that that is installed we're going to have to copy this code in just here and so if i just paste that in straight away then that gets us off to a nice start and so this is the configuration file that we're going to have to come back and edit in a second but for our project we're also going to be using the authentication and the firestore so we're just going to say import get off just like that from firebase slash auth and we're going to have one more that's firebase firestore and this is going to be called get firestorm so just after this line down here what we can do is we can say export const auth is equal to and call our get auth and pass it in the app just like that why did that do get or pass an app and likewise we can just say export const database is equal to a get firestore and pass in the app too so that's going to allow us to access our database from these modules anywhere throughout our document so yeah as i keep saying we're going to have to find this configuration file and so to do that if we come into our settings and come down the bottom and click that you know here we can see our apps we're going to click on this web app just like this we're going to call it next to do and we're going to register that app now we've already followed all this uh instruction but we're going to copy this information just here and paste it into this document just here now yeah you can totally see these keys you should not let anyone else see your keys that's really important and to prevent that what we're going to do is go.env it doesn't matter for this tutorial because i will be deleting this thingymcjiggybobby but essentially we can see that i'll get ignore uses a mv.local so we can rename that to dot local and i already have this prepared so i'm just going to copy it across and basically all i've done is i've initialized these keys so all of them have to start with the prefix next public and then the key and i've just copied all of these keys into the document just here and so now what i can do is i can replace this with process dot emv dot and then the name of the key which is obviously going to be next underscore public underscore you know api key just like that and so what i'm going to do is copy this and then select all of these just like that swap them all out oh i forgot one silly me and now we just have to update the name so that instead of api key this one is just going to be auth domain uh this one will be project id this one is going to be storage bucket and then here we have method massaging sender id and lastly we have app id and so this is just going to protect all this information from people on the internet wanting to use it and landing it with a massive firebase bill so cool that's our database all configured and since we actually don't need this anymore what i'm going to do is just use this specifically so we can't open that up but i can go npm run dev here and it should provision all this information here now obviously we can see that somewhere in here i have a incorrect thing which i can just search for and we see that it is here so instead pass a string cross origin is equal to true so let's just do that and then we'll restart it once more and see if that goes away and look at that it does and now we have our working application working nice and neat perfect our registration page and so we're good to create our authentication so essentially for the authentication how that's going to work is we're going to use a context and so the context is going to get initialized just under here so we'll say context and in here we're going to make a new file called auth auth context dot javascript now we have a better code to write in here but we're going to start off at the top by just saying import react use context uh use state use effect and use ref so all of them we're just going to say from react and how the context is going to work is it's basically going to be a global state or a wrapper for our entire application that's just going to allow any page to access this authentication information so after that we're just going to say import auth and we're going to import it from dot slash firebase just like that ah that's wrong sorry from dot dot slash firebase and we're also going to import our database from there too uh then we're going to import some functions from firebase authentication so that's going to be sign in with email and password we're going to say create user with email and password and we're also going to say sign out and we're going to have on auth state change and now there's a bunch of other functions that you can use for example you know update password or send password reset email or any of those and then the one last one that we're going to need is just going to be some firebase firestore functions and so that's going to be dock and get dock just like that from firebase firestore now in here we're just going to say const auth context is equal to react dot create context and call that as a function and then just in here we're going to export a function called use auth and that is just going to return use context and we're going to pass it the auth context and this little export function just saves you having to do this logic in every component that you would like to access that context information finally we're going to have export function auth provider and then here that's going to receive children we'll open that up and now we're going to need some state so this is going to be current user set current user equal to use state null we're also going to have a loading state so loading and set loading equal to use state null and then finally we're going to have a const user info is equal to use ref just like that and that's going to store all of their to-do's in it so it's going to be just once again another global state now in here we're going to have a function called sign up and this is going to take an email and a password and it's going to call the method create user with email and password path in the authentication email and password then we're going to return the next one is going to be function login once again email password just like that and this time we're going to return sign in with email password auth email and password then we're going to have function log out return sign out auth just like that and once again you could go ahead and do this for all of the other functions like update password or anything that you might like but i'm not going to stress it and then lastly what we're going to do is have a use effect just here and this is going to run on page load and basically we're going to go const on subscribe is equal to on or state change and so this is like a listener that listens into the authentication state and to it we provide the auth and we're going to provide an asynchronous function that receives the user and in here we're going to do some stuff in a minute and then after we've used that function we're just going to return unsubscribe to tidy up and yeah that's all good we'll see how this works in a minute actually no i guess we should probably do it now and so how this on or state change works is we're basically going to say pretty simply set current user equal to user and lastly set loading is equal to false uh so i made a mistake here that should say true so loading is true until false exactly so that's pretty neat and so now that we've defined this use effect the next thing we have to do for this context is just say const value is equal to and we're just going to pass in the current user and all these methods so login sign up log out and user info and that's going to be value and finally we're going to return and here we're going to go auth authcontext.provider and it's capital p provider and we're going to pass in value as equal to value as props and in here we're just going to render out children if not loading so if not loading render out children just like that magic so that is all good now the very last step with this context is to use it as a wrapper in our application and so just in here all we do is go auth provider and wrap our whole application in this auth provider and we have effectively implemented our context but it looks like i have an issue and that's because i spelt that wrong that should say changed not change so if i just update that refresh that page everything should be working we should have that context available to us and so we can come into our login component for example uh or even better into our where is it this index component just here and we can call that by just saying const uh current user is equal to use auth and we could console.log currentuser and we'll see that we get null in our console perfect absolutely we get a double render because it's react strict mode which is only for development so that's excellent now why don't we actually just register a user so here what we've got is a submit handler and basically we're going to have logic dependent on whether or not it is logging in or isn't so here i'm just going to say if is logging in so if they're just logging in what we're going to do is call that function so here i'm going to say const login is equal to use auth just like that and i can just say login email and pass in the password just like that pretty straightforward and i can say return that for example and now what i could do is just say otherwise they're not logged in and they're wanting to register and so here i could just say the function was called sign up so we can import sign up just like that and now i can say sign up email password absolute magic and so now if we come down into our application we already have submit handler working we should be able to check login so let's try login so if i just go banana gmail.com submit that and now i get this big error and that's because it doesn't exist and so that's actually good and it also makes me realize that this needs to be asynchronous because this method here needs to be awaited as does the sign up method so that is all good the last thing we're actually going to do is also just come into here and say try and have a catch block and essentially we already have this error state and so if there's an error we're just going to say set error is incorrect email or password and the try is just going to go on there and so that's just going to handle that a bit better and so if i do that again so let's say we have banan gmail.com whatever random password submit that we get incorrect email or password showing up but now if i were to register submit that we can check if current user changed and just console.log that here current user and so we can see that we have actually been logged in because now we have an active current user with all of this information just here so the login system is actually working now that is excellent because it means that we can come into this index document and just say we're checking for current user here we can just say not current user render login otherwise we render out user so if if there is a current user then we could just say it dashboard for example and we could make that component right now and just say newport new component user dashboard dot javascript rfc save that save that lastly just import it and so now the login screen is gone and that is all well and good so one thing that i don't currently like is the footer because i think it's just lying there so one thing we're quickly going to do is just come in here and say class flex uh justify center items center gap three and in here i'm just going to go to font awesome icons and we're just going to take instagram just like that paste that in there we're also going to just take linkedin and finally oh no didn't want that back get hub because why not i actually think i prefer the little piggy paste that in so that should look kind of cute just like that let's see how that looks so now we have these three little icons i'm just going to give them some py of three cute uh now i'm also just going to go duration 300 hover opacity 30 and cursor pointer now what i would recommend doing for these is putting them inside anchor tags so in this particular case what you do is you just go anchor uh like that and you would say href is equal to whatever was you know the length that you wanted to you could say target is equal to underscore blank to open up in a new page but that will just redirect you to a new page but now we can see that we have this little hover effect down the bottom for our little icons you could probably just increase the gap to maybe like eight that's too much five five looks good a small little page we've got our little icons and finally we get to doing our user dashboard i'll just zoom out let's go back to 125 100 cool uh actually just before we do i use the dashboard the other just the other thing i just want to quickly work on is how we could just include a super cool model uh for logging out let's say you had a menu and so in this particular case what i'm going to do is just make a new file and call that modal.javascript and then here we're going to go rfc and this is going to have a class of fixed uh width screen height screen uh inset of zero background white text slate 900. um we're also going to say flex and flex coal and in here we're going to have a div that's class of flex items center justify justify between this is going to have an h1 tag that just says menu and then underneath what we're going to do is once again come into here and just say close and take this little x mark and paste that in there like that and we're also just going to say border b border solid border slate 900 um and a padding of four and now underneath what we're going to do is just have another div secondary div and this is also just gonna have class of p for flex flex column uh gap of three and in here you could just have any buttons and so in this particular case i only really have one for the minute and that's just going to be log out uh and how this modal is going to work is it's going to receive some props and that's going to have const set open modal can't spell that modal is equal to props and we're going to define this in our header so we're going to need state in here use state uh and here we're just going to say const uh open modal and set open modal is equal to use state false um and we're going to use react fragments pull this one right down to the very bottom and in here we're just going to say open modal and we're going to render out the modal just like that we'll also just have to pass and set open modal is equal to a set open modal and the last thing we can do is open this model on the icon click so on click is equal to set open modal true just like that so now what we'll see is that when i come in here and click on this we get this modal showing up which you know it is what it is exactly it's not quite working 100 the way we wanted to but we'll see more about that in a second so what comes next well in this particular case what we're actually going to do is render this slightly differently and so down here what we're going to have to do well actually first up the top is just import react dom dom from react dom and so that's just going to allow us to access the document object model and we can use that by saying react dom did i spell that correctly react dom so it's actually react d-o-m like that dot create portal and how this portal works is the first argument is going to be all of our jsx and then the second one is going to be underscore document dot get element by id and we're just going to go portal now we'll see how that works in just a second but first we just quickly have to define document and so for that we're going to need some state so we're going to say const underscore document set and set underscore document is equal to use state null and we're just going to have a use effect just in here and that automatically imported just up there just so you note and this is going to run on page load and basically this is just to prevent any fiddly handling but we just set document on page load equal to the document uh and if it's not underscored document then we just want to return null and the reason we do that is because of the way next js renders components sometimes the document doesn't exist when you go to use it down here so this is just going to make sure that it does uh and consequently we can come into this thing here and since i copied this code across i already have this div available just here but now what we can see is we have our portal and so it's going to render it in this component and we can see that our to-do list is down the bottom and that is not how it should be so essentially and that's because i'm a complete and utter muppet and this should actually be logic in a different component so this should instead be used in the modal so just like that which means that we're also going to have to copy across this paste that in there we're going to have to copy across all of this logic because i'm a silly egg and we're just going to have to import use state and use effect um and lastly this line just there and this stuff just down here this document just there so we can just paste that back in and so now if i save that again this should be back the way it originally was just like that and now when i open up that we can see that our modal shows up perfectly we don't get any of the extra pages and we should be able to click on close so here we're going to call the set open we're going to say on click is equal to and that's going to be set open modal false so now we can close it open it close it open it uh you can also add some cool little hover effects on this particular case you could say duration 300 hover rotate 90. and so now we can see that if i come up here and do that it does a little spin which is kind of sweet we're also going to say cursor pointer and we're going to increase some font sizes so this is going to be font extra bold uh we're going to say text extra large maybe we could even go to excel because that still looks fine uh and on small we could say text five extra-large so now when we come on to a bigger screen it gets nice and big we get a huge little menu we also want select none and we also want to make that larger so here we can say text large small text xl so that's probably pretty good we've got our menu and now on our log out we actually just want to make sure that it does log out so here we're going to say class name is once again select none we could just say text and here what we could do is actually just say text small and on a small screen we could say text base but maybe that's way too small so i actually reckon we're going to say text base actually we can say text large and here we could just say text extra large so it's just a bit bigger for our menu and finally we can say duration 300 hover padding left is two and so what that will do is it means that when we hover over it it just comes out a little bit it's kind of fun and obviously cursor pointer now you want to click it and log out or you can close the page so that's super sweet and we could actually use that logout method so we could just say const log out as equal to use auth just here oh wrong one a u t h and we can just say on click is equal to use auth and so no it's not is equal to log out and so we can actually test this now so when i click log out we can see that our state is gone and so we want to add some more stuff to this so here what i'm going to do is actually just turn this into a function so i'm actually just going to say log out call that method but also set openmodal equal to false just like that so now if i close that we're logged out and our log our screen is rendering and so now if i log back in which i can't remember but we can actually look by coming into here and going into authentication we can see what the username was although i've totally found the password because i'm useless so in this particular case i'm actually just going to create a new user register banner at gmail if i can spell dot com one two three four five six submit we're logged in we can come into the menu we can log out and we can consequently log back in so that's really cool we actually have a fully functioning site now uh the last thing to do is do the user dashboard and the database so let's dive into that basically how that's going to work is we're going to want to give them a to-do layout and the way that i'm thinking we do it is if we come in here i created this user dashboard component and so we can just say class name is with full max with uh it's going to be 65 characters and mx is auto so that it's always centered we're also going to say flex flex call gap 3 and then on a small we're going to say gap five now in here what we're going to do is say const user info is equal to use auth and we'll have to import that and so that's just going to provide us any user info that we might have and so if we don't have any user info then we're going to render some stuff otherwise we're just going to render a button and so the way that we can do that is just use curly braces sorry if that didn't make a whole lot of sense what i just said but you'll see in a second so we take the curly braces like this and we're just going to say user info and this stuff here so that's just going to ensure that user info is not null um and in here we'll render out all of our to-do's in a moment but beneath that we're going to have a button which is going to have class of you know let's say background cyan 300 uh text slate 900 uh padding y of two i mean we could just and text center and in here we can just say add to do and i might just make that uppercase and let's say font medium for boldness and in this whole page we just want to say text is extra small but then a small screen text is small and this can be text large so now we have a button here um and how this button is going to work is we're going to give it a duration of 300 a hover effect of opacity 30 and i'm actually going to change this so i'm going to keep the text i'm going to change this to text cyan and instead of having the background i'm just going to say border border solid border cyan 300 so now it's just going to look like that which is a i think a better looking button we could even actually probably just get rid of this font medium so that's kind of cute so now we can add a to do uh what we want to display up here is the you know a place for them to have an input so we'll need some state for that so we can just have use state const add to do set add to do and that's equal to use state uh initially it's going to be false and the second one we're going to say const to do set to do is equal to use state and that's just going to be an empty string so in here above all of our to-do's what we can do is we can just have an input and the type is going to be equal to text and the placeholder is equal to enter to do and the value is going to be equal to to do and on change is equal to we have to get the event and we're going to set to do equal to e.target.value so the value of that input and finally we're just going to give it a class name equal to uh outline none padding two and obviously that should just about do it so let's see what that looks like so here we have our to-do i might just make the font size a little bit bigger so we're going to say text base and then small text is large and so now if we come on to a bigger screen that's how it looks and so in here we can enter out to do we're going to have to change the text color 900 uh and i might actually just make that three so it's a nice big box uh where you can enter whatever to do you might have now what i am going to do is just put this inside of a div so this is going to have class of flex and items stretch and the input is going to go first but after the input we're going to have a button that has class of width fit padding x of four small padding x of maybe six padding y of two small padding y of three uh and that's going to have a background of uh amber 400 text white and in here we're just going to have an add button and so what that's going to do is it's just going to sit there like that i might just make it font medium text uh bass how does that look that's not too bad and then in here what you can do is to the input you can just say flex 1 and now it's going to push out to expand the whole thing and so this little add button the way it's going to work is when we're entering it to do we're going to be able to select add at the end of it and so for that we're obviously going to want to add a hover effect so we need to go duration 300 hover opacity 40. so now when we hover it goes a bit dark and then the last thing i'm going to do is i don't want to show this button if the add to do is on so if add to do is true then we don't want to show it so we're going to inverse that logic just like that so now that if i refresh this page uh and wrap this add to do section in there because we only want to show it when we have it so add to do and now what's going to happen is we don't have any to do this but if i click add it should do it but it won't be so on click equals set add to do true add that on click handler i click it it gives us the ability to add this to do now the last thing we're going to do is just have a use effect that changes on user info and it says if not user info then basically actually no let's say if user info exists and because it's going to be probably an object so let's say object.keys user info dot length is equal to zero then we actually want to set add to do to true so that when i refresh the page if user info we're actually even better let's say if not user info and object dot keys so now when i refresh the page well essentially what this will do later is it will just set that to automatically true uh but yeah so that's pretty cool now we have a little to do that we can add the next thing we're just going to have to do is actually persist it and so for that what we're going to do is have some state and so the way the state will work is we'll just say const to do list set to do list is equal to use state null actually let's just go for an empty array just like that and just let me check something um while we're at it we can actually just delete this api folder here we don't need it and so the next thing is that when they added to do we're going to want to handle that so we're going to make a function function uh it's going to be an asynchronous function async function handle add to do open that up and in here what we're going to do is just say uh set to-do list and we're going to set an object and spread the current to-do list uh and what we're going to do is create a key that is the maximum of all the current keys so we're going to say object well it's actually going to be math.max dot object dot keys can i spell keys to do list and then to that we're going to add one so it's always a new and larger key and then the value is going to be whatever the current state of to-do is so that should add a to do we're obviously just going to add a clause that says if not to do then we just want to return because we don't want them to be adding invalid to do's and so now what we can do is just assign that to this add button here and we can say on click is equal to handle add to do and so now i should be able to say let's actually just console.log to do list just like that and so now when i say james is cool and click add we can see that negative infinity has given us james's cool and so that is problematic uh math.math so to-do list needs to be changed to an object i think it's the first thing so let's refresh that page and do that again so add to do banana okay infinity so the last thing we're going to do is just have a variable here to make it a bit clearer so we'll say const new key is equal to abstract all of this and just say or one so if that doesn't exist it's just going to set it to one otherwise it'll do it so let's try that new key refresh add to do still infinity so i guess we're going to have to be a bit smarter and just say since there's technically no keys we'll just say object dot keys dot to-do list dot length equals zero if it equals zero then we'll just return one otherwise we'll return that so i think it's probably going to be the most robust way to do that so let's once again refresh that page added to do and we can see that the key is one and so for that what we're going to do is in here this is where we're going to map them all out and so now we can say uh object dot keys to-do list dot map and we can just say to do take an index and we can return just a div for the minute that has that to do now when you return a map you also have to say that the key is equal to the index uh and so now we can see that it's actually rendering out the to-do whereas what we actually want to do is have the to-do list and take the value at that key and so now asd renders which is just what we wanted uh and so this is going to have some styling of its own and so we could just make a new component and so we're going to say to do card dot javascript rfc and i'm actually just going to probably so this is going to have props and let's just say const children is equal to props and in here we can just render out the children content like that i think is going to be the best way and so i can just change this to to do card just like that so now if i refresh that page added to do banana banana is out to do and it pops up so that's perfect now in our to-do card we can give that some styling so we're going to say class is padding 2 border border white border solid so that we get a nice little border around it um and here we're going to have a div and this is going to have a class of flex 1 because this is going to have a class of flex uh and items stretch just like that now we want the content to have a class of flex once it occupies most of the space and then after that we're going to have another div with some functionalities like delete and stuff like that later and so in here we're going to have two icons the first one is going to be delete let's see what comes up so i think we more specifically want a trash can so if i come in here we can open this up and we can have the trash can swap out the class for class name and then the other one is going to be a pencil which is just going to be to edit just like that so in here if they want to edit it they have the opportunity to and so i'm once again just going to give this a class of flex and a gap yeah just a class of flex um so now we can see here we have our two icons i might just say items center so that they're nice and centered and then for each of them i'm just going to give them a padding x of two px of two just like that so they sit down the end which is super sweet uh we're also going to say duration 300 for the pencil that we have the hover effect is going to be a rotate 45 and for the trash we're going to say duration 300 hover scale 110. so hover over that or that you could probably even go 125 for the trash can yeah so it jumps out at you and now we could also just do cursor pointer on the two of them cool and so that actually looks really cute we have a nice and neat little to-do list that we can copy and we'll be able to edit it soon uh so now when we add that to do i actually think i prefer this than having the button to be honest so honestly what we could do is just have this as a permanent ad feature and have all of our to-do is listed down below so i might come in here and for now just comment that out and we can just make this a permanent addition just like that so you can always do it and it also means that we can actually just comment that out for the minute too so now this is just always going to be there so i could say buy bananas add it and my to-do list shows up uh other neat things you can do is we can just come back in here and just for this we can just say uh capitalize just ah probably not actually because it will do it for all of them but just like that i think it's pretty good uh and the last thing i might just do is just say small p3 make it a bit bigger so now if i said aloha it adds a second to do and then it also makes me realize that when we added to do we also just want to set the to do to the original state which is the empty string so set to do to empty string so now when i add uh let's say we have pick up james from school we add that it enters it and it's all good um how does it look on a mobile device looks nice and neat very tidy excellent can't complain uh we have our nice little log out screen our little header our little icons the last thing to do is to persist it to a database and that is actually relatively straightforward the first thing we're going to have to do is just come into our database and we're going to start a collection called users now in here i'm just going to create a random one called master for the second but that is just going to look like that so how this is going to work is if we come into our uh user dashboard we're going to need some logic to write some information and so the logic that we're going to need in this component is import dock set dock just like that equal from firebase firestore uh and we're also going to have to import our database so import db from dot dot slash firebase just like that and so now what we can do is when we do this handling add to do thing we can just persist that to our database as well and so in here we can just say const user ref is equal to doc we pass the db we select the users field and in here we're going to say current user.uid and then the next thing we're going to do is say await set document we'll pass it the user ref just like that and now we're going to open up an object and in here we're going to have to do's for example just like that to do's is going to just be our the exact same thing we set it to here so it's just going to be new key uh and to do magic except the one last property we're going to have to pass in is merge is true otherwise that would what it would do is overwrite our document completely and that is not what we want and so now if we come back into our app and i say james is cool and add that we get an error because current user is not defined and so we have to import current user just like that and we'll see that if we come up here if i can find it i think i stopped consoling it but basically this user has an associated uh uid with their name and so when i added to do james is cool and if we come into our firebase we can see that we have this document here and we have james is cool and so it's super convenient uh this is the user id and so it will just if i add another one let's say for example by bananas click add it's been added to our to-do and it's merged them together so that is literally our data persistence the very last thing we have to do is obviously if i refresh the page the to-do's are still gone you know so i have to somehow pull them in on page load now there's two ways you could do this the way that we're going to do it is with react hooks so i'm going to make a new file called hooks and inside here i'm just going to have a file called fetch to do's dot javascript and in here we're going to create a component and it's going to be called use fetch to do's now for it we're going to need react use state uh use effect and use ref and we're also going to need some firebase functions so we're going to have import dock and get dock from firebase firestore uh and so now that we have them uh we'll also need import uh we can do that later okay so now that we have them we're going to have to define some variables just here so we're going to have const uh loading set loading is equal to you state true for the default state we're going to have const error set error is equal to use state null and finally we're going to have uh const to do's set to do's is equal to use state just like that and that will also be null so down here what we're going to do is instead of returning that we're actually just going to return an object that has loading error and to do's just like that magic and in here what we're going to do is write a use effect that runs on page load so we can pass it and empty a dependency array and we can define a function so we're going to say function fetch data it's an asynchronous function and in here we're going to have a try block and this is going to say const dark ref is equal to dark past in the database select users and select current id dot sorry current user dot uid so we'll need our current user so that'll be const current user is equal to use auth just like that uh and then in here we can have a catch just quickly error and a finally but after we have this uh doc id the next thing we're going to do is say const doc snap is equal to a weight get dock and we pass it the doc ref just like that and so now what we can say is if doc snap dot exists and call that method then we could just say console.log doc snap dot data and call that method two uh and i also just want to say if doc snap dot exist i forget which method it is so i'll just say console.log oopsy so now if we catch an error we're obviously going to want to set error equal to true uh or we could be more specific and say failed to load to do's and then finally we can set loading equal to false and so in this block here we're just going to run that fetch data function and now in our user dashboard we can call that in here so if we come down well actually let's do it at the top we'll say const uh to do's loading error is equal to use fetch to do's and run that just like that so now obviously nothing happens but if i go console.log to do's we get nothing back so let's just check that this is running if i console.log banana so banana is running and so we can see that when i run that if i add a console.logger the error in here that i'm actually getting an error and it's telling me that database is not defined and that's because we have to import db from.firebase and so now when i reload this we actually get our to-do's coming out so that's super cool and so in here what i can do is i can say well first we know that this has worked adequately and so i can say set to do's is equal to docsnap.data call that method.todos uh and so now we have our to-do is just there so that's super neat so i can remove all these console.logs that can go where's the other one that's one that's two i have to move that into there just like that and so i can remove that cool and now in here i can actually remove this to-do list object and just go off to do's instead so down here where i map them all out is just going to be to-do's to dos.map cannot defer okay and so the one other thing is that obviously it's going to have to be user info and not loading uh so the last thing we have to change is swap that out just like that refresh the page it loads and so what you could do is you could say you know if we have user info and loading and we could have just like a div and just have a tiny little loading state so you know we could open this up onto a new tab and in here we could have like let's say an atom or you know what's cool thinking i wonder if they have a brain thinking time tap loading what do they have for loading spanner so let's just do this uh we'll copy that in give it an adequate class name and we can just say animate spin in here and what that will do is when we're loading this let's actually also just say this will have a class flex 1 so now when i refresh the app we get that tiny little loading symbol so in this particular case what i just want to say is uh we need to so that's flex flex coal let's just make that flex flex one so that it occupies the whole space now when i refresh that that's there yeah i mean what we could just say flex or grid place items center let's see if that works yeah so you can see that tiny little loading icon i could even make it bigger so i could say text six extra large refresh we get the loading that shows up it's all good the same thing here loading icon to-do's have loaded and so just like that you actually have a super functional to-do app the last thing is obviously to edit and delete them and so for that what we're going to do is just say we'll use another state so i could change this to edit set edit as you stay false and so in this particular case we could say we can pass that into the card because that's where the thing is so set edit is equal to true sorry set edit is equal to set edit and we'll also say edit is equal to edit um and so what that will allow us to do is that we can come into our to-do card and on this particular click we can no sorry that's the delete it'll be this one on click is equal to set edit equal to true so we can have that in here so that'll be edit set edit uh edit and set edit and now when i click that it will set edit to true but what we actually want to do is make this whole thing relative and what we're going to have up here is just a edit and we're going to have a special div that when it's true well actually even better what we could do is we could just say instead of rendering out the children we could make that an optional render so watch this so when i say uh i will say edit if edit is false so we'll say check if edit is false then we're going to render our children just like that otherwise and we can open that up onto a new line we're going to have an input that has a class of bg uh let's say inherit uh text white just like that we'll say p sorry p2 uh placeholder well actually we can just set the value equal to the current children content and we can have the edited value set edited value just like that i think yep just like that and so now what we can do is actually change that so that's going to be edited value and we can say on change is equal to take the event set edited value e dot target dot value so what this is going to allow us to do is we'll see in one second but what i'm going to do for the minute is just say yeah actually that should be fine text white i don't know that i even need to add that padding but we will need an outline of none so that's put it as james's call why is it done that edit children flex one if i refresh that page it loads out to do's james is cool james is cool we have to comment that out and now when i click edit it displays both of them but the thing is that we only want to actually set it to a particular thing and so if we come into our user dashboard edit needs to be a truth statement and so what we're going to do is when we set edit we're going to have to pass in the index so that's going to be the index is equal to i and so now in our to-do card if we receive the index so no so when we click on an edit button we're actually going to make a change so we're not going to set that to true we're instead going to set it to the index so we do indeed have to pass down the index uh just like that so if i come in here and i just say index is equal to i but the edit parameter is actually going to be so let's just change that to edit bull is equal to edit is equal to the current i just like that so basically what will happen is it will only display on one of them so in this particular case if i do that well that didn't really work did it so i can close that set edit index let's just console.log console.log index zero zero one one okay so i'm actually just going to re-change this so set edit is going to be a variable so we've initially got it set to null is what i want it to uh if we're editing it then i want to set it to the to do so set edit i'm actually going to just create a handler up here so i'm going to say function handle add edit and this is going to say it's going to take an element so it's going to take the to do index orders to do key and i'm going to return set edit equal to that to do key just like that and that's going to be inside a curried function so that's going to handle the edit and so i can call that handle add edit is equal to handle add edit now the next thing is we don't need that so we do need an edit so edit is going to be equal to edit and so that's going to be the index and so the final thing we're going to have the bull is equal to and so we're just going to also have the to do key and so that's going to just be like this and so essentially in our to-do card if i just change this to the to-do key which i should realistically call it more properly to do key just there uh didn't like that did it to do key is equal to to do that should fix that and so now we receive the to do key and so basically instead this is just going to be if the edit is equal to the to do key then it replaces it so let's see what's happening there index is not defined where we get rid of that so now when i refresh this page it pulls the information in we click edit index is not defined where do i have index ah set edit it'll be this one i think line 16 yep so that's going to be to do key so now when i click edit set edit is not defined uh do i pass in a set edit no i do not okay ah so it's instead handle add edit so that gets changed handle edit and that is going to be just handle edit with the to do key just like that let's try that so now that's actually working so we have an input here that we can do but set edited value doesn't exist yet so in our main dashboard we can just add that in so we can say const edited value set edited value is equal to use state nothing uh and so what we're going to do is when we set the edited value i'm actually going to add in something here so not only are we going to set the edit true but we're going to set it to the current state so we're going to set edited value equal to to do's for that to do key and so just like that when i click that it didn't show up but i think the reason is is because in here i'm going to have to change nope that value is correct text white let me just refresh that page let's try consoling edited value so edited value is undefined so for some reason that didn't work to use to do key set edit so that seemed to work that was line 41. so if i just try console ah the reason is because i wasn't actually passing down edited value so we have to add that in here is equal to edited value so now when i click on that that all works and i also have to pass down set edited value equals set edited value uh so yeah that basically should do the trick let's try that once more so i refresh the page console.log that so now it's actually an input box that i can add to and the last thing i'm going to do is change that to a tick just like this so if the tech is displayed i'm actually just going to have some conditional logic here that just says uh edit well in this particular case it's going to be edit equals to do key question mark uh it's going to be this or that um so let's just try saving that so now when we edit we can see that we get that little tick which is kind of cute i'm just going to copy some of the styling so probably the same stuff as just here just like that paste that in there so now we have the little tick and then on the tech what i'm going to do is just have a handle handle resubmit function which i'm actually going to paste into here because we already have all the relevant functions so this is handle add to do we're going to have handle edit to do which is just going to have the same function or same content uh we have to define it as a function and make it asynchronous and so if edit or i guess it's edited value right is not then it just returns otherwise what it's going to do is not generate a new key uh it will set edited value and set set edited to uh null again and we're going to instead of having a new key we already have the key so that's going to be continue key is equal to edit and that should actually just overwrite it and so now if i save all of that let's say i click this tick currently for here it just says james is cool but if i click tick nothing happened and that's because i haven't assigned the function and so now if i just pass this function down in here so we're going to have handle edit to do this as that import it in here and we can just say on click with this particular one here so this on click is equal to and passing that function and so now when i click on it we get set to-do list is not defined and that's because it doesn't actually exist and honestly we do need it to do's so we'll also have to have set to do's uh and use fetch tools so we can just get that really quickly by going into a hook and making sure that that gets passed down as well set to do's oh that was the wrong one so we passed that down we update to do's set to do's is here just like that we change that new key and that just saves us having to re-fetch all of the information so now i can edit this it's now an edit field i can say banana click okay set to-do list is still not working and that's because that needs to be set to those i thought i'd change that i guess both of them have to be okay so let's try that once more sorry that was a bit chaotic uh the other thing we just have to make sure is that if we do have this input that the flex is still one so that it takes up the maximum amount of space because currently it's only when i click over here input flex is one flex one so that should just be flex so now we click off we click anywhere so now i say click the tick to-do list is not defined still got a couple more things to resolve so that's just going to be actually to-do's and this one is also going to be to-do's let's try that once more so if i take uh did it update in the store it set it to an empty string and that's probably because i'm a muppet and i'm actually setting these values to nothing before i do all of it so what we want to do is paste it down here you could actually you could have this one work first and then do the rest of it uh but you definitely want to make sure that this logic is beneath just like that especially this bottom line because we have to make sure that we still have the to-do accessible okay so now we refresh our page let's delete let's change this to banana update come back into our application edit that add some stuff click tick it goes away uh because we why is it gone away there's no longer an input value if we come back into the store it's still setting it to an empty string and that's because it's to-do which is an empty string whereas it should actually be edited value um just like that so let's try this once more sets asd we refresh our page we edit it asd asd we click tick and now it's updated and we refresh our page and that is persisted and then the very last thing is the button and so for the delete button that's actually super simple all we have to do is come up to here and input delete field and pass that well actually we can just have a function so we can say function handle delete it takes a to-do key just like the rest of them it's an asynchronous function and in here what we want to do is return an arrow function that first removes it from to do's so it's just going to be uh to delete to do's dot whatever index it was i guess is to do key so that's going to remove it from here and then the second thing we want to do is copy this logic once again so just like that take the user get the to-do's have the key and the key is going to be to do key and we just want to go delete field and call that as a function just like that so now once again we can pass this down into our little component here by just saying handle delete this handle delete uh a weight isn't allowed inside of a sorry this needs to be the async just like that and then we've passed that into our to-do card we can receive it in here so we're just going to say handle delete and then we can call this method on this icon here so we can just say on click is equal to handle delete and pass it in the to do key magic and so now when i run that to do key on click is expecting a delete and so now when i do that we can see that it's actually removed them both from my to-do list which is now an empty object so if i refresh the page that's all gone if i say banana it adds them all back handle add sorry i just need to fix this one last thing so in here we're still doing set to do's add to do that should be to do's that should also be to-do's to do is to do this to do is to use cool so that's all resolved uh let's add that back in add so we have banana it's back in the database um but now for the delete we need to make sure that it is updating our new thing and so the one thing it's not doing is we can't actually do that because it's a state so instead we just have to say const temp object is equal to to do's and then in here we can run this method on temp object and then finally what we can do is set to do's temp object and that should just eliminate that key from our object so now if i say james is cool we can add that and then if i delete bananas bananas is indeed deleted from here but for some reason it's not wanting to go out from there so i think maybe instead if i try spread it like that it might work let's try that so if i delete that okay so that actually worked that was perfect just because i'm a mopper and i missed this in the video james and just like that and so now we have full crud oh banana save that banana banana's updated yeah so that's pretty much our whole application just all done magic like that you can do whatever you want two small things you'll want to just change is here this should just be loading whereas currently it'll have user info and loading is the first one and then the second one is in the fetch to do list you'll also want to just add this tiny little else block afterwards to this doc snap but other than that you should be sweet uh thank you guys so much for watching but if you enjoyed please like and subscribe i super appreciate it and i'll catch you guys in the next one peace out you
Info
Channel: Smoljames
Views: 21,881
Rating: undefined out of 5
Keywords:
Id: UzMr7-0FgA0
Channel Id: undefined
Length: 116min 44sec (7004 seconds)
Published: Sat Jun 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.