Build a Fullstack Food Ordering App with Next.js 14 (react.js, mongo, tailwind)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome back today we are going to build this full stack foot ordering app using latest nextjs so this is our homepage H with a hero section here here we list Our Best Sellers from the database here we have a little bit about us section and contact us section we have also here some navigation like let's go for example to this menu here and as you can see here we list all of the menu items that we have in in our database uh let me show you I can for example add this classic chicken pizza if I click add to cart it will go straight to our shopping cart and for example in this one pepperoni pizza if I click here as you can see it says from $12 and this is because we have defined several sizes here so you can buy small medium large and then there are also some extras that you can pick if you want then I can just click here add to card and now we we have two menu items in our shopping cart all right so now let me show you the shopping cart here as you can see on the left side we can uh see our products and then we have a subtotal delivery fee and total we can remove um those items from our shopping cart if we want and then on the right we fill our address and phone and phone and so on and then if we H this pay button it will redirect us to stripe page and here we can just pay using our credit or debit card so let me just fill this uh information here and if I hit pay then it's PID paid and as you can see I'm redirected to the thank you for your order page where I can see uh what I ordered and the information about the address if we go here to login let me show you you can log in with both email and password you can create also here your account on the register page with an email and password or you or you can log in with Google so I will log in with my Google account here and if you log in you can go to your profile by clicking your name here and in here you can change your image information address like this and this address will be used on the shop shopping cart page and so you don't need to fill it manually every time you buy something if you are logged in as an admin you will also see those uh extra free tabs here so for example you can go to categories but only if you are an admin you will see this only if you are an admin and in here you can edit and add or delete the categories then as an admin you have also menu items here where you can add edit and delete menu items let me for example show you this pepperoni p uh in here as you can see we have a title description category we have base price and we have even here sizes so we can add edit and remove sizes and we can apply different prices for those sizes and we have even here extras that we can add for example extra cheese for $1 extra pepperoni for $2 and so on if you are not been you can also see all of the users and you can addit the address information about them images and you can also apply if they are admin or not so you can invite your friend and make him or her an admin if you are logged in you can see all of the orders and if you are an Adine you can even see orders of other people you can of course also open each order to see all of uh the information for this project we are going to use latest nextjs 14 Tailwind CSS for styling and for our database you will learn a lot about nextjs stripee checkout and Co react Libs you can use for your future projects this tutorial may look like it's very long because it's 12 hours but that's because I wanted to explain as much as possible to make it easy to follow even for beginners the whole project is built from scratch so there is no starter code or anything I will put the timestamps and the source code in the description and as always all I ask for is that you will smash that like button for me to give me some extra motivation for the future projects and if you have questions or anything let me know in the comments and now without further Ado let's dive into the code all right so as always we start with an empty directory here as you can see I have opened food ordering app an empty directory in my editor and here on the right side we have just an empty Chrome tab and now as you can see I have opened terminal here inside this directory so we can scaffold a new Next app right so I'm going to use yarn but you can use uh npm if you want but yarn is just a little bit faster so I will do yarn create uh app sry yarn create next app and uh let's just put a dot here so it will be installed in the current directory and now we have some questions typescript no not this time es link yes tailin CSS yes uh Source yes up router yes and uh customize the default uh import alas now now everything is installing and now we have everything installed so we have this public source and some files here all right but now let's start by uh opening this app right so in our terminal let's just do yarn Dev and we have our uh link here that we can open inside our Chrome browser let's see and we have an nextjs app running here all right so uh now let's be build a structure of our app first so we need a header on the top then we will have a hero uh section here and uh then we will have a menu and stuff like this all right so let's go to our source and inside up as you can see I will hide this terminal for now and we have layout and we have page let's start with layout uh here we have a font that is called inter and instead of inter I would like to use Roboto uh so I'm going to rename this and change this and let's rename this to lowercase Roboto right so now we have an error because we need to uh change here to Roboto and uh now let's see if I refresh still we have an error missing wave for font Roboto okay so we can have different weights here uh let's see I add here weight and um let's see can we do let's do a string and let's do I want to have several weights uh so I want to have 400 500 and 700 let's see if this will work uh I will put this as an array let's put those three here now it looks like it needs to be a string so I'm going to put it like this without an array and I'm going just to add commas here inside this string now let's see no this doesn't work well looks like we can do an array uh but here we have an another phone loader values must be explicitly Rel literals let's see what happens if we change to regular strings if we will still have this problem no it moved to this 500 so I'm going just to replace those uh back ticks to regular uh ticks like this so let's put it like like this and uh it works so now we have our Roboto font and yes it was an array that we need to put for weights all right so I think that will be it for now for our uh layout file we can change the metadata uh later let's go to page because here we have a lot of stuff going on so I'm going to remove all of this HTML here and I would just put I would just put a div with test inside uh we don't need this next image for now so I will remove it and I will see we have test we have this black background as you can see with white text and this is because inside the global CSS we have some styling here I'm going to remove it so we have only those Tailwind Imports and we have this white page now and uh that's better now uh let me go back to our uh layout because inside the layout I'm going to define a main component main element sorry and this is because I want the website to be centered in the middle so it will be something like this yeah something like this so uh here I will put a main and the children will go inside and for this main element I will put class name and let's do Max wave of uh the try 6 XL and let's do border and let's see how it looks like yeah so as you can see this ends here we just need to make it centered uh so as the MX Auto so the margins on the sides will be uh uh automatic automatically set and as you can see now it starts here and it ends here maybe that's too wide I want to make it a little bit more narrow so we do for XL and and uh yeah now it's uh much better all right so let's go to our page and now instead of this test uh and this div we need to put like several sections for our page first will be header so um let's replace this with just a react fragment and here the first thing we going to need is a header right so let's just put a header like this and uh inside our header we have a logo so let's put an a tag for now and here will be logo let's call our uh pizza place s uh Pizza S Pizza why not and then we will have a navigation so let's do nav tag and we will have like uh five elements here five links so I'm going just to put uh regular links for now or maybe actually we can just H change it to a link I think link will be better uh so let's do link and the first will be to uh home and I'm going to copy this for five because we'll have several links inside our navigation and we will do menu menu we will have also about we will have um contact and we will also have login something like this um that should be it let's change also this to uh link as well so our logo will be link and um yeah now let's see so now we have something like this and um now we need to style this a little bit so uh first let's see if we can add class names to the link component and I want this to be um text red 600 let's see if this will work yes it works um I want this to be I will remove this text R run alth maybe I would just leave it let's do text wave no h just wave let's see bold we can do font bold and semi bold let's do semi bold uh yes that's better uh for the logo I want this to be bigger so let's do text to XL yeah something like this I don't like this uh red color uh let's see if we can do 400 then it's like this 500 and then it's this I want to have my own color so to do this and I will go to Tailwind config and um let's see we have some config here background image I don't need this background image I only need to add the colors and I'm going to add primary color and uh for me the primary color will be will be let's go here this one f13 a01 and it's like red orangish color right and now we can go to page and instead of text red 500 I can do text primary and now it's the core that I want to use here all right so uh now we have our link here I'll put this here and this closing tag here below so this works now um I want to style those uh navigation items here so uh let me see for navigation I will add class names I will put it as Flex so the the will be next to each other but I also need to put flex on the header so the logo will be next to our navigation let's do Flex yes and let's align this in the middle so let's do items uh Center yes I'll make it a little bigger so it will be easier to see everything and um yeah now I want to do space here as big space as possible so let's do justify in between so I'm so this did this space automatic space here now I want to have some spacing between those so here inside navigation let's add gap of uh four let's see yes this works nice um this login sticks to the right side and the logo sticks to the left side so I'm going to go to our let's see inside app back to our layout and we have this with Max with but I'm going also to add padding on the sides maybe padding on all sides let's do four and this will give us some padding um as you can see from the top from the from the left from the sides and from the bottom I can remove this border we don't need this gray border anymore and yeah that looks uh nice so uh let's go back to our page and we have this header here um I'm going to change the colors here so let's do text and I want to do let's try gray 500 yes I think it works uh nice I want to make it semi bolts for those links let's do font semi bold yeah but uh let's make this lighter here 600 no another way 400 yeah I think this uh this will work let's zoom out yeah I think maybe a little bit darker let's put it that back to 500 uh yes and I think this will work now for the login I want to add extra class names to make it like a red button so let's do background uh primary yes and text white I'm going to put this like this uh yes now let's add some padding of uh padding on the sides of four and the padding on the top and the bottom of two so now we have something like this and now it's not aligned anymore so I need to go here and add items center now it's aligned I want more to have more pading on the side so I going to do six here and I also need to add rounded full so we'll have rounded Corners yeah yes this works nice I want to have even more uh on the sides P yeah like this and now let's zoom in let's see yeah I want to have even more spacing between all of those so let's see here I would do eight yeah I think that's much better and uh now and now I think we are done with our header all right so uh it would be nice to actually put this somewhere else because underneath we will have also a hero section and stuff like this so we don't want to have that much code in one place so inside source I'm going to create a new directory called component and where we can place our header let's see maybe let's create another directory uh called the layout and inside I'm going to create a component or a file called uh just header. JS and here export default function let's do just header and it will just return our header so let's go back here let's grab our header let's cut it from here let's put it here and now here inside our page let's just do header yes and now it's important for me here as you can see if it doesn't add this line automatically for you you need to add it manually we don't need those uh links uh because now it's imported inside header all right and let's go to our page and yeah so now we have only header here and now we can do a hero section here so on the hero section I want to have like a title description buttons and then here a photo of a pizza all right so um let's maybe create also um another component here for our hero so inside layout I'm going to add a file let's go hero. JS uh I'm calling this hero because it's always called hero section so let's do Hero Let's do return here and uh well let's just put react fragment for now and let's see what do we need here uh we need to have let's maybe do this to a section so we can put put section here uh or we can even remove this react fragment because we'll have only one HTML uh element here and for our section we need an H1 it will be our uh main title we need to have a some kind of uh extra text so let's put paragraph and uh let's put something here so let's do everything is be with a a piz yes and everything and for paragraph let's do p is the missing piece um that makes every day complete a simple yet delicious uh joy in life um I asked uh Chad B to generate those texts so H don't blame me all right so we have this H1 and paragraph and nothing is dis played here because we are not using our hero inside our page but let's change this and let's do hero now it's important that it should be visible yeah now we see this let's go back to hero and uh let's see now we also will need to have an image of a pizza so it's the image and um maybe instead of this image let's do image from uh next image and for alternative text I'm going to put here uh pizza and um now we need Source here right for the pizza image um I have prepared an Pizza image here and um I'm going just to download this uh we have three Source uh images here and you can find a link to those inside the description um so now I'm going to put uh those files let's see I put them inside public so I'm going to put this pizza image here inside public all right so we have pizza here Pizza PNG and I'm going also to put this salad one and salad 2 so uh I'm going to have this one and and now salad to as well and we will use it later for other uh elements so let's see salad one and now salad two oops it happened moveed sad two to public okay and now try to put our pizza so let's do uh SL p.png let's see if this will work no and it's missing required wi property I don't want to put the wi I want the wi to be automatic so um I'm going to do instead uh layout fill and object let's see object fit will be contain I think now let's see now we have a pizza here all right so I'm going to put this pizza into a div let's see something like this and for this div I'm going to put the wave to full and the have to uh Max let's see this didn't change anything let's also add relative okay now something have changed um I don't see my pizza but uh let's see if I change the WID to uh let's see 16 for example and this to 16 as well then we have a pizza here all right so as you can see the image takes the width of the parent div here uh but I want to have those text on the left and Pits on the right so how can we do this let's put the text into a separate div so H1 and paragraph here inside this div and then we have image inside separative for our section we need to put uh Flex yes uh but uh maybe instead of flex let's do grid let's see grid and let's do grid colums two so we'll have two colums uh now I think we don't need this with and half so let's see now uh looks like it uh works but let's see how big is the div here inside so have here we have the image here we have the div and um now I think if we make the anything bigger the pizza will get bigger as well so let's put here um for our H1 I'm going to put make this bigger so let's do text 4XL yeah uh that is uh nice everything is better with pizza I want this to be a little bit uh Bolder so let's do semi bold on semi bold yes uh that is nice now let's see and now I would like to have some spacing here so for our uh paragraph I'm going to add a margin top of four let's see yes that's cool now I need also to have a changeed Colors Let's do text Gray and let's do maybe 500 yes that looks fine and under the paragraph I also want to have buttons so let's change this margin to top and the bottom and now I will put the div for our buttons and we'll have a button to a button order now and a button to learn more all right and um they look nice here but um I want to style them a little bit so order now we have some class names here and um this those class names will be I want them to be almost the same as the button to login so let's do text uh White more uh padding X will be C8 and padding y will be two and we want to make it rounded full for Corners yeah that's nice uh I don't know if it's too big or not now let's keep it this way now uh we want to have space in between those buttons so for this div that is parent uh of our buttons I would do flex and gap of four now let's see yeah we have learn more here and we have order now uh now for this order now I also want to have an arrow to the right here inside this uh button so for this I'm going to use hero icons and let's SE for right and this is something that I want um but let's see if we have more options here no it looks like uh this one is what we're going to use so copy jsx let's see yeah copy jsx and let's put it as a separate component so inside components I'm going to create a new directory icons and side icons I will do new file and let's call this one maybe just write that JS export default function let's do WR and let's do return and here I will just paste this thing that I copied from the hero icons uh here we have a class name with with six and have six I'm going to cut it from here and instead I'm going to Define it as a variable here and it will be a property from here where the default will be this all right so uh now class name will be class name and this will be a property with those defaults now let's go back to hero and we have this order now I'm going to add this right icon here and uh let's see yeah something like this and to make this next to each other I'm going to put flex and a little gap of two so now let's see yeah that's uh better and the padding on the sides doesn't need to be that big so instead of eight I will do four now let's see yeah that's much better now for the learn more I want to also use um uh flex and this Arrow so let's do Flex Gap two and the inside I'm going also to add our uh whoops right uh Arrow let's see yes and I also want to have some spacing from the top and the bottom so the py2 and to pading um from for the top and the Bottom now I want this to be uh dark gray so is the uh text Gray 500 yeah uh maybe a little bit darker so let's test with 400 darker so another way around 600 yeah let's try with semi bold uh yeah I think this works nice so we have learn more and we have order now uh for order now I want this to be uppercase so I can change the text or I can do uppercase class here uh I think that the text is too big but let's see yeah I think that text inside the button is a little bit too big so uh I'm going to make it smaller so as's do text and as's do SM for small and um did it change anything I don't know let's see if I remove remve this yeah and so let's put it back text SM and now the text is not aligned with this uh icon here so uh we have Flex here so we can do items Center and now it's much better uh but I think for the text we can move it from the button and we can put it to the DA above here so it will be on both buttons right so um now I think it's uh better let's see uh we have this and this uh I want to have some spacing here right so um for our div with texts I'm going to add the some uh class names here I'm going to do padding on the top and the bottom of four so let's see yeah now we have this much of padding let's double this let's do eight so now we have this much of padding yeah I think that is uh that is better let's now see here inside our inspector yeah we have this much of pading let's make it even bigger let's do 12 and our pizza got even bigger so that is uh nice now I would like this column let's see and we have two columns and that are identical in width and this is because we have this grid colums too and what I want to do is to make this column first a little bit shorter than this one so um how can we do this we can go here and um let's try to do let's try to put this for for style into style so I'm going to remove this and now let's put style and um I'm going to do grid template oops grid template columns and here I will do maybe not uh let's not do this here instead I'm going to rename this to instead of grid I will put just hero section and I'm going to put it inside our style CSS or Global CSS let's see where it is we have uh inside up we have Global CSS let's do section. hero and I want to apply some Tailwind classes like grid and I want to do grid template colums to let's see I want to do 1.4 and 1.4 FR and then um6 FR let's see yeah so now we have something like this pizza is uh much much bigger and um now I would also would like to go to here and I want to split this text another way let's see uh everything is better with a pizza first I want the pizza to be red so I'm going to cut this pizza from here and let's do span with class names like uh text uh primary let's put pizza here inside I'm going to put span into separate uh lines here so now we have something like this uh I need to have a space here no breaking space um now I want to have a brake line after everything so let's do breake BR everything is better with a pizza and I want to have brake line here after better so let's do BR and I'm going to put with a here everything brake line is better break brake line with a pizza all right so now we have something like this and uh yeah I think it looks much meure now for this text here below I would like to St it a little bit more so I want this to be smaller text smm text SM so we have only two lines here and and I think now it works uh fine the only problem will be for uh mobile but uh it's both problematic for now for the header because we don't have enough space and also for the hero section but we'll fix it later for for header we need some mobile navigation and for header we need to put this into two separate lines or we can actually we can maybe get rid of this Pizza image all right so we have header we have hero and uh now it would be nice to put uh now it would be nice to put uh some kind of menu underneath with pizzas right so let's do this um but before we will do this I think I would like to have a little bit more spacing here between those and uh even here between lines so for paragraph margin top and margin bottom I would do six so we have more spacing here and maybe let's do even more spacing here between those lines so in uh inside our H uh one let's do leading let's C3 no that's too little let's do like 12 uh let's see yeah that works but let's see 16 now this doesn't change anything uh let's try 24 no nothing changed so I think we don't have enough value is here but let's try with the leading Clues okay that's uh that's too big let's see leading we have also relaxed so we have something like this um let's try with leading normal uh that much of spacing think that's uh that's too much uh let's see how much we will have without anything so I'm going to just remove well let's keep it this way I think it looks uh good enough all right so uh now I'm going to put a menu here so I want to have a title menu here and maybe with some subtitle and as you remember we want to have those salad leaves on the sides right so uh let's do this uh this will not be part of our hero so let's go to let's see inside up we have this page and um let's change here um because we want to have another element that will be our home menu right so maybe let's put this into layout uh I'm going to do new file and let's do home menu that home menu.js and there the export default function as always for new components home menu and return parentheses react fragment for now and the well here inside I want to have a small letters check hour and then bigger letters menu so I'm going to do H3 check hour let's put a Dave here instead of react fragment check hour and H2 menu menu yeah something like this um we don't see anything because we are not using this yet so let's go here and let's put this home menu here check our menu yes and now I would like to make uh I would like to style this a little bit first I want to do class name here and I want to do text Center I I want to uh Center the texts here maybe we can Center only the headers not the whole section so let's do text Center here into a separate div let's put those here and this they will have no classes for now and we can maybe change this to a section all right right so um check out will have will be gray and smaller but uppercase text uh gray 500 maybe 600 and um let's see I'll put this here yeah and I want to make this a little bit wider so we'll have more code visible here all right so thanks gray 600 uh let's make it semi bold semi bold and maybe a little bit lighter let's do 500 yes and then for our menu I want to do class names and I want to do um red so let's do text primary and bold so let's do bold font bold and uh I want to make this big so let's do text 4 XL yeah something like this uh can we add uh italic here uh yeah let's see if I remove it oops I I have removed too much bold font bold and text 4 XL like this and now if I add italic yeah I'm feeling this will this will work uh for now now I want to decrease the spacing here so for our H3 I'm going to put leading three yeah I think that is uh better maybe let's do four yeah four and uh this will work for now now I want to have those um as you remember those salad leaves and I'm going to put those into a separate div so uh let's put let's use next image component here and for the source I'm going to put salad one.png here and uh now we need Al text salad like this uh it's missing the wi property all right uh let's put some wiff uh let's do with of of 100 uh I think it needs to be like this and with pixels no uh invalid with uh numeric value okay so let's put just uh 100 uh has missing have property well I don't want to put with and have then I want to put this uh layout to be uh the same thing that we did for Hero Let's see uh layout fi and object F contain so let's do fi and object fit contain but now we need div for both of the salad images so let's put this here and for this da let's put a half of uh I don't know 16 and now we have a huge salad here uh let's change this to four uh I forgot to do relative yes so we have this small salad thing here let's uh increase it to 16 yes and uh 48 something like this this yes and let's do for second salad thing so I'm going to copy and paste this and let's change this to salad two uh that's uh nice now um instead of relative I want to do absolute and now we don't see them but if I add here left zero I still don't see them um it's at top zero here still don't see them but if we maybe add on this one relative no um I think this is because if we set to Absolute then we don't have any Whi and that is what uh destroys everything so um I will remove it I will put relative as it was here and relative here yes and uh now now what I want to do is to take this one to the left side and this one should go to the right side right so uh how can we do this um let's maybe first try back with absolute but we are going to add the with here with of 48 so now let's see yes this kind of kind of worked so let's do the same thing here 48 and let's add absolute positioning yes and this kind of worked so now this one should be left zero and the second one right zero so now it kind of works if we remove rela from this and then it's more to the left but doesn't uh help that much let's change this to Absolute and let's do left of zero right of zero on this parent and uh well then we have something like this it's not aligned to the left side all the way let's see why and let me inspect this one and we have section here then we have this uh div here maybe because we need to add the here with with of full let's see no this didn't help uh let's see what happens if we just remove absolute from here let's see uh then we have something like this um maybe I can even put abser back but this div is the parent of this image and I think what we need to do is to align the image to the left so let's see if I do here text uh left if this will change anything no let's see justify uh start no this didn't help let's try again I'm going to hit inspect here we have the image here and the whole image takes this amount of space and what we can do is to do minus left so let's do minus left and let's do 12 and uh now it kind of works so let's do the same thing for the for this one let's do minus right and let's do 12 here as well and this kind of worked right so now I want this one to pull it up a little bit so we have right uh -2 let's do top and let's do Min - 12 as well so now we have something like this and we have this horizontal scroll now as you can see and I think it's because this image takes too much space as you can see here and um we can fix it by doing that uh the section will have uh that the section will have overflow hidden or something like this or this one will have overflow hidden so this one that is absolute let's do overflow um overflow hidden let's maybe change to overflow X to Hidden now we don't see anything because this div is zero in ha so uh let's see I'm going to add hav here of 64 four yes uh I think that's maybe not enough so let's do 120 I don't know let's do full and uh let's see now we have something like this and the problem is that this image is cropped here so let's see this one this one is cropped and um I think it's cropped because of this one overflow x hidden yes so this looks like overflow x hidden doesn't work as it should uh let's then do just style like this and let's do overflow uh overflow X to Hidden now it still removes this top part so uh that's not good let's remove this overflow X we have wave of full and um and the problem is that this image that we pull to the right uh it's it has like some pading or empty SP spce on the right side and this happens because our par div here is a square so I think maybe it would be easier to actually use this whff and hav for images so let's me try to remove this uh layout and content fit and I'm going to put this with and half instead 195 for hav and let's see now let's see yeah now it's I think it's better let's remove this right off this and instead I want to have right off zero whoops right of zero yeah I think this uh this will work better let's see yeah um but now we don't need this uh W here on this one we can just remove it yeah now it's better now we can do top like minus 18 or 24 yes uh that looks nice we will put it under the this uh piz slice in a in a moment uh let's see let's do let's try here index uh um or maybe that zero minus Z of 10 yeah that's better and and this one looks fine I would say uh but we can also make it with w and he let's see the width on and half of this one let's see uh this is width and half 9 192 Nots are here 109 189 so let's put uh let's remove this layout and object picked and let's do wave of this and for the half half we will have this okay so now we have something like this and now we don't need the width we don't need the hav you can also remove the ha from here and we don't need this left to be minus 12 let's just put left zero and let's do minus top of 12 let's see now yeah I think it work it looks nice now I want to pull the left one even more let's put it here yeah and I want to pull this one a little bit so let's see let's do 24 yes but it should be underneath so let's do uh minus that oops minus Z of uh 10 yeah some this um this is maybe too much so I'm going to put here like 100 pixels let's see yeah let's change this to 70 yeah this uh I think this work this looks nice maybe we can pull this one even more on the right side let's see minus uh let's do 300 pixels uh that's too much 200 100 yeah I think this will this will work uh now for this those colums um I want the pizza to be maybe even bigger or I don't know let's keep it for now as it is uh we have our menu Here and Now what I want to do is uh underneath I want to have a grid of uh of Ms Right of menu items one two three one two three and so on so uh here we have div for the headers let's put here a div for a grid right with uh menu items so I'm going to put grid columns 3 let's put here grid grid colums 3 and let's also G add a gap of four and now let's put an an example me so it will be a div with an image uh but for now I'm going to put regular image for now it will say pizza and alternative text for now as you can see it's broken here now for this da I want to make make it h gray background gray of uh 300 let's do padding of four let's do rounded corners of not full but something like medium or maybe let's do large oops uh yes and I want the text to be centered inside let's do text Center uh yeah something like this and now under the image we will have a title let's maybe do H4 uh peoni Pizza just for now uh underneath we will have some small description that will be uh short like this maybe I'm going to put this into separate line because uh for the paragraph We are going to put text to be gray 500 something like this and I want this one to be small small SM SM yeah this looks nice and uh now I want to add the some classes for the title I want this to be semi bold and I want to have some a margin on the top and the bottom of let's say four I don't know maybe four is too big let's do three yeah uh maybe still too big let's do just two and now under here I want to have a button on to card right so let's do button with some classes and background primary text White uh rounded the full uh padding on the sides of uh let's do four padding on the top and the bottom of two and here let's put add two card and let's do $12 just for now later we will pull it from the from the database right uh more padding on the sides so let's do six uh yes and uh let's see yeah I think it looks almost nice if we zoom out the header should be bigger so let's do text uh XL yes uh this looks fine later we have also a pizza image here maybe let's put the pizza here a working Pizza PNG just for now and uh yeah uh now I want to have some spacing here so for the bottom let's do margin top of four let's see yeah we can increase this margin top and the bottom uh to three yeah I think this will this will work uh maybe a little bit lighter gray so let's see background gray let's do 200 yeah I think 200 uh looks nice now um even more spacing on the button on the sides so I'm going to do eight here yeah I think this uh looks nice now um this is one uh this is our uh box box for one item I'm going to put it as a separate component so we have components here icons oops icons layout uh I'm going to put another directory called menu and I'm going to take this uh whole div from here and I'm going to oops I'm going to create a new find here inside menu called menu item item. JS and here export default function menu menu item and let's do return and we want to return this div now let's use uh this one inside our uh where home menu here so let's do menu item and we have this one now we can put more of those whoops let's remove this line let's copy I want to have like six I don't know something like this and the this looks nice except that I would like to have some spacing here so here let's do margin bottom of four at least yes uh this uh looks okay let's zoom in a little bit uh yeah I think this looks fine maybe we can do a bigger Gap but it's four it's already big enough um now let's go inside my new item and I would like to have some more uh things here like uh I want to have on Hover effect on Hover the background will be white for the Box uh it didn't work let's see hover background white let's see if I refresh no um nothing have changed see no still nothing let's see if I inspect this one so let's see here uh it doesn't have let's see inside this one for our first Mill here open we have over background white so uh it doesn't give us white color maybe we need to group this let's see no still nothing let's see what happens if I remove background grade 200 and on Hover I want to do background red 500 still nothing I hover this and uh nothing happens but uh maybe I'm not hovering because I cannot select the text here as you can see so let's see what is blocking here and the thing that is blocking is this um da with the with the salads so let's go to our hero and let's fix it um I think it's uh let's see it's not here it's from the menu not menu item home menu and the absolute here here we have half of full let's remove this one and now as you can see it works so let's go back to my new item let's put background gray 200 and now on Hover it works we have this white uh let's add the trans transition transition all so we'll have small like 200 milliseconds transition between the colors and now I also want to do onover I want to have a small Shadow so let's see uh bigger Shadow let's do Shadow medium let's see um bigger to XL yeah something like this and I want to do the shadow bigger so let's do hover Shadow or darker let's do black yeah so we have something this uh maybe now I can make it uh maybe not black or maybe let's do black but uh 50% black so now we have something like this if I close it yeah um I think it looks nice maybe we can make it smaller let's do this to medium the shadow yeah uh let's change this black 50 to Black 75 let's see now okay that's too too much let's do 25 of black let's see yeah I think this uh this looks nice right so uh now we have here some uh pizzas and uh I think the images are too big so uh but we'll have different images later but let's put a div that will be parent for our image uh I want to do text Center and I want to do Max have of uh let's see let's do eight uh yes and for the image here I want to add the class names as well have Auto with auto something like this and this didn't change anything let's see why I'm going to inspect this uh element here and the div is this big but the image is uh much uh bigger I think that instead of ha and wh we should have Max have Auto and Max with uh Auto no let's see Max have will be just put maybe here just 10 and see how this will uh behave I think this is better so I'm going to remove this Max ha from the div and uh now for the image let's see let's make it a little bigger so let's do Max have of 12 maybe 24 somewhere this now I want this to be centered so I'm going to add the block here and MX Auto so it will be centered yeah and uh I think this is a little bit uh nicer all right so we are done with our menu and uh the next things that we need to fix will be for our homepage to have about and contact and uh let's go to our page and about and contact should be super simple as the section for contact so um um for about and the contact I would like to reuse those two um uh check out menu but uh I will have a different St uh different text for those uh we have this inside home menu let's see here we have a checkout menu and um I want to make a component of this so I'm going to copy this and let's go to components layout and let's do new file and let's call this one uh section headers header .js and let's do export default function section headers and here we will have two properties uh sub uh sub header and the main header yeah something like this now let's do return and inside let's just put those two and here iside instead of check out we will have a sub header and here instead of menu we will have a main header something like this I'll put those into separate lines so it will be easier to read now let's go to home menu and instead of this we can do uh section headers for the sub header we will have a check out and for the main header we will have a menu yes so now let's go back to our page page JS and now we want to do first abouts so let's do here inside section headers and I want to do a sub header or preheader of U um what can we do our story and Main header will be about us something like this um so let's see yeah now we want to put it in the middle right so let's do class names here text Center we want to do margin the top and the bottom of at least eight we probably better with something like 16 so we have some uh spacing here now uh paragraph for some lurm ipsum something uh like this but uh I want to add the class names I want to do Max wave of um 2XL MX Auto so it will be centered and uh let's see and uh some spacing on the top of four and T next uh should be grayish 500 and uh I think this will be good enough maybe we can do another paragraph also with Laura msum and I would like to do the same styling for the texts so I will put a div with class names of this text Gray 500 and instead of having this text gr 5002 here I'm going to put those paragraphs here into this St and we need to have more um also this Max with 2 XL I'm going to put this on this div above same with this MX Auto let's put it here now I would like to put margins here we don't need class names here I'm going to put margin top of um eight here let's see eight is too much let's do four now I would like to have a a spacing between the between the paragraphs so how can we do this we can do something like this on the parent we can do Flex we can do Flex colume I think and we can do a gap of four and now we have spacing between paragraphs uh maybe we can add another one paragraph with some lurm ipsum uh let's make it even shorter maybe something like this and let's make it even more narrow so the medium yeah something something in this uh style I think this uh Works nice now the last thing is uh our contact and let's go to well we are here uh let's put another section for contact and we are going to use those section headers and for sub header and let's do don't uh don't uh hesitate hesitate and the main header will be contact us all right and let me put this here then this here something like this now um I would just put a phone number like something like this plus 46 um I don't know we can put any number here um but uh this will be an a tag so let's do a tag with gra and uh let's put this not H1 let's maybe do this as in it doesn't need to be an H so let's just put this number into an a tag and it will be tell colon and the phone here without any spaces and let's put into new line and I'm going to add a class name here or class names text should be 4XL super big let's see yeah something like this uh I also want to make a everything text centered so now we have something like this and uh now let's see I want to do margin on the top and the bottom of eight and uh also here for the phone number margin top of eight and this didn't work maybe let's put this into separate div class name margin top of eight and let's put this a tag here inside we don't need this margin top in side here because we have it here and uh I think this works uh nice contact us and we have this phone number here uh below maybe we can do something like an underline and let's do text Gray 500 uh yeah now the last uh let's just do a small footer on the bottom of the page um I want to do a border top so we'll have some spacing here yes and let's put like padding of eight inside and uh we can do some copyright or something like this um something like this and let's do copy um 2023 All rights Reserve something like this just to have something here and uh let's make it also Center so let's do text Center and as do text Gray 500 yeah I think this uh this will work now that's also the mar top of eight so we have some spacing let's do more 16 and I think this looks nice uh looks good enough you can improve styling on the about us and the contact us um we can also put it into separate pages for now those links doesn't work but we have a basic styling for our uh website right so we have some here menu menu uh it should be menu here right uh right so let's go to home not home here we can or actually home menu uh let's put menu here right uh looks fine so we have now some basic uh layout and styling for our page and then now we can do that those links will scroll to a separate uh separate section uh to uh to the correct section sorry or we can later also change that uh all of this will be all of those links will go into separate uh pages right so there are different uh approaches for this maybe for now I will keep it this way that we have only one page and later I will change that we have several pages but uh the most important is that we just need this uh basic styling so now we can fix the login so we can log in and uh add pizzas or add meals to uh to cart or something like this but um what I want to do is also that we can log in and we can actually add a small admin panel so we can add meals menu items to our database because for now everything is hardcoded as you can see and and we just put everything is just pepperoni pizza we don't have any separate images separate prices it's just in some HTML so the next thing will be to fix the login and to do a small admin panel for all of this okay now let's continue and let's fix uh authentication so um here in the header we have this login button um but I think this time for authentication I'm going to show you how to do this both with uh social uh sign in so with Google account and with credentials so username and password so uh to do this um uh first I would like to have both login and register so let me see um we have this header here we need to go to header and uh we have one navigation here and I would like to have two navigations so first will be uh the regular this one for pages and the other will be for login and register so here we have our one navigation I will put another one and I will move this login here and I also want to have another link uh that will have some crav here and um I will have register here so now we have something like this I don't need the login here so now we have something like this and I want to change those two so first login and then register so here let's do login and here let's do uh register yeah and now I also want to have same styling here so Flex items Center and GAP uh eight as above text Gray 500 and semi bold and uh yeah now it's uh much better maybe we can decrease the spacing here from gap eight to maybe Gap four yeah I think this uh this works nice we could also probably decrease this spacing so we will have like left side and right side so let me see if I just move this logo inside the first navigation how it looks like yeah I think it looks uh much better maybe we could increase the spacing here so let me see we need to go to Hero section so let's go to Hero here and hero let's add some margin top of uh let's do eight so we'll have some spacing maybe that's too much let's do four yeah I think that uh that is much better right so uh now uh we have login and register let's go back to our header and let's fix those links so for login we we will it will go to SL login and for register it will go to slash register all right that is good now now let's see um we want to have some kind of register page so I if I click here it goes to SL register but uh we get four or four so let's fix it uh I'm going to create a register page so inside up I will do new directory called register and inside I will do page.js and here let's do export default function uh let's call this one maybe register page the function name doesn't really matter here but I try to do something I try to name it with some uh meaningful name so let's do return and let's put a div that will say register yeah so now we have register uh small problem I have here is that we don't see the header and the footer and nothing and that is because here inside this page you can see we have header here and footer here and it should be moved to our layout so let's do this uh from the page I'm going to remove this uh header uh and I will put it uh to our layout so here let's do uh header like this and we have header and now let's also move the footer that is hardcoded so let's grab it from here copy and let's paste it under the children so we have now some footer right that's uh nice let's go back to our Pates inside register and uh now let's see now uh I would like to have like a header here register uh it should be this red so let's see um maybe I will make this to a section not like this uh section for HTML let's put H1 that will say register and let's add some class names here so we can for example oops for example text Center this text text Center text Center and I want this to be text primary for the color and I want to do make it bigger so let's do text uh let's do maybe 4XL 4XL uh yeah this works now I want to have some spacing here so for this section I'm going to add margin top of eight yeah that's much better so now it would be nice to have some kind of U um some kind of uh inputs and I want to fix the navigation a little bit because now if I click one of those it doesn't do anything so I will go to uh my header and let's fix that home goes to slash and same for the logo it should go to slash and I think that's it for now so I can go back to the homepage yes and uh to register all right now uh for our register page uh um here below I would like to have some kind of um some kind of form right so under this H1 let's do a form I will remove this action for now and let's add an input that will say something like uh um yeah let's leave it like this text and the placeholder will be let's see email let's change this type to email as well and we need another one for password uh so now we have email and password Here we will also need we will also need a button that will be type of uh submit and uh register it will say register register all right so um we have email password and register we need to add some classes to this uh but I think we can just add it to all of the inputs and all of submit button so I'm going to add this into our globals here Global CSS so for input type uh input type of um email and input uh type of password and input type of text I'm going to add uh some styling here and I'm going to apply uh Tailwind classes it will be uh faster than writing just CSS so I want to to add some border I want to add a padding of um two I want to um make it the Border um let's see grayish so let's do maybe gray 500 now let's see now we have something like this uh 500 is too dark maybe let's do just uh 300 and I want light uh background color so let's do background gray and maybe not let's do 200 so now we have something like this and I want those to be block so let's do something like this so they are under each other and uh let's see uh I think this will work now um I want also to add a few things like I will apply more classes I will put block here and um I want to do with full so they take the full with and I want to add some margin on the top on the bottom bottom of four so we have something like this and let's also do rounded Corners rounded um rounded ONE XL all right so we have something like this let's make itth lighter so background gray 100 and I think this looks uh nice now let's do the button uh first I'm going to do like a default button and then I will also do a button that is type of uh submit or a button that has a class name of submit just in case in the future if we want to have this kind of uh button uh or maybe anything that has a class name of submit it can be a link so uh first let's do for all of the buttons I want them to be let's see um I want them to be grayish maybe with a border so let's apply some classes let's do block with full and I I want them to be text Gray uh 500 something like this maybe darker let's do 700 yeah and uh let's do text semi oops um not text I think it should be font semi bold yes and uh what else uh let's add some Border in the new line apply border and Border um not border let's do red here rad 1 XL and something like this let's make this border same color as the text so let's do gray uh 700 so we have something like this and um I think this looks almost fine I also need to add some padding on the sides will be six and on the and on the top and the bottom it will be two so we have this type of button yeah maybe the Border can be a little bit lighter so as the 500 yeah I think this looks fine for Thea both buttons but now uh for the submit buttons I'm going to apply classes like uh border zero and I only want to have background of primary instead and the text should be white and uh I think this will work uh maybe we can decrease the spacing between form items so here we have four let's change it to two so everything is closer to each other let's go back to our register page and now I want the whole form to be block and I want to add Max wave of U XL and I want to make it Center says do MX Auto margins on the sides of Auto so we have something like this that's too big let's do just uh SM instead so small uh still big I want to do then XS so so now we have something like this and I think this works nice now underneath I would like to have a text like or use or login with Google so here under this form I'm going to add the div and and another button uh log in with Google something like this uh maybe I will actually put this inside the form so we will it will be the same with yeah something like this um and here um above I will have a text or login with social media or login with uh with provider provider something like this and now I would like to have a little bit of spacing here so um for this div I'm going to add some class names like uh margin on the top and the bottom of four uh text Center and the text should be grayish so the TT 500 uh yes and that looks nice uh maybe even some uh spacing uh here so let's see um from this uh header let's do margin bottom of four let's see yeah I think this will this will work for now I would like to have a Google icon let's see if we can have it on here hero icons no we don't uh then let's just find it Google I IC on PNG transparent yeah uh so we can just uh grab it from here and a website so now I'm going just to put it here to public and uh let's see I'm going to rename it because it's some random string let's do Google let's go back here and uh let's put it here so I'm going to not here to the button um I think I will put it on the beginning of the button so let's do image image and the source will be SLG google.png and uh here log with Google or maybe empty alternative text uh we will also need to have with and have here if I remember correctly so let's do may be 32 and half of 32 as well now let's see how it looks like yeah almost uh let's do a class name of uh Flex uh let's see yeah maybe let's make it smaller a 24 and let's do a gap of four now let's see we have something like this now I want the text and everything to be in the middle let's do justify Center yeah now everything is in the middle and I think it looks uh nice maybe the Border could be lighter on the default uh uh button let's see global CSS default button text border let's see with 300 yeah I think this uh looks better right so now we have a register page here and um now I would like to start first by implementing this email and password register to do this uh we are going to use next out so let's go to next Al and uh let's uh see get started uh we need to do yarn ad next out so let's do this yarn add next out if you do npm you can use this and yeah but I'm going to use crn here uh now uh we need to add the this file for pages but we are not using Pages route we are using the latest nextjs 1 uh app router um so here's guide for us and uh we go here so let's uh see uh we need to go to up then API and off directory so let doing new directory API then inside let's do off directory off and then inside we need a directory with this weird name here and this is because we can grab all the requests that go to API of is the new directory this and then we need to create the file route. TS so let's do new file route TS all right so uh now let's just uh put this and let's see so this will not work because we cannot have those uh Dots here and um now let's see and now we have an error here saying that we need to have some off options like providers so let's do this let's scroll here and I don't see anything about the providers so uh let's see here getting started configuration here we have providers H credentials so uh here we have credentials provider and as you can see we just need need to have uh we need to copy this and we need to have this import so let's use this import let's add this import here and now uh for providers so let's put providers here providers will be in Array and for providers we are adding credentials provider so let's put this one here all right so um here should be providers plural and and now we have all of this code so uh let's get rid of this and then we have credentials we have a username and the password we need to change this because we will have uh actually email that will be type of email and um maybe we don't even need this uh array here let's get rid of this and no now we have an error so let's put it back email uh placeholder test at example.com then we have a password type password okay this looks fine now uh here we have authoriz and you need to provide your own logic that takes the credentials BL blah blah um we cannot do this right now because uh we don't have any database set up and um we need to First fix that we can register right before we can actually uh so we will get back to this first let's fix that we can actually register so uh inside API I will create a a directory called the register register and inside I will do a new file routes.js and here I'm going to handle export uh function post so when someone sends a post request I'm going to grab the request information and I'm going to handle this so let's go back to our register page and now let's see we have a input password this is react so we need a state for this right so let's do const uh email set email equals use state from react default will be empty string and let's do the same for um password set password like this so now it's uh complaining that we are doing use state in a server component and we can just fix it by doing uh use client on the top so we will say that this is actually a client component now it's fixed uh but now uh what I would like to do is as you can see we have stay for email and password but uh maybe or maybe not let's just use this and uh let's see how it will go so uh here first for email we are doing value email and on change as always uh let me put this into separate line on change we will get an event and we will just do set email event Target value and now the same thing uh for the password uh new line here on change and we have event and we will do set password event Target value so now we should be able to edit here yes that's correct and uh we have a button that is type of uh submit here and now because we are submitting this form let's add here on the form on submit and what do we want to do uh let's create a function for this handle uh form submit and let's run this function here on submit handle form submit like this and we get an event from the form and we want to do prevent default so we will not use this default form sending that we get from HTML and instead I want to to send a request to our register route inside API so uh let's do maybe we can use either fetch or we can use uh axios maybe this time let's use fetch so uh I want to send a request to slash API SL register and now here we can do here method and the method will be post and uh then uh I will want to also let's put this into lines like this I want to send body and body will be Json so let do Jon stringify and um let's see Json stringify and I want to send an object of email and password all right and I should probably also send headers uh like content uh type I think it is that uh what we are sending is actually application Json than that's it and this should work so uh now let's see what happens if I just put uh test uh test but before I will hit register let me open the console and let's see network this is what I'm interested in let's click register okay this doesn't work because I need to put an email test example.com now let's see register we get 500 error uh so let's see here what's the error about so uh no response is returned turned from the route okay that's uh correct because we have an empty function here so let's just return uh response uh Json and uh what do we want to send let's send just okay now if I clear here click register we get 200 and it says Okay so this works but now we want to add the user to the database so we can later do this uh authentication that we try to call copy from next out right so uh we want to save user to a database we don't have any database yet but I'm going to use uh database I will just I will just quickly create it uh let's go to Atlas sign in and uh I will sign in with my Google account to create an empty new project uh I'm going to create a new project and it's for free let's call this one uh food ordering yes I think uh that will work next create project all right and uh now we need to go to database and we need to build a database and um I don't want the paid version I want a free version so I will go here and uh this really doesn't matter here I will just hit create here some capture okay now we need to create a user and password for our uh for our user admin for the database so uh I'm going to name it uh like this food ordering and let's generate a password some random password I'm going to copy it and I will put it I will put it into my project inside EnV EnV and let's just put it as a comment for now something like this so we don't uh lose it let's create the user and now here IP addresses as you can see uh I can add my current IP address but it's already added automatically so I can just do finish and close go to over here and now it's creating the database for me one thing I would like to show you something if we go to database access or not uh network access add IP addresses when you publish your website somewhere you need to either add uh IP address of the server here or you need to click this one allow access from anywhere because otherwise your app will not be able to connect to the database from another IP because when you deploy to another server uh the app will try to connect uh the database from this from that another server and that server has another IP address than your home so it's not your home IP address let's go back to the database and let's see yes it's created so we have a database uh let's go to connect and I want to have a connection string so like an address to the database um we can put select one of those and uh here as you can see we can just have the connection uh string that we can just copy I think that you can just uh pick any uh option here if you do connect and then shell you also have a connection string here kind of or if you go I don't know to to vs code you also have a connection string that is almost the same I think so here I want to add it so as do URL and let's put it here so uh we let's have it here as a connection string and now as you can see here we need to replace this password thing so I'm going to uh cut this password from here and I'm going to put it here instead now um it ends here here with a slash and uh you should always put some name here after the slash because this will be your database name so you can do like food ordering or a test I think that if you don't put any name then the default name for the database will be uh test right uh let's save it we have a database we have a connection string but now we need to go back to our app API uh register route and here instead of okay uh I want to uh save a user to the database when you register right so to do this um I need to connect to our database with this connection string and I want to create a user put a user into collection so to do this I'm going to use mongus as always yarn add mongus and now this one is installing for mongus we need to create models for the database uh so I'm going to put this inside up let's do a new directory called models and I will create the model for our user let's do user.js and here let's define how our user will look like inside the database so let's do const user schema and new schema from mongus let's import this and now inside we just uh Define how it will look like so so we will have an email and um now type of this will be string and it will be required so it's the required true and let's also add that it will be I think unique unique to True okay uh now what else do we need we want to have password right uh so let's do type string and it will be required we can also do some validation here so we can do validation function like this and uh it will be a function so let's put a function and I think it should just return true or false but let's make sure mongus validate validate uh validate function so this is how we can put validate function um you just uh you can return a promise or you can also do like this as an object and then you do validator and but you can also use required instead and you can do something like this uh required to a a function uh like this and you can just check that uh for example here you check the drink and you check that bacon is bigger than free uh this is funny but uh but let's use something more professional so I will do valid dator and let's see validate so I'm going to put this as an object like this so first let's put this into separate lines so it will be easier to read we have validate and we are going to change this validate to an object like this and inside we need to have message so let do message H will be um um well the message will depend of uh how the password looks like right so uh maybe instead of having this as an object like this we will have just a function and we will just do new error if something is wrong so let's devalidate and let's put this back as an as a function and now uh what do we want to check uh we want to check that uh the password is uh looks correct right so let's do some testing um let's say that uh I think that the value will be actually here so um or we can do something like this and uh this password uh so uh let's do this let's just check first uh that validate colon um I think we can use this do value um only um where we use um um Regular function and not Arrow function but as you can see the value is here so we can just do pass as password and we can do just pass and we can check this string so first let's check if pass uh password has the length and it's bigger than let's see at least five characters and uh if it's not if it's uh if it's smaller if it's smaller then or maybe we can first check if uh if we have a length if we don't have a length um or uh pass length is smaller than five then we will throw an error the same way they do this uh let's see um here new error let's do new error and let's do in um not inv valid password let's do password let's there must be at least five characters yeah and uh then then let's test this so we have schema and we validate the password uh we also need to have a model here so let's do export const and uh user equals uh I want to check first the models if uh if is if this exists so let's check models if if we have user otherwise I want to create a new model with model function uh of the name user and our user schema all right and here for the schema I'm going also to add the time stamps to true just in case and now try to create our user inside register route so here first we want to connect the database so let's do mongus that mongus import mongus from mongus mongus connect and here process. env. URL so we connect to our database and now we want to create the user so let's do a wait because it's a database query let's import our user yes from models and now let's do crate and we want to grab the data from request body right so to do this first we need to grab the body so let's the body equals and now to do this we need to do await and request uh request not body request Json because we are sending Json right uh we have this red error on the await because we need to make this uh as sync function and now it's all right now uh here um we just put the body and the user should be created uh just to be sure I'm going to assign this newly created user to a constant here so let's do user equals user or maybe we can name it a created user and let's uh put it here so we can see this inside the response created user and now let's see here if I hit register again we get uh pending and uh now we have status 200 and inside the preview you can see that now we get ID we get updated ad created ad and the time stems and we have created user um the validation seems like it didn't work so let's see user and uh this didn't work so let's do return false here let's see if this will have and let's delete our user from the database so let's close this let's browse collection and we have users and let's delete this one right and now let's try again register and looks like it still works so this validate doesn't seem to work uh but this can be the issue because we need to restart our environment so let's start again and let's try to do another user let's clear here register pending okay let's see 500 let's see why here and uh we have an error can not resolve models user module not found that's weird let's see why user schema we are exporting user let's go to the route app models user everything looks fine here let's just restart here and let's try again register now still the same problem user cannot resolve app models user let's see why this looks fine let's go inside here export const user uh maybe let's uh assign it first let's assign it first and then let's maybe use export default uh user like this and let's go to the route and let's just import it this way now let's see if I hit register we get an error I'm going to restart environment once again register and we still get the error let's see how our Imports work so we have components here and uh this looks fine up models user here we have uh let's see uh do we have anything inside next config no this looks fine let's go back to API register route okay I'm going to try to move our models uh out maybe outside of the app to the source let's do refractor and now let's go back to API register route and let's uh remove this import for the user and let's try to import it again so let's do user from model C user and now I'm going to restart my environment and let's see if this helps let's do test three maybe or least test to register and no we have still the same error can resolve models user right let's see what's uh the problem there let's go to to models user and let's maybe put it as it was as not the default uh just export uh con user equals this and inside the route let's import it this way as not the default and let's try again so hit register and I will also restart the environment hit register and still the same problem let's see if it helps if I add that JS here and let's restart here register no still the same error can't resolve models user JS so uh I think I know what can be the problem this is some compiler errors and uh this can be fixed uh here I think uh we just need to Define all of the all of the paths so for example uh let me Define that uh we will have we will have app components and models so let's do app here and up here and uh I want to do the same for models and uh models and the same thing for components and this thing should fix everything so let me restart this and uh now let's see inside here we have a models yes and now let's see if I clear here and register pending still 500 let's see why cannot resolve models user and let's go to Source models Source models right so this didn't work but uh let's go to the route and um let's see instead of this we can just import the the regular way or let me also try something more let's uh let's go back and here let's also add the B a URL to a DOT and uh let's also do include include with include paths it just do include and let's do ad do this doesn't doesn't work okay because we need to do double quotes like this and uh now let's restart yarn Dev and uh let's see if I hit register no we still get the same error let's me try another thing and it's called the module specify what uh module code is generated and uh let's do es 2020 doesn't does it fix anything and no I don't think so but let's restart register no still the same error let's get rid of this let's go back to our route and let's import this uh um regular way without any short cuts and mod models and user so now it's saying you can shorten this with this uh but uh this doesn't work but this should so let me restart let's hit register and now we have something else we have user validation failed on the password so uh we need to uh provide the longer password right so um because as you remember inside models we have this validation for for the for the password password validate and we have that the length needs to be at least five all right so we have test two let's put test two here as well hit register and now we get uh 200 here as you can see so now it works um let's see test two let's go to the database let's refresh here and we have two let's delete the old one and we have only one with this email and this password the only thing that is problem here we don't want to store the password with clear text so uh instead I'm going to use a bcrypt for this so I think for this we can do something like this user schema user schema and add a pre so before before save I want to do uh I want to run a function and we will have a uh next here that we need to run so it will know that we can uh we want to go further let's maybe console log everything from here console log and uh let's do rest let's grab everything rest and let's see how this will look like so let's do test three with test uh three as a password and let's try to register and nothing happened let's try again I'll restart everything here test four test test four clear everything register uh we have only save options here and nothing more all right so looks like this uh pre will not work because we don't have the document but let's try here if we can do add the password and add the test 1 2 3 4 on the end um and let's do this when everything is correct so let's do here return password and let's see if this will change anything let's restart here uh let's do here five and here five as well register and let's check inside our database let's do refresh and we have another user let's see here but the password is only test five without this test 1 2 3 4 uh on the end all right if this doesn't work let's see if we can do something after the validation so user schema um after so let's do uh um after do we have after no we have pre and we should also have a post and post validate uh let's do a function and um I only want to do console log on the arguments that we will have here I just want to see what's uh inside let's try with test six and uh I think I forgot to restart here let's do test seven register and now we have arguments and we have one argument and this is our document so here we can change this document or we can change this to user we can call it user and um and let's see if our test 7 has been created push to the database let's see on the bottom yes we have test seven so here I would like to do something like this user and I want to change the password to um hashed something like this and now I want to check that if I create a user with test 8 register or I forgot to restart here as always let's do test n register and now let's go to here refresh and let's go test n as you can see the password is Hash but we don't want to make it hash instead we want to use uh for example bcrypt to bcrypt to create uh to Hash our password so uh let's see uh we just grab a B Crypt like this and we just hash the password so let's do yarn add bcrypt and uh now let's see how we can hash the password so let's do grab the password pass equals user password and now the new password should be add the encrypted version so let's see here we have a usage sync so we can do just uh something like this uh require bcrypt and we need to do generate salt and then we do something like this let try to put this here and instead of Co VAR we want to have const and we need to import this bcrypt and let's see if it's imported no it's not so let's do here import uh bcrypt from bcrypt and and here as a string and uh now let's see if this will work um here we have hashed password let's do hashed password equals this and this uh here we want to put our password right so let's do pass we can maybe rename this to uh uh something like not hashed not hashed pass word and here let's put not hashed password and here user password will be hashed password right and uh we can just simplify this by putting this uh like this user password equals and this bcrypt all right now let's try to uh restart here uh our environment and uh let's see if this will work as do test 10 register and let's see everything worked Let's uh refresh our database and let's see on here here as you can see we have a hashed password so that is uh that is nice so now let's see um we have hashed password but maybe we can simplify this we can make a function somewhere else and we can reuse this function so um because I don't want to put like uh this uh generate salt here I just want to have um one function for this or maybe we don't need it because we will have it only in one place on the the user let's keep it like it is now all right so uh now we can create the user we should have an alert that the user has been created because everything went okay so let's go to our register page right and now we want to have a here we have a fetch let's add a weight here and let's add assn here and now after here uh we want to say everything went okay so uh we want to update this uee to say everything is fine to update I we will need to have some kind of State uh let's say user created set user created and theault will be false uh and I want to have um uh some kind of State for when it's saving so let's do const uh creating user and set creating user default will be false all right and here on the beginning I'm I will set set uh creating user to true and here I will do set creating user to false and when it's creating I'm going to block this bton and block those inputs so uh let's see for inputs I will do uh not blocked uh but disabled and we want to make it disabled if uh is uh creating user create in user if this is true same for this input and for for this button that we have here register I want to make it disabled as well so like this I guess let's test with uh user 11 and I'm going to inspect uh this let's see this button let's see if I click nothing has uh changed uh but I think everything just worked so something is uh something is wrong uh maybe we need to add some Style in so let's go to Global CSS and now here I want to do styling for all of those inputs uh but disabled uh version of those uh so let's do disabled and let's do disabled and here disabled and what do I want to do I want to do uh maybe we can remove the Border or we can make them darker let's do darker apply background and gray 700 all right and now let's see if we do 12 let's just refresh and we have an error cannot resolve components layout header okay let's see why maybe because we've changed this uh let's see uh not here TS config no uh yes config here so cannot resolve components layout and there okay let's add the one that we had before here that uh if we have something this it will go there now cannot resolve layout header let's refresh let's also restart everything here okay we have an error again caching failed I'm going to remove those all then I'm going to put the as it was before so we will not have this weird error here uh can to resolve components Li out header components Li header cannot import let's remove even those because those didn't help anything okay so I found what is the problem and actually during restarting my environment um what happened was that uh nextjs added this file Tailwind not sorry not Tailwind TS config Json and as you can see uh here we have a compiler options uh but it doesn't have those paths that we have inside compiler options in JS config and uh to fix it those import problems uh for those paths that starts with ADD sign we just need to copy those paths from compiler options from JS config and we need to go to TS config and here inside compiler options we just add those paths Here and Now everything just works so we can most likely also go to register route and here for this user import we can simplify this with model user as it uh should be right so now let's go back to our user and U and let's see we have this um hashed password and we were about to fix that uh we can see uh some progress um so let's go to uh register route and not here register page sorry and here let's see we have this creating user that is uh false by default but when we create a user we set it to true and then if it's created we set back to false and we should disable those uh inputs let's see how they look like so I will just set it to true as you can see now those are blocked uh read only so I'm going to change styling a little bit let's go to globals and here for disabled I'm going to make them a little bit uh maybe brighter let's do 200 um maybe like 500 that's too dark 300 will be enough and um let's see now for the button button um maybe let's do the same button uh submit uh but that is uh disabled if it's disabled or disabled here uh I want to apply classes that will say cursor uh let's see cursor not default grab help help move cursor let's see do we have disabled no stop no let's see what else do we have wait uh progress pointer we have cursor not allowed this is something I want to also add to our blocked or disabled inputs so let's add it here and now as you can see we have this different H cursor uh now for this uh uh submit button let's also add the change the color so do maybe background red 400 yeah so we know it's disabled and uh now let's put back this that it's not uh disabled let's change this to false and now let's try to set this user created to true and now here we have register here we have register here we have the form and I want to change that uh is or maybe not is let's see user created user created user created um then I want to add the div with some class names like padding or maybe margin from the top and the bottom or four and I want to add a text saying user created uh now you can log in right so now we have this text user created now we can log in let's make it centered text Center and um user created now you can login and let's change this login to a link so let's put a link here to slash login and uh login I want to add a arrows here now you can log in now yeah it's a link uh I would like to add like uh class names here under underline now we can log in yes I also want to add a space here now we can uh yes and maybe uh break line here user created now we can log in yeah so let's Now set it to false and now let's check if uh this will work let's see um handle form submit first we set it to true for creating user then we create the user and then we set creating user to false and we also need to set user created to true because it's complete so now let's do test um I don't know 11 at example and let's do test 11 or yeah register user created now we can log in so that works really nice um I'm going to remove all of my users now to uh clear the database because we have like 20 users now uh I'm going to create a new one test at exam.com and test here let's hit register uh let's see what happens if I click register again uh we get errors and we get errors even for the first user so let's see um what's the the problem bcrypt is not defined let's see inside our register route no not here I think it's inside a models uh user B cryp note Define okay I don't know I probably commented this thing let's try again let's register this user and uh let's see register 500 let's see what's the problem bcrypt is not defined maybe I need to start this uh bcrypt is not Define now it should be fine module is not installed all right uh now let's try again register ending and we get 200 so now it works uh now I want to see what happens if I click again register it shouldn't uh register a new user with the same credentials here right because this one already exists but let's see what will happen I will clear everything register we just get 500 error and uh yeah we just get an error and nothing happens so let's go to our register page and let's see handle form submit uh we probably need to add a try catch here try let's try to do all of this and the catch we catch an error and um then uh with this error we just want to notify our UI that we have an error so let's do error and set error equals use State and default will be false and here let's just do Set uh error to true and uh here maybe underneath let's add an if um error if we have an error let's do end and let's do well the same thing that we did here but no links it will just say error and break line please try again later right so uh maybe ER error um an error has occurred occurred with r please try again later so uh now let's see let's see if I click register again well we just get an error here nothing happens let's refresh and test at example.com and test and uh nothing happened let's try again test at example.com test let's hit register user create okay that's not good uh it says us are created but it gets 500 let's see why um let's see let's see here looks like we shouldn't do try catch here but uh instead we should do uh let's see error and error has occurred let's try to get rid of this catch and try whoops and um no try let's put this back and and instead of doing a weit here I will do then and um maybe we can leave this a wait but uh I will grab the response cons to response equals this and let's conso log our response to response right so now if I click register we get the response and it has okay false so we can do something like this if response okay if response is not okay then set a error to true and um creating user false uh regardless if we have error or not user created true no only if it's okay if response okay then user created uh and set error only if response is not okay we could simplify this to first if it's okay then we say it's created otherwise so else H set error to True right now let's see um let me me copy this and I will refresh let do test register an error has occurred please try again later let's try with test one and test one register well now it says both user created now you can log in and an error has occurred and this is because we need to set error to false before we uh send a request we need to reset this right so now if I click register and um we still have both because we also need to have set user created to false on the beginning because we want to reset reset everything register uh error occurred let's test with test two test two register and now everything think works and we can go to login page all right so now this works we can register uh with credentials let's check our database uh for our users we have hashed passwords here uh as you can see so that is good we don't want to have a clear password wordss um or raw text passwords so that is good and uh now we just need to fix login uh so when I click here we will see a login page and uh we need to fix the login with provider uh here maybe underneath we can also have a text like already have an account uh or already M click here to login so inside this register page we can have uh under this button under this button a div um that will say existing account and existing account and then a link that will say login here um and it will go to SL login yeah something like this but of course we want to have some class names here like text Center and uh what else um some margin right margin on top and the bottom of four um and for the link we want to have an underline or something class name uh underline and for the texts we want to make them gray 500 and we want to have space here so I'm going to add the space like this okay and log in here I will add this Rao Raco arrows and this this looks nice existing account log in here uh this looks fine maybe we could add a border uh on the top of this div so we have like a line here that is nice H but let's also add padding top of four so we'll have some spacing and that looks nice only downside is that we have this uh footer that is uh really close um but that's okay that's okay for now we can fix this styling uh later so now we need to have um log l in page and we need to fix that we can log in with our users that we created with those credentials and so we can also log in with um Google here you can also add more providers if you want all right so now let's fix the login page shall we uh so let's click here login or if we click here we will have the same problem uh we don't have a login page and then when we have a login page we need to fix that we can login with those users uh with those passwords right so um let me see uh we have an API Here app we have a register uh we need also have uh to have a login directory here inside our app for login page and inside we just put the PJs export default function and let's let's name it login page uh for all of the for all of the pages I trying to put the name like uh the Pu name and then the page now inside this return um let's maybe check what we have uh for the register for the register page register page register page here and we have this as a section okay let's go to login page let's do section HTML like this section now we need an H1 let's copy this H1 from our register uh I will just copy this and I will put this thing here but instead of register I will have login right now let's see uh here we have login and we have a section even for this section we should have margin top of eight that we have a same thing for uh register so is the margin top of eight uh all right so now we need almost exactly the same for that we have for register uh so so we need the email password and then the button and then or login with provider uh login with Google and then almost the same thing uh existing account login here right so uh let's do this um underneath here let's do a form no action for now and we just need to have a input um well we can just copy those inputs from register page let's see I will uh grab those inputs uh like this and now let's go to login page and let's paste those inputs uh we don't have state for email and password so let's copy this as well so let me see email and password State let's go to login page let's put it here and for login page we also need to use uh use client here on the top because now it's a client component um let's see login creating user is not defined um we don't have it so let's put here and here false for now we don't want to block anything uh now we have this super long so I'm going to add the class names on this form to make it Max wave of Xs and let's make it Center with MX Auto like this now we need a button that will be a type of um submit and it will say login so now we have almost the same thing that we have on register but uh well it's uh login right uh we also need this or login with provider so U underneath um I think I would just copy from the register page let's see or login with provider and then the button to login with Google so let's spacee it here and now let's see login page yeah uh it works um let's see register and uh I think that we should even copy this part but change to to if we are on the login page uh don't have an account register here or something like this um or maybe not uh let's keep it like this for now uh we did some copy pasting here and I don't really like it uh so we will clean it uh both register and login page uh in a minute uh first I would like to fix the on submit on this form on submit and we will create a function handle form submit uh I will put it here function handle form submit and we get an event here that we need to do prevent default and then if we want to login First let's fix that we can log in with credentials right so let's do fetch request that will go to/ API login and this will be an assing function so let's add a weight and uh here let's let's add the uh body and the body will be Json stringify for object of email uh email and password right we also need to have headers to be a Content uh type I think we need to have it uh I always try to add it if it's not axis we are using and we are using instead our default Fetch and uh what else do we need here method method will be post post all right and that should be it and let's grab a response here and as you remember inside the response we have a field that is called okay and we can do if response. okay and then and if it's not okay then something else this will work we have it this way inside our register page uh another thing that we can do is to actually not get all of the response we can grab only the okay part and then we can do just if okay like this uh I think it was called okay let's just check inside our register page and more to the top yes it's response okay so that is correct so now um let's see um inside this we want to have a state to block our form right so for now it's disabled false on all of the inputs and let's also add it to the button false um let's add a state that will disable all of it um let's call it maybe login in progress set login in progress default will be of course false and on the beginning we will do set login in progress to true and uh after everything is done we will just set uh login progress to false doesn't matter if it's okay or not we will do set login in progress to false so now we let's do something like this instead instead of this false here here and here for disabled we will do login in progress so now if I click here uh it changes to the dark gray um the colors of those inputs as I don't know if you can see because it takes like just few milliseconds to try to uh log in right uh but now um uh let's see we have this uh this disabled login progress should be actually on this button and not on the login with Google now let's see yeah um now let's see uh we need to fix this endpoint right so we can know if uh those credentials are okay and we can log in with them so as you remember uh inside our API off we had those uh copy pasted stuff from next off here we have a credentials and we have this authorized function that we can use let's get rid of of this comment and uh we don't need to do anything from here we just need to do something like uh let's maybe do console log and um let's console log our credentials is it this credentials no uh it should be fine with just only credentials right and we don't need this user and we are just going to return turn null for now so I just want to see if uh something will happen but of course we need to change the this fetch as you can see here and instead let me see how we should go with those credentials credentials provider documentation I think we just need to send the request there so uh let me see here um let's try to do instead of onsubmit let's do action and let's go to / API here let's also add the method of uh post and action API let's see where it should go API of API of and now let's see we will also add here name to be email and here we will also add a name to be password and let's see if this will work uh if I do test at example.com and test let's open here the our console and let's see what will happen if I click login so we have some spinning so something is working I don't know what actually is uh going on here I think we shouldn't go there uh we shouldn't go to this uh API off I think that instead we should do something like this um on submit let's put back our handle handle form submit function and here instead of doing this fetch uh we will not create this and point ourself and instead we will use uh next out right so let's get rid of this and uh here we want to do sign in sign in and the provider will be creating shells all right and let's do a wait here and let's see what will happen if I hit login now well as you can see something happened uh we get a small working uh small working small warning next off URL and no secret so let's add those to our EnV file so let's do next uh how is it called next off URL so let's do next off uh URL equals and let's do HTTP Local Host 3,000 yes and um now let's also set our secret maybe here secret and some random stuff here and now let's use The Secret inside our uh route for uh this nexl so here we they also want to have a secret that we are going to grab from process environment uh secret that we have inside our that nvi right so this uh worked here and um now let's see and we have this console log I don't know if it showed anything uh let's try again here I will do oops let's refresh test at example.com and test test and now let's see I open open console here and here and let's hit login and looks like uh nothing happened here it just redirected us to this APR off page and this is not something we want instead um instead I would like to fix this aoriz functionality right so um let's maybe see if I restart my in my environment if this will help okay so now my think is running and I want to check if I will get this uh console log by any chance test at example.com let's do test let's do login and uh nothing happened we uh let's see we didn't had any uh console log here and no console logs here let's see what we have for the net NW workk I'm going to put test example.com test and let's clear the Network login and we get redirected now let's see uh no uh no console logs here providers let's see in the respon if we got anything useful no we don't let's see do we miss anything we have name credentials let's also add ID credentials all right and now for our login page H let's see maybe let's uh do cral with lowercase C because I think it should be ID all right and now let's do test at the example.com and test and I will copy this just in case and now we have a console log of credentials so um as you can see we get the call back URL and but this is not something I like because I don't want to have email and password here instead I would like to send it as an as extra data so here we can probably do this with email email and password password yes and now let's try again test test login and now as you can see we have both email and password here so let's go back to our authorized function and from the credentials we can grab email and password from credentials like this because we have email email and password here inside and now what we want to do uh return null if um we couldn't log in and we want to return user if emailing password is correct so first we want to grab the user uh but before we will do this we need to connect to the database right so let's do mongus mongus uh we need to import mongus here now it's connect it's imported now mongus connect here Pro process. env. uh URL all right and now let's do mongus and not M now we can grab the our user so let's do const user equals uh user user Let's see we need to import our user I cannot find the user Let's do let's import it manually here import user from and now let's do like this not components model and user and now let's do user we want to find one where email is email and if we have a user and the password is okay um maybe let's just do like this if we have a user then we want to compare password so let's do maybe here inside let's do bcrypt uh there's a function called compare um let's see maybe inside the documentation I do search for compare sync yeah there's a function called compare sync uh so let's run this compare sync and our password that we get from the cronal sent and the other password is from our user from the database password like this password and then we know if the password is okay so maybe we can do something like this password okay equals uh this it's not an if anymore so we can just do like this and we will also add if we have a user and B back Crypt compare um all right so now we know if we have a user and if the password is okay and so we also need to have a wait here because we are finding user uh from the database now um if password okay then we want to return our user all right right and uh now let's see we are grabbing credentials uh from we are grabbing email from credentials looks like they are saying that email doesn't exist or it's optional so instead grabbing uh those like this I would do email equals uh credentials uh email with this question mark in case if it's empty and I also need the password password equals credentials uh password all right still we have an issue with email and we and they say it's only username and password here inside but they are wrong because we get email as well and um think this is um this is partially because this is the only typescript file we have let's change this to JavaScript and now we don't have this problem anymore and uh let's try to log in let's do our t test example. come and test let's try to log in and we have an error let's see what happened um does not contain default export all right so let's go to here and Export const user yeah so we need to import it different way we need to import it like this right now let's try again test test login still error let's see user does not contain default export uh let's see here it should it looks fine for me let's maybe do yarn Dev again here to restart everything and uh now let's see I with the test test login and we get for one uh here I don't see anything maybe let's do console console log uh of the password okay I will put this as an object so we can see uh what's inside and here we have the typo it should be password and now let's see test test and uh let's see we get password test um I wanted password okay instead let's see um here I want to put test test and let's do login password okay true so it looks like uh it works so now uh instead of having this login and register here because uh here right now we are logged in I don't need this password K let's get rid of this and let's go to our header and instead of this login and register we want to uh use state right from uh we want to use session here sorry so let's use session equals uh use session from next out and um now I'm going to put use client here and um let's print our session with console log inside the browser let's see what do we have here your session must be wrapped inside session provider all right so we don't have this and we need to have it inside our app so uh how can we fix it well we need to go to our layout and we need to have a session provider let's try to just put it here inside main let's do session uh provider let's put it like this and here let's uh close it after the footer and let's see if this will uh fix this react context is UN unavailable in server components all right so it uh sounds like we cannot put our session provider here so what I'm going to do is I will remove this session Provider from here or maybe let's try to make this this will not work uh to make it uh client component for the whole layout so I will get rid of this uh session providers and I'm going to create a component called um app context let's do app context. JS and I'm going to create a hook called uh export function uh called um let's say app provider yeah and here I'm going to put our session session provider and all the children will go here inside children and I'm going to mark this as client component and now let's go to back to our layout and now let's do app provider like this uh the closing will go here and now it works and we see some session data that we are authenticated and we see the information about the user so that is cool right uh so let's go to our header header and as you can see we have this status that is authenticated so instead of grabbing call session let's just grab status from uh session status and now here we have this login and register navigation let's do something like this here inside if status equals authentic ated then if I'm un authenticated I want to have a logout button so let's uh copy I want to copy this with the styling so I'm going to copy the link with all this primary blah blah blah and it will say log out and I want to also do if status is not authenticated then I want to do um those two but because we have two elements here I need to put react fragment so that's why this empty HTML tag so now we have log out uh this log out doesn't work uh so let's fix it instead of this link register I'm going to change this to a button so uh let's see now yeah and we have class names here but I also need on click on this one and I will just put this as a sign out inline function and this should do the work so now we are logged in and if I click this log out I'm logged out and now I need to log in again so let's do test at example.com and test let try to use wrong credentials if I do test one it will go here all right uh so let's do test at example.com and test if I click login I'm logged in so that is nice um maybe we should be redirected to another page but uh we can and uh put it as an extra param to redirect uh but we will fix in the moment we are um logged in and we have this log out button we have also here status loading status authenticated and um let's see if I log out the status is unauthenticated so here to see the login the status needs to be unauthenticated so on the beginning I will not see anything if it's loading so so that is nice and um and now let's see um this looks fine uh the only problem is uh this uh button is weird so let's fix this one so let's go to our hero I think and here we have this button learn more and uh I don't want this border so let's do border zero it's the default border that we got uh yeah I think that is uh better um I also need to have items Center here and now I think it's uh fine now same for this button looks like we need to add flex and let's see flex and justify I justify Center here so it will be centered yes I think now it's better right uh we can register and we can log in with credentials and this works right right and we can log out now it will be nice to fix this uh login with Google before we will do this let me just refresh the database I want to see how it looks like yeah we have just few users here uh all right so now let's add the uh Google provider so for this I need to go to um Google Cloud the console and I'm going to create a new project so let's do new project and let's do food ordering let's create this project now let's select this project food ordering and we need to create our oaf and client so let's search here oaf client uh we have client consent screen yes let's start with this uh external create and the app name food ordering app and here my email and what else do we need the email again save and continue all right this works now let's go to credentials and let's create credentials o client ID application type web application and here we have those authorized redirect URLs uh if we go to uh let's see providers and we go to let's see Google you can see that for authorized red direct URS we need to put this for local host and then when you deploy it you can you need to also change it to your domain and add another one so uh I'm going to add this for Local Host let's put this one and let's hit create now it's created we have client ID and client secret so I'm going to add it to myv file let's do Google client ID and Google client client secret so first the client ID let's put it here client secret let's put it here and uh now let's see how we can add Google provider uh we just uh grab it like this import the Google provider so let's go to our API off Route here and let's grab Google provider and let's put Google provider like this here inside providers Google provider Google client ID Google client secret yes this looks fine and uh now let's go to our for example login page login page and we have this login with Google and to fix it I'm going to add on click here uh but I'll put this into separate line and this will just run this sign in function with provider Google all right so now let's see login if I click here sign in failed and then check your check the uh details provided okay something went wrong let's refresh let's try again maybe I will restart the environment just in case uh log in with Google and now it works I will select my account and I'm logged in as you can see now I have this log out button so I am actually logged in I think maybe I can add here a redirect uh URL here so I don't want to go to the login page after I logged in I want to go to the start page let's try again login login with Google let's try again refresh login with Google Now something went wrong let's restart everything here uh refresh login with Google and I'm going to log with my Gmail and the redirect didn't really work this didn't work let's see we have also call back URL let's try this one if I log out uh let's maybe try to log in with uh credentials this time but we also need to add this callback uh callback URL um to our credentials lugin so let's do call oops call back URL and start page test at example example.com and test here let's do login and we are on the homepage and we are logged in so that is really nice all right so this worked now the next uh thing we can log in and uh with Google and we can log out and here on the register page we also need to add this uh function here for login with Google so let's go to uh register page and we have this login with Google so I'm going to put this on click here and um now the problem is that um we we need to put sessions to our database because I think that those small problems we have that we cannot log in is actually because we don't have session inside database uh to fix it I'm going to use uh I'm going to use um here uh documentation and we have here we have providers it's not providers we need to have adapters here and I think this is all documentation I will go go to this page let's go to Providers not providers adapters sorry adapters and not dynb we need to have this is the latest page okay let's go to get started uh adapters and here we have mongodb adapter so we need to yarn add this let's do uh here in a new tab youn add this and uh now we need to create create this file um and uh let's create this let's create this inside let's see I'm going to put a new directory here here called lips and inside I will do a file called the connect. JS and I will put this this is typescript so I'm going to just remove those typings here and here as you can see we have mongodb Ur URI and for us it's URL instead so I'm going to change this uh this looks fine so I'm going just to save it and now we use uh adapters inside the config like this so let's go here API of route and um let's see we just do adapter and now let's do let's see mongodb adapter let's import this first mongodb adapter and now let's use it like this adapter mongodb adapter we have this client promise that we need to import as well and so let's try to Import Auto Import this yes I think this uh I think this worked let's see yes uh it imported from our lips so this works fine now uh now let's see if we will have session if we log in with Google uh let's try yes and now let's go to our database and we have sessions here so as you can see I have an active session let's try to log out login log with Google sign in failed so something went wrong uh let's see here I don't see any errors uh what is wrong sign in fail check your details provided below login login with Google well that's odd let's go to the login page and let's see what's uh the problem login page sign in Google maybe let's remove this uh call back URL and let's try log in with Google sign in fail check the CR you provided H but if I click here it will work and this is not the flow I would like to I would like to have so uh we need to fix this let's do log out and uh let's try again I will hit let's maybe try on the register page login with Google okay it works on the register page that is we weird let's try again register okay so it works on the register page but not on the on the login page login with Google now it doesn't work on the register page it works so let's see what's the difference so on the login page we have this on click sign in with Google and it's a client component and uh maybe I also need to add type of the button here because otherwise it will send this form it will trigger the form submit so maybe that's the problem let's go back to login and let's try login yeah and now it works so that was the problem we are sending this form I can put back this um URL call back URL to our uh homepage after we are logged in so let's try again login with Google and my account and we should go to the home page yes that's cool uh now uh what I want to fix is you probably seen that this page for login and for the register is very similar so I can open here login register and those are pretty much the same and um it will be nice to fix some stuff and to I don't know to make it simplified or maybe we can fix it later let's see here what is the the problem because we have some errors oh there are no errors here all right so now we can register and log in and our authentication works so this is this is nice and the next thing will be actually so we can instead of going to the homepage we can go to our profile page and we can edit information about our profile like address uh update name and stuff like this let's also check our database for users as you can see we have this test example.com user and here is my user that I used to log in when I logged in with Google so this is my dream here and uh yeah so we have several users now so next step will be to have uh some kind of user Panner so we can update profile information all right so now it would be nice to have a maybe here a profile uh link so maybe your email or something like this and then when you click on it you will go to your profile page so uh first let's go go to our header so inside components layout we have a header and here we have if it's authenticated we have this logout button but I also want to add the uh link to profile and because we have one it one element here for button we will need to have a react fragment because now we want to have two elements and now here let's just put a link to um let's see um it will say profile for now let's see um yeah we need to have a link so let's do slash profile and now let's see now we have profile uh but maybe it would be nice to have a name of the of the user right so we have a session here and we are conso loging it so let's see what do we have inside uh our session as you can see we have some data and inside data we have user and then we have email and I think sometimes we also have name if you log in with uh if you log in with Google here we have name so we have email and name so let's do something like this um let's define here user name and uh maybe not username as a username but users name so let's do something like this first we want to grab user data so um user inside data so let do const uh user data equals session and then we need to go inside session we need to go to um data and then user right uh session data user session data user all right and now inside user data we want to grab name let's see yes it's a name but if the name is not uh inside the object I want to grab email instead so let's do or let's do session not here sorry here or user data. email right and now we can use user name um instead of our profile so here I will do usern name like this and then now let's see Let me refresh we have an error because we are trying to access user but uh the data is undefined so I guess the problem is that on the beginning when we render this at the first time the session is empty and then and then we find the information in the database and then uh the use session is uh refreshing this session information here so let's do something like this I will add a question marks here in case those uh uh this information is empty now let's see I will refresh and let's see it looks like everything is uh uh empty I don't even see the uh log out button so something is uh wrong Let's see we are out authenticated but I don't see anything so let's see what uh what happened uh and it looks like uh I have just removed the status by accident so let's do status from session uh status all right and now let's see yeah so now I have my name here as you can see um it's in two lines I would like to have it only in uh one line or I would like to just grab the uh the first name so let's do something like this we have this username here what I want to do is I will change this to let so we can uh change the content of it and now let's check if username uh if it includes if the string includes a space then I want the username to be uh only the first part so I want to do username and not user data username I want to split using space and I want to only the first part so now now we have only loid here I will remove this console log we don't need this and then let's see include is undefined all right so and this doesn't work because this username can be null or undefined so let's first check if we have a username and username includes a space so now we have only David here uh we can add something like Hello uh colon if we want helloo cool on and we have something like this um I would like to put this in one line so let's see I will put this here this here and let me add some uh class names and uh let's see white space no W and now we have this in one line so uh I click to this and it goes to profile but as you can see we get for four because uh we don't have a route for this let me close API register and login here and I'm going to do new directory inside app and let's create a profile and inside we just need to do new file and page.js and inside this page JS export default function and let's call this one profile page and inside we just need to do well let's maybe start with a section a section like this and the H1 that will say profile profile right and we have something like this so um there is uh something like I would like to have this H1 that we have let me log out uh login here I would like to have this H1 so I will go to my login page and let me see I want to have this but with profile inside this uh but it will say profile and uh yeah now the problem is that we can actually go there to profile page oops to profile page and um even if we are not logged in so that is not good right first I will add some um margin from the top let's the margin top of four or maybe eight let's see how big is it on the our loging page it's eight okay so let's do the same we have profile page and uh well here I would like to do that if you are not logged in you shouldn't see this page you should be redirected to the login page so um I'm going to use session so let's do session equals use session yes and uh let's do conso log of our session and now let's see what do we have here um well we have an issue react context is not available in sever components right so let's make make it a client component use client and now let's see we have inside our session information status loading and then status unauthenticated so what I want to do if before we will return this H1 and so on first I want to check if uh status so let's grab the status con we can grab it maybe like this this time session status from session and I want to check that if status is loading then I want to to return here loading yes and then also if status is um unauthenticated we want to redirect we don't want to return this HTML we want to redirect so how can we do this um I think there is a redirect function that we can use from next let's try redirect to slash login yes and now let's see if I save application error a client side exception blah blah blah so uh we cannot redirect like this I think um let's maybe see if I return this redirect did it work does it work yes then it works so let me go to home and if I go to slash profile it redirects me to the login page so this uh works now right so uh let me remove this and um no here we are authenticated and um now what else do we want to do let's me maybe first uh log in with my Google account so we can access this page let's go to this profile and what do we want to have here well we want to have addresses or one address and we want to have uh well something that you can edit your profile so we can edit your name and maybe your image profile image right so uh let's fix it so we need to have some kind of um form here so you can edit your uh image and name and then maybe on the right side you will have addresses or maybe we can do everything in the middle um profile picture name and then addresses underneath maybe that will look better so let's put a form and um inside this form I will remove this action and I will add the class names so we can do Max wave of uh Xs and MX outo so it will be centered and inside this form what do we want to do we want to have an let me add the border for this form so we will see how it looks like okay so it ends here now I want to put the image on the left side and then name on the right side something like this uh so let me put a div and um this will be our first row of the form and uh well on the left side I want to have an uh upload for image so uh sometimes we will have image information inside session um and it comes from the user information from the database so I want to display it somehow here um Let Me Maybe first do console log on the session console log on the session so we can see where it is inside session data user and we have image here so that is nice so let Let's uh grab this uh image let's do const user image equals and then let's do session then we need to go to data then we go to user and then we go to image and uh now let's uh here is the first row the first row with the div and let's put an image but let's put it as an image from uh next image and the source will be the user image and I will um put here with will be let's may we do 64 and the H will be the same because it should be um it should be a square and alternative text let's add it as well as Avatar right now let's see uh loading and we have some error here uh saying that host name this Google user content is not configured under your uh next config see here for more info let's open this on the new tab and the thing is that if you add images to your app to your next app from different host names you need to add this H those host names so to let's go to next config and as you can see we need to add images remote patterns here so let's uh let's do this next config images and then inside images remote patterns all right and and the remote patterns is an array not an object so let's do an array and inside this array I want to add well something like this let's put it here and I want to put host name um maybe we can skip the Pu name and port and the only thing I want to add here is um well this host name googleusercontent.com let's try um Google and Google user content.com and let's see if this will help if I reload loading and no let's see if it help if I add this subdomain here let's save it and if I reload loading and I have my image and I don't want to have it like this I would like to add like here any a subdomain so let's see if this will work yeah it works so let's have it like this and let's go to our back to our profile page and I would like like to fix it a little bit so um first we have this div that will be first row and I want this to be uh some things will be on the left side like this image and other like an input for uh the name will be on the right side so let's add the placeholder with first and last name something like this and now I want this first if to be on the left and second on the right side so I do last name flex and uh let's see yeah that's good now I will add a gap of two uh that is nice now uh let's see why this input doesn't take the whole Space let's see well because the second div should grow the right side let's add a grow on the right side yes now it goes all the way to the right side and now I think I can remove the border from the form so let's remove this and now it looks like this so we have this Flags Gap two let's add items Center here so it will be centered the image and the input here now uh maybe we can do the image a little bit uh bigger and maybe we can make this form a little bit wider so as the medium on this form yeah I think that is better and now the image can be a little bit bigger so let's do maybe uh I don't know 12 the 125 I don't know yeah this looks nice um this looks nice maybe this this is too big uh let's do I know 80 80 pixels yes and under first and last name I want to have a button to to save it so underneath I want to have a button of uh type uh type will be submit submit and it will be save yeah something like this maybe it's too big I don't know uh I would like to have this uh image in the some uh some classes here so for this image let me try to add some class names uh let's do rounded um medium or maybe large let's see if this will work yes it does and um now I would also like to add the div above so we will have some padding I will put this image into this div and for this div I will add add some background of um gray 300 and some pading of four now let's see yeah something like this but uh maybe a smaller um smaller padding and also rounded here so I want to do here rounded large and smaller padding like two yeah this looks nice um and now here under the photo I would like to have a button to change Avatar so under the this image I will have a button of type uh button Buton uh change Avatar yeah something like this and we have this uh bton here uh it's not visible because I think the color is the same let's see if I change this grade to 800 yeah then we have some outline here so it's a little bit better let's see if I change to 100 yeah then we have something like this um I don't know what would uh work best here but uh maybe we can get rid of this background gray and we can increase the Gap here to maybe four so we will have more separation yeah uh now uh for the I don't want the IM I want I would like to have the image all the way to the right so it will be uh as big as the button so uh let me see instead of doing wh and have I will do um let's see on no layout and layout will be I don't remember let's go to Hero I don't remember how to do the image layout fill okay layout will be fill and um the div above needs to be relative let's do it like this and now let's see well almost let's put another div with class name relative just for the image relative just for the image and let's put it here now let's see I don't see the image let's add object fit contain I think it should be still no image let's see inside here object fit contain L out fill I think this is because uh let's see our uh div needs to be needs to have some hav here otherwise it nothing will be shown or maybe I don't know uh let's change the uh let's add some ha on this one to 24 I don't know if this will change anything yes it does but the problem is here I would like the image to take the whole with so uh let me try to do with um have full and weave full now let's see nothing is here let me see and we have 100% 100% And but we have no hav here on this div so that's why if if we would add a half here of like 100 pixels then we will see this but otherwise well we need to tell what theave will be and I don't want to define the hav I want the hav to be automatic so uh well let's get rid of this div that we have uh as a partent of the image and I don't want to have this uh this um object fit contain and I don't want to have this layout F instead I will do something like this I will change the WID to be zero and the half to be zero and what else I will do is that I will add here on the classes on the image the withi to be full and the half to be full now let's see and now we have something like this uh it looks really really weird um and looks like it's something wrong with because we did this zero and zero here uh let's see if we do maybe like 2 350 250 here and 250 here okay now we have something as you can see the image is smaller than 250 in W and in with and half but we added those classes here wave full and have full and it means it will take 100% um it's a little too big um because uh well it's uh it's not that sharp as it should be let's see yeah it's this big and we have stretched this a little bit and the image is 96 uh pixels and we stretch this to 153 so maybe we can make this smaller but to make it smaller we need to change this uh uh button to maybe something like edit and then it will be smaller all right and I would like to add a small margin bottom of four for this uh between this and this maybe four is too much let's do just two so we can edit the uh Avatar maybe that's still too big let's do one yeah that's good and uh now let's see we have here for the name and maybe I can add another input that is disabled just for the image so you can see your email so um input type um email and the value and value will not be editable so let's do just uh user session session data user email session data user email like this and you can see your email you cannot edit this because we don't have any change but I will also add here disabled to true so it's uh so it's disabled we could maybe style this disabled field uh a uh some a little bit uh uh more so let's go to Global CSS and as you can see for disabled we are doing darker gray let's maybe do lighter gray like this with no border so it's do border and zero so we have something like this but even for the text I would like this to be lighter not the dark let's do text Gray and let's do maybe something like 500 so we have something like this maybe even lighter for the text let's do uh 300 and we have something like this and well it's barely visible so I need to um add more styling to this to this let's make it a little darker like 300 but the text will be like 500 and no border so we have something similar that we had uh before and I think this looks best uh so we see that this is uh disabled and if you put a text here it's back so it's clearly visible that you can change stuff here but not here all right I think this this will work so we have this first and last name here uh but it should be filled with the uh state so let's go back to profile page and if we want to have something editable here we need to have state for this so let's call this uh user name and set username equals use session is is State and uh from react and here the default will actually come from session let's do session and then data and then user and then name or empty string and I'm add the question marks here in case anything of this is undefined right so first and last name uh let's put username into this input here we have this input I'm going to put here a value equals username and let's add on change let's do event and with this event let's do set username event Target value and now we have our my name here and I can change it and add stuff into it so this works uh now I can edit the input but now I should be able to uh save it right so uh when I click save on this button we will trigger submission on this form uh one thing I don't like is it looks like we have two forms in one form element we have one form element that is that takes actually two forms the one is this and the second is this so um well to fix it I will change this form to just ative and then I will put only those stuff into a form so it looks like it's this div that grows is the right it's the right side and I'm going to change it to a form element and I'm going to add on submit and for this on submit I will have a function called handle no not handle form submit because we will have several forms here instead I would like to have something like handle profile update handle profile info update something like this now we need to Define this function um let's see somewhere here above so let's do function handle profile info update and as always we get an event and we want to run prevent default on it and then let's send not AOS let's send fetch request to/ API SL profile why not and it will be a method of a post we want to send headers and those headers will have a content type uh application Json and what else do we need here we need body and um well um the body will be Json string if I and we want to send only our username because this is the only thing we are updating here maybe not as username let's send it as a name so name will be username all right and I think that will be it and this is an fetch is asnc function so I'm going to add asnc and a wait here a wait no no uh no equals here let's do response equals a wait and uh now we can do something like this we need to have this end point H for a post but because this is an update for our information I will change this to put and now uh let's create this endpoint inside our API so let's go to API and let's do new directory and let's do profile right and inside we need to put route Js route. Js and now export function putut and Export it will be ass sync function first and foremost we need to do connect to our database so uh we can do connect and but we want to use mongus so let's do mongus let's import mongus let's do connect and here we want to just do process EnV URL okay we are connected to the database what do we want to do now we want to grab the data so let's do const uh data equals we need to run wait here because uh when we grab request uh Json it will uh it's this is assing function I I think it's uh request Json let me just double check inside register yes it's request Json all right so uh we are uh we are grabbing data and then what do we want to do we want to grab we want to first check if data has a name if data or maybe we can check it other way if name in data not date data then we want to update the user name and um so let's do this so to update username we want to First grab the user and we want to grab the currently logged in user so let's do this and I will do this here so const user equals a weight uh get server get server session this is what I want to use and it will not be user it will be session right and the here we need to put our out options and our Al options are actually defined here here we have this is an object of our Al options I'm going to cut them from here and I'm going to uh Define them here up of so the const of options equals this right and then I will put them back here of options but I'm going to also export whoops I'm going to also export them as a constant so we can import it here inside our profile route of uh options let's import it and now we have our import here right out options we have it here and we have session maybe let's do cons Sol log of the session so we can see what's inside here we don't do anything yet and I will end this with just response Json with true so the route will work now let's see what happens here inside Network I will hit save and we are sending this put and we get 200 Let's see we get true here let's see in the console we get inside session we have user with name email and stuff so um because uh email is unique we can grab the user information we can grab email and then we can um see what has been sent here as a name let's also uh let's print both the session and the data that we are sending so let's see save and now as you can see inside session we have user inside data we have our new name that we are sending from here so now let's uh update so so first we want to grab the data so um first we want to grab the user uh so we know what is the email con uh email equals session user was it session user yes session user email user email and uh this way maybe we can first uh uh check if we have a email maybe no we don't need to check it let's just grab our user from the database so wait let's grab our user model and let's find one we want to find one by email to be email right and we have uh our user and we want to update our user actually we don't need to fetch it first we can just directly update it using our model so we can do user uh update uh update one and with this update one we need to First filter and then uh we want to filter by email we we want to update where this email is where email is the email inside this constant and we want to update what we want to update the name to be data name data name like this so if you just want to update inside users you just do uh user update one because we want to update only one row here is how we can find the user we find it with email and here the next object is what do we want to update we want to update the data the to be this name right so uh this should work so uh let me just add a weight here because it's a database query and uh let me try if I refresh here it should go back to well it's empty um it shouldn't be empty I don't know why it's empty let's refresh once again it's empty but it shouldn't be let's see why it's empty profile page and username should come from session um from session data username let's see why it's empty um I don't know uh let's see inside the console do we have any console log about the session no we don't let's do console log and let's do user um let's do session here and let's see we have data here user and we have name so something wrong here um because it's empty uh we do session data user name so let's do session data usern name something so something is wrong here and uh and uh I think this is because we initiate our state only once and the session the session actually changes so to fix it let's first this uh let's set this uh username to empty but then I will also add something like this I will add use effect use effect here here we will have a function and here we will have dependencies our dependency will be actually status and I will do something like this if status is um authenticated then I want to update our set username and the username will be will come from session uh data usern name okay and maybe we can change this from status to session or we can add both session and status because both of those are dependencies right and now as you can see we have our name here our name my name right so let's clear this and I want to add one to three one two three and uh let's save it and uh let's see what happened let's go to network we send a put request we it's return true let's see if I refresh uh well we get an the old name but let's see inside here I need to log in again inside our database let's browse collections let's go to users and let's see here is my name here is my Gmail so it looks like it didn't work uh let's see I will clear everything let's hit save we send the put request let's see payload we are sending the name but it's not updating let's go to profile route and let's see if we have name inside data let's maybe here console log everything let's console log our data because it's important to know if we have a name there and inside data we have a name so let's see let's do something like this uh if we have name in data so it should uh print true or false let's hit save and we have true so we know we get inside here so something here inside doesn't work let's see how how the email looks like let's console log the email let's hit save email email looks fine so um this should work now let's do both email and I want also to print this maybe let's check the documentation everything looks fine um update and let's put uh this into update field so we will see if everything works let's hit the save email is this and update is name to Pas okay let's add one to three save email is this update is this uh it looks fine let's uh hit refresh to see if we have this one to three somewhere or we don't now we I don't see update so uh something is uh wrong here we are doing update let's see the result of it Con result equals and let's put this log here and I'm going to add result now let's see I'm going to uh hit uh save again and let's see acknowledge true modified one matched count one so it looks like it uh should work right I just don't see the result inside my database let's see yeah and the name is not updated let's see if it's updated somewhere else no it's not see inside I no nothing here sessions no users no maybe I would just delete this user and let's see what will happen I will log in again log in with Google and let's go in with log in with my Gmail account and let's go here let's add one to three save and uh well it looks like it should uh it should update let's do refresh and let's scroll to the bottom of users no my name is is not updated let's see once again update one oops update one filter query well the email let's see the email should be my Gmail let's see uh email is my Gmail and we should change the name to this I'm going I will now try to commment this out and I will try to do this another way let's do first I'm going to grab my user con user equals and let's do just a wait user find one by my email and then I will do user name equals um uh equals data name then I do user save with a wait and then we will see if this will work so let's go back here let's do 1 2 3 4 save and we have an error let's see password is required okay so maybe that's why it uh it didn't update let's go to user and let's see um password is required let's see what happens if I just remove required then if I hit save you password is required maybe I need to restart my environment all right now let's hit save and we get an error data and salt arguments required okay and so something uh here was uh wrong so it looks like this function runs post validate even if we want to uh save uh even if we want to update the user and uh we don't want to run it this way we want to run this only when we create user so I think we will need to put this into register so inside the here where we create the user I will check this uh here instead and I will hash the password here so I'm going to to go back to here let's change this validate I will remove this validate from the password let's put it like this and now let's see here uh this is for creating users I'm going to paste this here instead of pass length I will first grab this pass equals body password and now let's see uh if it's wrong then we will throw an error but uh if it's okay we won't to Hash it so let's do something like this and we don't need this post stuff here let's put it here and we need to fix it because uh not hashed password will be uh just our pass from password and then we will have salt and then the hashed password so let's do const hashed password equals this and then we want to uh put it into body because as you can see we are saving just the body body password equals hash password all right and we can simplify this we can inline it like this and this should work so now let's see to our profile route if this will work let's hit save put request uh didn't work something is uh wrong let's see uh data I'm going to restart my environment to be sure that um that we get an error so it looks like now everything Works uh after restarting the environment so let me jump to the database and let's see if uh well if this will work no we I still have this name the old name without the numbers so um let's add here into our console log that uh I want to print user as well and we will see if it's updated let's hit save and usern name is uh still the same let's see here we are changing this let's print now data I want to check if we have name inside data let one two three save see um data name yes this looks fine let's print now user instead let's hit save now the user name is not changed okay I know what's uh what's the problem we can put back this the simpler The Simple Solution the problem is actually because our name is not defined here so let's do name type uh type will be a string and that's it now we can update this so uh we don't need the result either we can just update so one two three save and no errors here or we actually we got an error or did we let's clear everything save put 200 everything seems to work let's do refresh and now let's see no and nothing has changed let's see update one email name to this thing because we need to update our envir uh restart our environment now if I do save let's go here to our database refresh and now I have my one to three so uh now it works so uh now we can update and if I refresh here I still have my one to three so that is nice now I would like to be able to change my avatar here right so I can change it to a different uh photo so uh let me go back to our uh profile page and um well we don't need to have this response here maybe we can maybe before we will go to Avatar when I click here we are saving uh but we are not notifying that it's saved right so um maybe we would like to have like here above or something like this um the profile has been saved let's see uh I will style it first maybe under under this H1 I'll put in H2 the profile uh or maybe just profile saved profile uh saved and I will add some class names like text uh Center Center and uh let's see yeah like this profile saved uh but I will add like a a green I know of it will be green yeah let's do green background Green Let's do like 200 let's do some padding of four yeah something like this but I would like to put it inside this uh div so it will be more narrow yeah something like this and maybe let's just do 100 and let's add rounded large for rounded corners and uh well this looks fine I guess now and maybe we can add some border so it's the Border four to make it uh visible that's the Border green and let's do 500 so now we have something like this that's too too big and too too bold so let's do 300 and let's do regular border without this four just the border so now we have some on this profile saved well and I think it looks fine profile saved and but now it's visible all the time and I want to show it only if it's saved so here we have this uh response and we need to check if the response is okay and to save to say if it's uh um saved or not so let's do if response okay then we need to update State somewhere so let's add state for this uh let's call this one profile or may be just saved saved and set saved equals use state and default will be false and on the beginning here we will update this to false just to be sure to reset this and here if it's okay we will set it to True set save to true all right and uh now if I refresh we still see this because I need to add an a small if here so we have this H2 here and I will add uh is saved was it is saved let's see uh no it's just saved let's do saved if saved then let's print this H2 here okay so now I don't see anything but if I change something and I click save profile saved we can add another thing for when it's actually saving so let's do something like this um I would do uh here another state is saving and set is saving default will be US State uh of false and um here on the beginning we will the set is saving to false to true actually because we are about to save now so this will take like 100 milliseconds or so but after it's done we will set it back to false set is saving to false right but now we want to also add an here we want to add is saving and and now let's add something similar like this H2 and that will say saving dot dot dot and but maybe let's make it like a blue color with border of uh blue as well so now if I hit save it said s saving and then profile saved I can make it a little bit longer so you can see that it actually is saving I'm clear here here we have Thro link and if you want to make your request slower you can change here like to slow 3G now if I hit saved H it's saving and then it's saved so as as you can see this Tu are now like two 2 seconds or so yes 2 seconds um I can hit save again let me change something save saving and then profile saved let me remove no fro link refresh let's clear let's add the fro link to slow 3G and now let's try again saving and profile saved yeah that that looks really nice let's remove this fro link and uh now I would like to fix so we can also edit this uh profile picture right so um yeah um for this profile picture um I would like to do that when you click the on this edit you will uh see a file um this choose file window so uh let's fix it now let me go scroll here here we have this button that says edit well to first to edit to change uh to pick a file we will need to have an input of type file and and um well now we have here the input of type file as you can see it stretched everything uh but the thing is I'm going to make it uh hidden so let's add a class name hidden so now it's not visible but this edit doesn't work still but um I'm going to uh fix it by putting a label uh a label and I will put this input inside this label I don't need this HTML 4 and here inside I will put a span with edit instead of this button so now I have this edit here and if I click on it I get this uh file picker here so I can for example pick this image or maybe this or maybe this so um we have this edit working I have prepared my an image here of me uh but uh I want to style it a little bit so I want this to look like a bon so let's add some class names I want to add the Border rounded LG and let's add padding of four and let's see how it looks like yeah something like this but uh I want to change this to a block yeah something like this the padding is too big so let's do only two and let's do text center now let's see yeah this is uh much better maybe I will do this also a little bit uh darker let's see here on the on the on those buttons yeah a darker border so it's the border of gray 300 at least let do gray 300 yeah something like this and I want to also add the cursor of pointer so I have this hand when I click on the button so now it works and I can choose an image but as you can see nothing happens if I do this and this is because uh we change the value of of this input but uh we don't do anything with it so to do something with it I will add here on change on this uh input of type file and uh I will call this function handle uh file change we will have only one file change in this component I think so let's define it uh here function handle file change all right so um now um we get get an event and with this event um we not need to do stop propagation or prevent default I want to show you that inside this event we actually have information about the file so let me just refresh I will change this um change this image and here inside console we have this uh event information and inside the target we have value but this is just a uh fake F path as you can see uh the one thing I want to show you is that we have something called files here files and as you can see we have one file and here's information about our file it's a file object so let's grab our files here so let's do const files equals event files I add the question mark just in case if uh no this will never be empty so no question mark need so for files I want to check that the length of the files is bigger than zero and this means the array is not empty if the array is not empty it means that we can just send our file right we can upload our file so uh first I would like to uh well just uh send it I would like to send it uh with our fetch so let's do something like this let's do Fetch and and I will send it to/ API SL upload for now and let's add more stuff here I will add the wait and I need to add us Sync here right so uh what type of method it will be let's make it post because we are posting a new file right and now I think we need to send also body and the body will be well I think the EAS will be to send it not as a j because we are not sending strings we are sending file I think the easiest way would be to send it as a form data so um to prepare this form data I will do something like this account data equals new form form data and let's do data and set let's do files and let's add those files here and now let's try to do something this to the body let's put our data and now let's also add headers we want to inform that content type is um well it's form data let's search for this content type form data content type and let's search for form uh form data let's see I think we should use this thing multiart form data as you can see we have content type multiart form data so let's use it multiart form data as we would descend eror form okay and this this should work right this should uh this should send the image so now we need to have this endpoint inside our API so inside API we have a profile register we don't have upload directory so let's put upload and we need to have a route inside let's do route JS export default not default export function post and and uh well we will have a request information here let's just for now return a response that will say okay or true something like this now let's try to change our image open and let's see I will reload here edit let's pick the image and nothing is going on so nothing is send let's see and that's weird let's go back to our form profile page um let's see if if this function is actually run uh upload let's see upload and let's go to console edit this one open and this thing runs but uh we are not uh sending any any request let's see I will cut it from here and I will put it here I'll put upload to re reload edit put image open console we don't see any conso L here so it looks like file's length uh is not bigger than zero let's see why let's do okay I know why it's not inside event files it's in inside event Target files now it should work let's do refresh edit let's send this one open let's go to network and we have our upload here request and as you can see we are sending uh our files here but uh those are not send properly as you can see this is this looks bad not correct um maybe we we have actually only one file so let's send only one and here let's do files of zero and we will send only if the length is one right and we are going to send only one file uh and the first from the array Let's uh refresh edit this one and now we do upload and uh let's see uh we are now it looks better I think content type I don't see any uh more stuff here but maybe maybe it's okay let's see how big the request is size 244 bytes well let's see what do we have inside our console inside our console we don't have anything but we will see if we have anything by doing some console log on our request so now if I change here to an another image let me first refresh change the image let's see well we have some stuff here and uh cookies next URL but what I'm interested is actually uh form data method post uh body stream is undefined client but I don't see any information about our form data let's see uh from the request let's search for form data I think it's a function that we need to wait for and we need to add a think here let's do data equals and now let's do this and here let's just conso Lo data and let's see now if this will change anything edit let's upload this one and we get an error let's see what happened uh boundary not found so this is uh this is what was wrong let's see uh I will go back to this profile page and I will try to get rid of the headers for now and let's see if this will fix anything so refresh edit let's pick this one and now as you can see we don't need this those headers and we get form data with name name file and we get value so now it works let's go to our upload route and here as you remember inside data we have a file so we can probably do something like this if data and we can do get let's see if we have a get on form data because this is form data object object form data and uh let's see what do we have we have a get here so we can do a get on the file if we have the file then let's do console log saying we have file and maybe let's uh console log it as well data get file file right and now let's uh try to see how it works edit let's pick this one and we have file and we see size type name last modified and this is a file object as you can see that's why it says file here and it actually also contains the the data itself so the image the binary data about this uh about this image and we can actually upload it so if we have a data if we have a file here we can upload the file so to upload our file I'm going to use Amazon S free um this is the most popular way to store files and uh just so you know in case you don't have a credit card or something like this there's a nice um website called privacy.com and you can generate uh credit cards with you know prepaid so you can send them like $1 something like this they will generate you a credit card with $1 I'm not sponsored by them uh I'm just uh saying in case you some of you don't have any credit card uh all right but uh now maybe it will also work with debit card I don't know but you if you guys have a problem with it then I I've read and good things about that that website privacy.com well uh let's go to S3 and we are going to create a new buet create backet and let's call this one uh food ordering I think yeah let's call this one food ordering all right and acl's enabled um object writer we want to enable ACLS so we can change ACLS and we want to do that whoever writes files to the backet will uh will be able to change the ecls uh now uh Public Access we want to allow it so uh let's allow public access to the backet and I think that's it so let's hit create backet and let's see if we put ordering name already exists somewhere else so I'm going to name it David food ordering let's create this backet now it's created and now we need to create the user for it so let's go to uh security credentials and here we need to go to user create user and here I will do user called David food ordering same as the backet name and uh next and then uh what do you want to do attach policies I want to create only one policy so I'll click here create policy and let me create this policy here the only thing we will need is Service as free and uh we want to allow all as free actions but only on let's click all resources no only on specific resources I'm going to select here everything and the only thing I'm going to uncheck is the bucket name so here I'm going to specify um not any bucket name I want to specify that the bucket name is David would ordering so this is the only backet this user will be this policy will I'll apply to uh let's go next and policy name fod ordering s3e policy it doesn't really matter just so we can find it uh let's create this policy and now the policy is created let's go back to our user and we need to refresh policies and let's search for for ordering is our policy we just need this one policy for this user create user and we are golden let's search for David food ordering user and and okay the user is created we have this one policy let's go to security credentials and we want to here create access Keys um here application running outside AWS yes this sounds nice create access keys and we have access keys and this seems to uh look fine so we want to save them inside our EnV so let's do um let's do maybe how we can call it access key let's do AWS access key and also we will need AWS SEC secret key yeah uh like this and now uh access key copy paste and secret key copy paste I'm going to change it later so you guys cannot use it uh so we need to create uh create yourself right but uh now we have our uh user for S3 so we can go back to our upload route and we can upload a file a file that we have inside our data get file and we can upload this one to uh S3 right so to send this to S3 we are going to yarn add AWS SDK and yes AWS SDK yarn add whoops uh this didn't work let's see your add AWS SDK as do client S3 let's see now yes it's installing AWS SDK client S3 uh we can maybe now import it here so uh let's import or maybe we can do Dynamic Imports uh automatic Imports here so we have our file here uh what do we want to do we want to upload first we need to initiate our S3 client so let's do S3 client equals new new S3 uh client let's import this one from AWS SDK client S3 and uh now we need to specify some uh information about this client like region the region is I where when you create a backet you select region H I always select the default one which is Us East one and then you also need to have credentials credentials for your client and here we have access uh key access key ID and uh and we also have secret access key and we have this inside our EnV file so we can do the just process EnV AWS access key and here for the secret we do the same but it's called The Secret Key like this right so we have our S3 client prepared and now what do we want to do now with this client we want to upload our file right so how can we do this uh we are doing this with um S free client we are doing this with send but we are not sending file here instead we are sending a new put object command so we are sending commands uh let's see object uh command and this is also something we need to import it imports from me automatically and inside this command we need to specify um well some information we need to specify the backet and the backet is um well the backet name I will put it here I think it was David the food ordering if I remember correctly uh now uh we also need a key and the key will be file name uh as you can see here we actually have a file name like this EMG and this is our original F name but uh I want to change it I want to make it random why because if you upload this to S free and you upload someone else uploads with the same name then it will be a collision and we don't want to have any any collisions with the files so we need to have unique file names so we need to have a key so the file name that is unique let's first do new file name and and um what will be the new file name I want to Generate random random file name and um and I want to add this extension. jpeg so first let's grab extension and extension I will grab by first grabbing the whole name so let's grab the name uh from file. name and then I will split it with this dot to an array do split with a DOT and I will grab the last part how we can grab the last part well to grab the last part I can do a slice and I will do minus one I will comment this out for now and I will see how the extension looks like because I don't know if it's actually a string or an array so let's do like this and refresh I will open my console here edit let's open this one and as you can see it's an array so I want to grab the first part so let's do zero and now this looks fine uh all right so we have extension so we can do new file name and first I want to have some random string and to do this I will install something like unique ID and it generates just unique identifiers as you can see uh you run this function and it returns something like this so let's go so here yarn add unique ID and now it's installing I'm going to run it here unique idid it's not installed yet that's why I cannot uh import it automatically let's do import unique ID unique ID from unique ID let's see if this is correct way of importing it I will just copy paste it unique ID all right and now here I'm going to run it unique ID and I'm going to add a DOT with if extension extension now let's do console log to see how our new file name will look like so let's go here refresh edit let's pick this one and let's see here as you can see the new file name will look like this that JPEG and this is a unique file name and this uh this looks nice maybe not nice but it's Unique so it does the job so uh let's uncommon this and for the key we can put our our new F name right uh we have a backet we have the key and we want to specify ACLS and the ACs will be Public public Creed because when we when we send this command when we send this file we want this file to be publicly available all right uh so we have ACLS to be public we also need to send content type because we need to tell what what type of file is it and if you scroll a little bit up as you can see we have this type here and this is actually what we need to send so let's just do file type and uh I think this uh should do the job and the last thing is body and the body is the body of our file so um here we actually need um we cannot just send the file it will not work instead we need to send a buffer of uh of the file contents so um I will put here buffer as you can see it's now underlined it's not defined but I will prepare uh this uh here so uh we have a file and uh this file has a stream I don't know it's complicated but we just need to read this stream and uh um inside uh for for Loop let the for wa because uh file stream is actually an assing function and now for each Chun inside uh inside of this stream each Chun of file stream uh for each Chun we want to save this Chun somewhere so let's do uh con chunks chunks equals empty array and we are going to add all of the chunks together so let's push another Chun after we are done reading this Chun right and then if we have after we read all of the chunks uh we want to convert them to a buffer so let do con buffer equals and here just buffer and here con cut and here just our chunks and that should do the job and here we have here we put our buffer we have this await here and well this means we uploaded our file but uh now I want to do I want to know the link I want to return um return response response Json with the link well the link will look something like this htps and then the backet name the backet name is David food ordering and then we just do S3 ama Amazon aws.com SL and then the new file name so let's do plus and new file name right maybe we can make this uh shorter uh let's see uh I can put this bucket name somewhere here above let's do const backet equals this and here a backet and even here I will do just like this Plus+ and here between backet okay and maybe I can even put a link here above so it will look better so let's do responds Json link maybe we can call link to file doesn't really matter uh but it should respond with Json with the link so now let's see if this will work edit and let's open we are sending this upload and it's still pending okay we get 200 and the preview we get a link let's copy this one let's see and I see my photo here so now it works all right so we get a link so let's go to our profile page and let's see and we have this function called handle file change and we are sending this fetch request or post request and we get a response here let's grab the response and let's do console log response to see what's inside right so I will refresh everything here let's go to console I will pick uh this file again I will upload it inside the network you can see we send this request Quest and see let's see the response we have a response body and um well response body is actually our um our readable stream and it contains Json so let's grab it like this cons Json equals response uh body um well it shouldn't be the body I think we have Jon method here and we need to add a weight here so let's put like this and let's do log of just this Jason it should be a string so let's see I'm going to refresh here let's clear this and I will upload once again let's go to console and let's see we have our string so uh that worked nice so um this is not actually a TR Json well it is Json but it it has only this link it's a string so we have a link here so we have a link and and what do we want to do with the link well with the link we want to update this photo right so we want to put this link into this image into this user image this user image is actually comes from session if I remember correctly let's see uh user image it's defined here it comes from session well this is wrong and instead of this coming from the session we want to comit from the the state so let's prepare state for this image set image equals use State use State and default will be empty string and because we want to have session as the default we will go to here and when uh when we see that session or status of the session changes we will do set image to session uh let's see how it goes here I think it's session data user image like this and now we don't need this user image here instead we will just use this image from the state so let's see here we have user image let's just put image and let's refresh and let's see image is missing required Source property all right but uh it's just temporary problem so let's here do something like this if we have an image then show the show the image so let's put this image here now now if I refresh yeah it looks fine no warnings so uh now after we are done with the uploading and we have the link let's put it to our set image to our link so we will see if this will update let's do edit let's change our image and it's uploading uh it takes like several seconds to upload it and uh we Tred to set it and displayed best but again we have this problem that we need to uh list all of the all of the host names for our images so let's go to next config and let's add another uh protocol with the htps and same we did with Google user content let's add our um backet here so do host name and let's add our braet so let's try again refresh and uh loading now let's change the image to this one it's uploading and takes like 2 seconds and I don't see what's going on so I would like to add a I want to add a preloader or something but now it's updated the image is super big and uh well I would like to make it a little bit smaller right so let's go to profile page and let's see where is the image the image is here and for this uh for this div here on the left side uh I would like to Let's see add the max wave of uh XS or maybe I will do Max wave of like uh 120 pixels yeah let's see yeah I think this uh this looks uh better all right so we have this and um well it works it uploads it doesn't save to my profile because if I refresh it reads from the session and from the database we are just uploading we haven't saved it and uh let's fix this first right so it will save to our profile when we click save when we click save uh what will run is we will uh run this handle profile info update and we are sending name to be username but I also want to send um I also want to send a picture or however it's called let's see however how it's called inside session um inside data we have user and we have image yeah I want want to send image so here I'm going to add image and image will be actually image we have the same name into inside our state here so I'm going to send it to as a profile update and let's go to our uh here profile inside API and here as you can see we have if we have a name inside data then we are updating uh but I don't want to add another like if we have image inside data update user again because if you send both the new name and the new profile picture I don't want to update it twice so instead I'm going to do something like this um let's do const um update it will be an empty object and then if we have name uh if we have name in uh data then I'm going to add this into update so I'm going to add update name will be the data name like this I can actually do some this name update name will be data name and here where we are updating I would just check if we have anything inside update so if update is uh well maybe I can grab update uh Keys update keys and I can check that the length is bigger than zero and here I want also to check if we have an image inside the data if we do I want to add it to update update uh image will come from data image right and here we are sending only name but I want to send the whole update object right now let's see if this will work I refresh here and let's go here added it let's upload our file now it's uploading our new folder is uploading I'm going to add the preloader for it we have a new photo but we need to save it so now if I click save uh we get 500 let's see what's the problem let's open console here uh can under read the properties of undefined reading length Okay so this okay this doesn't work um I was wrong it should be object keys and here we put the object name it's update update and there's another thing we need to change inside our user we need to put image we need to Define it that it's type of string no it's not required U but we just need to tell that it exists I need to restart my environment because we did some changes here and now let's try to click the save button again and uh let's see and the profile saved so this worked now let's see what happens if I refresh if I refresh it's loading but it shows the old picture so something went wrong let's see our database refresh and let's see on the bottom we still have the old the old um image here and uh here um let's see I will go back to my profile route and uh well it should be an object we just put need to put it as an update it's already an object all right so now let's try again let's edit photo let's upload this one I still need to add the some kind of preloaded D And So It informs us that it's uploading but now let's try to save it profile saved let's see if it actually saved I will refresh and as you can see we have our new photo here what I want to do also is that uh if I select this one it will upload again but during the upload I want to see the message here uh so let me go back to the uh profile page we have this thing called is saving I want to have similar is uploading and set is uploading default will be false and here where we are uploading handle file change on the beginning uh before we'll send the request we will do set is uploading to true and then after we are done we will do set is uploading to false because we are done with uploading and now here we have something called saving dot dot dot with this blue thing I will do the same is uploading and parenthesis let's do another H2 with um uploading dot dot dot and now let's see let's refresh if I change this one to this one open now it says uploading and uh Now it's uploaded so that's cool I can save saving profile saved so that is really nice uh let's change this one to this MacBook uh photo uploading and uh now it's fine and I can save it and if I refresh I have this MacBook photo let's put this one back yes uploading and now it's uploaded let's save it so I will have a regular photo here okay so now we have our profile that we can update both the photo and uh and the name here so I can do maybe delete one letter here and if I refresh I don't have that letter all right so this works we can update uh the photo the Avatar and we can update the name the next part will be to update to be able to update addresses and uh uh but uh before we will do this uh I would like to clean this up a little bit uh because as you can see we have a lot of copy paste here for example for the saving and uploading uh this is the first thing I would like to fix I will just put a uh component for this uh profile saved it will be a div not H2 and same for this saving and uploading but what's more important is those two are almost the same and this almost two so I'm going to put this as a separate component inside components uh well we have menu layout maybe I will put this inside layout and inside layout I will do new file and uh let's call it uh first info box. JS and let's do export default function info box and we will have children here and let's do return and we'll just have this simple uh da here inside so let's put this here instead of saving I will print children right and now instead of this saving I I can do uh info box yes and it will say saving dot dot dot now here instead of uploading we will do the same info box uploading dot dot dot and uh this looks fine now for the saved we can do a green box so success box so let's do new I will just copy this copy and let's do new file success box .js and let's do export default function success Suess box whoops and return parenthesis let's just put this here and here just children and let's grab them from our properties here let's go back here and profile saved so let's do success success box and here profile saved yes we could all maybe do also something like error box if we need but uh well I will not handle errors here you can add yourself if response is not okay here or if response is not okay here you can add errors if you want all right so uh now we have this and uh we clean it up here a little bit and I think this uh this is clean enough maybe we could also make the Avatar different but well it's not that uh crucial for now because it just two lines or three so it's not that big of a deal and the next thing will be actually so we can add and remove addresses so uh here um underneath we will have a list of addresses so we can add and remove addresses when we order pizzas and then we can select addresses update our addresses and stuff like this right before we will go into addresses there is uh one more thing I would like to show you so we have those um boxes here profile saved and even if it's saving we have a blue box when it's saved it's green and this works fine but um I want to show you another solution for this and it would be using an existing library that we can just yarn add so uh here as you you can see we have for example if it's saving then it says saving if it's uploading it says it's uploading and if we have saved then we save profile saved and this works fine we have stayed for everything but there are uh other things that we can do um instead uh I want to show you how to use react to to react hot toast and this is like a simple popup as you can see and that you can trigger from code and it's really simple to add so as you can see we just need to yarn add react hot toast uh I just want to show you that you can uh do the same thing with different approaches you can have your own uh you can Implement your own uh info and success boxes or you can use a library like this so now I'm going to show you how to do this with uh this Library so as you can see we just need to yarn add this and then for basic usage we just need to add toaster somewhere to our um somewhere to our page and then we just trigger this with this toast function so uh let me add first this toaster that we need to add and I think I will add this to my let's see to my layout so here layout and let's add toe stir yes and let's see yes it is imported here we don't need a session provider here anymore and now we just we can just uh run toast like this so let me go back to our profile page and let's see let's maybe start with this upload um let me see here we have if it's uploading we have this blue info box that it's uploading let's remove this and let's see where we have this um set is uploading we have this function for upload here it is here we are setting when a file changes in inside a input type file we are first doing this uploading to true and after it's done we do set this uploading to false let's remove those two and well first we want to inform that it's uh uploading right and then we want to inform that uploading is complete we can do two boxes the first will be toast uh let's do toast uh uh like this and uh it will say uploading dot dot dot and after we are done with this request it will say toast and upload upload complete something like this upload complete and we can add some more stuff to this let's see uh you can see we have position style theme and um we can do even icons duration but there is something more if we go here we can do for example toast success uh so let's do toast. success and then it will be blueish H greenish sorry so now let's see what happens if I change I try to upload something I will put upload this Macbook so now it says uploading here and then upload complete so that is really nice uh there is also another way of implementing the same thing as you can see they have a promise here toast promise and and you just run this toast promise where the first uh parm or the first um the first argument is uh the promise and then the second is uh the second is uh well uh what should be shown when it's uh running the promise and then what should be shown if it's uh complete or yeah if it's done and then what should happen if there's an error and I think that's much better because this can this can fail right so um you can also put fetch into something like this and handle uh what should happen if uh if something fails here we should probably also do um if response okay uh then we want to do this toast success and uh if uh if response is not okay we should probably do toast toast uh error saying uh upload upload error or something like this and we will never see this because our uploading just works but uh well uh it's an easy way of handling errors right so uh now we fix this for uploading let's maybe do the same thing for saving profile and saved profile so I'm going to remove those boxes here and we also don't need those uh let's see we don't need those boxes here info box and success box we don't need them anymore because we are using now this react toast all right so let me see where where we are running this handle profile info update here we are setting um is saving to true and then when it's done we are sending we are setting this uh is saving to false so let's do something like this toast and let's have a function um just a regular info function saving dot dot dot and and then uh let's do after it's saved here let's do toast success and profile saved something like this and we don't need this and we don't need this and as you can see we have a lot of state that we don't need anymore for saved is saving and uploading so let's just uh remove it and now let's see um I will just hit save here and it has and it says saving and then profile saved we can probably also try to use this um toast promise for either upload or uh saving the profile because now as you can see if we click save then we first get the saving and then profile saved but when we see profile saved we shouldn't see this saving anymore right so uh let me try to implement this with uh promise so uh let's maybe here create a promise first uh let's do new promise and and here we will have a function that will have um that will have resolve and reject and now let's do something like this let's do saving uh saving promise equals this new promise and uh now let's do like this let's put this saving uh petch inside and uh we don't need to do a weight here we can add or maybe let's do a weight and let's do here a sync because we have this await and um let's remove this response okay and let's remove this saving all right and we have saving promise but now we need to also run this resolve and reject so what I want to do is I want to run one of those functions depending if the response is okay or not so if uh response is okay then uh resolve resolve uh otherwise else reject right and uh this should work work but we need to put this like this and let's let's see this should work now maybe we can put it more like like this so it will look better uh all right so we have our saving response and now we can use it with toast so let's do toast and the toast promise and here first is the response um sorry promise so let's do saving promise and then we have options like um loading and loading text will be saving the do dot dot and then let's do success and let's just do profile saved exclamation mark and if we have an error um error let's just say error all right and uh this looks fine let's see why why I have warning this because I should add a weight here all right now let's see uh if this will work I will do refresh here let's hit save saving and then we have profile saved so as you can see now when I click this save button first we have this saving and but then it's replaced with this profile saved so that's really nice maybe we can even do the same for the for the uploading so instead of doing uh two different toasts uh like um or three first we have uploading let me uh change this image if I do this first we have uploading then we will have upload complete but but we still see this uploading and after like few seconds it uh disappears this one first and then this one so uh let's get rid of those and let's get rid of this and let's see we have uh all of this that we need to run inside a promise so um we have this wait for fretch and then we wait for Json let's create a promise for this maybe we could do this without promise but uh and just using this fetch but uh let's uh let me show you how we can just create a promise let just saving promise or maybe uh upload promise equals new promise and then we resol and reject we just put all of this inside and um first here I will check because we are not checking if the response is okay so if response is okay so it's 200 or something like this and we don't have any 500 error if the response is okay we want to do uh this so we want to do this and we want to resolve our promise but if it's not okay we just we want to do uh let's see we want to do reject here for our promise and then here underneath we can do toast and promise and we need to add a weight here and first our promise will be upload promise then we need to add options here for loading it will say uploading dot dot dot then for Success it will say uploading upload complete upload complete and then for error it will say upload error yeah something like this so um now let's see if this works so I will refresh here let's do edit and I will uh upload this image uploading so it works it's uploading upload complete that works really nice we could probably make this simpler so let me see first I will first we can probably get a rid of this uh weight and this assn and let's try to do the same thing with then then response response as the arrow function here we don't have any response here because we don't have any weight and now let's put this response ifs here inside and no if everything uh works here we want to just uh uh first do this uh response Json to Json then we want to grab the link and we want to set the image to this link we don't need this and we don't need this and then we want to resolve as well otherwise if the response is not okay we are doing here reject but uh actually what I think we can do as well is we can just throw an uh throw an error new error saying U error yes and and um or maybe we can do like something went went wrong something went wrong all right and but we still have this promise but now uh let's see we have this reject we don't need this promise most likely let's see I will get rid of this promise and um and now I will do like this uh let me just change this initation to this and let's do saving promise equals this and um we don't have any resolve so I will get rid of this and I will just return this instead and this will be our um asnc function that will be returned let's see if this will actually work uh so I will do here shouldn't be saving promise it should be uh upload promise upload promise and let's see if this will work this way so let me change an image to this and it's uploading and upload complete so yeah it works uh it works because we are um we are sending this as a as an actually as a promise this is an uh assing function so that's why we can do that then and we can return um another uh assing function let's see what happens if we put this error on the beginning uh let's see if we will get an error so if I change an image back to this one let's see if it's uploading it's uploading but we should get an error yeah upload error so this is nice uh let's put this back as it should be and yeah we can also do this this way and we can actually also put all of this into here so we don't need to have it as a constant here we can just put all of this into here so let's try and we have something like this so we do toast promise and then we have this fetch we've then and stuff like this I don't know if it's better I pre I prefer to have it uh this way so we have upload promise but well it depends how you write your code um it doesn't really matter this looks fine uh with this Fetch and then returning response Json as another promise and throwing an error if the response is not okay but here we have also with just a saving Promise by creating a new promise with resolve and reject um this works uh too I think this one is a little bit shorter so uh so I think I like this one better without creating a separate promise for for everything and um yeah I think those toasts look really nice so if I click save profile saved that uh that looks nice if I refresh I have this new image but let me put back the actual uh picture of me uploading upload complete I have my picture here so that is really nice let's hit saved profile saved so yeah that works uh nicely and uh we have much less code uh here inside because we don't have those if saving then let's do info box if saved then let's do success box so that is uh nice right but now let's get into our addresses so here underneath I would like to have a list of addresses so let's get into it right so uh we can either put addresses here between this and the footer so here a list of addresses or we can put it maybe here just on the right side and we can do several addresses like uh depending where you want to uh where you want to um deliver your uh pizza or we can have several addresses so if you are on your parent house or something like this then you can have several addresses but I think it would be easier to start with just one address right so um here I think I'll start by putting for few more inputs for address uh stuff so we need like a phone number we need a street address we need a City postal code and Country so let's get into it um it will be several input so uh let's see first I will have a street um street address so let's do a street address street address and um street address not it will not be typ street address it will be just type of text and then we will have a placeholder saying uh street address right let's see yeah we have street address then um I also need to have another for uh city city and another one for postal code and country country and let's get the one for um postal code or zip or however you want to call it yeah so this looks fine um except that now I would like to have this part uh aligned to the left H to the top so it should go up let me see we have this Flex item Center here probably here we just need to get rid of this yeah uh now it looks better now um I think we can put uh City and postal code next to each other so let's see um here we have C in postal code I will do uh div flex and let's put those um here inside City postal code but first I want to have postal code and then City let's add a little bit of Gap like Gap two and now we have something like this postal code and city right uh let's add more Gap let's do four and let's see now yeah I think it looks uh fine all right so now we need to have state for all of those um so uh state for street address postal code City Country and we also need a phone number so maybe under the email we will first have a phone number uh let's the phone number and we have probably type for for this as well let's see the type can be checkbox color date email file hidden image month number let's do number number or do we have tell yeah we should we have also tell uh input type tell let's see yes it is so this one will work best because when you have a have it on your mobile it will show only numeric keyboard and but as you can see it's not styled we need to go to our Global CSS and here we need to add type of uh phone so let's do not phone tell okay and same for disabled we have for password we need to add for tell so let's do tell all right and now it's styled now we need to have state for all of those so let's go to profile page and let's go up to our state and let's see we will need state for phone set phone and we will need state for street address address and we need to have a a state for postal code and we need to have a state for City and we need to have um state for country all right uh now I have all of those and now we need to have uh we need to add value and unchange so let's do this um I'm going to put this maybe here so let's do value equals uh phone and then on change we will have event set phone event Target value and we will basically do the same thing for all of the other inputs um so let me do this maybe like this and now let's do value will be here street address street address and let's add on change on change we will get event set street address event Target value now let's see here we have postal code let's put some of this into new line and here let's do value postal code let's add on change event event we will do set postal code event a Target value and now here we have City let's put this here this here let's do Value City and on change event let's do set City Event Target value all right and the last one country let's put this here this here let's do value country and on change let's do event and let's do set country event Target value all right so we have now styling for or not Starry uh state for all of the inputs um it's a lot of inputs and this grew a little bit so we will later clean it up when we fix the uh saving even for our uh uh address right so uh um we don't need this session here anymore and we don't need to have this console log for the session now let's see uh when we hit this save we are saving profile and we are sending name and the image I would like to send more stuff so I want to send also um like street address all of this so let's uh send street address let's send the phone number phone let's send the postal code postal code city and Country so we are sending all of this to API profile now let's go there to API profile and um now here we are saving name and the and the image to our user let's do maybe the same thing with um let's do the same thing with our address but uh the thing is that even if I add this to um even if I add this to our user um object user model it will probably not be available to our session because session has only like email image and name it doesn't have ID of the user and none of this but we can still try to just save it to the user so um we can go to the user model and we can put all of this um property is all of new Fields here so we can do like phone it will be type of string and I can just copy this and put more of those and we are just going to change phone uh stet address type string and then we will also have a postal code postal code and we will also have a city and the last one will be country and that should do this so now I'm going to to also remove this import because we don't need it and now I'm going to restart my environment YN Dev let's run this again so we can have those new changes all right and let's go back to our profile route and now let's see I will add another if that will say if we have um if we have a city in data then we also want to add all of this uh CT and postal code and everything into this update object but as you can see inside um our profile page we are always sending everything uh like this we are not sending just few of those we are always sending all of those so um let's just skip this if we have a name if we have an image if we have a city we always have all of them all of them inside our data so we can just get rid of those ifs and instead of having this update here we can just update all of information that is inside our data object and now we don't have this update object so we can get rid of this if because we don't need this uh we just wherever comes inside data wherever comes inside the Json inside the request we are using this to save uh to update uh the user so we just grab the email from the from the session and we just update with the data that comes from the Json now it's much more simple now let me try to put the phone number I will just put 1 2 3 4 and let's see here inside our Network what will happen so I will hit uh save now it's saving and let's see profile saved so this uh looks nice let's see in the database if we have this one two 3 4 inside my user let's see database browse collections users let's scroll down we have image here and we have phone all right now let's go back to our profile page and let me open this here let's refresh but now it's uh it disappeared okay let's see if we have it inside session so I'm going to put back our session here console log for the session and let's see if we have it inside session so we have session data user and as you can see we have only email image and name only those three so we don't have for example ID we don't have email verified we don't have updated ad we don't have City Country phone none of those so um what can we do now well we can just grab all of the information about the profile so uh all the information about our user so here we have this put for updating uh let's add another one let's add a get for just uh returning all of the data so let's do export using function here we will do get and we don't need any request information here I guess first we just need to connect so let's connect to our database and then well we want to grab session and user email like this and then if we have an email of already logged in user we want to return all of the user information of this email so let's do return and let's do response Json but here inside I want to do a wait uh let's do user f find one and I want to find one by this email right and now let's go back to our profile page and we have this um use effect here that we are running when something changes with the session or session status and here inside we can do something like this we can do uh here fetch request so we will fetch the uh profile information about our user and then let's do response equals this it's just a regular get request and then when we have this uh response let's just weit add a weit here maybe let's do this with then because we have use effect here and use effect doesn't like if you do a wait uh if you do Asing functionality without that then and you do a wait instead so let's do then and then we will have a response and let's do Arrow function here like this with this response let's do uh Json and let's add then here for just when we are done with the Json and here we will have the dat we will have a data and so here we will have this Json to an object all right so we have this data let's just do a console log of this data this will be our user data that we are returning from API let's refresh and let's see uh now as you can see here we have all of the data so we get uh ID we get pH phone we get everything because we get everything we get also phone postal address street address and so on so now I'm going to use this data to set all of those uh street address set street address uh set postal code and so on all right so uh let's do start let's start with um maybe phone set phone and let's do here data phone then we need also to do the same thing for set stet address data uh street address then let's do set postal code data. postal code and now let's see we can do City so let's do set City and data city right and then let's do set country set country and here data country right uh do we have all of those 1 2 3 4 five 1 2 3 4 5 2 three four and five for the phone I guess we have all of those so so now if I refresh we get our number 1 2 3 4 so uh if I now change something here like I will do street address um test uh test uh Street one two three and I hit save we are saving now it's saved and if I refresh I should have now uh same thing yes uh seems to work this uh Works nice we can update our address looks really nice uh for now we have only one address per user uh but later we can add the so we can have several addresses let's add the postal code of 1 2 3 4 5 and the city I will just put um Stockholm here for now and country Sweden so we will have some data for this user here will be the phone number I will just um put some a random phone number something like this or you can add something like this I don't know it does doesn't really matter uh this looks now fine and maybe there's something wrong with the spacing here but uh we can fix it so let's go to the to this div that we have a flex uh and GAP and as you can see it has too much of a of a spacing and this is because we have a margin from this input we have a margin bottom here and we have margin top of those and we have double of the margin because we have from the bottom here and from the top here we have the same thing bottom here and top here uh for other inputs but the thing is if there if those inputs are next to each other then those two margins will collide and it will be joined so um now here we have double because those two are inside a separate div here as you can see so to fix it we can just add a class name on those two inputs saying there will be no margin on the top and the bottom of on those two and uh this should help let's see no this didn't help let's see why I will inspect here we still get a margin on those two so uh this didn't work maybe instead we can just put a style instead so let's do margin and we need to put an object here margin like this and it will be zero so now we have something like this uh I think it's better now let's just put the same thing for this input here and now it looks fine now we can probably decrease the uh Gap here to maybe two yeah and I think this looks uh much better and now we we can also add maybe some labels here because now everything is filled U but we don't know that this is actually name and this is phone number we don't have any labels we only have those placeholders but it would be much nicer to have labels so we will know what is what uh so let me see I will go here and first we have first and last name let me add the label and that will just say the same thing it will be first and uh last name let me see yeah we have this and um I will put the input maybe inside or maybe no let's put it next to the input all right so let me maybe put this um like this I will put the type and place orderer on one line and then value and then change on another line like this so we have label and then we have an input I need to have labels for all of those so we have like uh phone uh placeholder here phone number street address postal code City Country so um let's uh let's fix it first I'm and even here we have email but we don't have we don't even have a placeholder here for email so let's do here like this it's disabled we have a value but we don't have any placeholder a placeholder we probably don't need placeholder because it's always filled in but well doesn't really matter so let's do like this and let's add a label label for it saying um email right and now I don't like the styling of this but I will also add another one for phone let's do phone here phone um I don't like the styling we have a lot of margin here going on uh let's go back to our Global CSS and let's see what do we have here so we have margin on the top and the bottom of two I'm going to change it to margin bottom will be two uh or maybe let's do margin bottom four and margin top will be nothing so now as you can see the labels are are closer to the inputs maybe we can decrease it to two yeah I think this uh this looks fine uh now we don't have any spacing here but we will we can save it with when we get uh down here let's fix now the labels for the rest uh of the input so let's do a label for um let's see stet address and then we have those two that are next to each other so let's do a label for uh label for postal code postal code and let's do a label for uh City C right so now as you can see because of the everything is next to each other so uh to fix it I'm going to put uh two uh divs the first one for this label and this input and then the second for uh this uh City and input for City so now we have something like this and I think this will work fine then we have the last input so let's do the last label for our country here right and I think this uh this looks fine we don't have any spacing here though so uh let's try to remove this margin zero on those inputs and let's see what will look like yeah now we have the spacing so this uh looks better I would like to fix this uh those labels let's go to uh let's go to Global CSS and I will do something like this default styling for label I want to apply some Tailwind classes saying that the text will be gray 500 let's see yes uh looks nice I want the text to be smaller text as M yeah this works nice and maybe we can make it um closer to the inputs by changing the leading to three let's do leading two now this didn't do anything let's see let's refresh leading to class does not exist okay let's do leading and let's see what we have really snug let's do tight yeah I don't know if if this helps but uh well we can also add something like this label and if we have an input next to a label then I want to do margin top of minus 10 pixels and now as you can see they are actually um under the labels the inputs are under the labels let's decrease this to maybe four pixels yeah uh this looks okay maybe too close to each other minus two pixels yeah I think this uh this looks nice and maybe we can do labels even smaller I don't know I think this uh this will work for now all right so um this looks fine we have um profile with address we can edit all the address we can edit the name phone we can edit the avar if we want and saving works and we have those nice looking toasts so uh I think uh we are done here with editing profile and the next thing will be actually so uh an admin panel so we can do um well we can do we can add pizzas we can add other dishes meals and we can edit prices if we are an admin this is just a regular profile but let's say that if you are an admin we will check if this is email and this is one of uh admin's emails then you should have on your profile more uh more stuff uh like um admin panel where you can edit uh everything categories meals and prices and everything so we need to fix something that uh well let's say that um I am an admin we need to add me as an admin somewhere and then I should be able to actually do all of the admin stuff all right so now to have some kind of admins we need to first uh know who is admin right so first I want to add my user as an admin so I'm going to add it to to my database first manually so here's my database we have ACC session users I'm going to add a new collection here so uh let's call it just admins and let's just create this collection it will be empty and I'm going to insert a document here into this admins uh collection and the only field will be email and here I will just put my uh I will put my email here so let me just put my email and let's insert this one so now we have admins collection and it's uh it has the list of all of email admins right and I'm admin because my email is inside uh but now I would like to know it righty right so if uh if I'm an admin I would like to have it in uh profile information so as you remember inside our API profile get request we are fetching information about uh about our user but um we have also now this admins collection so it would be nice also to have information if this user is admin or not so for now we have collection of of admins but uh if we have it this way admins we need to look to a separate collection to admins and there's another way I I did this way for with my e-commerce uh project but I want to show you also another way I will get rid of this admins for now uh I will delete this one drop collection and let's go to users and I will add a property to my user so let's edit this one one and let's add a property called admin and the value will be true and let's change this from string to a binary and uh oh let's see maybe not binary let's see I will make it an Boolean sorry not binary Boolean admin sure and now let's go to our user model and let's add here uh admin and the type will be bullion and default will be false so by default a new created user is not an admin all right so we have information about admin let's uh restart our environment and now let's see here I will open here my network console and let's see what will we get uh so profile information get Let's see we have information here and as you can see it says admin true if I log in as another user user I will have this as admin false but now as you remember we are fetching all of this information inside our profile page so if we go here we have this um let's see we have it here and we have a file change and profile update and here we are fetching information about the user we are doing this get request to API profile and inside this data now we have also admin that is true or false so we can save it save it to our state like U um admin or maybe we can call it is admin and set is admin use State default will be false and um now let's do set is admin and as you remember inside data it's called admin not is admin in our database it's just called admin true or false and in here we have this as is admin we could use the same naming but it doesn't really matter so uh now know inside the state that I am admin so uh what can we do with this uh page I would like to do something like this that when I visit when I click on my name here I will see my profile but I would like to have more like tabs to have profile and admin stuff right so let me do something here here we have this H1 for profile uh header uh but instead I would like to have a div with uh buttons or links so I'm going to put a link here first to uh profile so let's put profile the first link will go to um just profile and then if you are an admin so let's do is admin let's do end I will do parenthesis there will be several elements here for admin so let's do react fragment here and now let's do link for um for other stuff like uh dishes or meals let's do first categories categories categories uh like this and let's call this one categories and now let's do another one for we can call it meals or we can call it the menu items maybe better menu uh items like this let's call this one here just items or I don't know we can put menu items and I think we will also need to have for users we can edit users we can edit the someone else address if you are an admin or you can edit if someone is an admin or not so let's do admins and or maybe just users users and uh here let's do users now let's see uh we have those tabs kind of now let's uh style it a little bit so inside this da let's do class names and the first I want to do uh in line Flex Flex in line not Flex initial let's do flex and let's add some gap of two and now what I would like to do is uh let me see we have those links here now what I want to do is for each link here um let me see I will select this one this one this one I will add class names to all of those um so let's do I want this to be remember you know instead of typing class names in all of those uh I will uh name this div above that is apparent I will name it the tabs and now I will go to globals and now I will do something like this div tabs and uh to anything that is a child to div tabs I'm going to apply some classes apply classes like backround primary uh text white um rounded the full rounded Po and let's add some padding on the uh top and the bottom of two and on the sides of four now let's see how it looks like yeah uh this looks much better uh but I don't want all of those to be active uh instead I want only one to be active and in this case should be profile so let's change this uh from text white and background primary to let's do background gray let's do gray 300 and text uh gray I don't know uh 700 now let's see now we have something like this uh I would like those to be centered uh and one of those needs to be red so how can we do this well we can do something like this class name and then we can check if the uh if the URL is profile and if it is then we can make this class and and we can add a class name active for now I will just add a active without checking because I just want to style it a little bit so it's do div uh tabs and then anything that is inside with class active we'll have following U class names so let's do background primary and text white all right now this one should be red yes uh let's go to our page here and now for the tabs um I want this one to be actually inline uh Flex let's see yes and now let's try to do MX outo on the sides so it will be centered no it's not but um well instead of doing inline Flex I will do just flex and now try to do justify and let's do maybe Center justify Center and now everything is uh in the middle right that uh that looks nice and we can move between uh those tabs now profile categories menu items would be nice maybe to put icons to those right profile user icon categories I don't know a list menu items I don't know chicken or something and users a group of people so uh first I will grab this and I will make make it as a separate component so let's cut it from here and let's see inside layout I will do a new component called let's call call it um tabs. JS I think this will be all the tabs we'll have or maybe let's call it uh user tabs user tabs. JS and here inside let's do export default function user tabs and well inside let's do a return and let's return all of this and here is we will need is admin so let's define it as a property is admin all right and now now let's try to use it so let's go back here to our profile page and now let's do user tabs and let's pass this admin to is admin from our state so now we have it and we don't need this H1 anymore but we will need some spacing here so on this da let's do margin top of uh four let me see maybe four is not enough let's do 8 C yeah I think that is much better so we have profile categories menu items and users all right so we have some navigation here and uh well the next thing would be to fix so we can click on categories and we will have a working page here so let's go to our I will close this API let's do new directory called um well cat gois and inside we will need a page.js so let's do page.js as the export default function let's do categories page yes let's do return and what do we want to return let's do a section for now and um now inside we will do just cator right and uh we have categories page we will need here some class names to make it uh more like centered and stuff like this so first let's do margin top will be eight let let's do Max wave of I don't know uh medium for now or maybe let's do large uh then let's do MX Auto so it will be centered let's see yeah something like this and then first I want to have our tabs so let's do user tabs and uh let's pass this admin to be false just for now or maybe let's pass it to true so we will see more of the tabs right we are on categories page but we see uh this one marked as profile that is active if I go here you can see it's profile it's okay but if I go to and click categories we are on categories page and but profile is selected I think that if we go here we can use something like use path name from next yes let's import this one let's do const path equals use path name and let's do conso log of it to see what we have inside so uh use path name only works in client components all right let's make this one client component let's do use client and uh now let's see I will do inspect here and let's see console the path is/ categories all right so that is nice uh thanks to this we can check which link is actually active so uh we can do something like this here we have profile and it's always active but instead of doing like this that it's always active let me first put this and this into separate line and let's put it here and let's put this here maybe like this we have class name active so it's always active but now let's do something like this if PA is exactly SL profile then it's active uh otherwise it's not active all right and now profile is active but if I go to categories it's not active so now we need to do the same thing for categories and menu items and I think we can do it a little bit simpler here I'm going to select uh all of those and uh let's do something like no this will not work let's do this manually so uh I put this here this here this here this here this here and this here so we will have more space something like this and uh like this like this and yeah something like this so we will have more spacing for all of the attributes now maybe I will just copy class name and and put it here and if path is actually cat categories then it's active here the path needs to be uh menu uh items and here the puth name needs to be users slash users all right so now we can tole between profile and categories and uh it looks fine uh when I go back to profile we have a little bit of loading because on our profile page uh when um as you can see if the session is session status is loading we only see loading text um and uh nothing more or maybe it's not about the session but it's about we are fetching information about our user so that's why on the beginning we have only profile and not information if it's admin or not here we are fetching information let me see here inside us effect we are fetching information about the profile um maybe we can add something like uh uh here information for profile fetched or something like this if we want um so let's do state for it so let's do const profile uh fetched and set profile fetched it will be false on the beginning but after we set all of this let's do also set profile fetch to true and uh now let's see now if we refresh with still have this loading and then we have only one tab on the beginning because we don't know that it's an admin uh but uh let me see here we are uh loading for uh if the session status is loading then we do loading let's also do the same if uh not profile fetched then let's also do loading so now loading whoops let's do or profile not fetched let's do refresh so we have loading and then we see all of the categories all the all of the tabs at the same time so we don't see profile first and then the rest I go to categories I go to profile we first see this loading thing right it would be nice probably to see uh some tabs even if uh user information is loading but well it's not that super uh important well now the problem is that on the categories page we also need to know if the user is admin or not because let me log out and I just logged out and if I go so I'm not logged in if I go to slash categories let's do slash categories I can still access this page right so the thing is that even if I'm on the categories page categories page here I need to have information somewhere here inside state if we are um if it's admin or not and uh if it's not an admin we should redirect to the login or profile page or well we shouldn't so show this page right so uh we can fetch the information about our profile the same way we do it here so on our profile page we have this uh fetch as you can see um we are fetching uh profile like this and then we set is admin from the profile information from the response so uh let's do the same thing on the categories page we need to have a effect here use effect and first let's just put a empty Arrow function we will not have any dependencies and here we will just do fetch on slash U slash uh Slash API slash profile and then let's do then we have response uh with this response we need to run Json then we will have data about our user and with this data we only need if it's admin or not so let's prepare uh this uh so let's do is uh admin set is admin equals use State uh from react default will be false and here we can do set is admin to data. admin all right so now um let's see we have an error you're importing component okay we need to do use client here use client yes and now we have an error right let's see what's the problem um fail to load the 500 okay so there's a 500 error yes on/ API SL profile let's see response maybe here cannot read properties of null reading user right so it looks the problem is we cannot fetch information about profile if we are not logged in so let's fix it inside our API profile so let's go to API and profile and Route and the problem is here so uh um we are grabbing user uh email but uh we are trying to read user here from session but session is empty so this is the this is the problem so how can we uh fix it we just need to check if user exists let's then add question mark So if it's empty it will not go further and here before we will fetch this user we will first check if there's no email then we will do a return response uh Json with null yeah something like this so now if I refresh we still get an error but it's because we are trying to read admin out of null right so uh let's go to our categories page or maybe here instead of null we can do empty object so we will not have any error yeah that's correct now let's go back to our categories uh page and let's see here we we have this is admin then we have set is admin so here we can maybe show those tabs or maybe not here not to show the tabs we will not show anything if you're not an admin so let's do something like this if not is admin then let's return uh not an not admin not an admin something like this so now I'm not logged in and I'm not an admin so that's why I get this not an admin you can change this to redirect if you want um or you can just uh keep it as uh like it is and if we just log in with an admin user and we should uh have it working by have an error and I don't know why let's see let's see let's refresh and log in with Google I will pick my user here I don't know what happened let's try to log in once again no something is not working let's see maybe I need to restart my environment let's see I will go back back to my local host 300 3,000 sorry and uh then let's do login login with Google and now and now as you can see it doesn't work the whole uh login functionality doesn't work it says to to confirm your identity sign in with the same account you signed originally I think I'm not sure but I think this can be uh an error because we changed this user model and they don't like it so uh let me try to delete my user here and uh I will go back to the login page and let's see if this will work then so I'm going to log with my user here and I'm logged in so it works uh but uh now I deleted everything and the problem is that we cannot have it inside uh users so if I refresh I will get my user back back but uh well I cannot store information uh there so I think we can maybe put an a separate collection for it called the user infos for or user Meta Meta uh so let's call the new correction and let's do user user infos yeah something like this and uh there inside I will put all of the information that we put inside our uh user model so so stuff like uh phone street address postal code City Country and is admin I'm going to put it uh to user info so I'm going to cut it from here and now let's let me put this into a separate model let's go to our models here I will do a new file and let's do user info. JS and let's define our model so let's do const user info schema first equal new schema schema and let's space this here we will need to have identification about who schema it is so let's do email and let's do type of string and let's do that it's required right let's add here time stamps as well so let's do time stamps to true and now let's define a model so let's do user uh info equals export const user info equals let's first try inside the models if we have user info otherwise let's do new model model uh model function let's see yes in imported model user info with user info schema user info schema with capital u here okay this should work now let's go back to let's see use user yeah this should work now let's go back to our profile route inside API and here as you can see we are returning a user with this email but the problem is now this user doesn't contain information about um information that we have inside user infos so I'm going to put this first here const user equals this and then I will also add user info here and I will actually do the same EX accept we will do here um user info find one and now we want to combine those two together here so let's put an object here and let's say that we want to combine those together so let's do user and do do dot user info so now our profile should work let me see um loading yeah we get some info here but now we need to fix that uh when we update when we update uh for example phone or something it should save this um not like this all of it to the user but instead it should put all of the info uh inside user info maybe accept the name because the name is inside user as you can see let's see here inside user we have a name that we can update but all of the rest should go to um so phone street address post code City Country and if it's admin or not it should go to user info right so here we have data but it's all of the data that we can that we are sending from the form so here instead I should I want to update only I want to update only name and actually name and image let me see yeah we have image and name that I want to put into this uh user so um let's instead of doing this data let's do con and let's do user data equals and we want to grab only uh name and uh name from data name and image from data image now let's put it here user data or actually we could inline this so let's just grab this and let's put this here and yeah this should work now uh if uh we want to update also our user info and we want to update one uh with uh where email is email and then what do we want to update we want to update everything that is inside our data except name and image well so how can we do this well there we can exclude we can look through but there is also another way of doing this so first I will simplify this one so uh we have data here that includes both the data for user and for user info so here we have name and image for user but in here we need to put from data a phone street address and so on so I'm going to grab it separately so I will do something like this I want to grab from data I want to grab name I want to grab also image and this way I can do something like this here I'm going to put name and image so those two that I grabbed from data I I want to update inside user collection user document and the rest from the data will go to our user info so I can do something like this um dot dot dot and let's call this one user info or maybe we can call it other user info H the name doesn't really matter but this way from data we will grab name and image to those constants and everything else will go into this other user info so with we can do something like this let's add a weight we want to update user info where email is email and but here we are going to put other user info right so this should work now let's see if it actually does I'm going to refresh first here and now let's see if we can do well uh one or I'm going to put first one to three let's do save saving profile saved let's refresh and I don't see my phone number so let's let's see if we are getting this information from our network if it's saved or not let's refresh and let's see profile 200 and we get a lot of weird stuff here where we fetch uh profile so this doesn't seem to work uh so let's see if I maybe do uh two Json or is there such a function uh let's see we have Jon no find one now I want to on the on the document I found I want to run um I want to do I want to have only information that is inside the document so I want to have only fields and I don't need this weird extra information I think there's a function called the lean that we can use on both the on both of those so let's see if I refresh and now we get 500 error um so not this way let's try doing this here so let's do Lin and here Lin yeah so let's save let's do refresh loading and now it works so let's do it here and we have email and we have uh well I think we have everything uh but I don't see my phone number let's see if updating works so I'm going to put for number one 2 three 4 let's save looks like it worked uh but if I refresh and I fetch my profile I don't see my phone number so um let's try again let's try to update let's see if it send Save and uh we get true from this request so looks like everything worked but uh um I know what's the problem we are updating one row inside user info but uh we don't have it yet there's no U there's no such user info that we can update there's no such uh user with this user info with this email that we are logged in with but uh there's something else we can use here instead and it's called find one find one and update okay and uh here we have a first filter then what we want to update but there are also options here query options as you can see and I think that inside those options we have a a flag called upsert that we can set to true and this upsert to True means that if we don't find um user info with this email and we cannot update with this data it will first create this um user info with this email and then it will also update with this information here so now let's try I'm going to put 1 2 3 4 5 let's do save and uh well let's see here I'm going to refresh let's see if we have anything inside our user infos well now we have two user infos so that is not good we have user infos here and user infos here and um user infos that's not good that we have two of those I'm going to delete I'm going to delete both of them and um I think I will delete this one as well and let's see how it will be created again so I'm going to save it again and let's refresh our database and let's see what will be created uh with lower case I okay so it created user infos for me with admin fals and but no no four number so we are doing this uh put request with this uh well let's see uh if I click save here we are doing put request with the payload name and image but we are not not sending the phone let's see why and let's go to our profile page let's go profile page and let's see handle profile info update so we looks like we just send everything inside the body we're sending name image phone and everything so if I add six here let's clear here we have phone number and let's click save we have this put request okay now we are sending phone and let's see our database let's refresh here user infos we have an email and but we don't have any phone right let's go to our user info model and um let's see so we have email Street postal okay we don't have any phone let's see if it uh is inside user yes it is we need to cut it from here and we need to put it to our uh user uh info schema so let's put it here and let's restart our environment here so um now let's try to save it uh once again with this saving saved now let's refresh here and let's see user infos we have an email we have an admin but we don't have any phone let's see hasn't been uh saved or sent let's see let's open here I'm going to clean everything let's hit save once again put request payload we don't have any phone number here let's let's change something and then hit save and now we have phone okay now let's do refresh user infos and we have our phone so that is nice so now if I refresh it should uh work to grab uh my phone yes it's uh it's okay it works and now I can edit this user info here and I can change this admin to true so if I refresh my page here I should have more tabs and yes I do so this works now let me go back to my categories page and here as you can see we are fetching if it's an admin or not and then if it's not an admin we do this not an admin so if I go to categories on the beginning it shows not an admin if I refresh because it's still loading I want to have stay uh for this loading phase so let's do uh admin info loading and set admin info loading you State default will be false and here let's do first um set is uh set admin info loading to true and then let's do set admin info loading to false and here we will do admin info loading if it's true then we will do return loading info dot dot dot something like this and now let's see if I refresh loading info and then we see loading info first we will have not an admin but then we will see a loading info and then we see everything maybe we can set this as a default to true and then if I refresh it will be loading info and then uh we will see all of the tabs here because we are an admin uh we can change it to loading user info and this works nice so as you can see now we have all of this code from Line 6 to 24 uh to check if uh if it's admin or not just for this page and because we will not use it only for categories but we will use it also for menu items and users I want to put uh I want to put this into a separate file so I would like to have a um a hook like use state but only for fetching user information uh the same that we have used uh session so uh let me create uh my custom hook for this and I will just put it inside components and I'm going to call it uh well let's do um let's call it maybe just use and I will call it use use profile use profile. JS and now here let's put export default function use profile and here inside I'm going to not put phone number I'm going to grab my use effect and admin and admin info loading I'm going to copy this from here and I'm going to put it here and now I will do something like this instead of doing in admin info loading and set admin info loading I will call this uh loading and set loading set loading I need to change it here as well Set uh loading and here uh set set loading set loading right set loading all right and here we have the set is admin maybe instead of just grabbing is admin to a separate State um constant we will just have data let's do uh data and set data and we will just put everything into our data so let's do set data and data from the from our profile all right and inside data we will have if it's ad me or not so uh here let's just return let's just return loading and let's return data all right so now we can use this as a as a hook so let's go to categories page and let's get rid of all of this and now let's do uh use profile I think it was used profile let's go back here yes it's used profile export default function use profile uh maybe let's call it not default so it will be easier to import let's go here use profile I cannot uh grab it let's see why export function use profile this should work but uh looks like it doesn't use profile let's try to import it here use profile let's import it maybe here manually import uh use use profile from components use profile all right and now con as you remember we are exporting or we are returning um loading and data from use and profile all right so now let's see this should be uh capital u either capital u but I think it should be better with using small U or and this type of uh hooks because every is small U so let's change this function name to small U like this and now uh we have it working let's see what's uh here here we have loading a and data we can rename those two to let's say profile loading and here we will have use profile profile data and now and we can do something like this if profile loading then return loading user info dot dot dot yeah and now if I refresh loading user info yes this looks really nice and then we know we are an admin but uh we don't know yet let's just check it profile data let's check admin if it's true or not if it's false let's do return not and admin all right and we have much simpler code as you can see now let's see if it works yes it works all right so uh now uh let's focus on our categories uh page for almin so we have profile here we have categories here and what do we want to have inside categories well as you can see on our homepage here we have only one category now and this is uh pizzas so let's do something similar let's go to categories and uh let's have a form for categories so we can add and remove categories so first we need a form to create categories right so we can have something like um category name and maybe a picture if we want to so uh first let's create a form for creating new categories and let's do form and here let's do an input and let's do a label and label will say category name let's say new category name and um let's save and let's see new category name yeah maybe we can add some spacing here so let's add the class name margin top of eight so we will have something like this it's much wider than uh then than the profile so let's do medium maybe here let's see yeah I think medium is better um so we have new category name and then we have this input but um I would like to have a Buttle on the right side and so I'm going to do something like this let's do div with class name flex and I will have two div two Dives the left and the right side for the left side let's put this and for the right side let's put a button of type um type submit and it will say add or maybe crate yeah so now we have something like this but we will fix it a little bit we need to add gap of two and items and so it will be aligned to the bottom so now we have something like this well almost what I wanted and one thing I want to add will be padding on the bottom of this div so let's do a padding bottom of two and now it's almost align so so I would say this uh this will work uh on the first D on the left side I want this to grow so I want to take it should take all of the all of the Wii all right so this will work except that um this button is two pixels smaller because it doesn't have this uh border that inputs have so uh I'm going to add some classes here to our button let's do class name let's do border and Border primary so now it should be a little bit bigger let's see if it is button let's see now it doesn't get any border but uh it should let's see why it doesn't border okay we are setting border withd to zero on the type submit uh let's go to globals and let's fix it um here we have uh border zero maybe instead of Border zero let's do border transparent no it will not do anything um let's do instead of Border zero let's do border primary here okay and now as you can see the it's two pixels bigger so it's uh more like in line with this input and now underneath I would like to have existing categories but uh we don't have any categories yet so now let's first fix so we can create a category like pizzas pizzas something like this so um let's fix so we can rate categories right let's go to categories page we have this input but we don't have any state for it it so let's uh do this let's do let's create a state called maybe new category uh name and so here new set new category new category name equals use State and default will be empty string and now let me see here for this input we will have value new category name and we also need to have our own change and we we have event set new category name event Target value this should work so now we should be able to put stuff here all right so now uh we need to have on our form for new uh for new categories we need to have on submit and let's create a function called maybe how can we call it handle a new category yeah handle new category submit handle new category submit now let's create this one function uh handle new category new category submit submit yes we will get an event as always and we need to run prevent default because it's a form and we don't want to submit this with regular HTML forms functionality right so um instead what do we want to do we want to send it with a post request somewhere so let's go to maybe API slash categories or how can we call it let's see we have uh yeah let's do categories to/ API SL categories and we want to send only name of the uh of the category so let's send name as new let's send new category name as name all right and we don't put it like this as we do with axios instead let me cut it from here and we send it as body and here we need to do Json stringify and inside let's put this uh as an object like this uh we also need to have method of post and then we also need to have headers I guess so let's do uh headers and I want to send the header of U content type and it will be application Json this should work now and this is fetch let's grab response of this p and let's add our syn and now we get response and maybe we can check if the response is okay or maybe we can U uh add a toast so we will see if uh if it worked or not let's create a um a promise out of it const and let's call this one maybe creation and creation promise equals new promise resolve and reject arof function and now let's put this thing inside and we need to add a weight here to our Arrow function uh asnc I mean and now let's do something like this if uh if responds okay then we will do resolve and otherwise we will do reject reject all right so this uh should work but here instead of this we should do uh if response okay then resolve and if it's not else then reject yeah this should work and we have our creation promise so now we can do toast uh from react hot toast and let's do promise and our promise is creation promise and now we can add more stuff like U let's add a weight here and here we will have waiting I think no it was loading loading it will say let's have a message saying creating your new category dot dot dot if it success it will say well um category created and um if it's Error it will say error error sorry something like this so uh now it will say error because we don't have this endp point here but let's try let's do test create error sorry create error sorry that is really cool test error sorry all right so let's create an endpoint for this let's go here API and let's create categories directory categories and inside categories we need a route so let's do route. JS and here first we need to do export function post because we are going to post a new category we will need our data and we will need to have Json from our request so is the data equals await request Json and we need to add a here and now let's see we have data so now we can create our we can grab the name um let's maybe grab from here not all the data let's grab only name and now we can create a category we should probably also check here if it's an admin or not but we will do this in a in a moment first let's just create a category so we need a model for this here we have models let's do new file and let's call this one category. JS first we need schema so let's do category schema equals new schema schema from mongus and well inside I want to have here time stamps of course time STS to true and here I want to have name that will be string and well let's put this like this type string and we will do also required to True right so uh now we can create the model so let's do category equals uh and let's add export here as well category equals first we need to always uh check for existing models uh let's check for category otherwise let's do a new model uh with our category as a name and C category schema as our schema all right now let's go back to categories route and let's see I'm going to import this category let's do create and let's create with only this name we will add a weight here and Let's do let's assign this to a constant so we can maybe return it if we want let's do category category document yeah we can call it category or just category document and we want to respond with it so let's do to return response Json and C category document and this should work now let's try to uh create test category let's hit uh create but first I will do inspect and network let's do create post 200 and the preview as you can see we get a new document from the database we get our newly created category with name test we have ID and we have everything all right so this worked and uh it's nice that we can actually create categories but uh now uh here underneath I would like to have here a list of my categories right so uh well let's go back to our categories page and well let's see underneath here under this form I want to have a list of categories let's maybe put this as uh I don't know as a div with uh with um or maybe not da let's put it as a UL with allies inside so uh first I need to grab all of the categories from somewhere so how can we do this uh we need to have use effect for this so when our page loads it will uh run uh axos or Not axos Sorry fetch to uh to fetch all of the categories for now as you can see we don't have any dependencies or not for now because we want to run this function here inside when our page loads so first let's do Fetch and let's say it will go go to/ API categories we don't have this endpoint yet so let's go to categories route inside API and let's do export a sync function get and uh basically we want inside this get to return all of the categories from the database so let's do just return response Json and here we will do a weit and we will do category and we want to find all so let's do just find and this should work now let's go back here and well we fetch all the categories let's do then with the response we will do Arrow function then from the response we want to convert to adjon so let's do responsejson then and then we will have all of categories here categories as a response it will be an array of categories so with this those categories we want to send them to a state so let's do here const category not category categories and set categories you state default will be empty array and here we want to do set categories to categories this right so now this should work and now if I go down here uh where we have this UL I want to do something like this maybe instead of you I will do just da here I will check if we have a categories if we have categories uh length that is bigger than zero let's do end is do categories map and we want to do with each category let's call it just C so it will be uh shorter to write with each category I'm going to put a div and I want to put category name here so here we have test because we have one C that is called test well but now um I would like to have it as a nice looking list or something like this so uh well how can we do this maybe we can have something like this let's put this div like this and we will have two spans inside and first we'll be addit category and here we will have another span with the category name inside and now we will do something like this on this da I want this div to be kind of button let's see what happens if I put button here nothing happens we don't have styling for this but I will do something like this I want this to be background gray 300 and maybe lighter let's do 200 and I want to do here also rounded of uh large something like this and I want to add a padding of four maybe four is too much let's do two and and uh well what else can we want do we want to do let's see how it looks like and this category the padding on the SES should be bigger that's the PX4 yeah this this looks nice maybe we want to have also some spacing here I'm going to put here flex and gap of two let's see yeah edit category test maybe let's just do only gap of of one right this uh looks fine for the first span I make it more like uh transparent so let's do text Gray uh let's make it text Gray 500 and we have something like this now on the div I will make it also cursor pointer so it will look like we can click this one and uh well maybe I will also do the round corners should be bigger so let's the let's let's see rounded large well I don't know rounded XL let's do XL and now let's do maybe not edit category instead I would just have a I would like to have something that will um maybe a label here above that will say or a title let's put an H2 title above that will say uh edit category edit category cool on let's see yeah I think it looks fine let's add some class names like margin top of eight let's see how it looks like yeah and um well um I think this works fine I will just get rid of this span and yeah I think this uh this looks fine maybe I would like to do the same styling as we have here so on this one let's add the text SM and I want to do text Gray 500 now let's see edit category and I can click on this one all right so um I cannot edit yet because if I click nothing happens but what I want to do is first to maybe change it to a button yeah so now we have something like this with a border and I'm going to also add some margin bottom on this buttom margin bottom of at least two in case we'll have later more categories uh what's more is I want to add another category create another category like test two but before I will do this here we have this create button let's see uh when I create a new category I want to refresh this list and this list is fetched only when we load the page so uh to fix it first I'm going to grab it I'm going to put it into a new function called Fetch categories and let's put it here and now inside here let's do fetch categories as it was but when we create here handle new category submit and here we are fetching all of this let's also run our fetch categories function all right and now let's see if I do test two click create category created and as you can see we have test two here and this should be also cleared so let's also add here set the new category name to empty string and now let's see if I do test three create and it's created so this is nice all right so U this looks fine maybe we can decrease the padding and the spacing here between so let's do let's see we have button margin bottom let's do only one yeah and I think this will work fine edit category and those are buttons but they don't do anything uh what I want to do is uh I want to do that when you click on this on this for example it will the title will go here and we will edit this will change to edit all right so how can we do this um when we click on a button on this one test free we want to inform our state that we are now editing this test free categories Test free category so um we I will create a state for this and and it will be called um it will be called well we can call it active category or edited edited category set edited category and default will be null and if it's null if edited category is a null then we we then we know it's a new category that we are creating all right so if I click on this one test three for example let me fix this functionality I will put the class names here here I will add on click on click on click we want to do let's put our function here and let's do Set uh set edited category to our C so our current category inside the loop so now if I do click here and we informed our state that uh this edited category will have an object of C so our document of this specific category so now we can use this to change some stuff inside this form so for example example we can do something like this we have this button here saying crate we can do something like this edited category if we have something inside it will say update otherwise whoops up update otherwise it will say create and we have here label new category name we will also have um here something like if we have edited category then it will say uh update uh category category otherwise it will say new create new category or maybe new category name sorry let's grab this from here let's do a like this update category maybe let's put this into separate line This label should go here so if we have edited category maybe we should call it category editing category I don't know um then we will it will say update Cate category otherwise new category to update so if I refresh we have new category name and create if I click we'll have update category and update here I will also add if we have edited category and only uh it I will add here colon and I will print edited category name so we have we have something like this uh update category test three I will add here a space as well uh update category test three uh maybe I can add the Bold here uh let's see update category test three and uh I would like to have this test free filled here inside this input so to fill this input this input is actually our uh let's see this input is actually our new category name and because this can be either new category name or existing category name I'm going to change this uh state name to just category name so let's do category name and here I will do set the category name and we need to change it here above as well so let's do category name and set category name and we are using this later when we update stuff so let's do here category name and here let's do set category name right so now let's see if I clicked on test free we have this test free here but still nothing here and this is because here we have our button and on click we are doing um we set this edited category but uh something more I would like to do is to do this but also I would like to do another thing I want to do set category name to category name right so now let's refresh if I click update category Test free and we have this test free here and we have our update button but now um when we click this update button it will submit our form and as you can see the name of the function is handle new category submit let's rename this to handle category submit and let's do the same here handle category submit now the problem is when we uh do this uh it always send a post request to our API categories and this will always create a new category it doesn't have functionality to actually update the category so uh how can we know uh how can we change it if we have something inside edited category we know it's an update so let's do here if edited category then we will do put otherwise we will do Post right and uh if we are updating we are sending this new name but we need to also send uh ID to this Json as well so uh how can we do this well to do this first I'm going to grab this and I will put it as a data somewhere above let's call this one data and let's define it here data equals this and here I will also add if it's edited category then to the data I want to add ID to be equal from edited category underscore ID or maybe let's call it underscore ID uh to make it same as we have it in the database and this way if it's uh if it's a new category we'll have only this data and not ID if it's uh if we're updating a a category this will be an object and we will get also ID into our data we will send with put request we don't have any put functionality inside this uh endpoint so let's fix it inside our categories route we have post but we don't have any we don't have any put yet so let me do export ass sync function put and we want to grab our request and we want to H grab all of the data so let's do data equals await request Json and now um maybe instead of data we can directly grab our underscore ID and the name and now we can do something like this we want to do a wait category uh update whoops uh up update uh one we want to update one by this uh unders ID and we want to update only our name right and then we can do return response Json true to just uh inform that we are okay all right so here let's see we get a response and if everything is okay we are setting this category name to empty and uh well then we do this uh fetch categories to refetch all of the categories then we do resolve or reject on the on the promise but then we have this toast as you can see here and it always says creating new category category created here I would like to do if it's an update then uh then if it's an update then we know we have an object here so it's not an empty State and we can change here uh message right so let's do something like this if edited category then something otherwise Crea a new category if uh edited category let's maybe put this like this if edited category I'm going to um say when it's loading um updating category category dot dot dot and let's do maybe similar thing here if we have edited category then let's do something otherwise something else maybe let's let's put it back as like this no let's put it into several lines uh here on success uh category category updated and uh yeah now let's try to update this let's do refresh let's update test three let's change the name to test 3 1 let's hit update category updated and we have this test 3 1 uh it still says um update category three test three because we forg not to actually here reset our edited category back to null so let's do this let's refresh let's do test 31 let's do test uh rename it to test 321 let's hit update and category updated it's refreshed here and this is empty so we can create new categories right so now we can create categories let's maybe create another one like test four let's hit create we have it here we can uh addit this one to testore test 4ore 2 and it works we don't have any images for categories but for now uh we don't need this we have a categories here and we can edit and delete them and stuff like this now uh it would be name it would be nice to have same functionality actually for our menu items for now it's uh 44 but we need to have similar functionality for menu items so let's create a page for this and let's close API and inside up let's do new directory and um let's call it maybe just uh or let's do menu items yeah menu items and inside we need to do page.js and Export default function function menu uh items page yes and here I'm going to return I want to return a section uh with that will have a class name of uh margin top of eight so we'll have some spacing and here inside I want to have our user uh tabs but all of this uh let me see if this will work uh yeah it kind of works but the problem is we are not sending this is admin let's send it to True uh but first we need to check that we are actually an admin the same way we did it with our um categories as remember we can grab um loading and data from um what was it called it was called use uh profile yes and um here we can do something like this if loading um we can do then return loading user info dot dot dot and here we can do something like this if data admin is not is false then we'll do return not an admin and we will not display um all of this now let's see we need to make it a client components so let's do import not import sorry uh use client yes and the loading user info categories profile categories menu items yes I think it uh it works uh fine and we have this loading user info wherever we click maybe later we can fix that something in the middle shows and not on the uh top left corner but uh it works for now all right so we have menu items and we know that we are actually an admin logged in admin here so uh what do we want to do now we want to have something similar to categories right so um we want to have a way of creating a new menu item them and then editing uh we want to edit uh menu items so let's do a similar form first so we can create our first um our first uh menu item so let's do like this form let's add class names class name and let's do margin top of eight and inside we will need div Flex with some gap of let's do two inside we will have left and right side because on the left we will have an input uh with a label of um this label will say menu item name and on the right side we'll have a button that will be type of uh type of submit and it will say maybe save or it will say on the beginning create so we can create a new stuff here all right so here first things first for this uh form here we want to do Max wave of XL or I don't know medium and the MX Auto so it will be centered like this yes let's see how it looks like here yeah I think this will work then the left side should grow so let's do a class name grow and here on the flex I want to do items and so it will be aligned to the bottom I want to do on this botom I want to add the class names to make it the margin bottom to so it will be more in the line with the input and I think this looks nice but um here we will need menu item name and we will also need uh a picture right so we need to have both um both um photo of a um pizza for example and we also need to have a name and then pricing and more stuff so uh we will have description we will have price we will have properties so maybe we will not have it as a simple um form like this like we have on the categories but we will actually need to have something more complicated like um here when we click menu items first we will have a do you want to create a new or do you want to update an existing but first let's do a form so we can create one right so uh we will need 's let's see image we will need the title or name description and um and then a price and then maybe some extra step for sizings and Extras if we want to but let's first focus on the on the title image description and price so we need to have a title a description image and price so I think we can do a similar layout that we have here with the profile uh so let's do something like this we have instead of having this button crate here I'm going to get rid of it and we need don't need this div we don't need this div maybe actually we need yeah but on the left side we'll have an image that will not be here yet and here items let's do items uh start so it will be aligned to the top we want to have more gaps so let's do Gap four and on the left we will have an upload for a photo right all right so uh menu item name let's do just uh the uh item name then I want to have more like stuff description price so let's do here and description and here we will have a price uh item name description and here I will do maybe best base price because later I'm going to add all functionality so we can have different sizes of pizzas or maybe some extras too so this is base price and um well so we have a form here we will also need a button to actually save it so let's do a button of type submit and it will say save for now yeah this uh this should work and on the left now we need to have the same upload functionality that we have here on the profile page so how can we do this uh I would like to copy some things uh because we will update to the same backet and we will do very similar things there so let's go to our profile page and let's see we have this huge function called the handle file change as you can see it's this big and the well I would like to put it somewhere else so we can just have this input type file um so uh um let me go back to the profile yes here and now I want to put this handle file change somewhere else so I'm going to copy this uh let's uh copy and let's see where we can put it uh we don't want to put it inside any app we want to put it somewhere else we can put it inside the components uh but maybe it's better to put inside lips so let's do a new file inside Libs and let's call this one uh upload or maybe we can put it actually inside the components uh and we will create a nice looking uh component for this so Avatar and the button so let's do component uh inside components I will do um image uh image input or how can we call it editable image as do editable uh image maybe we can put it inside layout I don't know yeah let's put it inside layout um layout out let's do new and let's do editable image. JS and here let's do export default function editable image all right and we want to have uh here properties of a link and uh we want to also have a function to inform when we set a new link so let's do link and set link and now I'm going to paste this uh function here that is super long and file change as you can see and then here underneath I'm going to return um I'm going to return something similar to this so let's go back to the profile and let me grab all of this I want to grab the the image and um I want to grab the image and this label with the input so I will copy this I will go back to editable image I put react fragment because we have several uh h XML elements here and now we can see if we have an image then we are printing this instead of image I'm going to use this link if have a link We display this uh image with this uh link and then we have a label so we can do handle file change uh so this is the function we are running and now instead of doing set image I'm going to do set link right and this should work now and now we can go back to profile page and now we don't need all of this instead we are going to put here editable image like this and let's see if it works no it doesn't because we don't send any link our link is actually image and our set link will be set image so our component editable image can inform our component this component the our our page about uh new uploaded uh image the link to the new uploaded image we don't need this upload function anymore as you can see it's with a gray name so it's not used anywhere and now our file will be a little bit shorter but what's most most important let me also check if it still works uh I'm going to change this to my new photo here let's do up open here and uploading this works nice and I will put here country as well Sweden let's hit save saving profile saved this works really nice let's do refresh everything is saved so that's nice let's go back to menu items and here we have placeholder for image let's go menu items page and here let's just put our uh editable image simple as that editable image and we don't have any link for this or set link uh but we'll create state for it so let's do const image set image equal use State not use session use State and default will be empty string we don't need this import for your session and now here uh the link will be image and here set link will be set image all right so now we can click edit here uh would be nice to know that uh we don't have an image here so let's go here inside this component and here we can do something like this if no link let's do end and let's do a div with um class names some class names and inside we'll have a text no image and the side the face or maybe just no image and I want to add like a a background gray of 200 let's see how this will look like yeah maybe let's add some padding of four on all of the sides yes and the text should be grayish let's do text Gray 500 and I want to do rounded corners of uh LG large right and also margin bottom of one the same as we have with the image right and now I should be able to put some image here so let's try with this one uploading yeah that looks nice and upload complete and it looks fine maybe it's a little too big so I will go back to her menu items page and on this Dave I will do Max WD of uh 200 pixels so we will have something like this um yeah I think this uh this looks good enough um maybe we could also try to change this to a grid instead grid and here let's do grid calls and can we do one or third something like this no this will not uh work um but uh let's see 13 FR can we do like this no um let's add here um maybe something instead so I'm going to remove this and instead for our grid I'm going to add style and I will do grid template uh template columns and I will do something like 0.3 frr and 7fr and let's put class names here and start styling style here below and now as you can see we have 30 and 70% we should probably do the same thing for uh profile but well I don't think it's that important and the text here should be centered so let's go back here and let's see no image let's put text Center okay and this looks fine let's do refresh edit let's upload this photo yeah it looks nice uploading and upload complete yeah this looks nice then we can upload image we can put some stuff here test test and let do 1 2 3 4 here and then we can save a menu item so uh now let's maybe fix so we can actually save a menu item uh menu items page and here we have buttons we have uh submit what else do we want to do uh on this form we want to add on submit and and let's call our function um handle um form submit simple as that yeah and let's define it maybe here function and it will be of course asking function handle form submit as always we get an event here that we need to block with prevent default and uh now what do we want to do uh we prevent default of this uh form sending now we want to grab the image and we you want to grab the info of all of our inputs but hey we don't have State for the inputs yet so let's do state let's do con we will need name we will need also description and we will also need the base price base price and this should work now we need to fix our inputs so um I will do on all of those something like this first I will put type here and I will do value and on change we will do event and then we will do um some stuff uh called for example let's maybe fix first uh for one or let's put everything uh same thing for every input so here I will do name and here I will do set name and it will be event Target value and now let's uh we will have same thing for all of those uh we need to fix it so here I will do description and here I will do set description and here I will have B base price and here I will do Set uh base price all right so we have a name like um um I don't know Pizza uh Pizza one and description will be I don't know and base price will be $10 then we can hit save and our form we submit and this function will run so uh when we run this we want to do a fetch function run a fetch uh end point with API let's do maybe menu items and here I want to do method of uh post for now because we are posting a new menu item we want to send body and body will be Json stringify we want to do here uh we want to send everything that we have in side state so let's do image name description and base price yeah or all of it uh so uh maybe we can put this data somewhere here about const data equals this and we can put it in one line so stringify data right and we need to put headers we need to have a Content uh type uh application Json right and we can add a weight here const response response equals this and uh I would like to add again uh toaster toast toaster react react hot toast for this so I'm going to create the new promise uh saving promise equals new promise response reject and I'm going to put this inside and then uh I need to make this one a SN and now I will do something like this if a response uh is okay then I will do I don't need those um I will do reject resolve resolve and else if the response is not okay I will do reject all right and uh now here I will await toast uh toast uh from react hot toast and promise and here I put our my saving promise and here for the options I will do first for loading it will say saving uh this tasty item and for Success uh it will say saved and for error it will say error yeah simple as that so now it should be it should throw an error because we don't have menu items endpoint yet so if I click save saving error right so uh now we need to fix this Endo let's go to our app API and now we need menu items directory menu items and inside we need a route so let's do a new file and let's do route JS and we need uh export uh a sync function called uh post and we will have request stuff here and first let's grab data from request Json and of course we need to add a weight here because it's a stream and now if we have a data uh what do we want to do we want to create a new uh we want to put it into database into menu items so let's create a model for this models new file menu menu item do menu item. JS so is do first menu item schema equals new schema yes from mongus and I want to have us always time stamps to True uh so I will have some extra data uh but now inside our menu item schema I want to have those free stuff and image so let's do something like this first image it will be type um type uh string and I think I would just copy this and I'm going to put like name and description and the last one will be base price and base price base price will be actually number all right so uh that's it and uh now we can create a model so let's do export con uh menu item equals uh models first let's check for models uh menu item otherwise let's do new model function and menu item with our menu item schema all right because base price is a number I'm not sure if we need to convert it but let's see if this will work let's go to menu items throughoute inside API let's try to create our menu item let's import this one let's hit create with our data and we need to add weight and let's assign the result to menu item document and then let's return response Json with this menu item doc so we can see uh if it worked one thing I forgot about is to connect to our database so let's do um mongus uh connect and here process. env. URL yeah I forgot about this and probably I forgot also about this somewhere else let's see and probably also inside the categories yes I need to put this here and inside all of those so let's put it here here and here let's see profile profile looks fine I think the rest is fine let's go back to menu it items and this should work now so let's go back to our menu items page here and maybe we can now try to save all of this so let's uh pick an image and now it's uploading I'm going to open here my network tab to see what's here inside here I will put description base price 10 let's hit save post 200 and as you can see base par is 10 description desk name Pizza one and even the image is here so everything seems to work it just worked uh so now we can actually create new menu items so the next thing will be actually so we can list them somewhere and when we enter this page let's go back to categories when we go to menu items first maybe we should see a list of all menu items and this form should be actually somewhere else like SL menu items SL new or something like this so um yeah this is what we need to do next so uh let's do this uh first I'm going to create a page for this menu items as the new category a new directory inside called the new and inside let's do new file called well it's not inside API let's remove it from here and I want to do this inside menu items inside uh app so it's the new directory new and inside we want to do page JS page JS and now let's do export default function new category not new category new menu item page yes and well first we need to have check for the profile right const and let's grab uh loading and data from use profile and then if loading it will say return uh loading user info dot dot dot and then we want to check if it's not an admin if not data admin then we want to do return not uh not an admin dot dot dot uh no dots all right and then we know it's an admin so we can do return and we can here return this uh this form right so let's move this form from there so let's go menu items page and I think we just need to move all of this section let's cut it and here I'm going to put just uh just a div for now uh it will say menu items and I will move this to here on my section but now we need to uh move all the functionality as well so I'm going to cut all of this from menu items page and I'm going to put it into here so let's put this here and now we have two loading and data we don't need two of those this works now yes I think it does um we need to have uh also here our loading and data from use profile but we have a lot of imports that we don't need here so this is our simple um menu items page we need to make it more uh Advanced now so let's add a section section with class name margin top of a and now here we need to have those user uh tabs with is admin being true right uh we have new item menu items here I want to have a link a link to uh Slash new not new SL menu items menu items SL new so it will say create a new menu item something like this yeah uh but this should be uh more like uh centered or something like this so let's do Max wave on the section of uh medium and let's do MX Auto and now let's see yeah something like this uh for this link uh I want to put it inside the div with some margin on the top so we can have some styling some spacing uh now for this link I'm going to put this into uh like this and I'm going to add some class names on this link to make it more like a button let's see create new uh menu item uh I'm going also to we can click it but uh well I would like to have more styling like uh this one so um let me see maybe instead of having this class I'm going to do background gray or maybe let's go to our globals and let's fix class for this so we have button let's also have a class name that's called button now let's go back here let's put back our button and now we have something like this I think it looks fine um those don't look that fine I think I would prefer them to be white same way we have it here uh but that's not that big of an issue um we have this link it's a button um well maybe we can make it centered or maybe we can add an icon here so I would like to have this right icon we created this before so we have something like this now uh I will add a flex here so uh so maybe it will be next to each other no maybe because I need to add span and let's put this text inside no this didn't help let's see why inspect and let's see button Flex what is display block let's change it inside Global from uh block to flex and and now it's better um now I'm going to also add justify um justify Center and now it's more more centered and I'm going also to add a gap of at least two yeah and I think this looks nice let's see if we have uh destroyed something else now everything CLS fine let's go back to menu items and now I can click here create new menu item and now we have an error let's see are importing blah blah blah I think it's about this um use client that we miss inside menu items new uh new menu item page on the top we we need to have use client and now let's see now it looks fine now here on the top it would be nice to have a function like a button go to uh all menu items so uh here I would like to have maybe here under the tabs I will have it St with a link link and that will go to slash menu items and this link will show um and this link will say we have a span go to or maybe show all menu items um or maybe go back I don't know uh and uh well this should work I will add here some class name of a button and I need to add some styling on this div above so let's do Max wave Max wave of medium and MX Auto and margin top of eight and uh let's also add this right arrow right right yeah and and this should work uh maybe we should have an arrow to the left I don't know let's go to this right arrow and let's see yeah I will create an an arrow to the left so let's call it left that JS and I'm creating uh this inside this icons directory as you can see uh I'm going just to copy paste all of it into this left I will just rename it to left and I need to replace this SVG right so let's go to Hero icons let's search for left and let's copy this and let's put it here and as you remember we want to replace those class names with class names that we get as property now let's go back to new page and instead of this right I'm going to add here left uh Arrow here so now let's see how it looks like and show all menu items uh I think it works nice yeah and now if we we can go create new menu item or we can go back when we create a new menu item and we have this form we are on the page menu items SL new this one is not red anymore so let's uh fix it let's go to user tabs and here we have something like this if path is menu items but it can be either menu items or menu items new so uh how can we fix it we can do something like this we can do pu test um or monot test um it should be first should we have a menu uh item and then we do a test and we test it against our path and now let's see now it's uh red because it includes manyu items we can also do it another way we can do some of this puth includes menu items menu items and this works too or you can do reg exess so even if you go back it's red right so here we can create a new uh menu item let's see um new page and um if it's uh done then it shows this saved and uh maybe then we should redirect this now we don't need to do anything I'm going just to reset everything here so let's reset uh this to set name to empty string let's do set image to empty string well let's see if we save it what do we want to do maybe we want to go to the list instead so um to read direct I will do something like this redirect and let's go to slash menu items yeah and let's hit return here just I don't know we probably don't need this let's see if this will work so let's create a new um I'm going to use this image and let's put this as Pizza 2 description desk base price 12 let's hit save and let's see what happened we get an error and I think the error is about next redirect and uh we cannot use redirect inside functions like this so to fix it I will create a state and this state will be called redirect uh to um items and set redirect to items default state will be false uh but here when we where we want to do redirect I will do Set uh redirect to items to true and now here I will do if set if redirect to items if it's true then I will do return and redirect uh redirect to SL men items like this so um now let's clear this and let's see if this work let's do a pizza pizza free I think let's upload some image let's maybe put an image of me why not let's put description here base base price of 14 let's hit save and as you can see we have been redirected to the menu items page so that is nice now it will be nice to on this menu items page to list everything uh to list all of them in new items so we can edit them right so um so to list them um we need to have a use effect here use effect from react let's do Arrow function no dependencies so empty array here and here let's do no accessory Fetch and let's do slash API slash hm slash men items and this will be a get request so we need we don't need to Define our method to be get because get is default and we don't need any extra options here instead we can do just that then response and with the response we can do response to Json and then we will do um the we will have uh actually our menu items here that we can save into State we don't have a state for this yet but I'm going to create it so let's do menu items set menu menu items equals use State and default will be an empty array here here let's do set menu items to menu items that we get from here from the Json and this should work but uh we don't have this get End point4 menu items yet so let's go to API menu items throughout and that's fixed our get so let do export ass sync function get and first we need to connect to the database and then we can do return response Json with all of the menu items so here we just need to do await and menu item and just find because we want to find all of them let's do this and this should work now let's go to menu item page and let's see this should probably work we should have it our menu items in this um in this state here so maybe here under this div let's put another div and here let's check it if menu items uh length is bigger than zero then let's do end and let's do menu items uh map and for each menu and for each item let's call it item we will do parenthesis Dave and let's do item. name and let's see if we will have them here no this didn't work let's see why I will refresh okay now we see them so now it works and um yeah so now instead of div I will put a I will put a button button with uh two t and let's add some class names just in case let's see yeah I want to add margin bottom of two uh or maybe one and here I I want to put an H to saying uh edit menu item and we will have some class names here like text small and uh text Gray 500 and um yeah I want to have margin top here as well margin top of four at least four yeah I think this will work let's see on the categories here we have much more spacing maybe let's do also like eight here so we will have more spacing edit menu item H Pizza one pizza 2 Pizza 3 Let's see categories yeah uh I think this will this will work I don't like that for categories those are gray let's go back to categories page and let's see why those are gray uh we have this background gray um 200 on those buttons so let's remove it and now those are white as well all right so uh this works nice now instead of a button I want to have a link for those categories no not here let's put it back to a button I want to go to menu items uh page and here for this uh button I want to change this to a link because I want to do that when you uh when you click on it it will go to a specific page for this uh for this uh specific item it will show a form for this we will not change anything inside this page on this state will go to a separate page uh I'm going to put here button class so we will have our styling and here on the ref we will go to menu items slash uh edit slash and then the ID of the item so let the item id like this so now if I click on this one it will go menu items slash edit slash then ID it doesn't work yet but uh well we we have it uh we have links uh another thing that would be nice is actually to have uh uh images here not only and not only the titles right so uh Let Me Maybe put an uh an image here image image and let's do Source will be actually item image and the here will be nothing and now let's see if this will work now we need to have wave and have thing that instead of with and half I will have this um layout uh layout and I don't remember what was the layout thing here um so I'm going to go to the hero uh layout fill okay layout fill um or actually um I can do we need to have a div with relative here and we need to put this image inside and for this we also need to have minimum wave and and we need to have some wave and half so let's do wave will be 24 and half will be 24 and now we have something like this the problem is that those are um those images will be stretched so that's not good um let's remove maybe this liod fill and I'm going to add this wave of 100 and half of half of 100 here instead and I'm going to Let's maybe leave this uh da for now let's see how this looks like I think it looks fine let's see how those are rendered uh because as you can see those are not 100 by 100 rendered size 100 by 66 so here you just put maximum wave and maximum he and it just to and the correct thing all right uh instead of having one by one I would like to to have something else so here we are looping through all of those links but I will create a parent div that will be a grid with grid uh Columns of uh four so we will have four um oops not from here I want to grab all of the mapping so we should have now four in one in one line maybe we can change it to three let's change it to three and uh well I will put uh we don't need to have this one link to be Flex um or maybe I will let it be flexed but uh the direction will be colume so let's do Flex colume yes so it will be not from left to right but from top to bottom instead uh right so we have something like this and now maybe we can put here another div with something like text Center to just Center everything yeah and now we have something like this I want to have spacing between those so let's add a gap of two and um yeah this looks fine so we can edit those but the links don't work yet but we will fix it in a moment and the most important P part is that we can um edit those maybe we can change the styling because those are not buttons anymore and we should make those more like of a like this one so more gray is background and I think it would be much better to to have it this way so let's go to menu items and instead of having this as a as a button uh I will I want to change it to well let's say I'm going to put those class names here so we'll have more space and let's do something like background gray uh 300 and let's do rounded large and I want to have a padding of four yes that's my much nicer let's see here maybe it's not 300 maybe it should be 200 or something like this let's do 200 and uh this looks nice uh I'm going to change this to like 200 by 200 so the images will be bigger and I want to do on the image I want to add some class names as well like cred medium so we'll have rounded Corners here uh this looks good enough I think now we can uh now we can work with it let's see yeah I think this uh this will be good so we can click on those Styles and we can later edit those menu items and here we can create more menu items so now let's fix that uh page for editing a new uh an existing menu item let's go here let's close API uh or maybe let's start with API inside API we have this menu items route and we have a post for creating new but we also need to have a uh put for uh updating right so we connect first uh then let's remove all of this connect then we grab data from Json uh instead of grabbing data like this I'm going to First grab ID and then I'm going to grab rest of the data and here I'm going to do something like this I want to update only using this underscore ID so let's do await and let's do menu item and I want to update um let's do this time update find by ID and update I have IMD here and the data is here and uh that's it so I can do just return response Json with true and that's it and we have an endpoint put for our menu items now let's create a page so we don't have this 44 page let's go to let's close API menu items we have this new here let's do also edit edit uh and inside we need to have a page.js uh the content will be almost the same as we have on the new page here so the form will be very similar we will have all the same inputs so um to not copy paste it or maybe we can first copy paste it uh everything that is inside here and going to uh copy and I'm going to from here I'm going to put this here but first let's put here export default function edit menu item page and Let's do let's paste everything here let's save now let's see what will happen let's do refresh and this didn't work this didn't work because it shouldn't be here and because it's not just sledit it's slash edit and then the ID so we need to do a new directory here called all the ID like this and then this page we need to put it inside here yeah and now let's see if I refresh uh I forgot to put on the top uh this uh use client all right and now now we have this um we have save and we have all of this and the problem now is that we are not fetching information first so if I go here and I want to edit this one I need to fetch the information about this menu item so how can I do this uh I need to add the use effect somewhere here use effect and then H let's do Arrow function here and then no dependencies and here let's do something this not accessorry again patch on API menu uh items and this will return all of them in new items but that's fine I can just look through them and uh now let's do something like this then response with the response I'm going to response Json then with the all of the all of the items I'm going to do something like this uh I need to find a specific uh item of this ID how can I do this um I can do this using this uh path name or using uh parms that we have here it's not uh parms I think uh it's called Somewhere El somewhere else um but let's try to do this const pars equals use parms I think it's parms yes and uh now let's maybe first here the console log of our parms to see if we will get our ID here so we get an object and we have parum ID right so I'm only interested in this ID so I'm going to patch it like this we have our ID that we are interested in and now when we receive all of the menu items here that you can see here if I just refresh menu items I just need to look through them and check if any of those have an underscore ID of ID that is here without underscore so uh now let's check um I want to find my um item inside items and I want to find it by checking that this item in inside this items has an underscore ID that is the same as ID from the uh use parms here all right and then I know I can do console log of this item right one thing I forgot about is deleting we need to implement it in both categories and menu items but this will uh we will fix it in the mile so now uh if I go to here con log I as you can see we have open pizza one if I go to back to menu items I open pizza 3 it's a pizza free now that is open so now I can just fill all of this with my item info so let's do set image item image and then let's do also set name to item name and let's do set description to item description and let's do set base price to uh I it base price and let's see I think that's it so we have this and now if I refresh let's see everything is filled in so if I select this one pizza 2 with this Forest everything is filled in now we have this handle form submit uh we need to change this uh post to put and we have this uh data here we need to add uh underscore ID to be the the ID from pams and this should work I think let's do pizza 2 updated and let's hit save and uh saved and we have this pizza 2 updated and it seems to work uh there's a lot of copy paste here as you can see for this form and um we have the form for both creating a new menu item and changing uh an menu item is almost the same so we could maybe put it as a as a one component but well uh not need it now uh we can simplify it later we can refactor this later for now uh it works and now what we need to fix is that uh well we can create and update categories we can create and update menu items we need to be able also to delete if we don't want to have one of those categories we need to have a uh button to delete same with menu items if we want to delete something that is that we don't want to have so now we will fix so we can delete those and then we can fix the users and admins there all right there is another thing we are missing here on the menu items uh we have base price of 12 but I would like to implement here uh extra additional prices for example if you have a pizza with different uh sizes like small medium large or extra extra stuff on your pizza it should be we should have um this information here somewhere right so for example if you want to have a pizza that is medium it will be a little bit more expensive and you want to have extra pepperoni it will cost uh extra $2 or something like this so um I want to have it now so um we need to fix it to do this uh as you remember we have form for creating a new menu item and for editing uh menu item those two forms are almost or actually uh the same as you can see if I scroll to uh for example this return here and this is new um uh menu items new page so it looks like this we have a section with form and if I go to edit form and scroll to the exact same position you can see that it's exactly the same so I will do first some small refactoring because I want to have it as a as one component all of this uh so I can also add the extra inputs for sizes and so on so uh we have this form and now we are on the uh edit form and um let's see it's a section then we have this form how much do we want to have in this component well maybe let's put all of this except the button or maybe we can even include the button everything uh let me see here we have the section here we have user tabs then we have this button to go back and then we have the form well maybe it would be best to have first form as a separate component so let me first grab the form let's uh C cut it from here cut and now if I save it will disappear but let me go back to um here and let's see where we can put it uh we can put it in uh components yeah somewhere here and maybe let's put it into layout uh let's do new file and let's call this one menu item form. JS and here let's do export default function menu item form and now let's uh put everything here inside a return so return and let's put all of this as you can see we don't have a state for this uh so we need to also copy the state so let's go back to the uh edit page and let's scroll up here and here we have um state so we have image name description base price and uh and so on let's grab those four image name description base price let's cut it from here and let's put this into here all right and uh now uh what do we want to do we have now State uh for all of the inputs inside this form we don't have this handle form submit and we need to Define it as um as a property here right so let's do on submit let's call it on submit so so it will be easier and here on submit all right and now let's see if we have everything I think yes we do now uh if we use this uh component we want to uh pass the information uh like defaults about this uh um about this menu item right so let's do here I will pass here menu item and here we will use uh this as default so let's do menu item item image and now let's do the same for menu item uh name and here default for menu item description and here menu item base price we can add also another defaults like just in case let's add empty string in case some of those are null or something like this so we have something like this now let's go back to this menu items edit page um let's see uh um here we are fetching all of this here we have this handle form submit and here is our return it's super small right now here we need to under the button we need to put our new form so it's called menu item form yes let's put it like this and now we should be able to sit no we don't see and it's because we don't send there's an error because if you don't put menu item as a property it try to access the image which is uh empty and N so I'm going to add question marks here in case it's empty it will use those empty strings right but now let's go back to here and uh we want because this edit page we want to pass our menu item for now I will put null but the thing is here we fetch information about the menu item and we don't want to put it to State like this uh for each specific property instead I want to put it as one thing um because we need this only as one thing so let's do const and let's do menu item set menu item equals use State and default will be let's say null and here instead of doing all of those four I will do set menu item and here I will just put item that we find here and now we can use this menu item down here so let's do menu item like this and let's see if I refresh Let's see we have everything filled in if I go here everything is filled in so that is nice so now we have on inside our let's see uh menu items edit ID page we we use this form here let's do the same for the new uh new uh what it called new for creating new menu item but before I think I forgot about this handle form blah blah blah so let's do on submit and here we can pass our handle form submit function like this now let's go to our new page and here again I think we can just get rid of the whole form and here we are just going to use menu item form imported yes uh for our menu item it will be null and for our on submit we need to pass let's see handle form submit right and um let's see where we have this handle form submit here uh here we have as you can see state for everything and we don't need this anymore it's used somewhere it's used inside this handle form submit so that is a small problem let's get rid of the state and here inside this handle form submit uh we are trying to get image name description based price and so on so uh to to have it actually we need to have it from our um menu item form this component needs to pass this information here on submit so let's do um I will put this on submit into separate line I will convert this to an arrow function on submit let's put event and I want to also pass all of the information here all of the state description and base price like this so we have all of the information as a second param now if we go here uh to the handle form submit we have data here as the second param so we don't need to H grab data here from the state that doesn't exist anymore right so this works we need to fix the same thing on the edit page I guess let's scroll here here let's put data and let's get rid of this except here we have underscore ID that we need to uh add so um we don't we probably don't have it inside the in the uh component that is this form so I will remove this and um I'm going to redefine the data data equals and I want to put everything from the data as you can see we are creating a new object we are spreading the data information that um the form component passes and we also add this uh underscore ID and the ID comes from the URL and it's here all right so now let's see if this will still work uh we've done some refactoring and I think it works so uh let's see um if I added Pizza 1 let's change to Pizza 1 updated let's save saved Pizza 1 updated uh Works nice so now I want to add those um extra properties so you can have extra sizes and um other um let's say other prices for different sizes uh so so um we have here base price but I would like to add something like uh let me see let's first open this menu item form let's scroll down here and before the save button I want to have here extra sizes so we can add small medium large or something like this I'm going to put a Dave here uh with um a little bit of padding in color so let's do background Gray uh let's do 200 and inside I will put a label that will say um size this sizes and uh yeah uh let's add a little bit of padding like padding two and rounded medium at least so we have something like this let's add also margin bottom of two so we have something like this um and now um here um as you can see uh we don't have any sizes yet but we need to have a button so we can add them so add um add size specific price um or maybe add size uh like medium or large large something like this you can probably name it better uh all right and this button I would like this to be background of white so we have something like this could be a little bit smaller but I think that's okay for now uh maybe we can make this shorter add item size okay and um now we don't need to have any sizes but if you want you can click on it and you should see a row where you can add extra price for specific sizing so uh now let's see we have sizes here and um we have this button we need to add on click for this button right so something will happen uh when we click on it onclick and we need to add a type of uh button so it will not submit the form right on click what do we want to do on click we want to have a row where it will say you need to put a you need to put um name for the size and extra price uh so let's do this um on click we will run a function that will be called add size and we need to Define this function maybe let's do it here a function add size and this function will add a row so we need to have a state for sizes sizes sizes and set sizes sizes equals use and state and default will be empty array and if we want to add the size what it should do is it should res uh set sizes it should grab old sizes and old sizes and it should add a new size to the old sizes so let's do return we want to put here new array of old sizes and we want to add another size and the size will be a name that will be empty string and we will also have here price which will be Zero by default all right and uh now we have this let's try to print those sizes um here above the button so here let's do uh if uh sizes uh sizes length is bigger than zero let's do end and let's do sizes map and for each size we want to do parenthesis and let's put a div and I will put here an input for uh name so let's do placeholder for uh size size and name and another input for uh price so let's put the this type of number and here placeholder um extra price something like this and um now we don't use this yet but let's put this here so um maybe yeah let's put it here on the end value will be size of name and here value will be size of H price let's see if it's correct yes um let's put this um and the price will be actually not the total price so if you want large it will not be 12 if if the base price is 10 the price will be additional price in this scenario maybe we can name it um let's put it as extra maybe not extra price um Coast uh price I don't know let's keep it as a price for now uh all right so we have this uh now we will also need to have let's see if this button will work yeah it kind of does um here we have number uh let's put it as a text and we will style it later uh now I want this to be flexed this div uh something like this and let's add a gap of two yes and uh think this looks fine um now let's see we have two inputs and we can put size names uh I want to have labels for both of the inputs so let's put divs um so we can have left and right side for several HTML elements input one input two and let's put labels here label label first for size name and the second will be label for um um extra price here um yeah something like this and now now we have value but we don't have any on change right and we need to specify this as well so on change on change we'll grab an event and we want to to addit this specific size uh how we can do this we need to update our sizes uh so it will reflect it will update the whole state for sizes so we need to run set sizes and um we need to grab the previous sizes and I think it will be much easier to use a um separate function um it will be let's name this function just um edit size and let's put an arrow function here with event and we will pass the event and we want to also pass the index which size is it is it first second and so on so um I'm going to pass here index and I will pass it here edit size now the same thing here uh for the price so we need to have on change and event and let's do edit edit size with the event event and index and we know what we need to know what type of uh what we are changing here so let's put here price and here on the third par I will put uh name right now we need to Define this function event index and and the property so as do function uh edit size first we get event then we get index and then we have what type of property we are editing so this can be either name or price as a string so um first let's get new value const uh const const new value and we get it from event Target value then um we want to do Set uh set sizes and let's get previous uh sizes the old values and now uh we want to do Define new sizes and it will be a copy of previous uh size this we should be size this size this so now we have a copy of new SI oops size this and now we go to new sizes of this specific index and this specific property and we change this uh value to new value and now we just return here new sizes so it will update this new sizes so it will update uh with this function set sizes now let's check if we can put stuff here I think it works um so I can edit this and let's put another one test two 1 two three yeah I think it uh I think it works uh we should be able also to remove sides right so I need to have a a small button here so we can remove them uh let's scroll down here here we have those sizes uh let's add another div for the third column and here we will have a small button with class name background white and I I want to have an X here yeah something like this and I want everything to be aligned to the bottom so we have Flex here uh let's put items end so now it's aligned to the bottom but if I add margin bottom of two for this x it will be more like this all right um I think this this will work for now uh this button needs to be type of um button so it will not submit this form and let's see now we can add the on click uh for this button to remove a specific row so um if we want to uh remove let's do Arrow function we actually don't need an event here so let's do just um Arrow function like this and we just want to do set sizes let's grab the previous sizes and we want to do um all of the previous sizes except the one with the index of this index so how can we do this a simple way we can do something like this previous sizes filter and we can filter by value and index we can check that uh we need to put here inside filter we put an arrow function like this we get value of a specific uh size and index and we just check that index is uh is the same as index right um let me see uh we can probably make it simpler by putting this into a separate function so let's put this function here let's name it the remove uh size and the only thing we will need here is an index and let's put all of this code there uh so uh I'm going to cut from here and it was remove index of this specific index all right and now let's put the code here all right so we do set sizes we get the previous sizes and we return previous sizes but we first filter them by checking that the index of the size is the same well it should be different than the index that we want to remove because we want to re return here every size where the index is not the same as the index we want to remove I can probably rename it index to remove and here I can change this to index uh and here just Index right so now let's see if I put test one and extra price one test one test two extra price two let's add another one test three extra price three let's remove this one in the middle so now we have test one and test three this works nice and uh and I think it's uh it's okay um all right so now we have those sizes and we can remove them them we can add them and um and it seems to work fine maybe instead of this x we could have a trash icon so let's do search for trash and let's copy this one jsx and let's go to our icons icons here and let's do new file and let's call it just uh trash. JS and let's do export default function trash and uh let's do return here and let's put it here all right uh here we have those default class names I'm going to put it as a uh property class name and let's put it here class name and the default is this all right so now we have this icon class name and here we should have class with double s name um and now let's see I want to I have this trash icon I want to go to my form and here where we have sizes uh I want to change this x to a trash icon so let's put trash like this and now let's see yeah we have a trash icon it takes uh um some amount of space on the on the left and right and I would like to change it for the for this button let's change let's check if I can do p PX of uh zero if this will help yes it does let's change it to maybe two yeah I think this is uh better now right so um this looks fine now and uh maybe for the for this button I will add also a plus icon that would be nice right so let's go to Hero icons and let's search for plus and I think this one looks fine let's um go to our icons let's do new file and let's do plus. um export default function plus and let's put return and and here inside return let's put our SVG as always I'm going to put this class name as default with this uh with those classes here let's cut them from here let's put this as a property and let's put those defaults here now let's put our plus into menu item form so we have let's see extra price here we have this button for trash here we have the button for add item size so I will do something like this I going to put this plus here let's do plus yes and this I'm going to put it inside this pan so let's see how it looks like now add item size um I think it looks fine maybe this plus is a little bit too big but I can make it smaller with just um class name and I can assign classes like with of four and a of four and now it's smaller the only thing that I need to fix is here items Center so it will be centered and uh yeah now I think it looks fine um maybe we can have also for Save uh also icons and icons for all of those but we will fix it uh later uh now this uh sizes it takes um some space both here inside our HTML and we have even here three functions um so maybe it would be nice to have it as a separate component so I'm going to create a separate component for this um let's put it inside the layout and let's call this one menu item props uh or maybe price props that um JS and with capital M and I called it this way because uh here we have a here here we have sizes but later I'm going also to add the extras like extra pepperoni extra and so on and it will be a completely different group so let's first fix that we can have sizes here so let's do export default function and let's do it was called menu item price uh let's see price uh props price props maybe we can call it extras I don't know let's call it menu item price props let's return here and uh well first we want to paste all of this HTML here inside so let me see we have a button here and here we have this whole gray box so I'm going to just grab it like this let's cut this from here and let's put this here so as you can see it's like 40 lines already so it's good that we mov this now we need the state so let's uh scroll up here we will need those remove size edit size and add size as well so I'm going to put those functions here now we need to have state and let's go here and as you can see the state we need is this sizes and set sizes so let's get it uh here and now um I think this should work let's just try to use it uh here so let's use it uh here menu item props price props like this but we want this um this component to inform our form when something changes so I want to also have this uh sizes here as well so let's do sizes and set um sizes and set sizes here equals use State and default will be empty array and I'm going to pass those uh here so let's do here uh let's call those um props um let's do props uh equals and um we will have props and set props and props will be sizes sizes and here set props will be set sies all right and now let's go here inside and let's grab those props and set props and um instead of doing this sizes and set sizes I'm going to change this two uh set props here so let's do let's select all of those let's do set that props and um now let's go to our sizes let's see here we have those sizes and let's uh rename those to props and uh this is not like all the props it's just props uh it's just menu item price props but I think props is much shorter to ride and um okay now we have two columns here and um we should also rename this function at its size and add size to something more like add prop so let's edit this ad size to add prop and now let's re rename this edit size to let's see it's in two places to edit prop so we will have a better naming and now remove size let's rename this to um remove prop right and uh we have this all the sizes Let's uh rename it as well so I'm going to select um in on those two places and let's do old props all right and uh now we don't need this use State anymore let's go back here and let's see if this will work let's do one two three and test one extra price one test two extra price two test three extra price three let's remove the middle one and looks like it works so now let's go to menu item price no let's keep here here on the form and and um it works but um if we go to menu item price props we have those warding about the prices and um maybe we can um first fix the sizes this whole label here let's have it as a name and let's grab it as a property here name of this uh price prop group and now let's go back here to menu item form and this uh price props will be called name with sizes sizes like this so we have sizes here and um we have here sizes but we also have a button that says um add item size um let's add add label add label and here I will have something like um um add add item size and it will be text for the button let's go here and add label and let's use this add label here so here let's do add label and uh now we have labels for here extra price and the name I think we can just rename this size name to just name and we are golden name and extra price all right and uh now you may thinking why we are doing this why we make it so generic and it's because now we can do add another group and it will have a name of uh let's say a um extra ingredients and let's put this like this and now as you can see we can add extra ingredients let's also add here uh stuff like add label um add ingredients uh prices so something like this and we need state for this um so like we have wave sizes and site sizes uh we will have uh something like like extra ingredient in ingredient prices and set extra ingredient prices you stay default will be empty array let's pass them down here so let's the props will be extra ingredient prices and set props will be set extra ingredient prices right uh I'm going to put this ending here so it will be uh so it will look nicer this thing here and now uh let's see if I crush and we have it here uh I'm going to put three here and maybe two here let's see if this work work uh size small extra price zero uh now the size will be medium extra price uh two and here large extra price four extra ingredients let's do I don't know cheese extra price uh one and here maybe ham and let's do extra price one one as well uh so uh this um looks nice the only thing is that we are not saving it so we have this uh on submit but we are not passing this um to our information about the item so we can add it like this uh sizes and extra ingredient prices maybe we can actually name uh this extra ingredients prices um or maybe let's keep it this way I don't know it doesn't hurt to have longer names so um I need to put maybe this into separate line so we will have more uh spacing and uh let's put maybe this here no it can be like this let's put this here and this here and this here so it will be easier to to read it all right so uh we have it now we need to handle this sizes and extra ingredients inside our um this uh edit page so for example this inside our handle form submit data we are grabbing all of the data and we are sending this to API menu items uh put if we are updating and post if we if we create a new let's go now to this uh API uh here API uh menu items route and we have all of this data here and here and we create it or we update this so we need to go to this menu item and we need to actually update here so we will have um sizes and we also need to have this uh what was it called uh let's go here it was called extra ingredient prices and maybe we could actually name it to like sizes prices or yeah let's do sizes or maybe I don't know extra ingredient prices here we have wave prices and on the another part we on the sizes we have no it doesn't really matter let's do sizes and xray gradient prices so here sizes and extra in gradient prices all right and we need to specify how those will look like right so I will do an another schema just for those two let's do const uh and it will be extra prices and or extra price and extra price will be a schema where we we where uh we will have like a name that will be a string and price that will be a number and uh now here in sizes IT sizes will have type of extra price that is an um and sorry the type will be an array of extra prices schema and maybe let's rename it to extra price schema and let's put here extra price schema and same for the extra ingredient prices the type of this field will be an array of extra prices schema extra price schema right now I need to restart my environment so we will have those new changes inside our uh menu item schema and um let's see if they if it will be saved so now if I hit uh save saving this this tasty item saved okay uh I don't even remember which one was it I think it was Pizza 1 no nothing saved here Pizza 2 Nothing pizza 3 nothing okay I don't see anything let's see if it's saved into database all right so let's go database and let's see browse Collections and let's see if we have here menu items and let's see if any of those has those extra ingredients here we have some extra ingredients so we have sizes and we have um here medium price two large price four yeah so this works nice so we have it on let's see which item Pizza to updated let's go Pizza to update so this one has it inside the database but it's not displayed let's see why H let's go to our menu item form and uh let's see we are grabbing this menu item but uh we don't set the defaults as we do with image name we don't do this for uh sizes so let's do here menu item uh sizes or default would be empty array and here the same thing uh menu item and question mark Dot and extra ingredient prices or or default will be Mt right so uh this is like super long now maybe we can make it um a little bit shorter let's see if I make it maybe something like uh this yeah so it will be easy easier to read and now let's see if I refresh will I get my sizes yeah and now now a nice think will be so we can open and close those uh sections here so as you remember this one is called menu item price props and here we have this uh label here maybe first we can also make this label this one a little bit bigger or a little bit darker so let's do class name and let's do maybe don't call it uh label let's put a div and let's put an A3 here and it will say our what was it I think it was label um no it's a name it's a name so we have something like this sizes um let's make it more grayish so let's do class name uh text Gray of um let's do 700 something like this let's see sizes yes and I want to have a button maybe next to sizes that will do close and open so um I want to have like a toggle button here and when I click it it will uh open and close this uh section I want this to be next to this H frame so on this div I'm going to do flex and uh I'm going to do gap of one right so uh this button takes too much space so the first thing is that I going I need to put type of uh sorry not here type of uh button on it button and uh what else I need to put also some class names Let Me Maybe put those class names here I will put class names here type here and let's put this here and this here and now the class names will be um I want this um button to be shorter so let's do display of flex um colume is the flex colume no not Flex this is Direction Flex inline or how is it called inline Flex the class name is called inline flex and now I want to make it uh smaller the the button so I want to shrink so as the shrink uh this didn't help maybe it will help if we add grow on this A3 no it didn't and let's try with putting another div and let's put this uh button inside this div okay now it's like uh Now button is smaller so that is good and um let's remove this shrink let's see yeah the shrink is not needed uh I want to uh make smaller padding so let's do padding on every side of just one and now I would like to have a toggle icon for up and down and um so let's do maybe search for res size no up up and we have something like uh this this looks nice I want to have something like this uh up and down um so we can toggle this or we can have icons like this uh Chevron up and Chevron down um I think I will take those um we have this one and then we need to have another one to open so we need to Chevron up and Chevron down let's add those um icons inside the components icons let's call this one sh Chevron down. JS let's see if I uh call it correctly uh let's see yes and let's do here um export default function sh run down and let's do a return here and let's paste this now we need to grab those class names in case we want to change something here let's put class name and now let's put our class name here as default let's do the same for Chevron down let's do new f file Chevron down. JS no uh this time we need to do up sorry Chevron upjs export default function shevron um up and let's do return and inside we need to have a Chevron up icon here so let's search for this one copy jsx let's put it here and for those uh class names that we get here let's use it as a property called class name that we will grab here uh class uh class name and the default will be this so now it looks like this and now let's use it let's go to menu item price props here we have the toogle and I want to have first the Chevron down icon Chevron down icon let's see how this will look like uh here yeah it looks like this uh I want to add background uh of white here on this uh yes now we have Flex let's do items Center so it looks like this um well it looks um fine but maybe we can put this uh sizes um uh into this button that would be nice right let's put this uh label here into a span and we don't need this H3 anymore and we don't need this div and we probably don't need this uh div for the Flex so we can put this like this now we have the sizes like this and um I don't want to have any background here and I don't need to have any border so let's do border zero yes and I want this to be align to the left so let's do justify start so we have something like this now if I click on it nothing happens and if I click I want to toggle if it's open open or not let's create a state for this is open and set is open and equals use State and the default will be false so by default it will be closed use State let's import this one from react and now here for the Chevron let's do first is open if it's open then we want to have an icon to close it so let's do chevron uh up and if it's not so let's we can do not is open and we can do the this and Chevron down like this so now it should be closed but we still see everything here and this is because we need to put another Dave here that will just uh have all of this inside so let's put this all of this into this Dave and the thing is that we need to make this div hidden uh we need to make this div hidden if it's is open is false so here I would do is open uh if it's open we will have a class name block other wise we have class name hidden so now as you can see it's hidden but if I click it nothing happens because the button doesn't have any on click let's the button on click let's do Arrow function and let's do set is open and I'm just going to do something like this I will go get the previous value and I will just return the opposite so now if I click yeah it opens and closes so that is nice um maybe I can also put a number of how many sizes and how many extra ingent prices we have here so um here we have this name let's also another um span here and in par parenthesis we will have a props length so let's do um here props length uh like this I'll add here question marks just in case so we have extra sizes here of three and here extra ingredients of two that so that looks nice um and if I go and edit for example this one it will say sizes zero extra ingredients zero um yeah but uh it works and it looks much nicer now so now we have uh those sizes and extra ingredients and and this is because for example um Pizza 2 will have um I will remove this updated Pizza 2 will have a base price of 12 but if you want to have a small then it will be 12 but if you want to have a medium it will be 12 + 2 so 14 for medium and then $16 for large pizza let's hit save let's see if it still saves yes uh Works nice so uh now this uh Works uh we have menu items and uh we can add and remove those extra properties the next thing would be so we can actually remove delete menu items if I want to delete Pizza free uh how can I do this and same with categories if I want to delete this one I cannot do this and the one small thing I forgot about is that when you edit an menu item uh we need to assign a category right so for example test category or something like this we don't have any category here so now we will first do category and then delete on both uh menu items and categories and then we can go to users and other means all right so now let's fix so we can actually delete categories and we can Del so we can also delete the menu items so um for categories I think uh we can do something like this first we will change this to existing categories and then we will have a table where you can click the name or you can click edit or delete button so uh let me go first to categories so let's open uh category page let's see categories page yes and now let's see for the label saying uh where is it edit category let's change it to existing categories existing categories yes and uh yeah here we have existing categories and uh now maybe we can do something like a table um out of it or let's do maybe rows and but we will have an edit and delete button on the right side so uh here we have a button let's change this to a div so uh now we have Dives uh we need to have some uh extra class names here let's do background of gray uh 100 let's see how this will look like yeah I think it looks fine I'm going to remove this cursor pointer from from this and uh so those are not clickable anymore uh Let me refresh let's see but um yeah they are clickable because they have this on click but we'll move it in a in a second uh here we can have this category name and I'm going to move this on click to this uh to this span so let's move it here and now if I just click the row uh nothing happens but if I click H the name it moves here so I can edit this all right so um now uh we can do something like this um I'm going to add here cursor pointer so let's see here we have the span let's add the class names here so let's do a class name and let's add um H underline no on Hover we will have underline but I want to also have cursor of type pointer let's see yeah so I can overover and I can click on them to edit Here and Now on the right side I want to have like two uh buttons edit and delete so um here we have first the span then let's add two buttons button of type uh type button the first one will be added and the second will be delete button here the elite so now we have something like this uh I don't like that those take so much space so I will put those two into uh div like this now let's see uh now it looks like this um for this div here I'm going to put the well we have Flex here uh but um well let's see first I'm going to change this span maybe to a div oops uh to a div and I'm going to add grow here so it will grow to as much of space as possible all right and uh now for those two buttons uh I want to add some space for those two and so here on this one I'm going to add the flex and gap of one and now they are next to each other so that is much better and uh now uh if I click uh edit I want to edit and if I quickly click delete I want to delete it uh I think I will remove this when I click on the uh name it will uh edit and instead I'm going to move it only to the edit button so let's let me grab this on click I'm going to cut it from here and let me just reformat this the name will be on here and this uh edit will go like this and here we are going to add our on click so now I can I need to also remove those underlines on Hover let's remove underlines and cursor pointer from this uh name and now if I click edit uh we can edit here um all right now what else uh is uh I can edit those uh but I also want to be able to delete those so um let's see uh we have this button type button but I want to add something like um delete so let's do here on click and this will be a database uh request right uh so we need to have a function that will be handle uh Delete uh button so maybe here let's do a function handle delete click and for a specific category we want to know what is this category ID and um let's try to do this and here inside I will just for now only do console log of this ID now down here let's do on click uh I'm going to do handle delete click and uh Let's see we need to have ID so let's do category doore ID and now let's see if I do inspect here let's do console and we have some errors here but we'll fix it later delete and I see the ID all right so now let's see uh Let's do let's send a request to our API so let's do not Axel sorry Fetch and it will go to/ API slash uh I think it will be delete not delete SL API SL categories and now here let's do method will be delete and uh I think uh that's all here I'm going also to add the um here undd equals uh and now let's add this underscore so this time we are going to add this to a query let's add a weight here and as Sync here and well after it's done what do we want to do we maybe we want to also add the react toes here so let's see I'm going to add the let's just call it promise equals new promise resolve reject Arrow function and uh let's put this thing inside and I need to add a think here const equals uh const uh response equals this and now if response is okay then we are doing result resolve um resolve otherwise else we will do reject all right so we have our promise now let's do um toast toast uh promise let's put our promise here and here let's do uh loading will be deleting dot dot dot and then if success it will say deleted and then if error it will say just error yeah and we need to add a weight here and what else we also need to do uh we need to refresh so maybe even here before we need to fetch all the categories once again so we just run this fetch categories so let's do fetch uh categories and this should do the trick uh but this should run after uh after promise is complete so maybe let's put it here fetch categories all right uh now let's see we don't have uh Delete um handled for this/ API SL categories so let's uh fix it let's go to SL API slash categories and here we need to do export a sync function uh Delete delete and uh now let's first connect to the database and then I need to get uh our query so I think we need to use request here so as the request query and I don't know how it looks like so let's do just conso log on this and let's return response Json of true so we will see how it looks like inside the our console here so if I click delete here uh it says undefined so uh this looks like it's undefined let's see if we can do like this as a function let's see delete and no we get an a query we get an error request query is not a function let's check for something called search PS all right let's scroll to the bottom if I click delete it's uh undefined let's search then let's check for just request uh search if I click here still undefined maybe if I uh do like this delete no still undefine I think it's inside request URL and then search uh search PS let's see like this if I click delete undefined but uh if we just do URL then if I click delete and then we have something okay then let's do something like this cons URL equals equals new URL and let's do request url url url like this and now I can do something like this because URL is an object now I can do search BMS and let's see how this will look like this Del it and as you can see we have URL search bars object with this ID so we can probably do something like this const uh ID equals uh url. search bars. get andore ID and now let's try to console log only this underscore ID to see if it works let's delete this one here and our underscore ID is displayed so now we want to just delete uh category of this uh of this underscore ID so let's do delete uh one by this underscore ID and let's add the wait here and I think that should be it so um let me see I'm going to make it a little bit smaller let's try to delete Test 4ore 2 I will first uh refresh just to be sure that everything works here delete uh let's delete Test 4ore 2 delete oh and it's deleted so it worked if I refresh yeah everything seems to work we have some warnings here but I'm going to fix them later let's go back to categories page and I want to fix some styling to make those labels in the middle so let's see here I'm going to do items send Center and now let's see yeah now those are centered so that is uh nice right so now we can edit and uh edit and delete categories maybe here it would be nice so if you addit a category so for example this one and actually you don't want to edit uh instead you would like to uh create a new one so instead of clicking on on this categories page or you actually need to go to First profile and then categories to have a form for creating a new category and we will have a button somewhere here consel consel editing so uh let me scroll up a little bit and and let's see uh here we have this uh form and um let's see here we have this button and maybe I will do another uh button here that will say uh cancel yes and to make those next to each other I will add a gap of uh one with flex maybe Gap two let's see yeah I think this uh this will work so uh here we have this cancel button and I'm going just to add a simple on click the only thing we need to change here is uh Set uh edited category to null yeah so let's click this one whoops it uh didn't work as I wanted because we forgot to add type of button and we actually submitted the form instead so let's do this onclick this and let's put cancel here yeah so let me refresh and let's see let's edit this test uh 3 to one edit let's do cancel and it worked it canell but we still have this old name here so um I'm going to put this into an arrow function with those uh with extra stuff inside so let's do like uh let's see let's do like this let's put this here and let's also reset this set category name to empty string so now let me refresh if I want to edit this one we have update category test 3 2 1 and here we have the name so we can change it but if I do click cancel uh it disappeared and we can add the new one let's add the new one test five create it's created here let's edit and let's do test five updated let's hit update and we have it test five updated here so this works we can edit delete categories now let's go to menu items and uh here we have let's go to Pizza one with this MacBook image and here I would like to have a button to be able to delete um to delete a menu item first let's go to API menu uh menu items menu uh items uh route and I'm going to prepare a route for delete so is the assn function theit and I'm going to essentially do the same that we did for categories so I'm going to copy all of it but we are not going to delete a category and instead we are going to delete menu item so that's the only thing that I changed here all right so now let's go to our page for uh menu item so let's go to menu item page uh I want to go to the edit page so let's see here's the edit page menu item edit page and as you can see we are using a form here um under this form I'm going to add a button that will be delete uh this menu item so here we have it's super large and um with this div I'm going to add Max withd of medium let's do MX Autos it will be centered so margin top of four so we will have some uh spacing and uh well actually I would like this to um start here and end here um but never mind uh we can fix it another way I would like this to take only um or maybe we can have it this big I don't really know now I want this one to be smaller so uh inside this div let's add another div that will have some border border and let's put this button instead for this one I'm going to make it Max wave of extra small and the margin left of Auto now let's see now it's this big and to make it even smaller I will add more padding left of four now let's see yeah now those are identical so uh let's remove this border and we can change this one to be Xs and let's do ml Auto margin top of four ping left of uh four and we don't need this one and we need only one div well no actually not because first needs to be Center so let's put the this Dave bag back and here MX Auto yes and we don't need padding uh left of four here we only need to have uh let's see here we should have medium let's do medium and now it's correct so we actually need two divs all right so we have this delete menu item here and uh when I click this one I want to do almost the same thing that we do with categories so uh let's add the function delete uh handle handle delete click and I only need my ID here or actually I don't need ID because I have it uh here this here is the ID so I don't need this pum here uh I just need to do a fetch request to slash uh Slash API slash uh here we have menu items and the method will be delete delete and what else do we need here I think that's it I'm going to add ASN here and uh well uh we can do like this we need to add our underscore ID and it's inside the ID now uh I'm going to add um this uh put it as a promise so let's do promise equals new promise and let's put this inside here and let's see let's add a weight here let's do const response equals this and now let's do if um response okay then we will do resolve uh otherwise else we will do reject reject and this should work we have our promise let's do toast uh to post uh promise and Let's do let's put our prise here and uh then we will add loading it will say deleting do do Dot and if success it will say deleted and if error it will say uh error yeah we need to add a wait here and uh what else after deleting we want to uh redirect so let's set this redirect to items to True uh um maybe here all right so uh Pizza one updated uh let's try to delete this one delete this menu item if I click on this one nothing happened it's because we don't use this function yet let's scroll to the button let's put this text here this here and let's add on click and let's put this function like this Let me refresh and now if I click delete this menu item error something didn't work let's see network and let's see what went wrong wrong menu items uh okay I'm putting ID like this without doing ID equals okay and now it should work let's delete this menu item still an error let's see what's the problem let's see uh request is not defined all right let's go to our menu items route okay I forgot about putting request here now delete deleted and now Pizza one is not uh visible here all right so um this uh worked uh we have only Pizza 2 and pizza 3 here so that is nice and so we can now edit and delete both categories and menu items maybe I will put like real pizzas here we will fix it in a moment but the next part will be actually so we can have users and admins inside our users page right so I think this is the next thing we are going to do before we will go into users there's one small thing I would like to fix um as you can see if we click on this delete button it will delete this category and same if we click uh this it will delete this uh menu item I think it would be nice to have some kind of confirmation not if you just accidentally click this one so um in other of my projects I'm doing like sweet alert confirmation popups and we can do this uh here as as well but uh I think we can have something uh else here we can Implement something else so I think that um in uh this project I'm going to implement um a confirmation button uh without using any third party Library so we have a delete button both here and on categories and I'm going to create uh I'm going to create a a components for this so let's see inside components um we have icons layout menu maybe I will do here inside components I will do delete button delete button.js and let's do export default function delete button and inside um I want to have properties like label uh label for the delete button what else do I want to have let's maybe first do this delete but button so let's go to the uh let's go to the menu items route and not menu items right um let's go to uh menu editing uh page for menu item so we have this delete this uh delete this menu item and I'm going to uh just copy this uh button it's just a regular button so let's go to our delete button let's put a button here uh but button like this let's do type of button just in case and here let's put a label now let's use this one also we will need also like on confirm um or maybe let's do on delete okay and uh and then we will not do this yet we will not use on delete yet but we will have it let's go back to this uh page where we have this edit page for the menu item if I go here and here I have this button here instead of having this button I'm going to use my uh Delete uh button delete button and let's add label to be this so let's put label like this and uh let's also we don't need a closing tag here we can just put it like this and handle theet click we need we want to pass it as well and I'm going to to pass it as um on delete handle uh Delete click okay and uh now we have this button here yeah it looks fine maybe we can delete the let's see uh margin top from 4 to two yeah and let's go to the delete button as you know um now if I click nothing should happen because as you can see this on delete is not implemented here we have just a button with label no onclick uh property on this one so what I want to do first is uh when you click this button it will show a confirmation so we need to have a state for this show uh confirm show confirmation I don't know if should be show confirm maybe show confirm and set show confirm equals use State and from react default will be false and when you click on this one on click it will just run an arrow function doing set show confirm to true and now if um if show confirm instead of this button we will return here uh div and that will be type of uh Flex so let's do Flex here and let's do gap of two and we will have here two buttons button uh of type uh button let's do two and the first one will be cancel and uh canel and the second one will be yes delete and I'm going to add a class name here of primary so it will be redish so now let's see if I click this one you can see we have two buttons cancel and yes has delete if you let's put this cancel text here uh let's add on click if you click cancel we are going to do set shenir to false so if I click on this one we go back to this but if I click yes delete which should be red uh let's see why it's not let's go to globals and we have a button um it should have a submit let's also do the same that button with class name primary will be also red yes and um this should work um maybe it will be nice to have some kind of text above here so I'm going to put another div let's put this uh here inside but here I'm going to add an I know H4 do you or let's do div do you or maybe are you sure something like this are you sure you want to delete delete delete question mark and let's add some margin top of one here and uh yeah now we have something like this delete are you sure you want to delete yes delete or cancel now this delete uh is delete doesn't do anything we need to add on click for this one so let's fix type here class name here and here let's do on click and let's add our uh on delete as you can see so let's put on delete here and let's maybe try let's maybe not try here yet but instead let's do the same for categories we have this delete let's go to categories page and where is our delete button delete here instead of the button I'm going to use a delete button uh yes and our label will be uh Delete delete or maybe we can put it as a string like this delete and on delete I want to run this handle delete something handle delete click handle delete click but we need uh our underscore ID so to fix it I'm going to um add Arrow function here and here I'm going to put my category underscore ID now let's see uh maybe I will reformat this like this and this will go here if I click here whoops uh well it doesn't look that good because we don't have enough space here um so uh how can I how can I fix it h we can make it uh on the top of the screen maybe so uh let me go back to this delete button and instead of putting this in place as we have it now uh let's do something like this uh we will have this first div will be uh our popup in the middle of the screen so let's do class name and let's do position fixed and let's do maybe I don't know top zero or something like this yeah so now it's here uh let's now do H there the fix top zero left uh zero okay so now it should should be top left corner yes uh let's add some background of uh let's do background of I don't know white let's add some padding of four and rounded the corners of uh medium or maybe large so now we have a white box here but um well let's see uh instead of having it here I want this to be centered so I'm going to put a div another div and with some class names and it will be parent for this white box and here in this Dave I'm going to put uh flex and items uh items Center let's see uh didn't do anything but if we add half of full and we will make it absolute and inser zero uh like this let's see still nothing let me inspect this one so this uh this takes all of the space and this one one is here we can just remove this uh fixed and now we have this in the middle our box but we need to add justify justify Center as well so now it's in the middle and if we add maybe let's change this to fixed fixed and we can also add some background of uh black 50% so now we have something like this and uh this should work but let's change the is to maybe 90% or maybe 80 yeah this uh looks fine um maybe I want also to here is delete H let's add here no breaking space so it will be in one line and I think this works fine now we can hit conso delete conso and let's see on the menu items I think it should be the same way uh Delete console delete conso yeah it works fine let's see here delete consel let's delete one category maybe this one test uh just test we have two test categories yes delete deleted but we still see this popup so that is uh that is not good um let's see um when you click yes delete uh we should run this function that is provided as a property but we should also uh close this popup so let's do let's do Arrow function like this let's run on delete but let's also show do set show confirm to false yes and let's maybe put this into separate lines like this so it will be easier to follow now we have another test uh a category here test without a number let's try to delete this one yeah everything worked so now we have a nice popups um Let Me Maybe create a menu item with test one 2 3 4 let's save this one uh it doesn't have an image let's Del delete this one delete yes delete deleted and everything works nice the next thing before we will go to users we actually need to fix one more prank and this is category for menu items so this is what I'm going to fix next so now let's fix that we can do select categories on inside this form so we have it inside menu uh item form and we just need to put a category here right so let's see uh we have name description price and uh we need to put category somewhere maybe between price and description here we have description uh here let's also put label for our category and here let's put a select select for our categories right so we need to have a list of all possible categories uh let's go up here here and let's add just a use effect to fetch all of the categories Arrow function here and now dependencies and we can just do fetch on API categories to fetch all of the categories because we already have this end point let's do then and with the response we need to do response Json and then with this uh Json uh that we get it's actually just uh category let's put Cuts maybe not categories and with this categories we want to save them somewhere inside the our state here so let the const and let's do categories and set categories and here the default will be actually first empty array all right uh so we have categories let's put them to our state set categories and let's do categories from our Json here uh response from the database now let's see uh we have category here select but uh it doesn't uh work yet um let's go here to our select uh where is it here we have select but we don't have any options let's do something like this if categories uh do uh question mark. length is bigger than zero then let's do category map and for each category let's do parenthesis and let's put an option that will be like this category name here and when it comes to Value I want only category ID here so now we have uh something like this as you can see but I want to style our select so let's go to our globals and here we have four buttons here we have four inputs uh so let me add here select as well so now we have something like this test two and so on um now when I save it let's go to menu item form um well before I will save it there is no uh State for the selected category right so let's uh let's have it maybe here const category and set category and let's say it will be also as pass like this from the menu item if we have any all right uh and so we have it now let's scroll back to our select let's put the value will be uh category and on change we will have a event and let's do set category and event Target value as always right so now let's see can I change the categories yes I can and uh now let's see how it's uh being saved so when we save something we just do this on submit and we send all of the information let's just add category here to all of the information from the form and now we need to go to our API for categories uh route and here for both put and post Let's see we just send uh for post here we this is for categories I want to have for menu items menu uh item API route it's a menu item uh route like this here we are sending all of the data like this and I want to we send all of the data so let's go to menu item model and let's just add the category here so uh maybe here after description let's add category and category you may think it will be a string here but actually it's an ID right we are sending an ID so let's do do something like this let's grab mongus and the types and let's do object ID right this should do the work and now let's see if this will be saved so let's go to menu items let's go to Pizza 2 and category let's pick test five let's save this one let's go back here no it didn't work uh let's see why uh I will go to the database let's go to menu items and let's see uh base price I know because I forgot to restart my environment so let's restart it and now let's see here on Pizza 2 I pick test five uh save saved okay let's open pizza 2 once again and it's test five okay uh I'm going to create maybe a more real category now pizzas or maybe just pizza let's create this category let's go to menu items let's go to Pizza 2 and let's change this one to Pizza okay and now same for this one let's change it to Pizza let's save yeah and uh it seems like it worked another thing that you may want to fix uh or add um another thing uh that would be a cool feature is that you cannot delete categories that has that have some menu items so for example Pizza category shouldn't be deletable because we have two menu items that are inside this category but that's just and nice to have uh think and it's not that crucial uh for the basic project that we're building now uh so we are done here and I think the next step will be actually to fix now our users and admins we should also add probably orders uh so we can see all of the orders so let's go to user tabs and let's add here some orders so I'm going to just duplicate duplicate users and let's do orders and let's do here if orders then it's active and the URL is orders all right so now we have something like this uh we don't have enough space here everything should be a little bit wider so uh let's make it wider let's go to all of those pages and let's fix it let's go to categories page let's see uh categories page medium let's change it to large and let's go also so to menu items uh here and let's see Max with medium let's change it to large and this one for the new page uh let's see uh here let's do Max with large and the profile the same thing here let's scroll up and Max with let's do large and now I think that's all let's see no profile profile looks fine and uh I think it should be even wider but uh that's okay um let's uh or actually let's fix it let's do XL extra large so now it's this big and maybe we can do 2 XL so we have something like this uh for categories let's go to categories page and let's change this one to 2XL to make it wider menu items let's go to menu items page here let's see we will have a Max with 2 XL yeah and if I edit or delete this looks almost fine we need to change this to uh to XL and same for new let's do two XL Max with and let's see categories profile categories menu items and if I click here to add one looks fine except this form this form is too narrow so I'm going to make it a little bit wider um form. JS menu item form here and let's change this one Max Swift to to XL and uh now we have something like this so uh it looks nice right uh so we can still edit categories and we can also edit uh menu items right uh we can even even add some icons if we want to all of those buttons uh but uh I will fix maybe later now let's go into uh fixing users and admins all right so now it would be nice to fix uh users so uh for now when we click users we get just 44 um page not found and if you're an admin and you go to users I would like to um an admin to see all of the users like a table of users so you can edit them and uh Delete maybe not delete but edit them like all the profile information uh like this and and um select if a user is uh admin or not right so uh first maybe let's create a page for users uh so uh let's close this categories menu items profile we need inside up a directory called um users and inside we need to have page JS file so let's do page JS and inside let's do export default function and and let's call it users page and I think we can just do return here with um section and let's add some class names like margin top of U margin top of eight yes let's see uh let's put test here test users so we can see everything yes and now we want to make this section A Max wave of 2 XL and MX outo so it will be centered and we will start with uh user uh tabs like this so we will have our tabs here now I don't know why but I see only profile let's go to users if I click users I see only profile let's see why let's go to user tabs and let's see how this looks like so here we have a users and the wall and if I'm on the users page I see only profile let's see why so if it's admin then I see the rest so I need to pass um admin is admin to true but uh first I want to hear check if you are an actually an admin so as on the another Pages we are going to grab the data and loading from use profile and um let's do if loading then let's do uh return loading user info we have it in several places so later I think we can change it so it will be a preloader or something like this now if you are not data admin so it will return uh not not an admin right and now let's see we have an error uh because we need to have use client here on the top use client right uh now we have users here so um well let's see maybe we can do something like we can print a a table like this one uh for users so we can edit them uh so let's start with this uh first we are going to need uh to have a use effect so let's do use effect here from react and uh we need to have we need to grab users so let's the FH request to/ API SL users we don't have this endpoint yet but we are going to uh fix it so let's go to here let's see API let's do new directory called the users and inside we will need to have route JS so let's go new fine route JS and uh now let's see we have a route and we want to have export ass sync function get to get all of the users right so um no return here yet first we need to H connect to our database so let's do mongos connect and here as always process EnV URL we are connected to the database now what do we want to do just return all of the users um do we have um model for user let's see models yes we do so let's do just return response Json and we want to put users here so let's maybe grab them here users equals a wait and let's do user import this one let's do just find we want to find all of the users so no pars here and we can just put users here you can also put like the whole a weight uh thing here inside it doesn't really matter it should just work now let's go back to the users page and uh let's see uh when we get the those users let's do then with the response we are going to do response Json and this is an assing function so we need to do then or we need to do await and uh well here um with have this then we will have our uh users here so we want to save those users to estate so let's put estate here let's do users Set uh oops set users equals here use State let's import use state from react default will be empty aray now let's do set users uh to our users from our Json and uh this should work now users yeah now it's correct and now we want to print those users and maybe somewhere here under those user tabs so let's do something like this let's check first if users uh length is bigger than zero then let's do users map and we want to for each user let's do parenthesis and for each user let's put a div with some class names here right and um well for now I will put background gray 300 rounded large let's do margin bottom of two and uh let's add some padding padding of four and now for each I want to put uh first span with a user name if we have then another span with user uh let's say email all right now I'm going to put here flex and uh well and then I'm going to do simp like this first I will put a div with those two spans inside and then I will do another div with a button to let's say edit a user now let's see how this will look like let's go back to users here and it looks terrible uh but no don't worry we can fix it first on this I'm going to add some margin top of eight to have some spacing yes I think that's better now the background I would like this to be lighter like this one so let's see how we can do this let's try with 100 yeah I think this works nice now we have too much padding here I think so let let's remove this or maybe let's change this padding to one and let's see yeah I think that's much better uh and now I want to have pading only only on the sides let's see on the categories yes only on the sides uh for this main Dave here so let's do padding one but padding on the sides will be four and uh yeah now I want to also add the items Center so everything will be in the middle yes that's cool and I want to add a gap between items of four yes and now we have those uh names next to im as you can see but we can fix it by putting here another flex and gap of four so we have some spacing uh now um here we don't have names for the those users uh so I'm going to do username or no name name something like this uh so we have no name here maybe it could be like a uh italic text uh so let's see uh I'm going to do if we have username uh then we are going to put username here inside a span so let's put this uh here but if we don't uh wait a second and I'm going to put it like this if we have let's remove it if we have usern name let's do then and let's do a span here inside with user. name all right and let's convert this one to Boolean and now here if we don't have user name so one exclamation mark let's do then and let's do span oops span uh we we will not have username so let's put no name but we will have different classes in this and in this in this one I want to put the italic italic text so it's yeah like this all right and um maybe for both those uh I'm going to put both two Alternatives into a div so I can add a text Gray of uh 500 so uh the name is more grayish maybe we can make it like 700 uh but this one uh let's see no name will be removed here and for EMA it will be more even more grayish so let's do text Gray 500 let's see 300 uh I think that's too too much of a gray color and uh and I don't really like it and another thing is that it will be much nicer to have everything in line right so um let's see for now we have this main div that holds a whole row let's change this Flex to a grid and let's do grid Columns of three so now we have something like this and uh let's fix it a little bit inside this grid calls three we want to have three items so this is first item this is second item and we want to have three items or you know what actually I want to do something else uh instead of doing free columns on the same WID I will put this back to flex and um first I will remove those columns and now um the inside this Flex I will have two parts the first part will be with texts and the second will be with buttons and uh for the texts I'm going to add this grow so the texts take as much of the space as possible all the way here to the edit buttons and now instead of this one being flexed I'm going to put it as grid and grid columns two and the first will be with name and the second will be with email and now as you can see everything is in line and we have we have grid columns too but we can add that if the screen is big enough we can do grid columns three and those will be now closer to each other all right and we can make it a little darker here let's do maybe 400 500 here and uh let's see yes this looks nice and uh maybe on this one let's do 900 so it's almost like Black uh all right so this works we have this button that doesn't do anything yet but we will fix it in a in a second so um we have this edit button uh but I think that we should not have that button but uh we should have it as a link instead so when you click it you should see a page like this for a specific user so um let's do a link so let's do link and now let's add C and the C will be slash users slash and then ID of the user so let the user doore ID now let's see uh this looks now a little bit worse and this is because we don't have this button class on the on the on this link so let's put this like this and let's the class name here of a button let's see yeah that's much better and if I click on one I'm redirected to this page that we get 44 on so uh let me go here to the uh let's close API let's see open users inside we need to put uh we have users and then we have ID we don't have edit as we had with Cate with menu items we have only just slash and then ID so let's do a new category and let's put ID like this and inside we want to put page JS so let's do page JS and inside let's do export default function edit user page let's name it like this and inside let's put return and we want to have let's say a section with some class names because we are going to need this margin top of eight uh M Max uh Auto and Max we of 2XL as we do everywhere else and now uh we need to have our user tabs and let's put is admin to true and now on the top here as always we need to know if it's loading user information profile information and we want to have data from that uh use profile and here if it's loading we want to do uh load L loading low whoops low link user profile and if it's not an admin so let's do not whoops not data admin then we are want to do return not uh an admin all right so uh now let's see we will need to have our use uh client on the top and now we have our tabs here as you can see users is not selected and this is because we need to go inside here and let's see for the users to be selected the path needs to be users uh let's change that it will just include users so let's do path uh includes um users SL users and that's it so now it's selected now let's go back to our edit user page let's put uh let's put a div with some class names let's do margin top of eight and inside where will have user form user info form so we can edit a user and now the thing is I want the form to be exactly this so I want to edit any user and edit anything with the user right so I need to go to the profile page and I need to create a component out of this so let's see uh let's go to profile we have this profile page and let's see we have this big form here and it's ends here and it starts here it's a form uh but uh this form element it includes only uh only this part the right part and the editable image is here so um I actually want to have this whole div that starts here and I want to have both the editable image and the form here so uh I'm going to fix it I'm going to put this profile form thing into a separate component so let me grab all of this let's see where does it end here let's cut it from here now we don't have anything here uh now we can put it somewhere else so let's see let's put inside components and uh where do we have it uh let's put maybe inside layout we have one form for menu item let's put another one here so maybe we could put a directory called forms I don't know uh let's put this here let's put user form. JS and here let's do export default function user form and let's do return and let's for now just return everything and as you can see we don't have those stat dates for phone set phone street address and so on so let's go back to our profile page and let's just put everything let's just cut everything from our profile page and let's put it uh there so uh here we have it let's remove this console log for the session um what do we need here uh we need to have a Let's see we will need to have image phone street address postal code City Country do we need to have this is admin I don't know we probably do I don't know uh do we use later if it's admin or not um we use it here um well let's keep this this ad me for now let's focus on the just those editable fields country City postal code street address phone image and we should probably have name as well I don't know why we don't have a name name here is name uh I will take name as well and let's see if this will work let's grab all of this let's cut it from here and let's put this to our user form right and I'm going to use like a defaults um from here we will have a user property and we will put the defaults for all of uh all of the state here so um the thing is I want to grab like this oops uh this oops this those names can I select just those names yes and now let's try to do something like this H we want to grab user and this property or an empty string as default so now what we have uh we have state for each property like for example image and um default will be from property user and if we have image then it will be a default for our state here inside the form otherwise if it's not passed or it's empty it will be an empty string that will be used right so now let's also put use uh client here on the top just in case and now let's go back to our profile page so here we are fetching uh every information about the user and as you can see we don't have this State anymore because we moved this the form I think that instead of putting this separately one by one I'm going to put it uh to uh one uh State called user so let's do user and set user and let's do equals use State whoops equals use State and use State and the default will be null all right and here instead of set phone set blah blah blah and um and so on I'm going to do just set user and let's do just this data thing all right so uh now we have our user here so we can pass it uh here inside a user form that we are going to use user form let's import this one let's pass our user from our state here and this should do the trick uh the problem is that we have this now unused uh function that should handle profile update so uh we need to put it to uh as a property here so it's the on save equals and let's do handle profile update uh let's see handle profile info update let's put it like this and now let's go to this uh form and let's grab on Save and on Save Let's see we want to run it here instead of this on Save maybe let's put this as an arrow function uh and uh we want to pass event object from this submit so let's do event here here and event here and uh here we will also need to pass all of the new state of the user so new name and so on if anything have changed so I'm going to put this the same way we did with menu item if I remember correctly so let me just put uh this like this let's see uh on submit we have this and um can we put it maybe here and this here let's see maybe something like this and now here all of the information so username image phone and uh what else street address street address City Country postal code let's put this uh maybe into separate lines so it will be easier to uh to see and uh yeah now let's go to our profile page and let's see what's still broken so it looks like there's um there's this function that we are using but instead of uh grabbing all of uh everything like this uh we should uh just uh we should just use uh data that comes as a param here so we have this data as you can see here we were removing uh renaming username to name let's do the same here into inside of our user form so let's put the name to be our uh username to be our name so we don't need to rename anything here and we can just grab and put our data here as a second par because as remember here inside user form we are doing something like this we have this on submit and we run this on Save first parm is event and the second parm is an object of all of the properties of um our user state so uh now let's see we still have an error on the profile page 24 Let's see we have this username and we have this image here set image all right so what is the problem the problem here is that uh well we Tred to put name and image from the session we don't need this anymore because we fetch all of this from uh from profile so we don't need those let's see now uh do we see loading session is not defined okay where is the session that is not defined inside user form uh line 40 let's see line 40 line 40 here we have session and we do okay so the value of the user email is uh is taken from session let's just take it from profile instead so let's do um user. email all right and now let's see if this will work yeah uh so this works and I see my profile and let's see if I can update my profile so it's the 1 2 3 4 on the postal code and on the city I'm going to put just Stockholm and let's try to save it profile saved what happens if I refresh it's still saved um for the name I see it's empty uh let's see why it's empty I think I should see my name here um here we have value username and let's see why it's empty okay I think it's empty because the property on the user model user yes model it's name and not usern name so now if I refresh still empty let's try to console log the user and let's see what data we have here inside so let's see uh name is actually empty okay so that's why uh no worries I'm going just to fail it uh manually so I'm going to put my name here no worries uh let's see so um here I have my user here I have my profile here I see all of the users even including my user and now when I click edit I want to see this I want to use the same form but for users edit page let's go to user ID page and now instead of user info form I'm going to use user user uh form and we need to pass our user here so for now I'm going to put null but we need to fetch this user so how can we do this we can do something this we can put use effect and uh now let's do that uh Arrow function dependencies there will be no dependencies here inside I'm going to put a fetch I'm going to grab all of the all of the users and I'm will just filter through them to uh to just grab what I need so let's do then response with the response I want to do response Json and then I want to do grab all of the users and I want to find my user that I need so first I need to have ID from uh use um well it was use pars if I remember correctly uh let's just uh check I'm going to print this uh ID here so I Know It uh it works yes it does let's remove it here and now from this those users I want to find them the same way um we did it uh with u with menu items I think menu items ID page let's see yeah we had the same thing somewhere here let's see yeah as you can see we defined and we tried to find it by uh ID so uh let's define here and we want to find user where user ID is the same as ID from the URL and we can assign it to our user and this user let's put this user to our state so let's do user and set user equals use State and default will be null right so now let's put set user to user here and uh now let's put our user to this form user and yeah I can edit my user let's see what happens if I pick another user test one uh yeah I see the EMA test one so it looks fine um the problem we will have now is uh we don't have any onsave function so uh let's uh add the onsave function here um it will be handle save uh button click let's call it like this handle save button click and let's put this function maybe somewhere here before any return let's do function handle save button click and now what do we want to do first we have this event and data here for the event we want to do prevent default and now inside the data we have all of the state from all of those fields image and all of this so uh we want to uh send it to the uh let's say we want to send it to a profile um as a put request so let's do fetch SL API SL profile um but um uh here we are need to do method of put because it's an update uh let's also add headers because I want to add this um content uh type of um application Json and I think we need to have a body as well uh here Json uh stringify and I'm going to put this as a new object of all of the field that we have inside data dot dot dot data and I'm going to send alcore ID to be ID from my uh PS here from the URL and uh this is because uh let's go to our API profile route and let's go to put as you can see our put request we have only to update our own profile and here I actually can pick another profile so uh let's do something like this uh let me see uh here we are grabbing session session email so we check we what email what user we want want to update instead let's do something like this uh we here grab all of the data and um well what I would like to do here is to First grab uh underscore ID like this and now let's check something like this let's do maybe console log underscore ID like this and uh let's see I will do here return response uh Json true I want to stop all of this uh here and I want to see what happens if I try to grab ID from the data but data doesn't have it inside profile so let's see here if I click save it says just ID undefined okay that's fine so uh now if I have ID if I have underscore ID I want to update user of uh of this specific underscore ID so I want to do this uh I want to do this uh first wait a second I want to first update user uh like this but using underscore ID to find it and and then I want to update also also user info by using my underscore ID otherwise we know it's a profile so we want to update for our own user so we want to do actually this instead all right so uh now we now we have it uh two uh those two parts are almost exactly the same this one and those two lines the only difference is here we have underscore ID underscore ID and here we have email email so we can actually do something like this here on the top I will do let filter equals empty array and here if we have ID then the filter will be actually our underscore ID and otherwise uh here the filter filter will be actually object of with only email and now we can do here instead of this underscore ID we can put filter same thing here because uh well uh we have it uh email is U email is our filter so we can put filter and now those two and those two are exactly the same so we can get rid of those here and let's get rid of those here and let's just put this as one thing here so now we have uh this and um this looks fine uh let's see if this will work so um let's maybe update first my uh user here my profile I will do that with Pasco with two o uh and let's refresh and and it's saved now let's go to users let's edit my own user I'm going to remove this extra o and I click save nothing happens but I think it actually saved yes it saved I forgot just to put those toast notifications okay but it seems to that it works let's see I will edit now test two and I'm going to put uh an image for uh this user of uh let's put this MacBook for now and I'm going to put test to as name and for phone 1 2 3 4 and here I'm going to put Barcelona why not and let's hit save and I don't see any toaster but I forgot to add them let's just refresh and uh well city is not saved but let's see uh test test two the name is saved let's click edit the image is saved but the city is not as the Barcelona once again let's hit save and let's refresh crash the city doesn't save so let's uh see why let me go back to the to the I don't know uh users ID page and let's see here we are maybe let's first check if it saves here I'm going to change this to stockh home with 2m save profile saved if I refresh it's it it works for the profile let's see if it works uh for users for users I don't see my city here so that's the problem so let me go to the users edit user page here we are grabbing user and then we are setting this to um to user okay I know what is the problem we are F we are finding the user but the problem is we have only user information and not information that is inside user infos as you remember let's go to the database and let's browse Collections and we have a user that has only basic info about each user like name email and image and we have user infos that has like a country City and so on so we grab a user but we also need to grab a profile information uh let's go to our API profile route and let's see our get requ so here inside profile get we are fetching information for our own user because we are using session but here what I would like to implement is that uh if we have an ID underscore ID inside the query I want to fetch information for a specific user I think we did the same thing for let me see um users no we did the same thing for menu items let's see uh put post get no not here categories and get no uh no uh but doesn't really matter let's go to um profile and uh let's see we connect to the database uh first let's try to grab an ID from our query so um maybe let's go first to the categories route and um categories uh not categories route we want to go to users edit page and here instead of grabbing all of the users and only uh users um here those users uh collection we want to do SL API slash profile I think yeah it's singular and I'm going to put here ID to be equal my ID here uh but maybe I'm going to put this as underscore ID as this P right and now it will not um respond with users all of the users but only a specific user that is for this ID so we don't need to find this inside the collection now let me go back to our profile uh profile route and as remember we need to find underscore ID uh query parm so first Let's do let's grab a request information from here then we can do something like this UR equals a new URL from request URL and then we can do um URL and I think it's search pars get underscore ID we can check if we have underscore ID so let's do const uh and let's do underscore ID equals this and uh then I think we can do something like this if we have underscore ID then we can do something otherwise we know know that we want to return information for our own user so uh let's do something like this we grab user and user info and then we just put everything like this right but if we have ID we want to uh find the user and put and uh we want to find the user using this underscore ID and we want to find user info using um email from this user so let's do email to be user email right and then we want to return this uh as one object like this and this should work nice uh I think the only problem we can have is that um both user and user info can have underscore IDs um so in in this response we will have underscore ID from user info I I know if it's a problem yet but uh uh we will check this in a moment all right uh there is some uh duplicate code uh here we are using we are trying to find user here we are using underscore here we are using email so we can do something like this let's do let filter equals and uh well let's put this as an empty object actually this line return response and here return response is the same so I can actually grab it from here and I can put this here and we don't need this and now uh here we are finding user here we are finding user info here user user info the only thing that changes is this Filter part for finding user and for finding uh user info so let's put first here filter for filter for user and the filter for user um is if we have ID uh will be to uh find it with ID like this and here if we don't have an ID our filter user will be so we can find it with this email that we get from session so um and maybe let's put this uh here all right uh so now we don't need this uh here and we don't need this one we can just put it as one thing let's put this one here instead of using email let's put filter user okay and we have user here we don't need this one because we rely on this filter user now to fix user info here and user info here as you can see here we have filter is that we try to find it by user email that we get from the user and here we are getting from the email from the from the session actually we can just get rid of this one and pick this one let's put this one uh here below and we can rely on the email from our user email all right and now let's remove those Extra Spaces and uh let's see I think this should work let's see if it does uh if I refresh here we have users let's see if I can see my city yes I can see my city let's remove the this one let's hit save let's refresh let's see if it's saved no it is not um let's see what is the problem and um let's see um it doesn't save from the users let's see why if I do inspect let's do network if I click uh save but I will first change this one save we are saving profile with this put request let's see do we send Stockon with 1 m yes we do so there's something wrong with our put request here uh let me see uh do we send underscore ID yes we send is it the same as the user ID yes it's correct so let's see what is wrong we filter here we try to find user okay we try to find user with this underscore ID and it works fine I guess but for user info we cannot rely on this filter the same filter because user info has different underscore ID so here we need to change uh we need to rely that uh we want to update by using email or was it user email let's see user infos and it's email I think yes it's email that we use as as the key um let me see here I don't see any emails but let's put email to be user uh email like this and we don't have any user email here um we don't have any user so um first we want to grab a user like this so we need to have user using this filter so let's do await user find one and let's put this filter all right and so now we have user and now let's see if this will work let's do refresh just in case let's clear everything let's remove this double M let's save and it says it's saved let's refresh and let's see yes it looks like it's saved so uh let me maybe change another user let's go to this test two let's do test two two here uh let's put Barcelona and for the phone let's put 4321 and Country will be Spain let's hit save and let's refresh and everything is saved so yeah now we can save users we can change uh names images and stuff like this uh but now um we need to have an ability to know if a user is an admin or not so um we need to also be able to edit if a specific user is an admin or not inside this form we don't have any checkbox if it's admin or not so to fix it I'm going to add a checkbox so we can mark that yeah this user is an admin and I want to make also for example test22 also an admin so we need to have a checkbox for this uh and and it also would be nice to F put those to to take all of the with right let's see how it looks like here yeah same thing so let's go to our uh profile page uh let's go to profile form actually so we want to have our user form it's called user form and uh here let's see uh we have this country and um we have City let's see country postal code and city we have this one as flex and but why it doesn't take the whole with let's see why um so here we have this the flank and the wall we should let add uh grow on those two divs so let's do class name grow or actually we can get rid of this grow and we instead of flex we can just do grid and do grid uh Columns of two and let's see now yeah now they take all of the space so this works now I want to put a checkbook if it's un or not maybe under the country before the save button so uh here let's do a div and we will have an input of type checkbox and I'm going to have a label but this time I'm going to put this uh label maybe on the right side here and um the label will be we will say uh admin so now let's see uh yeah we have something like this admin um we can add back this HTM L 4 and I'm going to put ID of U admin checkbox and here for html4 I'm going to put admin checkbox so now if we click on the admin it will select or unselect uh this uh checkbox now um for this label I want to add some paddings so let's do a lot of padding like uh maybe even we can put this in put into this uh label and for this admin let's put this into a additional span yeah it doesn't change anything but now we can do something like this let's do padding of at least two and um now I want more padding so and I want to make this one as a block uh let's also add a border to see how it looks like yeah so we can click on the whole thing here now for the input of type checkbox let's add class names here as well I want margin right to be two and yeah that's correct and now uh this whole label I want this one to be flex and items uh Center and I will do a gap of two so I don't need this margin right of two let's see yes I can click on the whole thing and uh now let's see I want to have some margin bottom of two so we have some spacing yeah that looks fine and uh now I don't know maybe we can remove the uh remove the border so let's get to border and let's remove it yeah so we have something like this admin that we can select or unselect um maybe the whole row shouldn't be clickable like it is now and instead I'm going to do uh here inline Flex so let's do inline Flex so now if I click here the admin is not selected but if I click here then it is yeah I think it works fine uh now we need to have state for this checkbox right so um well let's scroll up and here let's do con maybe under the last one const uh admin and set admin you state the default will come from the user admin uh otherwise it will be false as default right so here let's do something like this let's see here we have this admin let's put this ID here type class name blah blah blah we need to put also value to be let's say one uh as a string and now let's do something like this the check property will be true if it's if admin is true and uh now uh I want to also add on change or maybe on click on click I will grab an event and I will do something like the set admin and I will set it base if the target if the event Target is uh I think it should be checked let's see if this will work uh Can I toggle yeah and I want to also see the value of uh admin Json on stringify admin so let's see false true false true false true and it's uh true for now let's see for other users test 22 it's false okay uh so it works now the thing is that um if you edit your profile and you're not an admin you shouldn't see this right so let's say um that we will grab information about this uh uh uh like this let's see I will grab it here const and I'm going to only grab data from use profile use profile and I will name this data to um current user uh maybe not current logged in user uh data and uh I'm going to use it to display to decide if we should display this uh admin checkbox I would do logged in user data if the logged in user data if you are an admin let's do then and let's pull let's put this whole div inside so uh now I see uh this checkbox uh but if I am not a user if I'm not an admin I will not see this checkbox right so um if I log out and I will log in as a different user let's see um I will log in as uh J let's go to my profile and I see my image but I don't see this uh I don't see this uh is admin or not so let me go back to my user that is an admin and now let me go here users yeah and uh now let's see uh we have our users uh working we can edit them and we can even do that uh let's say test 22 will be also an admin let's see if this will save yeah we still don't have those um toasters old toast uh so let's go to our uh let's see our users edit page and here we have the fetch let's put this as a promise so let's do um maybe const promise equals new promise resolve and reject we will need to have an ass syn thing here and and let's put this fetch uh inside let's add the response equals this wait and now if response is okay then we will do resolve otherwise we will do uh otherwise we will do reject and yes now um I I can do toast uh from react hot toast let's do promise um and um now I can do something like this I can put promise here and now I can do like loading it will say saving user dot dot dot if it's success it will say user uh saved and if error it will say error while um or maybe an error has occured occured while uh saving the user yeah uh so now if I hit save here user saved if I refresh um if I refresh the admin thing is not uh saved so let's me add just a wait here and uh let's see I need to add a Sync here and now let's see um let's go to the form user form and I think this is because we are not sending this admin thing to our on S save so let's uh add it here admin and now it should do the trick so if I select admin save user saved if I refresh uh admin is still selected if I unselect this one and save let's do refresh and uh it's not selected yeah uh so it's not selected let's save it should be not selected not selected let's now select this one and save and now if I refresh it's still selected let's unselect this one save and now it should be un selected yeah so that is uh that is uh cool now um so this thing works this thing works and um and we can basically edit uh all of the profiles that all of the users that we have so that is nice the next thing will be actually orders but before we will do the orders I I would like to display all of the pizzas from my database for now they are hardcoded and I will add some real categories and real menu items uh first all right so I created the three categories Pizza Pasta and dessert and I put also some menu items here so I have like 1 through four five six pizzas three pastas and two desserts and if you are wondering where I took all the images and names I just took it from cisss pizza here so you can also take it if you want or can add your own menu items uh one thing I was thinking about is that um for the categories it would be nice first to have also some kind of order so for example um right now I have a pizza pasta and dessert maybe it's fine but later you can also add like an order so you don't have only the name but you have order like one two three so you can sort those and then for menu item I think they are cool enough so for the uh start page here as you can see we have this check out menu here but uh I think it would be better to change it to uh check out our best sellers or something like this and then we will have a button we will have only three items here and we will have a button underneath saying check out our whole menu and same when you click on the menu here it will go to the page where we have only menu and we have all of the categories so this is what I'm going to do now uh let's first go to our start page so let's see I will close this API let's go to page here uh we have some lsum here that's fine let's see where we have our uh menu items section headers uh we need to find here is About Us section headers home menu here we have it let's go inside and here we have our menu items so first I want to change this to um maybe check out uh our uh our best sellers and here inside I would like to have let's say free latest meals for now so uh how can I do this let's go to um let's go up here and let's change this to uh client component uh so let's use uh client here and let's add use effect use effect from react Arrow function and no dependencies uh what I want to do now is to just fetch fre latest items so um let's do here Fetch and slash API SL SL menu items and uh now uh this will be a get request I don't need any extra PS let's do then and let's do menu items and now let's do something like this this will not be menu items sorry here we will have response and first we need to do response Json and then we will have menu items it will be all of the menu items and we want to have only the latest threee let's save for now so I want to do um menu items and let's do slice and let's do uh minus three let's see minus three so we will have three from the from the end and let's do best uh maybe last uh three equals this and let's see console log maybe we can call it best sellers even if those are not best sellers yet and we will call them this way and uh let's see how this will look like so if I go here to inspect let's go to console and we have array of three and as you can see we have three Ms here so now let's save this to uh state so let's do Best Sellers and set best sellers equals and uh maybe not let's don't call it best sellers but uh featured I don't know we can also add a CH box for menu items if we want to select manually what menu items we want to uh have we could implement this so uh maybe that would be nice but for now let's just use our uh latest free let's do use uh State and default will be an empty array and now let's see now let's do here set best sellers to best sellers or we could just do something like this cut this from here and let's put it here and uh now let's see now let's do only uh let's remove this and let's do something like this best sellers let's see if the length is bigger than zero and let's do then best sellers map and for each item uh let's do Arrow function and let's see for each I want to do menu item and I want to pass everything about this item let's now go here and here we can grab all of the properties we want so we can grab image we can grab name and we can grab description and uh we can grab base price and well uh let's see I'm going to put this here and let's put this uh here and um what else do we have we have also sizes and we have all so let's see I will go to models and the menu item we have also this extra ingredient prices and let's pull them also here and now let's see um here we have uh title so let's change it and let's change it to name so now we have pepperoni pizza cheese pizza blah blah blah uh here we have image so let's change this to image let's see yes we have three different pizzas as you can see uh now um for my menu items uh I added only basic prices here base price 11 and I don't have any sizes or extra ingredients except this pepperoni pizza where I have a base price of 12 but I have also size this for medium it's extra $2 and extra ingredients if you if you want to have extra cheese or extra pepperoni you pay exra here and so now let's see here we have pepperoni pizza cheese pizza and beef Pizza those two have only base prices but this one have uh sizes and so on so what I want to do is um now to put the correct base prices here so instead of this $12 let's do only dollar sign and let's put here base price right and I don't see any um and numbers here so let's see if we have it inside our database yeah it should be inside the database let's see what is uh what is the issue here so let's go to menu item form and let's see maybe it's called different way uh it's called base price so let's go back to menu item we have base price here but it looks like it's uh it's empty let's maybe try to do something like this I will put here Jon Jon stringify and let's do base price whoops I know see what's the problem it should be C here so now let's do base price like this and now it should work let's see yeah 12 12 and 12 maybe we can change one of those prices uh we can change some of those prices let's do go to beef pizza and uh let's see P Pizza let's change this one to 14 and uh we have also Chase Pizza let's change it to 11 let's see Chase pizza and let's change this one to 11 so we'll have different uh prices prices sorry right now we will not fix uh add the card yet and instead um I want to fix this menu page first so uh let's go or maybe before let's also fix those uh descriptions here so here let's put uh description and we will have a lot of description here so um so I want to make it shorter and add dot dot dot if it's too long so uh to fix it and I will do something like this we can do that with CSS so let's try with Max half off um uh let's see 16 so now we have something like this and now we can add overflow um overflow oops overflow y uh clip I think it's like clip yes and uh now there's something like overflow uh ellipses let's see no I think there's something called instead of uh overflow ellipses there's trate yeah and now we have dot dot dot right now now let's see if I remove this clip uh nothing changes let's change this H from this to I know 30 36 no uh still nothing let's see I'm going to change this to 120 pixels still uh nothing let's see how big is uh this paragraph it's still only this big I think we need to change this uh truncate to something else and instead let's do text clip and let's do also um text uh ellipses and uh now let's see this is this big now we need to add I think overflow overflow ellipses still nothing let's see what happens if I change this to overflow hidden let's see uh I think it's too big let's change this to I don't know something like 60 pixels so now it's hidden let's change to ellipses uh I think we cannot have those two at the same time so let's do text ellipses only and um let's see let's do overflow hidden so now it's only hidden I think that uh it was fine with this truncate but we need to add something called line Clump and let's do free now we have only one line let's remove this Max hav and let's see still one line let's remove this uh trate okay and now now we have three lines so that looks better and it's trated with those dot dot dot so that is nice so we have both image Title Here description and the correct price so that is nice and uh now let me see now it would be nice to have this menu page working right so inside up let's do directory called the menu and inside we need to put page JS so let's do page JS and let's do export default function menu page and well let's do return and L put maybe just a section for now saying uh menu here and let's see how this will look like uh we cannot click on it or we can but it doesn't do anything let's go to header and for the menu let's go to slash menu and we can also fix about to go to the homepage but let's scroll to about and same with contact let's go to contact like this and the menu goes here about doesn't scroll down but we'll fix it let's go back to the uh our homepage so let's see let's go here page here inside up directory and let's see here we have about Us section so let's do ID of about and let's see if I click about then it Scrolls to about and now for the contact let's do ID of uh contact and it will also scroll so you have click contact it uh didn't scroll let's see contact without the hashtag here so let's see contact and it Scrolls to the bottom right now menu page let's go to menu page and or maybe before we will do this I would like to have this scroll a little bit better so if I click about it shouldn't scroll immediately and instead it should have this smooth scrolling and I think to fix it um we need to go to layout and for our HTML we need to add a class name called scroll smooth and now let's see if I if I click contact yes it works fine so if I click contact from here uh didn't work let's see let's refresh let's click about yeah fine contact fine okay let's go to menu and it seems that uh the Smo scrolling worked let's go to our menu page and well here I would like to have this uh section title first or first we want to grab all of the categories and uh all of the uh menu items right so let's put menu items here with categories just as a text here I will put use effect uh from react and here let's put a function without any dependencies and now we want to grab all of the categories so let's do fetch for the uh categories so let's do API cat and let's do then with the response uh we are uh we will do response Json and then we are getting those categories and we want to set them to state so let's do con categories set categories equals use State and default will be empty array now let's do set categories with those uh categories all right and now let's do the same thing for our menu items so let's do menu items and now here fetch let's do SL API slash menu items and then we will do with the response we will do exactly the same thing so we can do just response uh Json then menu item set menu items like this and now here instead of this text I will do something like this if we have categories if we have categories let's do categories length is bigger than zero so we have some categories then let's do categories let's do map and for each category let's do just C let's do parenthesis and let's do something like this IP put the div and inside this div I will do section uh headers uh but I will do only main header and I will put here category name all right so now let's see I need to put use client on the top uh let's do here use client right so uh Pizza Pasta dessert that's fine maybe I can add some here on the section I can add uh margin top of eight to have some spacing and um well for the section headers uh I want those to be centered so I'll put div with text Center Center oops Center and I'll put those section headers here yeah and now uh for here we have header then I want to have uh menu items for those uh for this specific category so let's do something like this um let's do menu items and let's uh filter to have only menu item of this specific category so I want to do if uh we menu category is the same as category ID and then I will do map on this and for each menu item let's do just maybe item so it will be easier to to see what it is let's do for each item I want to do a div let's say for now and let's say item here so uh here we have 1 2 3 4 5 six and here we have three here we have two for desserts uh maybe now instead of item I will do menu item component from uh menu it from menu item components and I'm going to pass all of the stuff from menu item like this so now we have something like this it doesn't look good but uh we will fix it so I think that for all menu items we will need a div and I'm going to put those menu items here and for this da we are going to put grid with grid columns free and gap of four so now we have something like this it's much better uh what else I would like to do is to add some margin top of uh four and margin bottom of eight so now we have a pizzas and we have six pizzas we have a pasta and we have three pastas and we have two desserts yeah so this looks pretty nice and uh and now we have our menu working maybe we'll be nice to have some kind of uh extra uh descriptions for the categories uh if you want but I think this is good enough maybe we could also add the more spacing uh let's see margin top let's do uh margin bottom I will do 12 and for margin top I will do six so we will have even more spacing for the spacing between the Mills I think it's correct is the same that we have on the homepage all right so uh now we will need to have some kind of this un to card functionality right so if you remember we had this uh app context I think somewhere components we have app context uh with session provider and we will need to have another context for our card right so I'm going to create it here con and let's do cart context equals and let's do I think it was create context create context from react and uh whoops let's do oops let's go back here and empty here object as the default now we have a session provider here and I'm going to need also to have uh our C card content text provider as well so let's put children here inside here we are going to need to have a value let's put empty object for now here I'm going to put some State and uh well for the state we will need to have uh cart items right so let's call this one cart products and Set uh card products equals use state uh State and from react and the default will be empty array and here we are going to pass uh both of those so let's pass here card products and Set Card products in case we will need them now uh if we go to let's see uh menu item we have this button that uh should add to cart let me put this maybe like this and if we want to do on click um here I would do Arrow function for now H will be nice we will be helpful to have a separate function here called the add to card uh or yeah something like this so let's do function add to card and we are going to just uh use it from the context inside menu item uh component add to card we want to know what product we want to add the card so let's do product ID product ID and uh well what else do we want to know maybe we can uh take all of the uh product object the whole product object so product and uh what else uh we will take product and we know need to know what will be the configuration of it so what size and uh uh if there are any extras so let's do size that will be no by default and Extras that will be also null or maybe an empty array for sizes you can pick only one and for extras you can pick several and uh then we will do here Set Card products and uh well in here we will go previous products Arrow function and here let's do const new products and we are going to do all of the previous products but we are going also to add our uh product uh product as a new object like this with our size and Extras like this and maybe we can also add the quantity um I'm going to put this new object here above const uh let's call this one card product equals this and let's add the No No quantity here here we are just adding this card product all right and um now we just need to do return new products and this should work now uh if we want to just fix it uh like this let's go to menu item and let's do here let's grab this function Let's do const let's grab add to cart function from use uh context and here we need to put our card uh card context right let's see card context we need to export it let's do like this and here let's do card uh context and now let's see yeah so we have now this add to card so let's do here add to card function with our product info uh our product info is basically all of this so uh maybe on instead of putting those like this I'm going to cut them from here uh I'll put here menu item and here below I will do const I'll put all of those whoops like this from menu item so we will have all of those uh variables but here inside add to card I will just put menu item all right so now if I click on this one we get an error let's see why let's see to console and let's see add to card is not a function so looks like add to card is not a function let's see inside our app context it's because we are not exporting it so let's do add to C like this and now let's see unexpected token yes it should be comma here and now let's see can I add this one yeah it looks like it works nothing happens but we will fix it in a moment let's go to header and we have this logout here uh next to the logout I would like to have an icon uh shopping cart icon but only if we have any products so here I'm going to do something like this uh I'm going to grab uh our uh card products from use context use context and card context yes and now I'm going to grab those card products and after let's see here we have authenticated or unauth indicated here let's do if card products length is bigger than zero then uh let's do uh parenthesis here and let's put a link to a card so let's do let's put just card and here the length say the card products length and uh let's see nothing is visible let's add here craft to just slash card all right so it looks like this did didn't work yeah now it works as you can see we have 1 2 3 4 5 and so on uh well maybe we shouldn't have it based on the amount of products so I'm going to remove this if from here and we are going to have this link it doesn't matter if we have anything in the cart or not um so now we need to fix few things the and we will have we will need to fix sizes X extras so we can pick like size from our pepperoni pizza if we want medium or so and Extras another thing is that when I reload everything disappears uh the context is cleared so um to do this I will go back to the app context and uh well in here I want to grab first uh local storage because I'm going to save everything into local storage so let's do cons local storage equals here first we need to uh check if we have a window available so window is not undefined then we will go window local storage otherwise null all right so I have a local storage here and uh now now I will do something like this I will add here use effect from react and arrow function here dependency will be card uh products so so if car products changes I want to first check if we have l l here uh so if we have local storage that's is available and um then uh what I want to do um I want to also check if the if the number of products is bigger than zero or maybe not maybe I don't need to I don't need to do this uh maybe first let's put this actually as a function let's put a function Save card products to uh Storage storage maybe we should put local storage local storage like this and now let's check if we have LS then let's do LS and let's do set item and let's put this as a card and here we need to put Json stringify and our card products right so now uh when we add product product to a card we want to run this function save uh card products to local storage uh maybe we can run it here inside with our new products uh we can take uh car products uh from here as a param and uh now let's see add to card yeah for now this should be enough but I will also add as you can see now it's empty I will add use effect here and that Arrow function no dependencies so um it will do something like this I will move it here uh above this and it will do something like this when our uploads uh for the first time uh we want to check if we have something inside local storage so let's do if we have local storage and local storage get item of the cart uh then we want to put uh stuff from the inside to our uh state so let's do something this Set Card products and now here we need to UNR un stringify it uh so let's do Json pars and here inside I'm going to do LS and get item and the card right so now let's see um if I refresh I add one two three pizzas as you can see now if I refresh we still have three pizzas so that's cool that works now now let's see uh we will probably need some other functions like clear card or something like this so let's do function clear card and this function will actually do only Set Card products to empty array and uh Save card products to local storage also empty array and we can pass this function uh later let's also add the function to remove a product function remove card uh card product uh singular and we will take an index from the uh shopping cart so uh let's do something like this here we will do Set Card products and from the previous uh card products we are going to do Arrow function here and we want to filter those so the const new cart products equals previous card products and we want to filter those and we filter with arrow function and here we can get the value and the index and here we will just check that the this index is different than this so I'm going to rename the this to index to remove and here I will check index 2 index is different than index uh index to remove all right now maybe I put this into separate line and now we can just do return new card products or simpler we can just do yeah let's do return new card products and we will also need to do Save card products to local storage with new card products like this so let's also pass this remove card product and clear card uh to our context here remove card product and clear card in case people need this uh later right so um now let's see we have three pizzas here maybe we can even add a dessert so now we have four items in our shopping cart and uh now let's see we will need to fix a popup or pizzas so for example if you open a if you want to add a pepperoni pizza it should ask you for what size you want and um and then we need to have a card fixed um so um first let's maybe fix this uh popup so what we need to do is to go to this uh menu item and uh uh and uh let's see here uh we have this add to card functionality uh from our card context let's rename this one to add to uh add to cart um or maybe not let let's not rename it yet but instead of instead of running this function here I will have um function here called handle add to card uh button click right and uh now just in case I'm going to add here type of button and I'm going to run this function here so let's do handle add to card button click all right and what we want to want to do here is that if this menu item doesn't have any sizes so if sizes length is uh zeros and there are no extra ingredient prices things so if this length is also zero then we can do just add to card and then and here we are just going to pass all of the menu item information and that's it and uh this way we have the same behavior I just click and the number of items increases uh all right so um let's see um but if some of those are not empty what should we do well before we will do anything I would like to have this toast thing so let's do toast uh and let's do success and let's do added to cart and now let's see if we will have this toast yeah we have added to cart uh that is really nice now let's see add to card and uh maybe we should put it below after we add the card but uh let's see if uh else if we have sizes or extra ingredients we should show a popup right so to show a popup we will need to have a state for this so let's do const and let's do show uh popup pop up and set show popup equals use State and default will be false false and here else we will do set show popup to true all right and uh well let's see now here we have our item uh maybe I will put like a react fragment here and it will end and here on the bottom and uh now I'll fix the indentation to push it a little bit here now here I will do if we have show popup then let's do something like this I will put the div first we need to have some kind of backdrop so let's do fixed and inser zero and background color of uh black uh 80% so uh if I click on pepperoni we have this backdrop because we want to have a popup here so let's do um let's do a popup uh let's put another div here and this one will be uh White so let's add some class names here like uh myr to White let's add padding of four let's put test inside and now this one will be flex and I will add items Center and justify um justify Center so now this popup is in the middle now I will add around the the corners of uh let's do maybe large not not GL LG yeah and now let's see now I would like to put this uh all of this uh Pizza information uh so uh I want to put all of this uh inside basically so it will be nice to have it as a uh separate component so I'm going to grab this and this will be actually just this menu item tile so let's go to here components menu let's do new file and let's do menu item tile JS and here export default function menu item tile we can call it also box if you want you can name it like this uh doesn't really matter and here let's just put all of this and we we are going to need all of this uh item from here as a property and we need Let's see we will need also to have this uh handle add to card button click uh so let me see we are going to grab it like this and let's put here on add to card as a property and the rest will be item and here we want to grab uh image and description and let's see uh name and the base price base price from our item and I think that here we should just go with uh on uh on add to card now let's see let's go back to our menu item and let's put here menu item tile and we are going to pass on add to card we are going to run our handle add to card button click and we are also going to pass all all about our menu item here menu item like this all right so now let's maybe put this into separate lines so it will be easier to follow uh yeah so now this looks fine now um we have this white box here and instead of test I want to um display everything like this so uh maybe let's put this here so we have something like this uh well the thing the thing I don't like is this hover effect and I don't want to have this out to card 12 so I'm actually not going to reuse this component instead I'm going just to use regular image here and so on so for example here I'm going to put image and here I'm going to put this uh name of this uh this specific uh dish so let's see uh sorry menu item uh let's see what's wrong here error image with Source blah blah blah is missing with Okay so let's do wi of um 200 and let's do have of 200 as well so let's see now yeah so now we have our piz like this I will do wave of 300 and uh now under the image I want to have uh the title let's put this as an H2 with a name and let's put some class name here I want this to be text large and bold yes and text Center this bold didn't work let's see why bold F bold so we have pepperoni pizza now underneath I want to have description full description so let's do description like uh this description uh I think it's a little bit too long um too wide sorry so let's do here on this white box let's do Max wave of medium so we have something like this the image here should be centered so uh let me see how we can Center it uh here we have this image and I think it's display Bo so we can do something like this we can do class name and MX Auto so now it's centered let me put some of those attributes into a separate line so it will be easier to read this image thing let's see yeah I think this works nice the description should also be centered so let's do text Center on the description or yeah this will work and it should be more grayish so let's do um text Gray uh 600 or maybe 500 let's make the text smaller yeah something like this and we want to have some spacing so let's do here margin bottom of uh four yes something maybe that's too much let's do just uh two and now let's see under I need to have sizes here right maybe here as well let's do put margin bottom of two now for the sizes uh I need to first check if we have something like sizes so let's let's do if we have sizes uh where length is bigger than zero then let's do and then let's do parenthesis let's put a div just a div like this and it will say here A3 pick uh your size uh let's see pick your size and for this da I want this to be backround gray 300 with some rounded rounded medium corners and padding of at least two yeah maybe a little bit uh lighter so let's do background gray 200 and uh now now uh let's see um pick your size what do we want to have here well here I want to have sizes listed so let's do something like this uh for each size so let's do sizes map for each size I want to have parenthesis here and let's put a div or maybe instead of div let's put a label and inside each label we have input of type uh radio uh and now let's see we will need to have size name and size price right so let's see so we have a small zero medium uh 12 medium two and large four instead of having this size like uh a small zero I want to have the final price like the pizza Price Plus the uh price of the sizing so I'm going to do base price plus this and here I'm going to put dollar sign so we have small 12 medium 14 and so on now for this label let's put this uh block so we have like this and let's maybe add some padding of uh one on the top and the bottom so we have something like this uh maybe we could also do uh some Borders or something like this so let's do border and I'm going to actually remove this gray color here and we don't need the rounded Corners so now I have something like this uh I can select all of those because they don't have any name let's put name here and uh for this input radio the name will be side so now I can toggle between those uh let me see uh what else do we want to have let's add more padding here and maybe two on all sides and let's add rounded corners of medium on the those labels and let's also add margin bottom of one at least between those and uh maybe we can add some kind of like a gray color instead of block let's do flex and uh let's add items Center and let's add the Gap so we will have some spacing between the the input here and the labels I think this looks good enough maybe we can increase the Gap and uh yeah I think this looks good maybe we can make the padding even bigger like four I don't know um I think it looks fine now for the piure size I'm going to Center this as well so so let's do text Center and let's do more grayish so let's do text Gray of 500 pick your size yeah maybe a little bit darker let's do 300 no another way around 700 pick your size and the this looks fine now we want to have also some kind of uh check boxes for extras so here after sizes let's check if we have any extra ingredient price if the length is bigger than uh zero then let's do end parenthesis and let's put almost the same thing so let's do div uh let's add the here we had this padding of two I think we can change it to padding on the top and the bottom of to so let's do the same thing and uh maybe I can just copy this and put this here instead of uh looping for sizes I will have extra ingredient prices and for each uh let's call this um let's call this extra thing extra thing I will have something like this extra cheese but the price will not be will not include Bas price so we have extra cheese one extra pepperoni two and those will be check boxes so let's do check boxes and the name will be the name of the uh extra thing because we can select several so the extra thing name right so we can select either both or zero nothing or one of those doesn't matter here we can select only one all right so now let's see um we will need to have a state and we will need to have button on the bottom so let's me first put the button so let bu button of type uh type uh button and and uh well let's see if we have a button here we need to have add to card and here we have something like selected price selected price so this price here will be dynamic depending what you select here maybe here for $1 we will do plus so let's see plus $1 and so on here and uh now for this button we will add a class name called primary so we will have some um red color here going on yeah add to uh add to here uh now one problem I think we will have is if it we have too much inside the popup we cannot scroll it let's see let's see where I have this paragraph here if I put like uh much more text like this I cannot scroll inside here inside this uh uh white box so let me see here we have this white box and let's do Max have of uh screen and now can I scroll no uh let's add overflow uh overflow scroll now let's see now I can scroll inside uh I would like to have some spacing from the top so let's do here on the white box margin y of8 let's see uh this didn't help up uh let's see why Max have off screen I think it's because we have Max saave off screen let's try to fix it uh well first I'm going to remove this maxh screen let's see okay uh but now uh it's in the middle and I don't I cannot scroll it maybe here instead of fixed uh inser zero I'm going to change this to top uh zero and left zero and let's see now yeah I need to add right zero now let's see I can scroll the screen behind uh but not uh the popup here so I think to fix it we can do something like this uh we will have a separate div here for the content of this white box so uh here I will put this image and all everything even the button let oops let's cut this and let's put this inside this uh div and this div will have those scrolling classes so as the Overflow uh scroll let's put this here and uh well actually maybe it's not uh maybe it's not needed let's have it here and here I'm going also to add um max half of uh I will add it separately here as style because I'm going to calculate it Style Max uhave of uh and here let's do Cal 100 view hav minus and let's do maybe I don't know 40 pixels something like this I'm going to put this and this into separate lines and now we have something like this so it works uh we need to do minus maybe 80 so we have some spacing from the bottom maybe even more let's do 100 yeah uh 100 is is too much for this one I think because it removed a little bit of this black thing uh let's change here back to ins set of zero and I think this looks good enough uh let's change this overflow uh scroll to overflow y to scroll so it's scrolling only on the uh from the top to the bottom now uh we have this padding of four let's change it to padding of two and let's add another pading of to here so we have some spacing from this scrolling line all right uh now I think I can remove this uh uh text we have too much of the text so let's uh get rid of this yeah and let me put this description here and this paragraph here and uh yeah now this looks fine so this works we can scroll both here and here now and uh we need to have state for those uh menu items uh extras sizes and so on so let's fix it uh so um let's put a state here called selected size and set selected selected size equals use State and default will be null right and now let's see uh when I selected when I select one of those let's see here we have labels for extra ingredients here we have labels for uh here we have labels for uh sizes so here I will do something like this uh on click I will do Arrow function and I will do set selected size and here I'm going to put uh let's see I'm going to put size uh can we have size ID or something like this um or we can put just everything that is inside size yeah let's just put all of the information about the size into our selected size um we need to also check if it's checked and it's checked when uh it's checked when um selected size uh name is the same as uh the current size that is is here inside the loop so let's do oops let's put the name here right so now let's open this one oops something wrong uh reading name from the selected size let's add question mark here because this selected size can be null let's open pepperoni pizza and let's see we have small medium large that's cool now let's a f state for those checkboxes so uh let's see label here we have input type uh checkbox let's add on click and we are going to need um here let's see we will need a state for this right so let's see con here we will have plural selected extras and set selected extras you state default will be empt R right and this will be a little bit uh more complicated or will it be [Music] uh I think it will so I will do a separate function for this uh for this when you click one of those so I would do function uh handle extra uh extra thing click and now I will do here just event and I'm going to do console log on the event and I think that will be it for this here I'm going just to use this function handle add extra handle extra thing click yeah so now let's see I'm going to open my console let's see pepperoni and if I scroll and add extra cheese we have event and what I want to do is go to Target and we have this checked true and this is what I'm interested in so uh I can check if we want to remove or uh or we want to add it so let's do const checked equals event Target Target checked and then we can do something like this if checked then we know we want to add it so if checked we want to add it so let's do set selected extras and let's say that the second parm here will be the extra thing all right if we want to add it then we will do grab the previous uh State previous the value we are going to put all of the previews and we are going to add this extra thing here if it's not checked it means it's unchecked and we want to remove it so let's do set selected the extras and uh we want to remove it so let's see uh we'll grab the previous state and uh from the previous state we want to remove it so let's do previous and let's do filter and we want to filter where the extra EXT extra name is uh is different than our extra thing name then we know it will be removed so let's do return here and this should work but we need to pass this extra thing so let's see here first we will do to Arrow function we pass event and we pass our extra thing here from the loop so now let's see if I will select can I select unselect yes uh and this kind of works maybe here um above uh it shouldn't say pick your size for the uh extra things let's change this to uh any extras extras um and here I want to also do Json stringify um extras selected extras selected extras so now let's see nothing if I select this one we have one now we have we have two uh we have extra pepperoni and extra cheese as you can see let's unselect one now we have only extra cheese yeah so it works let's remove this Json and now we want to have this selected price right so let's calculate this on the here before the return selected price and selected price let's change this to a let for now uh on the beginning it will be base price but then we will do something like this uh for each of the selected if we have selected size as do if we have selected price sorry not selected price selected size then we need to add selected size to our uh selected price right so let do selected price plus equals selected size price right then if we have selected extras uh and uh so let's check that the length is bigger than zero then uh we want to do something like this for each of the extra thing so uh for each extra thing inside for uh each con extra of selected extras uh we want to add it to the price so let's do selected price uh plus equals extra price all right so now let's now see if uh this one will will be correct so let's put this one here and now let's see uh I'm going to close this one so uh Now it's 12 nothing is selected if I select if I select small we have 12 medium 14 large 16 okay let's select 14 and now let's see extra cheese it should be 15 yes now if I select this one 17 let's unselect this one should be 16 yeah and select this one 14 15 17 16 yeah I think it works 15 17 $90 yeah let's only add this dollar sign here so we have uh $19 all right so this uh works for the calculating uh prices here um now if we have um if we have sizes the first size should be selected as default right so let me see we have this selected size it's not by default uh but let's add that uh maybe I will put this maybe into separate lines first and now instead of this being null by default it will take the first size if there are any sizes if sizes length is uh or we can just pick the first size here size zero price uh but just in case I'm going to add question marks if in case any of those is empty otherwise null so now if I open pepperoni the first should be selected but it's not uh it's because we shouldn't pick price here and we should put the whole object now as you can see the first one is selected small and you have bck this one 14 16 so that is nice uh another thing that would be cool to have here is to have button sticky to the bottom so let's do here let's see here we have this button let's do sticky sticky yes and let's do bottom of two and now let's see as you can see it's uh sticky uh it's above this extra pepperoni so that is nice uh let's refresh and let's see add to card if I add the this console here as you can see now it's Stick it to the bottom at two card as 12 so that is uh that is nice all right so uh I can do $13 yeah this works uh one small problem here is that I cannot close this thing so uh so let's fix it now um well I want to click outside like on this gray thing so uh here on this div I want to add uh on click and I want to add uh if you click on this gray thing I want to do set show popup to false so now if I click cck here it closes but the problem is that let me open even if I click here the event from the for example image is propagated down here so um to fix it I will go to this Dave and that is a child and I will do on click so if this one is clicked I'm going to grab the event and I will just do event stop propagation so now if I open if I click here inside on the white box it doesn't propagate this event down to this uh black uh Shadow right uh bug drop sorry but if I click here uh everything uh is closed then all right so uh this looks fine uh maybe we can even add a add a close button on the very bottom so let's see uh here under this one let's put a button that will say uh cancel cancel and it will only only uh do on click and let's do set show popup to false and let's put this into separate line cancel will go here now let's see we can scroll to the cancel yeah fine let's add some class names let's add margin top of two so we'll have some spacing yeah so we can close it even from the pup uh Works nice we have this add to card but uh as you can see add to card we've selected price um it doesn't do anything so we need to add on click for this one and um we have this handle extra well where is it handle add to card button click and um well let's see uh maybe we can do the same function here inside this uh button here so let's do handle add to car button click uh but uh well let's see here we are checking uh we need to first check if we have an open an open B uh popup so if show pop up uh then let's stop this here return nothing uh then we know we need to run for this configuration so let's do um add to card but with this menu item and but we also want to put uh Let's see we want to put the size information here so let's do selected size and selected extras all right and we also want to do this added to card and after we added let's also do set show popup to false so we can close it so now I can do medium Pizza extra pepperoni add to card and it closed and we show this here uh but we have some repetitions here um and we need to fix also that after we add to card we need to reset those two so let's do set selected size to the default uh or null or default doesn't really matter H we don't need to reset it yet um it's not necessary uh but let's make this thing simp simple uh so uh first this uh line here I want to put it as a constant and this says this says uh if we don't if we don't have any options and we don't have extra ingredients then we just add to card uh let's put this as h options equals this and let's put h options let's put plural here if we has uh well has options should be if this is bigger than zero or or this is bigger than zero and this should be uh another way around now so let's put this thing and this let's put this thing here and um now we have this show popup here and U let's put else here and let's put those two things uh here and we don't need this to have this return anymore so now uh now here we are adding to cart uh here we we are also adding two card and the only difference is that when we have this show popup we also add those two so let me see um let let's first put those outside of this else if for now and let's put those here inside where we add to car but as you remember this is for where we have a popup and this is where we when we don't have a popup uh this and the this is the same so we I can put this as one and uh now we can always do set show popup to false it doesn't need to be even open so let's put this here now uh if we have a popup we want to do this if we don't have a popup we want to do this so let's do something like this if show popup then we want to add like this else we want to add like this all right and we don't need to have this if else from here and now let's see let's make it even simpler we have this if has options then show popup and then nothing else so we can do something like this if has options then uh show popup and let's stop here so let's do return so now we don't need to have this if uh else and we can just fix the indentation here all right so now let's see if we have a popup then we add it like this otherwise we add it like this and I think it will just work if we just put this uh well or actually I don't know selected size will be null and selected xors will be empty aray I think this will work even for uh stuff that uh don't have any extra uh sizes so let's put it like this we don't need those spacings here and this should work so now uh let me try to add a regular pizza yes it looks like it works pepperoni uh let's see we have nine items inside cart let's add pepperoni with extra cheese okay looks like it doesn't work and uh let's see if it has options then we show pop up nothing else okay so it stops here that's why we it doesn't go further if has options and popup is not open not open how we can do not open show popup okay so now let's see if I click yeah then it works we have 10 items here right so um now let's see I think we can go to our card that doesn't uh work yet but this will be the next thing that we are going to fix uh one more thing is that uh for the pepperoni we have add to card 12 maybe if we have uh if you want you can do something like this um for the menu items that have some extra options uh we can add like from this price so let me show you um menu item tile let's go here we have add to card uh but we can do something like this if we have sizes sizes do we have sizes here no but we can grab them if we have sizes and let's also grab let's put this like this and let's put sizes and extra uh let's see how is it called extra extra ingredient prices extra ingredient prices and now here if we have sizes length of bigger than zero that's other question mark just in case or extra ingredient prices length is bigger than zero and let's put this into parenthesis one of those now now let's do end parenthesis so if we have something like this we can put a text called from and um maybe let's put span first and let's do uh from dollars and base price otherwise we can do the same with uh exclamation mark Or we can do here um and here instead of those we will do this and here I will do span and regular add to card so let's put like this and now for this uh for the regular we have add to card 11 and this one we have uh from $12 we can also change this to back to add to card and here we can do uh parenthesis from $11 like this yeah doesn't really matter uh it works uh I can I'm showing just that you can have different uh buttons depending if there's a popup or not for this specific uh for this specific thing uh menu item uh now we have this cart uh on the top let's fix it uh on the header uh we have this cart I would like to have an uh an icon for this so let's go to Hero icons uh let's search for cart and uh well uh I don't know which one you prefer but I think I will P this take this shopping card uh so let's go two icons let's do new file and let's do card JS maybe not card let's call it the shopping cart let's do rename and let's do shopping cart JS here export default function shopping cart and let's do return and let's do paste everything now uh for this I want to have this as a property class name and let's put this here class name and the default will be this now let put let's put our icon here so uh Link Link go here instead of this card I'm going to have my shopping shopping card icon and the rest let's put the rest into a span like this now let's see how it looks like uh yeah uh but uh I want this to be uh this thing to be here maybe on the top right corner of this shopping cart so uh for this link I'm going to add a class name relative and for the span I'm going to add a class name uh absolute all right now I don't need to have those parentheses anymore and now let's see I will do top zero top zero here write zero yeah and now let's put this here this is here um I want background to be primary yes text to be white text to be small and the padding of one and rounded Corners round the fult uh yes leading of uh see fre so it will be smaller and uh now let's pull it up so let's do minus minus top of three maybe two and minus right of two yeah so we have something like this and uh and this uh should work now and maybe more padding on the sides let's see padding on the top and the bottom will be one padding on the sides will be two yeah and maybe we can pull it right even more so let's do right minus 4 or three four and let's do even smaller text text XS yes and uh well padding on the sides let's put it back to one so let's do 10 and uh yeah this will work for now now uh the next thing is that we'll fix our card and so we can also do so we can uh place an order right and so we can first also um manage our card we can remove pizzas and so on all right so now to fix our card page the first thing we are going to need is uh to create a card directory inside our app directory so let's do here new and directory and let's do cart and inside we need to do page JS so page JS and let's do export theault function card page and now let's do here return and I'm going to put a section here called U let's do class name here CL last name and let the margin top of eight and let's put card here as a text all right so here is our shopping cart page and I think that we can do something like this on the left side I'm going to have like all of the products and on the right side we will have like a checkout box so uh let's see here inside I'm going to first put an H1 and um I put here shopping cart uh or maybe just uh check out check out and uh then I will have a div uh yes and here inside I will have a left side and a right side let's do right here and for this one I'm going to put here grid grid columns two so we'll have left and right side all right so uh now I'm going also to add some gap of at least four here and uh now let me see now for the left side we will have uh products so here I can do like products and but the thing is that I will list the products from the shopping cart right but first let's fix this checkout title here so here I want to put um uh text and uh or actually we can do uh use a component called um think something with header um section section headers and Main header will be cart and no subheader so now we have something like this but I want this one to be in the middle so I'm going to put a the with class name text Center here and I will put this thing here inside all right so for this one I'm going to add a little bit of margin top as well and now now I think it looks fine now let's go to the products and I think that just for the products we will just grab the products from the card context right so let's do const and let's see how it was called uh card context is here so I think it was uh called card products so let's grab card products from use uh context you context from react yes and here let's put our uh card context and everything is imported this looks fine so now we can list our products um first let's do maybe something like this if there are no products so card uh length is uh card length is zero and then let's do sorry not cart card products length is zero then let's do a div saying no products no products in your shopping cart right but if we have products so if we have card products length that is bigger than zero let's do end and then let's map through them so let's do card products and let's do map and for each product we will do parenthesis here and let's put the Dave with uh product name and now let's see um we cannot use this inside server components uh context inside server components so we need to put use client here on the top and now we have everything that we have inside our uh shopping cart so we have like 10 lines here um what I need to do is that for some of those we will have an additional size like small medium large and Extras so uh and I want to also display an image so let's do this um first Let's do an image so I'm going to put a separate D with an image here image and the source of this will be product image and uh here nothing for now and let's see we need to pass with and if so let's do with of uh 240 and half will be 240 as well now let's see yeah now we have images uh now for this uh Dave here that is parent of the image Let's uh make it that this will be Max width of uh or maybe let's just do WID of 64 something like this uh let's see if this worked let's do inspect here and uh after I think it works but we need to let's make it smaller let's do maybe 12 let's see yeah now images are super small let's do wave of 24 yeah uh now I want the text to be on the left side instead I would like the text to be on the right side so let's put this text thing on the another div that will be our right side and here on this parent I'm going to put the flex yeah so now we have some like this and we have flex but I will also add the something maybe like uh a gap let's do a gap of four between the image and the text yes so we have something like this now let's do also margin bottom of at least four so we have more spacing between uh rows and uh now maybe I will add a a small border on the bottom let's see yes so we have a border like this um let's even add some uh padding so let's do maybe padding on the top and the bottom of four and now let's also add the items Center so everything will be like centered here and yeah I think this looks nice and but now what I would like to add is uh maybe we can decrease the space think a little bit so let's do here two and margin bottom let's change to two yeah and here we have title but I want to have um extra stuff underneath here so if it's uh in case it's uh size or something I want to also have it so let's add here brake line uh or maybe not brake line let's put this product name into an H3 so let's put this here here and here I'm going to put the div for the size but only if we have any size so let's do product uh size and let's do end I don't know if it was size or if it was selected size let's see uh app context and when we add a product let's see um add product we add size yeah so we have it uh a size or and we have extras inside this uh product here so let's do if we have size then let's do this div and let's do something like this size coolon and let's P let's put a span with the actual size so let's do size oops not like this product size and now let's see uh looks like it didn't work I think it's because we need to put size size name and now let's see here we have pepperoni size medium so this is nice and now let's do something like this if product has extras and length of those is bigger than zero then let's do end parenthesis let's put a div with uh with something like this uh let's put extras coolon and let's put a span and inside the span we are going to grab and pull uh all of the extras uh maybe not inside the span and we're going to put this um as uh like this let's put this into separate diffs so let's do um like this and let's do product extras and let's map through them and for each uh extra extra thing I'm going to put a div with uh extra name and uh I want to do plus dollar and um or I don't know if we want to maybe just uh how much is it in the so let's do extra price yeah so now let's see uh for example here we have extra cheese for $1 and here we have extra cheese for $1 and extra pepperoni for $2 now it will be nice to style it a little better and to have also a button to remove a product so uh for the for the names I think the names look okay let's fix the sizing thing so here we have sizing thing and let's put this like this and now for the size I want the text to be small and to be more grayish so let's do gray 500 and now let's see now we have something like this size medium and uh now for the extras I think that uh maybe we can get rid of the text extras and uh we can just uh keep the those lines here so let's get rid of this text extras and let's see we have extra cheese for $1 and extra pepperoni uh for those texts maybe we can also make uh let's see on this div let's do text small and let's do text Gray 500 so now it looks like this and um I think uh it looks fine but uh we want to make this size thing different from the exas so um or we could also put medium in on the on the beginning of the menu item but let's keep it for now here size medium and um now I want this to be different so I think I will put this as black color for now let's remove this text Gray 500 from this and now we have something like this maybe we can do text Gray like 700 700 let's see yeah and the title I want the title to be bold or semi bold let's do class name semi font semi bold and let's see now we have something like this I think uh it looks fine and maybe we can do the size even darker so I'm going to remove this yeah and then we have uh something like this uh now we need to have total price for each item so here like $12 and here with those extras it will be $15 so let's put here here we have the right side div here is the left side div for the image here is the right side div for the all of text let's put another one inside this Flex parent with the price and the price will be I don't know let's put like $12 here just for now as you can see here and uh and now for the host $12 let's make them also bigger so let's do text large and let's do text or semi bold semi B semi bold now let's see yeah something like this and on the most right side I want to have a button to uh remove a item remove something like this so uh now it looks like this and um to fix it so everything will be in line I'm going to put grow on the second da here with all of those texts so on this let's put class name of grow so it will push the rest to the right all right so uh this looks fine uh except that for the remove I want to have a trash icon so let's put this here trash uh trash let's import and now let's see and I think it looks fine except I want to decrease paddings so let's do padding of uh two and now it looks looks like this and I think this is fine maybe we can increase the gaps uh a little bit more especially here but we can also do like margin left uh if we if you want so on this div let's add margin left of uh two so we will have more spacing here and and I think it looks fine now let's fix those $12 it should be uh um it should be total price so uh how can we um calculate the total price and to do this um we need to take product base price and then if we have a sizing price we also need to add it and then if we have extras we also need to add them so uh how can we do this um we would be nice to have a function for this let's put this function inside app context and here we have C context let's also put export function um called card product price so we can calculate it and here we are going to pass card product and to calculate this uh we will do something like this SL price for the beginning it will be uh card product base uh price and then we will do something like this if we have a card product size then we are all going to add this to our price uh so the card product size price and then if we have extras so let's do card product um extras and then let's do end length is bigger than zero then we will do something like this for each extra let's do car product extras um for each const extra thing of those let's do something like this for each extra we want to add it to the price let's do price extra do price and now we just need to do return price and this function should work so now let's go here to our card page and here I'm going to put to the use this function so card product uh price and here we just put our uh card product so product all right so uh we have 17 here for those extras and size medium let's put also a dollar sign here on the beginning and it looks fine now would be nice to fix this uh button that removes uh from card so let's put this button to be type of button first and on click and on click uh we have this function inside our card context and the function is called remove card product and as you can see the param is index to remove so we need to know the index the index we can grab it from our Loop here's our Loop we are using map and as you can see here we have our product but we can also grab index from here and um let's use this index so let's go here on click let's do Arrow function and let's do and we need this function remove from from cart I think it was called remove from card let's see remove card product let's grab remove card product yes and let's now use this function remove card product and now we need this index here right so now if I click uh remove from this one it will be removed and now let's see v pizza and the next is sausage pizza if I remove veggie pizza it's not here and even if I refresh it's the sausage pizza that uh comes first all right now uh let me see we have this remove card product here let me go inside this function and let's see yeah we are updating local storage uh another thing will be that would be nice is to have this uh success toast thing so let me add this here let's do toast import from react Hood toast that's success and let's put uh here product removed uh yeah so if I now removed the sausage pizza product removed okay it hit uh twice so something is wrong here maybe I can put it here outside of this Set Card products let's see uh if I want to remove pasta Alfredo yeah now we have it only once um yeah this looks fine we have two chicken pizzas and so let's remove one and let's remove this v pizza and let's remove one of pepperonis and uh let's remove this one so now we have only two pizzas here all right so now we see what is the total here and it should be this plus this and so uh now we can maybe fix the right side of the um uh right side of the of this checkout page but before we will do this maybe it would be nice to have a total here on the bottom so um let's see let's go to our card page and let's see here we are looping through all of those uh products and uh now let's see what's this div about yeah it needs to be inside this div so here we will have a div for total and uh let's put total and now let's put a total uh price price for everything so how can we total uh calculate total price we just take all of the products so let's do cart products we map through them and for each product we want to grab the price so let's do card product price for this product and we want to H know the total so let's do math sum I think it was some let's see uh some I don't know if there's such function or if we need to do something else let's do math some js no there's no such function um so we need to so we need to add it manually or we can or we can look through them uh I will remove it from here for now and I will calculate the total here so let's do let total equals zero and uh now let's do something like this uh for each uh card or or for each product in uh card products I'm going to do update total and I'm going to add our product uh total price so let's do um let's use this function card product price for this product and now we have our total here let's see here total let's put total and let's put dollar sign here like this and now let's see do we have a total not a number so something is wrong here let's see a card product price for each product inside this uh card products and we added to Total uh but it looks like doesn't work let's refresh no it doesn't work but car product price seems to work because we are using it here for those prices something is wrong but uh let's see console log I want to do cono log on the card product price for each product and now let's see inspect console and it's undefined for each one um so something is wrong with this function or something is wrong with this Loop here let's also check console log on the p and wow it looks like 0 1 01 okay it shouldn't be in because with in we get only keys I want to have off and now it should work so let me see the total now the total is $29 correct now um I want to have a lot of padding so let's do padding on the top and the bottom of four and padding let's see now yeah now I want this to be aligned to the right so let do text uh right and let's see now I want to have spacing so I want to pull it more to the left so let me see I'm going to add the padding crite of eight and now let's see yeah almost there let's do maybe ping right 24 too much let's do like some something like 16 yeah that's much better now this 29 should be much bigger so instead of putting this like this I'm going to put a span and for this span I'm going to add the class names like text large and semi bold now let's see total 29 let's add a no breaking space here so we can have some some um spacing here maybe we can add instead a padding left of two and here for this total um let's see how it looks like now yeah maybe for the total I will put uh sub tootal for now sub tootal I will call it subtotal and I will make it grayish so let's put span with class names and that class name here will be text Gray 500 and let's put subtotal here inside let's also put this here and this here so it will be easier to read and I think it looks fine maybe it would be better to have this title more here to the uh to the left side and I don't know we have it here for now um May and maybe another thing would be to have on the left side here a title saying uh something like uh your products in your shopping cart or menu items menu items in your shopping cart or something like this but first let's fix the right side here where we will have some kind of uh checkup so uh let's see here we have a div for the right side uh what I want to do here is I will add a gray background of uh let's say 200 yes and I will put a check check out here let's put this as an H2 checkout and here I'm going to make it wher like 100 let's add a padding of four let's add rounded of large so uh rounded corners on the bottom we will have of course and the whole thing will be a form of course and on the bottom we'll have button of type uh submit submit and it will say um p and then the total total like this for now and in between we want to have some labels with uh uh text here and inputs for the address so I want to have a label yeah like address and then an input for uh for input type text for uh for example here stet address and the country and so on yeah something uh something like this uh but I want to also have like phone number and so on and everything that we basically have here so we have phone street address postal code and the city and Country so basically I would like to just uh take this part and put it as a separate component so let's do this let's go to um components and let's see layout I think it's inside layout we have this uh user form and uh let's see here we have a lot of uh a lot of um inputs here we have phone phone street address postal code city and so on and Country so let's use it uh let's start here from the phone and the City Country here ends uh our input for the country let's cut it from here here and let's put it as a separate component inside layout why not let's put it as address inputs. JS and here let's do export default function address inputs and let's do return and we have many elements here so I'm going to put a react fragment let's paste everything and as you can see we don't have this uh state things and uh we we all need this so uh let's do maybe something like this we are going to grab two properties the first will be address that will have all of these fields and uh the second will be set address uh props set address prop and here we have address props all of the props and uh now let's do something like this let's grab everything so phone straet uh stet Street uh address and uh let's see postal code and the city uh and Country from uh address props like this and now as you can see we have those uh Setters for our state instead of those we are going to use this set address prop so um let's do something like this for each input that we have some think like this I'm going to change uh oops I'm going to change this function so I selected everywhere to set address prop and the first uh will be the first par here will be a string saying what is the property so here we will have a phone here we will have um something called the street address here we will have postal code and then City and and then country here okay so we have this set address prop function that we are going to call here now let's go back to our profile so we can fix it inside user form and here let's do something like this and um let's do address address inputs and address props here we need to put uh everything object of everything that we have related to the to the uh to the address right so we need to have like street address postal code City Country and so on so uh so let's put it uh let's put the street address and uh we need also phone street address uh postal code city and uh what else City postal code country and let's see do we have something else street address post code City Country City Country post code Street address I think that's it and uh now another thing that we will need I can put it maybe as one line like this another thing we will need is this Set uh address property so as you remember it's a function so let's may put this as an AR function for now where the first is the name of the property prop name like phone or something and the second part is value let's put value like this and um now basically here is uh that I need to have a function that will first check if this is like a phone then we will do set phone and so on and um but to make it a little bit simpler I'm going to put everything or maybe not everything let's create this as a function so uh let's put a function here function called the uh handle address change and the first will be uh property name or yeah property name and then the value and property name will be like a City postal code country and so on uh we can basically do something like this if the property name is uh City we will do set city with the new value and we need to do the same thing so let's do something like this same thing for 1 two three four five things so let's see first we will have a phone so it's the phone then we will have street address and then we will have U here we have City postal code here we will have a set postal code oops and then we will have a city and then here we will have country and the set country let's see phone here we will have set phone phone set phone street address set street address postal code set postal code city set City okay uh it looks fine now let's use this function down here so let's just put it like this and this should do this uh let's see if I can edit let's put uh test address 1 2 three if I hit save saving profile saved if I refresh it's still saved now let's go back to our checkout and let's use this address inputs um let's put put this into our card page and here instead of this one let's put address inputs and let's see we need to pass here our address props for now I'm going to put an empty object and now as you can see we have um those inputs here we don't have state for our address uh so let's go to the top and let's define it we can Define err Frank from one by one like street address and so on but I think would be maybe easier to have this as one state so let's do something like this uh address and set address equals use State and default will be an empty object all right so let's put this here uh as address and now as you remember we need to have handle changes inside those inputs using set address prop and uh to to handle this as you remember we will have the prop name the uh address prop name and then the new value here and with this we are going to do set address and uh basically we are grabbing the P previous address uh previous address State and we are going to use it uh maybe let's put this as a separate function called handle hand handle address change and let's put this on the top uh function handle uh address change and um we will grab here property name property name as per and value right so with those property name and value all we want to do is we want to do set address and we want to grab the previous value of the address so let's do previous address and we want to do something like this we want to grab the previous so let's do return uh copy of previous address except that this property name should have this new value and uh this should work we can even simplify this let's see if it works if we can update yeah I think it works uh now we can simplify this we can put this remove the return and we can put this uh like this let's see no and this will not work we actually will need return or extra parenthesis here right uh so we have something like this and now let's see we can do check out and it seems that those inputs are fine all right nothing is saved here but that's okay uh now another thing is that if you are logged in I would like to fill this uh form for you and we should get rid of this extra address here so let's see Andress label let's remove it and now let's see uh we have something called the um use profile use profile and we can grab the data like this data from use profile let's rename it to profile data and let's do a console log to see if we have address there inside so let's do like this and the data is not defined here because it was renamed to profile data now let's see let's do inspect and console yes it's an object and let's see and we have City Country and everything here so uh so this looks uh nice um let's see we can use the data from here to put everything inside our address so let's do this uh let's do something like this use effect let's put empty Arrow function for now for dependent is we are going to use profile data and we are going to do something like this if we have inside profile data City then uh we are going to do set address for our form and uh here for the set address we can just grab everything from the profile data and we can put it here but the problem is that here we have even um like name image and so on and the thing is that that we want to only grab uh stuff from the address so let's grab those stuff here uh so let's grab phone uh Street uh street address City and the postal code and uh what else postal code City Country from profile data and then let's put all of those into a separate uh uh a separate constant so let's do const address from profile equals and we can just copy this and we can put this like this and we can maybe put this as an like this into several lines to make it easier to read I don't know if it makes any difference to reading experience but here you go and here we are going to put address from profile and this way when I refresh um it feels it fills uh fills the information from my profile page so if I go to my profile and I change this address here to uh like 32 one test address 3 to1 and um and I hit save I go to my profile here here we have test address street address test address 321 as I saved before so that is nice uh so we have our card here uh maybe it would be nice to have uh more Gap here between those two things so let me see um gap of four let's do gap of eight yeah and I think this looks much nicer uh maybe even the spacing here so let's do margin top of eight yeah so we have something like this and I think this looks uh good enough uh maybe this subtotal can be a little bit higher let's see uh we we have subtotal um let's see subtotal we have it here let's change this one to two so it will be closer and let's see subtotal here yeah if I remove like padding y uh let's see yeah I don't know why it still has those uh this spacing I think it's from margin so yeah that's okay we don't need those margins I think so let's see here we have a margin bottom of two let's remove it yeah and now we have some pink like this uh let's go back to sub total I want to add a little bit of padding y let's do two because now we don't have those margins and for those spacings I think we can increase them so let's see let's do four and let's see yeah now we have more spacing I think it looks nice all right so our card looks fine let's see if if uh everything still works if we can add the let's see I'm going to remove classic chicken let's remove let's refresh and now let's go to the menu and let's add uh classic chicken it says added to cart and we have this classic chicken one more thing I would like to add for our cart and menu experience is there is a there's a package called the I think it was react flying uh item and basically what it does is that when you click on something it will send like half visible image to the card and it looks really nice so I'm going to add it uh there's something called we have component menu item tile or menu item where we have our button right button that does uh this add two card so uh let's see uh why want to do is that when you add to cart it will do the same kind of uh thing um so if you click on this add to cart it will send this image to the cart uh if you have like pepperoni pizza it opens a popup and then you have add to card with the with the all of the those stuffs um so uh I think we'll need to have different functionality for the those buttons first um let me see um we have this add to card and uh it's this one add to cart and we know that uh this one add to cart will should send the image like this to the shopping cart only if we don't have this from blah blah blah so uh let me see add to card selected price and here we have menu item tile let's let's see here we have a add to card base price and here we have add to card from base price uh here we are checking if we have extras or sizings let's put this as a separate uh constant here con has sizes or extras equals and I'm going to put uh this here like this and now I can use it instead of this has extras H sizes or extras then we are showing uh from this price as we are doing for pepperoni because we have sizes here small medium large and Extras here but for the classic chicken uh we don't have any extras or anything I can show you in myu items for example for pepperoni I added the sizes here and extra stuff but for example for um I don't know veggie pizza I don't have any sizes or ingredients that's why when we go to the menu veg Pizza is add to card $11 always and pepperoni pizza is add to card from $12 because it has extra sizes or extra uh it has sizes or extras but now uh we have this button here and what we can do is that uh uh we can do something like this um first I'm going to put only this button add to part uh as a separate component uh so in our components we have menu I'm going to add a button a new file here called add to card uh button button.js and let's see what we will need here and let's go back to our menu item or menu item tile and our button is information has sizes or extras and the base price and have this functionally add to card um so let me copy this and let's go to our new add to card button let's put let's create a component export default function add to card uh button and let's do return here return let's put the button and we will need to have H sizes or extras as a property see I'm going to put this here as into separate lines and as SES are extras and we will need to have some kind of like on click instead of this uh on add to card so let's put on click here and uh now let's put here let's also grab base price and I think that's it now let's go to menu item tile we can remove this one and we can just do add to cart button and we can just put head sizes or extra to head sizes or extras and we also need to add our on click and for on click it was I think um our add to card function yes and then we also need to have let's see what else base price so let's do base price it's base price and that's it now thanks to this if we have this button separately it's always this button it's not the button that shows uh here because we don't have this from blah blah blah it's always the button that is inside this tile uh thanks to this we can know that if we have this from blah blah blah then we cannot do this flying image if you click uh this one let's see uh pepperoni pizza it doesn't add to the card it shows popup so we can so we add to card only if we don't have this from thing so here we don't have from thing so we need to check if has sizes or extras and if we don't have sizes or extras I want to implement this and I can show you how it works here uh as you can see it sends an image and we are going to send an image to our card so uh here we have button type button then we have on click and extra classes and so on what I want to do is here first if we don't have has uh if we don't have sizes or extras then I'm going to do return and I'm going to use this uh F flying button so let's import this one I don't know if we installed this one but let's uh install it let's do yarn add and let's install this one and um now let's see now let's import this one so let's go up uh here let's import and now we can use it so we just put it uh like this uh flying button here we need here we need to have uh image source so um let's put this fly like this for now and let's see here we have fly fly fly here we have add to card from $12 because this one opens a popup uh we need to have image here right so let's also grab it as a property and let's put this one here image let's go back to item tile and let's pass our image here as well image image I think we have this inside property yeah let's go back to out car button and now let's see what happens if I CLI click on fly as you can see we have flying pizzas it uh they fly to the wrong place but we can add some extra properties here called uh Target top and Target left so let's do Target top equals uh let's do like 5% and uh now let's also add Target uh left and here I'm going to do like 95% so now if I do classic chicken it flies to the shopping cart so that is uh nice um those buttons look really bad let's see if we can add some class names here here so I'm going to put those uh the same class names here so let's put like this and uh as you can see those class names do not work um let's see uh I'm going to let's get inside let's see if there's a property called No this code is not readable let's see in the documentation class names no there's no information about this but we can uh style it differently uh we can do something like this uh we can put a div here above saying um let's have a class name that will be flying uh button uh parent something like this and let's put our flying button inside and we don't need those class names and now we will go to our globals CSS and we will do something like this flying Bon parent and flying button parent and the the button that is inside will have those styles that we are going to apply here and those will be the same that we have for this uh submit uh button so let's see yeah so now it looks much better uh we will need some extra classes that we have here margin top uh background primary and so maybe we can add some of them here like this and round the the full we need to red full on our Global CSS let's put like this and I think it looks much better now so uh let's see let's change this fly to the text that should be there so the text that should be there is this one and so let's put this one here yeah so now it's correct but now we don't need this one because if it doesn't has extra sizes it's handled here so this will never run so so actually I can just put it like this and here I'm going to add and if it has extra sizes then we do add to card from but if we go here it always has extra sizes because if it doesn't we do return here and the code stops so I don't need to have this and this so let's put like this and now let's see this looks fine let's save it and now let's see so if I will add classic chicken it's sends classic chicken pizza to the cart uh it doesn't update this number and it uh let's see why we have this on click here but we don't have flying button on click let's see let's see if I add this on click here let's see I will refresh add to card no still nothing let's see let's see how they are doing this uh they have flying button let's search for click no nothing here maybe we can do something like this div let's put just a div with on click of and this on click from the parms and yes and now let's put add to card inside and let's see if this will do the trick yeah now it adds to the card and um it even shows this added to card I don't know if we need this uh if you want you can go to ab ab context and add two c and you can remove this uh let's see where it is um add to card here we have for removed product and uh here we don't have for the add to card I think it's inside um let's see where is it add two card no it's not it's not there anymore all right but uh added two card yeah let's sear for this added to cart in inside menu item okay so let's remove it let's refresh and let's see now we just have flying pizzas and the flying desserts yeah so that is uh nice um well um you can have add the to card confirmation if you want or you can just have a um or you can just have a just flying Pizza another thing we could actually change here is that here we can have options like uh a think position and we can do top uh right let's see and now if we add something add to card add to card and uh yeah so if you want this looks also nice it depends on you um so I'm going to remove this toast thing and I will have only flying pizzas and flying images sorry all right uh so uh now we have flying pizzas but if we have like pepperoni that has extra stuff we need to also fix that uh when we click this one it will uh have flying pizza so let's go to menu item and here we have this popup thing and here we have a separate button and that uh that does those uh that adds to um adds to card so um let's replace this button with uh or let's put this button into our uh flying button I think it was called flying button so let's put this button inside our flying button now let's see if I want to add pepperoni pizza uh it looks like this if I click nothing happens we get an error let's see what what's the error about I cannot repes of null reading style okay so we need I guess it's because flying bottom is empty let's do Target top of 5% and Target left of 95% and the source I think it's for the image so let's put image here and let's put those into separate uh lines yeah and now let's see again if I do pepperoni on two card uh still in eror let's see why read the properties of null reading style okay so something is wrong here with our flying button um let's see what will if it if it will work if I will have this flying button like this and will say test and let's open pepperoni piz and let's hit test okay so SEC cany test works so uh the only thing here is that we will need to have um in instead of a button we will have a div with our on click that we have here and all of those classes so let's put um those classes and onclick uh here and this text let's put this inside this div so we don't need this uh button here anymore and we have this add to card and it doesn't work I think it doesn't work let's see um style I think it doesn't work because uh it hides the popup um before uh the image um the sending of the image is complete so um when we do this I don't want to hide the popup inside this function um after directly I want to wait like 1 second so here we are uh hiding the popup I want to wait one second let's just set time out and first we have call back so let's put this into callback and here we have DeLay So let's put 1 second now let's see if this will help and let's refresh and and I want to grab pepperoni add to card and as you can see it works it uh it uh adds to card with this animation and it closes the popup or it did once let's see once again add to card add to card and we still see the popup maybe we can do something like this um I will add a Sync here and instead of set timeout I'm going to do a delay first so let's do uh await and let's do something like this Set uh no await new promise with a resolve function and we'll set timeout with resolve function after 1 second and then here we will have a set show pop up to false now let's see I will refresh and let's the pepperoni pizza add to card and it works fine we can decrease this to maybe like 600 milliseconds let's see let's see here a to card yeah it works nicely it doesn't uh hide the popup let's see why add to cart add to cart and I still see the popup let's see why here we have some warnings and so on nothing about the popup let's see wait new promise resolve let's do here console log and let's do hiding popup Hi D popup and now let's see inspect console let's add the pepperoni and I don't see this hiding popup let's see why uh looks like it stopped somewhere uh somewhere here it needs to be here so let's do also here console log if it has options and now let's see if I refresh let's add the pepperoni it says add options true but it hi the popup and it shows some errors but uh I think that's because we need to have like full second here let's do refresh and let's test again add to card and and nothing more we have only add to card so uh let's see I will do console log add to card and now let's see add to card add to card true hiding popup let's try again uh we get animation but now no console logs Now it worked and let's do again I will clear here add to card okay it worked let's do once again let's clear everything add to cart okay so it uh worked let's do once again on our pepperoni pizza let's see add to cart true hiding popup okay so it seems like uh it works and uh we have a lot of uh pepperoni pizzas so I'm going to remove uh some some of them so let me remove all of those and I will have only one with some extras so this works and now we are oops now we are done with uh our flying pizzas flying images and uh yeah I think it looks fine now we have even classic chicken pizza yes and now let's only test the last one hour pepperoni pizza that will be me medium with extra cheese let's add it to cart and looks like it works pepperoni pizza medium with extra cheese okay let's add also maybe a large pepperoni pizza with all of the extras extras for $19 and now let's see here yeah uh it worked let's remove some of them uh so we are done with our uh card we have some uh popups we have some cool animations uh we have sub tottal here and we have checkout with uh all of the information from the profile if someone is not logged in um so if you are a guest so for example I can log out uh I need to fill it manually I'm not logged in anymore but I still see uh my pizzas here and I can do the checkout and but I need to fill everything manually The Next Step will be actually uh so we can do a checkout with stripe and uh so later we can also see our orders uh inside our profile so if you are logged in you can go to orders and you should see your own orders or if you're an admin as I am you should see all of the orders so that is the next step that we need to fix so that will be it for this video I'm going to put a part two in the description if you want to fix the rest of stuff here fix some warnings and deploy it on ver so check out the description otherwise we have a fully working site here as you can see we have a cool looking start page with uh some hero section here best sellers listed from the database about us and contact we have nice looking menu page where we have some cool popups we can pick some sizes if we want we have some extras that we can add for menu items we have categories menu items and then everything looks really nice for the login we have a working login for both credentials email and password and we can also log in with Google and that's the prefer way of for me to log in and for the profile as you can see we have a lot of stuff here going on we can edit remove and so on with categories and even menu items so this looks really nice everything seems to be working we can upload change images and add extras here and we can even add it users make them admins or not and we can even see here all of the orders that's all for this video I hope you learned something useful and if you did please click the like button and subscribe if you want to see more videos like this one have a nice day and see you in the next video
Info
Channel: Coding With Dawid
Views: 158,786
Rating: undefined out of 5
Keywords: next js, next js project, next project, next js tutorial, next js food ordering, next js food ordering app, next js resturant website, next js resturant app, next js food ordering project, next js resturant project, next js app, food ordering app, restaurant app, food ordering project, javascript project, fullstack project, fullstack javascript app, fullstack javascript project, fullstack javascript, js, app, project, restaurant website, restaurant website next js
Id: nGoSP3MBV2E
Channel Id: undefined
Length: 694min 43sec (41683 seconds)
Published: Sun Nov 12 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.