Next.js 14 Admin Dashboard Tutorial | Fullstack Next.js 14 Project with Server Actions
Lama Dev
0:00 Hello friends today we are going
0:01 to create this beautiful dashboard application using
0:05 nextjs 14 we'll Design This homepage and after that you will learn how
0:10 to fatch data using the new version of nextjs this is important because we
0:16 will not use an API route anymore we will patch and update our data
0:21 on the server components you will learn how to use pagination how
0:26 to search for any item and you will see how how easy to create
0:31 all these functionalities without using any use State and use effect hooks we
0:36 will fetch the data using the nextjs
0:39 navigation and it improves the user experience
0:42 and the search engine optimization and after that you will learn the most
0:47 exciting part nextjs server actions as soon as you click here it's going
0:52 to revalidate your data and here you can add a new user with server
0:58 actions let's see the user it will display the user detail and we can
1:09 update the data and we will do the same things for the products
1:16 and finally we will build the authentication
1:19 and protect our routes using a middleware
1:24 let's log out as you can see it redirects me to the login
1:28 page and now I can cannot reach the dashboard let's write the wrong credentials
1:34 and to show this error we'll be using the new use form State
1:39 hook this hook allows us to get the response from a server action if
1:44 there's an error we are going to update the form State and if
1:49 I write the correct credentials I will be redirected to the dashboard and now
1:55 I cannot see the login page it's a great project to learn the new
1:59 new features of nextjs 14 and in the next video I will create
2:04 a complete nextjs tutorial if you don't want to miss that you can
2:09 open your notifications and after completing
2:12 this tutorial we'll deploy our project using hostinger
2:16 as you know it's the hosting sponsor of the channel and I create
2:20 different projects using hostinger every month
2:23 and for this project I'm going to choose
2:25 a VPS hosting if you choose the most popular VPS you will get
2:30 a really generous RAM storage and bandwidth so you can deploy all your projects
2:36 on a single server and these servers are super fast because they use
2:41 mvme ssds and one of the most powerful AMD processors and now there is
2:48 the biggest discount of the year only for Black Friday and if you want
2:53 to get an extra discount use the link in the description choose your time
2:58 period and and apply the lamad dev coupon code here after purchasing you
3:04 are ready to set up your server choose any location we are going
3:09 to install a panel and it's going to be Cloud panel let's create
3:14 a password and finish the setup after this process it will be ready to deploy
3:22 your apps so let's create our application and deploy it to our server
3:31 okay let's open up vscode and create here a new folder and inside
3:36 this folder we will create our next application to do that you can open
3:41 up your terminal and say MPX create next app and latest if you do
3:49 that it's going to install the latest version of nextjs but I recommend
3:54 you to use my GitHub repository and this starter Branch because if you watch
3:58 this video after the release date some
4:01 dependency versions might be different to prevent
4:04 any possible errors you can use
4:06 this repository I also removed all the unnecessary
4:10 files and styles so we are going to create everything from scratch without
4:15 wasting time so I'm going to come back and make sure you choose
4:21 this starter Branch because at the end of the video I'm going to create
4:24 another Branch here and it's going
4:26 to be the completed version of the application
4:30 and after choosing starter Fork this branch and it's going to create a new
4:35 repository on your account so it will be easier for you to follow
4:38 your steps during the development after forking you can come here and copy
4:44 your URL and come here let's remove this I will say get clone paste
4:52 your url Dot and enter as you can see they are here but we
4:59 don't have our libraries let's install I will say mpm install and not
5:06 modules folder is here right now it's ready to run let's run I
5:11 will say mpm run down let's open up Local Host 3000 okay it's here
5:21 so let's decide what we are going to create this is going to be
5:24 our homepage and everybody will be able to reach this page but after
5:29 that we are going to create this dashboard and we will be able
5:32 to see this page only when we are logged in basically we are going
5:37 to have three main Pages the homepage the login page and the dashboard
5:43 let me log in okay let's create them and after we will start designing
5:52 our dashboard if you check the app directory you going to see the page
5:59 file here this is our homepage let's create dashboard and login pages page.
6:10 jsx and another folder and it's going
6:13 to be login let's create our functions I will
6:20 say login page and dashboard page if you
6:30 don't know how I'm using this shortcut you
6:33 can watch my vscode video and you can learn how to create these react cipit okay
6:42 let's see this is the homepage dashboard
6:49 and login okay perfect let's start with this dashboard
6:55 I'm going to open up my example as you can see we have a sidebar
6:59 here and a na bar and if you check other Pages like users you will see
7:05 that the sidebar and nbar is still here or if you open up any other
7:11 Pages they are still here basically they are going to be a part of our dashboard
7:16 layout so instead of creating sidebar and nailbar
7:20 components and use them for every single
7:23 page we can add them into our layout and we are not going to waste
7:27 our time let's do that firstly I'm
7:31 going to create my nbar and sidebar components
7:34 to do that you can create here components
7:36 folder or UI folder let's say UI because
7:40 in the documentation of nextjs they are using
7:43 UI and inside I will say dashboard components
7:53 login page components and we can create homepage
7:56 components inside directly this UI folder but remember
8:00 the nabar and sidebar belongs to dashboard we are not going to use it
8:04 in the homepage or login page this is
8:07 why I created this folder and inside let's say
8:12 nowbar oops nowbar and sidebar let's create
8:21 our components and my component I will do the same thing for the nbar and let's
8:35 use them inside our dashboard to do that I'm
8:38 going to create my layout jsx and as you realize we have the main layout
8:49 here let me shrink this and whatever I add here let's say test and this H1
9:01 tag is going to appear everywhere in dashboard
9:05 in homepage and login page by the way
9:10 there's an error because I used it before body tag it should be inside
9:15 but anyway this is how we are using layouts so I can do the same thing
9:20 for the dashboard page I'm going to remove this and as you can see we are
9:27 going to need a children and this children
9:29 will be our main content basically this ad
9:35 page users page or these contents so let's take this children I'm going to close
9:45 here and I will say children and inside my layout I will say menu de
9:54 and it's going to contain our sidebar
9:58 and after this div I'm going to create another
10:00 one and it's going to contain our nebar and this children so first one will
10:07 be nowar and our children let's save this by the way and perfect so if I
10:20 create any other page inside this dashboard
10:23 we are going to keep seeing this sidebar
10:25 and N let's create inside dashboard I will
10:29 say users and products let's create our Pages page.
10:40 jsx let's say products page and users Page by the way the name has to be page
10:50 if you create any other name here it's not
10:53 going to work the extension can be JS jsx or TSX let's say users page let's see
11:10 as you can see perfect and product okay this is
11:15 how we are using nextjs layouts so let's give
11:19 some style as you can see there's a space
11:22 here but in our application we don't have
11:25 any space it starts from here as you can
11:28 see the color is different so let's give
11:32 a global style if you install a next application you're
11:36 going to see that your Global CS is inside the app directory but I want to move
11:41 this into UI folder like that let's open up
11:50 layout and change here it's going to be UI
11:55 and Global CSS and this is the recommended
11:58 folder structure in the nextjs documentation by the way
12:02 I'm going to create a complete nextjs course
12:05 and in this course I'm going to share my thoughts
12:08 about this structure or generally about next Jaz
12:13 but for now for this tutorial let's stick to official
12:16 documentation and use it like that inside UI
12:20 we are going to create our components and we
12:23 are going to Define our CSS files okay
12:27 let's actually close everything and open up Global CSS
12:32 first say I want to give a background
12:34 and text color for my application to do that I'm
12:37 going to create some variables I will say root
12:41 let's say background color and it's going to be
12:44 these dark color and I'm going to create
12:47 the soft version of this color BJ soft and it's
12:51 going to be this color and the text color
12:54 will be white but also I'm going to create
12:58 the software version text soft and I'm going
13:02 to paste my color here it's going to be
13:05 this gray color okay let's use this inside
13:09 our application to do that I'm going to be
13:11 using body and I will say background color is
13:16 BG and the default color is text color is
13:22 text and let's remove the default margin and padding
13:26 using Universal selector and I will say box
13:31 sizing and Border box if you don't know fundamentals
13:36 if you don't know what's the universal selector why
13:39 we are using our background color inside body what's
13:43 HTML you can just check my previous tutorial you're
13:46 going to find awesome CSS tricks and that video
13:50 will be in the cart on the top right you can check that video and come back okay
13:57 and what else if you create any link it's going to have a default color to prent
14:04 this I'm going to choose all the links and I
14:07 will say color will be inherited from the parent
14:11 so we are not going to Define any color here and I'm going to delete the text
14:15 decoration it's going to be num because by default
14:18 there is an underline I'm going to remove
14:21 that and that's all this is our Global Styles
14:26 I can close here and let's give a style
14:30 for our dashboard in our example as you can
14:36 see we have two main sections this sidebar container
14:40 and our content basically we are going to be
14:42 using flexbox so inside dashboard I'm going to create
14:47 a CSS file and it's going to be dashboard.
14:51 module.
14:52 CSS there's a typo here okay and each component is
14:58 is going to have its own CSS file so I will
15:01 say nowar module let's copy this and paste for sidebar
15:13 oops inside sidebar component okay let's close them and this is
15:20 our main CSS file and what I'm going to do
15:24 is create a container and make that container display Flex let's
15:30 open up our page I'm going to close everything here
15:34 this is our layout and I will say class name styles.
15:42 container let's import our CSS by the way I'll say
15:47 import styles from UI dashboard CSS okay there's a warning
15:55 here because I forgot the dashboard folder and I'm
16:01 going to give class name for this sidebar container styles.
16:07 let's say menu and it's going to be content okay and in our example
16:18 as you can see this menu is smaller than our content so we can
16:22 give some sizes firstly let's open up our CSS file here and I'm going
16:27 to close this menu menu and I will say container display flex and for menu
16:34 container I'm going to give Flex one and for Content container Flex will be
16:41 four times bigger than menu like that let's give our background for the menu
16:50 I'll say background color we can use our variable here and it's going to be
16:56 PG soft it's here if it's not visible enough it's because of the video
17:05 If you create your own application you are going to see that this color
17:08 is much softer and let's give some padding okay and I will do the same
17:20 thing for my content before this content container let's take care of our site
17:28 bar I'm going to open up my sidebar container here and sidebar CSS here
17:37 and let's give class name styles do
17:42 container let's import styles from sidebar module
17:51 CSS before giving any style let's create our items those links I'm just going
17:59 to copy and paste my data as you can see we have some categories
18:07 and each category has some links inside which
18:11 includes icon the link URL and the title
18:16 and for those icons we are going to be using react icon Library let's
18:22 do that I'm going to open up my terminal and I will say m
18:28 PM install react icons and I'm going to write the version as I said
18:34 if you don't want to see any conflict any error you should install exactly
18:39 the same versions after that you can update I will enter let's close again
18:46 and I'm going to import my icons like that if you want to you can
18:52 visit this website and search for any
18:55 icon for example let's choose material icons
19:01 and here if you want to use this icon just click on that and it's
19:06 going to copy this component and you can import this here okay right now
19:13 we can show our items in our sidebar to do that I'm going to be
19:18 using map I will say menu items map and for each item let's say
19:24 each category we are going to create a do actually let's say a list
19:32 here and I'm going to WRA my map here and I'm going to call
19:39 a list item let's check what we have as you can see each category has
19:44 a title and list let's use this title cat do title of course there
19:52 is a warning because we didn't use key value let's say key and again cat.
19:59 tile because it's Unique let's see I'm going to close
20:05 here I'm going to open up dashboard oops I
20:10 didn't use curly brackets and perfect and I can do
20:18 the same thing for our links this list to do
20:23 that I'm going to create another component let me make
20:28 this bigger and inside sidebar I'm going to create let's
20:33 a menual link I'm going to copy this and create
20:36 my component and CSS let's create our function and using
20:50 this component I can show my links let's take
20:53 our item here first first here I'm going to show
20:59 my icons and item do title let's make this a link
21:09 and the path will be item do path let's check
21:15 [Music] again as you can see title path and icon
21:23 okay let's use this component here I'm going to wrap
21:26 my category title let's say span and I'm going
21:31 to give a class name and it's going to be styles.
21:35 category and after that again a map because we are using our lists
21:44 cat and I will say item and for each item I'm going
21:48 to call my component menu link component and I can pass this here
21:55 we need a unique key and it's going to be item do
22:01 title let's see okay perfect right now I can give my style
22:09 I'm going to use this container firstly I'm going to make this position
22:14 sticky that because in our example when I scroll down as you
22:18 can see it stays here so I will say position sticky and I
22:25 can give any position here let's say forly we can't see anything
22:30 here because we cannot scroll right now let's give style for our items
22:38 but firstly there is a user div here as you can see
22:41 we have image and user text let's create that before this Ur I'm
22:48 going to say user and it's going to have an image source
22:56 and I'm going to give a size let's say 50 pixels like
23:07 that and for now let's use this image where is our public folder
23:14 here we are going to be using this image because we don't have
23:18 any user yet so I will say avatar.png sorry no Avatar okay
23:30 after this image I can create another div here and it's going
23:34 to be our user detail first one will be our username let's say
23:40 John do and one more and it's going to be the title let's
23:45 give class name username and user title okay right now I can
23:58 give my style firstly it's going to be display Flags our items will
24:03 be horizontal let's Center them and gap between image and title will be
24:09 20 pixels like this let's give margin here 20 pixels and for user
24:19 image let's make this circle border radius 50% and I will say
24:26 object fit cover by the way I don't have any class name that's
24:36 SK okay and let's make them vertical user detail display flex but it's
24:48 going to be vertical okay let's make this Boulder font F 500
24:58 perfect and I can decrease this font size and I'm going to change
25:07 its color and it's going to be our soft color okay what
25:15 about our list firstly I'm going to delete this list decoration let's
25:20 give a class name sorry it's Ali it's going to be list styles.
25:27 list let's use it I will say list style and it's going to be nor let's change
25:36 this category names it's here again it's going to be
25:45 soft font fate will be Bol and font size will be smaller and I'm going to give
25:52 margin to top and bottom let's let's take care
25:58 of our items we have container here I'm going
26:04 to open this here and let's say padding again display Flex
26:09 align item Center I'm going to Center the icon
26:13 and the text and gap between those items will
26:16 be 10 pixels okay right now I can give
26:21 another class name when it's active we can show different
26:24 background for example we are in the dashboard
26:27 and it's going to softer color let's check like
26:30 this and also when I hover over I'm going
26:33 to change the background so I will say when I H
26:43 the background color will be this color and also
26:47 I'm going to give here a condition I will check my URL if this part of the URL
26:53 equals our link path it's going to be active to do that we are going to be using
26:59 use path name hook const path name as you can
27:05 see it comes from next navigation let's see what
27:10 we have I say console lock of course to use
27:14 this hook our component should be a client component
27:17 so I will say use client directive as you
27:23 can see for each link it shows our path
27:26 name and since it's equal to this link it's going
27:30 to be active so let's write here a condition
27:35 and I will say it's going to be container
27:38 but also I'm going to check the path name
27:42 if it equals item path is going to be styles.
27:49 active so let's use this class name I will say
27:53 if it's active it's going to be this color like
27:56 that okay let's give some margin and change the Border radius
28:03 it's going to be five from top and bottom and Border
28:08 radius will be 10 pixels okay perfect this is what
28:15 we want so let's take care of this nowbar I'm going
28:21 to close everything and open up nowb bar and open
28:26 up the s and I'm going to move this here quickly
28:31 let's say container and let's import this CSS actually I
28:36 can use my cipet like that it's much easier and firstly
28:43 we are going to have a title here and again
28:45 we are going to take this title from our path name
28:48 and after we are going to have another container this search
28:51 bar and those icons so I will see use client
29:00 and again my hook here let's import and I'm going
29:04 to import my icons like that it comes from react icons
29:12 firstly we are going to have a title div and I'm
29:17 going to write here the path name but be careful
29:22 here as you can see it's dashboard but if I
29:25 use the users link as you can see the path name
29:29 is dashboard and users if you want to you can
29:32 leave it like that but if you want to use only
29:36 the last item you should use a split function split
29:41 use slash and using this slash I can separate my path
29:46 name and I'm going to take the last item to do
29:50 that I can use pop function let's see and perfect
29:57 let me make this smaller and I will say menu
30:03 do and inside we are going to have the search de
30:08 inside this D yeah I'm going to have this icon
30:12 and input my icon component here MD search and let's create
30:20 an input I'm going to give placeholder and it's going
30:23 to be search and I'm going to give a class name styles.
30:30 input after this search component search D I
30:35 can show my icons and let's paste them
30:42 okay as you can see we can give any size here in this case they are going
30:46 to be 20 pixels like that let's give
30:52 a style firstly our container will be display
30:57 Flex so everything will be horizontal let's separate
31:01 our items using just fire content and I'm going
31:07 to Center them vertically perfect let's give
31:12 a background I'm going to give exactly the same
31:16 color so let's say padding first I'm going
31:20 to give border radius 10 pixels and background color
31:24 will be our soft color let's say BG soft okay let's change this title color will
31:38 be soft uh font weight will be bolt
31:46 and I can capitalize this first letter text transform
31:50 will be capitalize what about this menu again
31:56 it's going to be horizontal and I'm going
31:57 to separate them display Flex align item Center
32:02 and let's separate using Gap and for the search
32:11 I'm going to give this color it's going to beit lighter and I'm going to give
32:15 space here so let's say Gap 10 and background
32:23 color will be these light color let's give
32:26 pad inside and Border radius will be 10
32:32 pixels and for the input there's a default
32:37 background color as you can see it's white
32:40 let's change this I will say transparent we are
32:45 not going to see any background color or any border and the text color will be
32:53 our Tex color okay awesome let's separate them
33:02 and complete our now bar I will say icons gap
33:07 between items will be 20 now we have created our sidebar and now bar by the way
33:16 we didn't use log out icon let's create that button after this URL I'm going
33:25 to create a button and I will say log out let's give a class name and also
33:33 I'm going to use this icon MD log out okay in our example as you can see
33:42 we don't have any background or border it's
33:45 going to be just like these links but it
33:48 has to be a button because we are going to be using Ser actions when I
33:52 explain that you are going to understand better
33:54 but for now let's give our style I will
34:00 say log out I'm going to give exactly the same style as we gave for our links
34:08 but additionally I'm going to delete the background
34:10 color because it's a button or let's say
34:14 background nonone border nonone and the width will
34:19 be 100% okay there is still background okay let's
34:29 change this color it's going to be white and perfect and I can give how effect
34:40 and I'm going to change the background it's
34:44 going to be just like links okay and that's
34:53 all let's delete this console lock and I
34:58 can close everything and let's see what we have here as you can see we have
35:03 some cards here and after this component that shows
35:07 our users and the transactions and we are going to have a chart here and finally
35:14 those sticky boxes and they all are going
35:18 to be inside dashboard UI I'm going to open up
35:23 my sidebar and inside dashboard I'm going to say cart cart jsx and CSS let's say
35:40 container and let's actually copy this and paste
35:46 inside our dashboard and it's going to be chart
35:50 let's change [Music] them and again actually let's
35:59 do two more components and it's going to be
36:10 transactions right bar and what else okay that's
36:23 all card transaction chart and right bar let's
36:27 remove this and let's create our functions okay
36:48 I can close them and let's take care
36:51 of our cards I'm going to take my CSS file here and I'm going to call all
36:56 my components inside my dashboard dashboard page and let's
37:03 create a d and it's going to be
37:05 cards and I'm going to call my card here let's import we are going to have three
37:13 cards by the way let's import our Styles UI and dashboard okay as you can see
37:28 we have two sections this section and this right
37:32 bar section let's create our div firstly I'm
37:36 going to give here class name let's say
37:40 proper and the first section will be let's
37:43 say main section it's going to include all
37:47 our components and other section will be let's say
37:51 site and it's going to contain our right bar after these cards I'm going to call
38:01 transactions and chart let's make this display flag
38:06 first and give size for Main and site because
38:10 in our example as you can see this main block is much bigger than this right bar
38:15 so I'm going to open up my CSS dashboard module CSS as you can see we have
38:20 our main items but inside content we are
38:24 going to have a rapper main block side block
38:30 and inside the main block we have our Cuts
38:34 so let's make this display flex and gap
38:37 between Main and sidebar will be 20 pixels
38:41 and I'm going to give some padding here
38:46 okay let's separate them this main block will
38:49 be bigger so let's say Flex three and it's
38:55 going to be one and I'm going to separate my items inside this main block to do
39:00 that I can use flex box and column and gap between each item will be 20
39:07 like that what about those cards again it's
39:09 going to be horizontal and just why content
39:14 will be space between okay perfect so let's
39:22 take care of our cut component I can close
39:25 here and this page inside our card we are going to have an icon a title
39:32 a number here and is description let's do
39:37 that I'm going to use my icon and the size
39:41 will be 24 pixels and after that I'm going to create a du and it's going
39:47 to include our texts firstly we are going
39:50 to have a title let's say total users let's
39:58 give here any number and finally let's take
40:03 this from here and paste and I'm going
40:07 to change this percentage because each color will
40:10 be different let's give aan and it class name
40:15 will be positive it can be positive or negative we can take this as a prop
40:23 of course but for now it can stay like
40:26 that let's give class name for our title styles.
40:30 title I'm going to copy this and paste here and let's
40:37 say number let's give here also I'm going to say
40:42 detail okay let's give our style firstly I'm going
40:46 to change the background again for the radius our items will
40:51 be horizontal this icon and those texts and this text
40:56 container container again will be display flex but Flex direction will
40:59 be column and I'm going to change Tex sizes let's
41:02 do that and firstly let's give our background color it's going
41:08 to be BG let's give our padding border radius it's
41:13 going to be display flag gap between icon and text
41:17 20 and I will say cursor pointer and for texts
41:23 again display flex but column let's change text sizes for number
41:32 for example is going to be bigger 24 pixels and font
41:36 weight will be 500 and for the detail it's going
41:40 to be smaller 14 and the font weight will be
41:44 300 and if it's positive the text color will be lime
41:51 if it's not it's going to be let's say red
41:56 that but where is our background color oh I said BG
42:01 it's going to be soft of course but their sizes
42:04 are small let's give 100% and perfect and I can give
42:13 different background when I hover over let's take our container
42:19 and H effect and the background color will be softer let
42:23 me copy and paste actually I can assign this as a variable
42:29 but anyway when I hover over it's this color
42:34 and what about this component let's open up I'm going
42:37 to close them and open up my component and it
42:43 CSS file as you can see we have a title
42:50 here and after that we are going to create a table
42:53 and each row is going to include the username and image
42:57 status date and amount inside container I will say h2
43:02 tag and it's going to be our title latest transactions
43:08 and after that a table let's give class name actually styles.
43:14 table and title okay and inside this table and I'm going to create
43:25 my table head and body basically it's going to be our titles
43:31 those titles and body will be our users let's create our rows
43:41 the first one will be name status date and amount and inside
43:51 body we are going to have our users the first one will
43:54 be user IM image and username status date and amount let's create
44:00 our image user image it comes from next image quickly I will
44:06 say source and again we can use no Avatar PNG let's give
44:12 our size it's going to be 40 pixels and height it's going
44:18 to be the same and let's give class name because it's going
44:21 to be a circle so we can change it using this class
44:25 name and I will say user image okay after this let's give username
44:32 John do and we are going to write here status but as you
44:38 can see we have different status here pending on or cancelled
44:42 for each item we can give different span let's say pending for example
44:52 but also I'm going to give a main style I can say styles.
44:57 status and also the style name and I can
45:01 write here any date and any number here okay let's
45:12 give different users and I'm going to change this status
45:17 I'm just going to copy this and the second
45:23 one will be done and canceled okay right now
45:39 I can give my style let's give our background color
45:44 BG soft padding will be 20 pixels and Border radius
45:52 and for this title let's change its color and font
45:55 weight and I'm going to give space here let's say
46:02 20 pixels font weight will be thinner and the color
46:07 will be our soft color tag soft what about
46:13 this table as you can see it's small let's make
46:16 this 100% perfect and for each item inside I'm going
46:25 to give some heading let's use table again and I'm
46:30 going to choose TD and let's say 10 pixels
46:36 did I give any class name here or not okay
46:39 I didn't and before them I'm going to create a d and it's going to be user and I
46:50 can wrap my image and this username okay let's
46:56 say user I'm going to separate them and elign items
47:01 will be Center okay let's change this image it's
47:06 going to be a circle remember we have user image
47:09 firstly I will say object fit it's going to be
47:13 C and Border radius will be 50% and what about
47:20 those STS I'm going to give some border radius 5
47:28 pixels padding will be five again I'm going to decrease
47:32 the font size and the color will be white
47:37 but when it comes to each item I'm going to change
47:40 their colors I mean background colors pending it's going
47:45 to be this color let's duplicate this I will say
47:50 done and canceled and I'm going to paste my color
47:56 like that okay awesome and let's check as you can
48:07 see we have an chart here to do that we
48:10 are going to be using rechart Library let's open
48:13 up our terminal and I will say mpm I
48:17 recharts and the version will be 2.9.0 let's see what
48:25 we can and create let's open up re charts.org.nz
48:55 a data and using this data we can show the numbers
48:59 we can compare them as you can see it's
49:02 comparing PV and UV and after creating our data using
49:09 responsive container and line chart components we can create
49:13 this chart let me copy this let's close everything and open
49:21 up charts inside this container I'm going to create
49:30 my title first let's write any Title Here and After
49:35 I'm Going to paste my items let's import our components
49:40 here I'm going to copy this paste here and also
49:46 we are going to have this data but I'm
49:48 not going to use this one I'm going to use
49:50 my own data let's paste here as you can see
49:55 see we are going to compare the visit and click
49:58 numbers and the name of each section will be
50:01 the days of the week so instead of py I'm
50:05 going to say visit and instead of UV it's
50:09 going to be click let see I can close here
50:15 of course this chart is interactive so we cannot use
50:18 so component it's going to be use client but it's
50:27 going to Infinity to prevent this I should give
50:31 height for the container let's say 450 and perfect let's
50:41 give style for our container I'm going to change
50:43 the background again as you always do I'm going to say
50:47 soft padding and Border radius what about this title
50:54 I'm going to give exactly the same style font fate
50:58 will be smaller color will be softer uh margin bottom
51:07 of course I didn't give class name let's give styles.
51:15 title and there's a trick here if you
51:18 are using responsive container I recommend you to change
51:21 this height and make it 90% other wise you
51:25 can see some overflows and okay awesome as you can
51:32 see this background is white and also we have
51:35 this container behind let's see it's a little bit
51:40 different let's remove that container we don't need
51:45 this and I can remove this from import perfect and I'm
51:56 going to change the background color of this tool
51:59 tip so I'm going to come here and say
52:02 content style the background color will be our main
52:06 color but I cannot use our variables here I should
52:09 drag the pass like that and I'm going
52:14 to remove the Border it's going to be none okay
52:23 what about this right bar we have two items
52:27 and each item has this title another title a subtitle
52:31 here and a description and this button and for the first
52:36 item we are going to have this image let's do that I can close them and open
52:42 up right bar so let's create our first item
52:54 as I said the first item has an image
52:57 so let's create here another do and I'm going
53:00 to say background container and inside I'm going to create
53:03 an image it's going to be this image I'm not going to give size I will just say
53:18 fill so it's going to fill inside the container
53:24 Alt and after that I can create my texts
53:28 so let's say do texts the first one will be
53:34 let's say notification title subtitle and description let's copy
53:46 this actually after that I'm going to say H3
53:52 tag and it's going to be this tag title
53:57 another span uh description let's say P tag okay let's
54:11 give different class names title subtitle and description
54:24 and after we are going to have this button
54:26 and as you can see there's an icon here let's
54:29 create after this P tag I'm going to say button
54:35 and a class name and let's say button
54:38 and inside my icon player icon this one and I
54:44 will say watch and after I'm going to create
54:48 another item and it's not going to have any image
54:51 actually I can directly copy and paste there's nothing
54:57 different we don't have to waste time like that okay
55:05 let's give style let's see first oops there is
55:11 something wrong here this is our container after we
55:16 have item one de is missing here I think
55:23 okay let's import this of course the image is
55:31 too big let's fix this firstly I'm going to say
55:36 BG container so we can see our image I'm
55:39 going to give absolute positioning so I'm going
55:42 to show it on the bottom right bottom zero right
55:47 zero and I'm going to give some size it's
55:49 going to be 50% it's not going to contain
55:52 the whole container of course if you are using
56:00 position absolute the parent should be position relative our parent
56:04 is item okay let's change this object fit it
56:14 looks a little bit weird let's come here give class
56:19 name styles do let's say BG object fit will
56:28 be cover and I'm going to change its opacity
56:35 perfect and let's take care of our items but before
56:39 when I scroll it should stay there so I'm
56:42 going to say position fixed perfect and let's take
56:50 care of our items I'm going to give my background
56:53 color you can directly use background soft
56:59 or in our example there is a linear gradient the top
57:03 of the element will be lighter let me actually
57:06 copy and paste as you can see the bottom
57:11 is darker and the top is lighter and I'm
57:16 going to give some padding from top and bottom
57:19 and Border radius will be as always 10 pixels
57:24 and going to give margin bottom I'm going to separate
57:27 my items it's going to be 20 pixels
57:30 and that's all what about each item inside I will
57:37 say texts display flags flag direction will be column
57:44 I'm going to separate my items perfect let's give
57:49 style for our texts notification font weight will be
57:56 bolt and title is going to be 500 and font
58:01 size will be smaller and let's give soft color
58:07 text soft now finally we have a button I'm
58:13 going to give some padding Insight let's check I'm
58:17 going to separate my items give border radius and background
58:21 color and the text code will be white align
58:26 item Center and let's separate them and the background
58:31 color will be this purple color it's going to be
58:35 white I'm going to delete the Border oops it's
58:40 going to be non and Border radius 5 pixels and we can click on this so I will
58:48 say cursor pointer okay as you can see it
58:54 size is too much so it's going to be maximum
59:01 content okay but as you realize it's cropping
59:04 our image so instead of cover I can say contain
59:10 so it's going to fit inside this container it's
59:13 not going to crop perfect but there is something wrong
59:17 with this second item when I paste my item
59:21 I made a mistake here I think so let's
59:25 don't waste time and copy paste again oh okay
59:31 in our example it was text but we use text
59:36 let's remove this and it's going to fix okay
59:40 perfect it looks really nice so let's take care
59:44 of users page let's see what we have it's
59:49 really easy we are just going to add here
59:51 a container we are going to have top bar
59:55 and this content inside top bar we are going
59:57 to have search container and this button and inside
1:00:01 this content we are going to have table and after we
1:00:04 are going to create this pagination by the way
1:00:07 there's a footer here but we didn't create let's
1:00:10 create quickly I'm going to close them open up
1:00:16 dashboards inside this UI I'm going to say footer I'm
1:00:29 going to create my component and this CSS it's
1:00:35 really easy there is nothing fancy we are going
1:00:39 to have two items let's say logo another D
1:00:45 and it's going to be this text let's say text
1:00:52 let's separate them I will say container ER display
1:00:56 flag align item Center and just fire content space
1:01:01 between and as you can see its font weight
1:01:04 is Bolt and this text is smaller I'm going
1:01:10 to say logo font we will be Bol and text will be 12 pixels let's use it inside
1:01:20 our dashboard I'm going to open up my layout
1:01:24 and after this children I'm going to say show me
1:01:28 my footer as you can see its color is
1:01:34 different and we don't have any space here let's
1:01:39 change firstly I'm going to give here margin top
1:01:44 and the color will be our soft color that's all
1:01:52 so let's take care of our users page I'm
1:01:56 going to close them open up users oops it's dashboard
1:02:02 inside users let's close this so let's create our containers
1:02:11 firstly I'm going to say the main container styles.
1:02:18 container by the way we don't have CSS file let's
1:02:23 import import import styles from App directory UI folder dashboard
1:02:31 UI users and the CSS let's check okay it doesn't
1:02:39 exist let's open up UI dashboards let's close them actually
1:02:45 we can see better okay as you can see we
1:02:49 don't have our Pages yet let's create I will say
1:02:53 users page and inside we are going to create components
1:02:58 belong to this page and also the main CSS file okay
1:03:06 there is no problem anymore let's do the same thing
1:03:09 for products page okay let's create container like that okay
1:03:27 I can close this menu and let's create other containers
1:03:32 as I said top container and content container and after
1:03:37 we are going to add other items so let's say
1:03:42 top another one is going to be let's say bottom
1:03:47 or actually we can directly create our table we don't
1:03:52 have to give any container so class name will be styles.
1:03:57 table okay inside our top container we are going to have
1:04:02 two items search and button but this search component will be functional
1:04:08 when I search for any name it's going to fatch our data
1:04:11 so instead of writing this here directly inside our component I can
1:04:16 create a sub component inside users I'm going to say search component
1:04:24 but but creating this inside our page is not a good idea
1:04:28 because we are using exactly the same functionality for the products
1:04:32 as you can see it's going to be here so this component doesn't
1:04:36 belong to products or users the better option is creating our component
1:04:41 inside dashboard because it's a common component so I'm going to come
1:04:47 here and say search component jsx let's create our function and this CSS
1:05:08 okay so let's use this here search component and as you
1:05:16 can see we have different placeholder here search for product search
1:05:21 for user so we can take it as a prop so I'm going
1:05:26 to say placeholder and I can use it here it's the user
1:05:39 page I'm going to take this prop here I will say placeholder
1:05:44 and I'm going to use it inside my input let's create
1:05:49 our items first first one will be the icon and input and I
1:05:58 can use this placeholder here let's give class name I'm going
1:06:04 to say input and let's give some style let's see first as you
1:06:12 can see it's exactly the same style so I'm not going
1:06:15 to create this again I'm just going to copy and paste it's exactly
1:06:20 the same thing and after let's give a style for our container
1:06:28 as you can see there is no placeholder let's give I can
1:06:31 close this search bar for now and I'm going to say placeholder
1:06:39 search for a user okay let's create our button here I'm going
1:06:53 to give class last name styles do add button of course it's
1:07:00 going to be a link when we click on this button we
1:07:04 are going to open up add new user page so HRA will
1:07:09 be dashboard users and at I couldn't import okay so let's separate
1:07:18 them inside top I'm going to say display Flags align item Center
1:07:23 and justify content will be space between okay by the way let's give
1:07:31 margin for our container and background background color will be our main
1:07:38 color main soft color BG soft I'm going to give padding B
1:07:45 the radius and margin top okay what about this button it was
1:07:57 add button I think let's check okay I'm going to give some
1:08:06 pading and background color will be our purple color remember we use
1:08:11 this for the right bar and the text color will be white
1:08:15 or let's say text color I'm going to delete the Border I'm
1:08:23 going to give border radius is going to be rounded and we
1:08:28 can click perfect and what about our table let's see what we
1:08:38 have first name email created at roll and action by the way
1:08:45 there is a mistake here it should be status and after action
1:08:50 let's create again have hat and bu and the first one will
1:09:02 be name email created at rooll and status and for the buttons
1:09:15 we are going to be creating action column and let's create
1:09:19 our first user I'm going to create a row and the first
1:09:23 item will be the username and the user image so again I can
1:09:29 create a d which is user and inside we have user image
1:09:37 and after username John do let's give our image here no Avatar
1:09:50 size will be 40 pixels and I'm going to give class name
1:09:57 so we can give object fit user image let's create other items
1:10:07 TD and it's going to be user email John gmail.com another one
1:10:13 is going to be date let's give any date here let's say
1:10:21 admin status will be active and our buttons Let's see we have
1:10:27 two buttons View and delete let's create again I'm going to create
1:10:33 a link first I'm not going to write anything here for now
1:10:41 when we patch our users we are going to send here
1:10:44 the user ID let's create here our view button and I'm going
1:10:50 to give class name it's going to be a button button styles do
1:10:56 button but also the view button because its color will be different
1:11:04 styles do let's say view I'm going to duplicate this and it's
1:11:10 going to be delete okay let's see let's q a style I'm
1:11:21 going to open up my CSS file here and let's copy our table
1:11:31 and start firstly it's going to be 100% it's going to contain
1:11:36 all our component and for each item I'm going to give
1:11:40 padding remember how we are doing this let's take care of this user
1:11:53 gap between items will be 10 and I'm going to Center
1:11:57 them perfect let's make this circle quickly user image border radius
1:12:07 and also object fit and for the buttons let's actually create here
1:12:17 a do buttons it's going to contain our view and delete buttons
1:12:25 again gap between them and for each button I'm going to give padding
1:12:32 from top and bottom left and right let's give some border radius
1:12:40 color will be our text color I'm going to delete the default
1:12:48 border and cursor will be pointer like that let's change colors
1:12:55 for view the color will be teal this green color and if it's
1:13:03 delete the background color will be this dark red color perfect and finally
1:13:12 we can create the pagination component let's open up sidebar and again
1:13:18 inside dashboard I'm going to say pagination again it's a common component
1:13:27 I'm not creating this inside users jsx create my component and let's
1:13:39 create this CSS okay let's use it here after table I'm going
1:13:52 to say imagination let's see what we have inside we are going
1:14:01 to have two buttons when it's disabled its color will be different
1:14:05 there is nothing fancy let's quickly create inside pagination let's close here
1:14:13 actually I'm going to create two buttons the first one will be
1:14:22 previous and the second one will be next that's all for now
1:14:29 let's give style I'm going to give some pading I'm going
1:14:34 to separate my items space between and for each button the padding will
1:14:45 be five and 10 csor will be pointer and when it's disabled
1:14:56 the cursor will be not allowed Let's test I'm going to say
1:15:07 disabled okay perfect if you want to you can give different
1:15:11 background or whatever you want for me it's perfect so let's do
1:15:16 the same thing for the products page I'm going to close everything
1:15:22 and let's open up products actually I can copy everything here and just
1:15:31 change my table let's import link image I'm going to import
1:15:45 my Styles main folder app UI dashboard products and CSS let's see oops
1:16:05 it should be dot of course we did an import search
1:16:16 and pagination okay there is no error we are going to change
1:16:25 our rows by the way let's change this placeholder also search
1:16:30 for a product and I'm going to change this link it's going to be
1:16:36 product and let's see what we are going to have we are
1:16:43 going to have title description price created at stock number and actions
1:16:51 let's change them title description again created at but before it's going
1:17:00 to be a price the stock and action and instead of user
1:17:08 I can say product let's copy this actually we can use multiple
1:17:13 times and instead of no a let's check our image it's going
1:17:19 to be no product and after the product name let's say Ione
1:17:34 the description let's write here description for now created at but before
1:17:39 as I said the price and the stock number and that's all
1:17:48 let's see perfect let's give our style it's going to be exactly
1:17:54 the same style the only difference is this user container it's going
1:17:58 to be product container so let's take everything inside users and paste
1:18:07 inside products and I'm going to change here okay by the way
1:18:16 there is a space here to prevent this let's open up
1:18:20 our dashboard module and and I'm going to say minimum height is
1:18:25 going to be 100 VH okay so what else we have we
1:18:32 have this view page as you can see the item image
1:18:36 and a form here that we can edit our item by the way
1:18:41 it looks a little bit ugly maybe we can change here we
1:18:44 can give more space and after that we are going to have
1:18:48 this add page that we can add new product or user let's
1:18:52 create create those pages inside dashboard and product I'm going to say
1:19:03 add page let's say add product page and I'm going to change
1:19:15 this link is going to be app folder UI dashboard products and it's
1:19:23 a different page so I will say add product and the CSS
1:19:32 let's create this inside dashboard products at product folder and it's CSS
1:19:49 file okay let's see if it works or not I'm going
1:19:53 to click here okay there is something wrong oh because I said at.
1:20:01 jsx as I said if you are creating a page it has to be page okay
1:20:08 awesome let's see what we have it's the user page let's open up products as you
1:20:15 can see we have some inputs and text
1:20:19 area and select button here let's let's create
1:20:23 them it's really easy I'm going to create
1:20:26 here a form let's give class name styles.
1:20:31 form and inside let's create our first input placeholder will be title
1:20:39 the product title and the name will be exactly the same it's important
1:20:43 because we are going to push this item into database using this name
1:20:49 and I will say required we cannot send any product without its
1:20:55 title and what else we have select here that we can choose
1:21:00 any category let's create I will say select name will be let's say
1:21:08 category and inside we are going to create some options and the first
1:21:13 one will be let's say kitchen of course we are going to give
1:21:17 here a value again kitchen let's give some more let see phone
1:21:30 computer let's make them capital okay it's enough as you can see it's
1:21:40 here but the initial value is Kitchen instead I'm going to use
1:21:45 this text so I'm going to create one more option here it's going
1:21:52 to be choose a category and the value will be general just
1:22:00 like work press and after that another input at this time is going
1:22:05 to be a number because we are going to pass here our price
1:22:09 placeholder will be price and the name another one is going to be
1:22:16 stock number color size it's going to be a text color and size
1:22:32 and finally we are going to create this text area and it's
1:22:40 going to be the description let's give placeholder and it's going to be
1:22:51 description I can increase rows let's say 16 I can delete columns
1:22:57 and finally a button and I will say submit and the type
1:23:03 will be submit okay let's give our [Music] style I'm going to close
1:23:13 everything here open up the ad page and CSS okay so let's SK
1:23:24 our background as we always do I'm going to say war and BG
1:23:30 soft and again padding and Border radius and margin top after that let's
1:23:37 fix our form I'm going to say display flex and let's give
1:23:43 padding for our input and text area I will say form input
1:23:49 text area and also for the s I'm going to give padding 30
1:23:58 as you can see all items are horizontal but if I say
1:24:03 flx wrap and wrap it's not going to overflow anymore so if I
1:24:10 give some size for my inputs it's going to look better let's copy
1:24:18 this and let's say 45 pixels I don't want to make this 50
1:24:22 because I want to give space here okay there is no space
1:24:26 because we didn't say justy content space between let's give and perfect so
1:24:37 let's remove those background colors and borders it's going to be transparent
1:24:44 color will be our text color and I will give border radius okay
1:24:57 let's use space between them perfect maybe I can give different border let's
1:25:09 say two pixels solid and this gray color Okay much better but why
1:25:17 it didn't work because I didn't give with okay awesome and for this text
1:25:27 area I can give 100% okay and finally this button again
1:25:46 100% I'm going to use some padding and the background color will
1:25:51 be teal let's change the the text color it's going to be white
1:25:57 I'm going to delete the Border default border border radius and finally cursor
1:26:05 pointer okay so let's do the same thing for the users page when
1:26:13 I click here we are going to see the new user page
1:26:16 let's create I'm going to close them open up my menu and here
1:26:21 actually I can copy and paste this and change the name add user
1:26:32 page in this case it's going to be user let's create this actually
1:26:45 again I can copy and paste users is here and I'm going
1:26:53 to change the file name add user and here okay let's see what
1:27:04 we are going to change I'm going to open my example here
1:27:11 username email password phone is admin select is active and address let's change
1:27:20 I'll say username email password phone and let's change them by the way
1:27:33 it's going to be email password phone it's not going to be
1:27:41 required by the way it can be empty select will be is admin
1:27:49 by default it's going to be false let's say is admin and it's
1:27:56 going to be selected and let's say yes and no and false
1:28:12 let's remove this and I will do the same thing for is
1:28:21 active and the default value will be let's say true and after
1:28:26 that address and button let's remove them okay that's all let's see perfect
1:28:45 in our example we don't have any border and this background color is
1:28:49 different let's change it can can be darker I said transparent but I'm
1:28:56 going to change it and it's going to be BG so this dark
1:29:01 color it's much better I think let's do the same thing for other
1:29:09 one okay and one more thing we are going to need and it's
1:29:14 going to be view page when I click here it's going to show
1:29:18 the single users information and we will be able to edit our user
1:29:23 let's check I'm going to click as you can see this is
1:29:27 the user ID there is a user information here and the edit
1:29:33 form let's do that I'm going to come here inside users and I'm
1:29:39 going to create a new folder and it's going to be ID
1:29:43 basically this ID can be anything if we say users and any ID
1:29:50 it's going to show that page and using this ID we will
1:29:54 be able to fetch our user let's create our page and component
1:30:05 and let's say single user page and I'm going to change Here app
1:30:12 UI dashboard users single user and CSS so let's create create this I'm
1:30:22 going to copy inside users I'm going to create new file and paste
1:30:29 this so it's going to create this folder like that let's say
1:30:37 container and let's open up our page firstly we are going to have
1:30:42 two sections information section and the form section so let's say do info
1:30:51 container and one more and it's going to be form container and inside
1:30:59 this info container we are going to show our image and the user
1:31:03 information let's create actually the image container and I'm going to create
1:31:11 an image source will be let's say no Avatar again and I
1:31:20 will say F it's going to fill its container and after that let's
1:31:25 just say John do after that I can create my inputs but each
1:31:31 input has a label so let's say label username let's remove
1:31:38 this and after that input name will be username and the placeholder will be
1:31:45 the latest name of this user as you can see its name
1:31:49 is hello we can see here so let's say joho for now
1:31:56 and I will do the same thing for other inputs let's say email
1:32:05 like that it's going to be email type password type will be password
1:32:18 it can stay like that else we have phone text and phone
1:32:32 and I will say address it's going to be text area it's going
1:32:37 to be a little bit bigger and address New York and what else
1:32:47 we have is admin and is active let's create our label and I'm
1:32:59 going to create a select it's going to be is admin and inside
1:33:04 my options true or false I'm not going to write anything else
1:33:16 if the previous value is false it's going to show no if
1:33:20 it's true is going to show yes but we are going to give
1:33:24 this functionality later let's do the same thing for is active
1:33:34 and that's all I think I'm going to save and let's see okay
1:33:42 our link is different let's open up users page and I'm going
1:33:50 to change this link it's going to be dashboard users and the user ID
1:33:56 for now let's say test and I will do the same thing
1:34:00 for products let's see right now I'm going to click okay there is
1:34:15 something wrong because I forgot slash here okay it's here but there's
1:34:27 something wrong there's a broken image of course it's going to be no
1:34:33 out there and it contains all this screen because we didn't give
1:34:37 any height and width for the parent let's fix that I can close
1:34:42 those pages and move this CSS file here firstly let's take care
1:34:48 of our image container so we can see our items but before let's separate
1:34:55 our sections as you can see this section is smaller so I'm
1:34:59 going to say flx one flax 3 info container flx one of course
1:35:07 it should be display flag let's give gap between them and after
1:35:14 form container uh flax three after that let's give size for the container
1:35:23 image container I will say 100% And the height will be let's
1:35:30 say 300 pixels and if I say position relative it's going to fit
1:35:36 inside this container like that let's give border radius if I do
1:35:45 that it's not going to be visible because it's overflowing so let's say overflow
1:35:50 hidden perfect and let's give background color for the info container BG
1:36:02 soft again padding uh border radius and I can give space here actually
1:36:12 let's give for the container perfect and let's change this font we
1:36:24 and I'm going to give margin bottom here I'm going to separate my image
1:36:28 and this text maybe let's change this color it's going to be
1:36:36 soft color okay so what about this form container let's do the same
1:36:44 thing background padding and Border radius after that I'm going to select
1:36:51 my my form by the way I didn't create any form let's create styles.
1:36:58 form let's drop our items like that okay I will say display flx flx direction
1:37:09 will be column and let's change our items I will say form input text area
1:37:22 and select I'm going to give padding 20 some border I'm going to change
1:37:31 the Border radius 5 pixels and the background color will be dark color so I will
1:37:38 say BG and the text color will be text okay let's give space between them
1:37:50 actually actually I can directly give here and I want to decrease the font size
1:37:57 of labels I'll say form label it's going to be 12 so let's create our button
1:38:14 grab be 100% let's keep padding background
1:38:18 color again till and the color will be
1:38:22 white I mean the text color let's delete default border and give border radius
1:38:35 and we can click let's give space here okay by the way I didn't like
1:38:48 this space I can't change it I'm going to come here info container and I'm
1:38:54 going to say height will be maximum content like this by the way I can delete
1:39:02 this placeholder we shouldn't see our password
1:39:09 like that okay it's not the best maybe
1:39:13 I can make some changes here if I make you can find it in the GitHub
1:39:18 repos story but for now it can stay like this so let's create our login
1:39:22 page and after we can give our functionalities
1:39:26 let's open up login and in our example
1:39:31 I'm going to log out as you can see it's really easy I'm going
1:39:36 to create a box here title to inputs and button and if I give wrong
1:39:41 credentials it's going to show here an error so let's come back and open up
1:39:46 login page let's say container and inside
1:39:55 I'm going to create a form let's import
1:39:59 these Styles app directory UI login page and CSS let's create this and inside
1:40:18 this form we are going to have two
1:40:20 inputs first one will be username and password
1:40:29 and finally a button let's say login let's give a Style by the way it's
1:40:36 inside the login page it should be here okay so what I'm going to do is
1:40:45 giving full size here because I'm going to Center everything think like that uh
1:40:58 for this form let's give background PG soft
1:41:06 I'm going to give some padding and Border
1:41:08 radius let's give width and height and my items will be vertical so I will
1:41:15 say column and I will say justy
1:41:18 content Center okay let's give space between them
1:41:26 perfect and what about inputs I'm going to choose my form and input inside
1:41:35 and again 30 pixels border border radius 5
1:41:45 pixels and the background color will be BG
1:41:50 so so it's going to be darker and the color will be text color
1:41:57 and for the button again 30 pixels background
1:42:07 color will be our green color text color
1:42:11 will be text variable I'm going to delete the border and give cursor pointer
1:42:22 and Border radius here okay that's all but I didn't give any title here I'm just
1:42:34 going to come here and say H1 tag and login of course it should be
1:42:40 inside form it's going to be vertical and I can Center this I'm going to open
1:42:51 up my form and I will say align item Center as you can see
1:42:57 their size are smaller right now because we
1:43:00 centered them so let's give 100% okay perfect
1:43:13 and that's all this is our design the login page and dashboard we can can
1:43:20 see our users we can view single user add new user by the way did
1:43:29 I give same thing for products or not okay I didn't let's create quickly
1:43:35 and after you are going to learn how to fatch data I'm going to copy
1:43:42 this and paste for products remember it's
1:43:48 the UI folder I'm going to change the name
1:43:52 it's going to be product and let's open up our page and create ID and again
1:44:03 I'm going to copy this and paste and I'm going to change my URL here
1:44:10 it's going to be product and let's change here single product page okay I'm not
1:44:21 going to change here because it's going to be dynamic it can stay like
1:44:26 that first table will be title it's going to be the previous title so I can
1:44:34 leave it like that what else we have let's check price stock color and size
1:44:45 it's going to be a number stock let's give any number here color and size
1:45:03 and after that we can choose our category
1:45:06 and finally this description let's change here
1:45:21 is going to be the previous category
1:45:31 and finally description and it's going to be
1:45:37 a text area and the placeholder will be description let's see again I should fix
1:45:57 this link I'm going to open up products
1:46:00 page and actually I created here but there
1:46:03 is something wrong let's remove this and I'm going to click okay right now we
1:46:11 are ready let's see how to fetch data to do that I can open up
1:46:17 my users page and here we have are going to fatch all the users
1:46:22 inside our database but we are going to show here let's say five or 10
1:46:27 items so we are going to be using pagination so let's open up our users
1:46:34 page and fatch our users to do that we are going to need a database
1:46:40 and for this project we are going to be using mongod DP we can use
1:46:44 any other database but it will be easier
1:46:47 for us because we are not using typescript so we will be able to validate
1:46:51 our schema using mongus you are going to understand
1:46:54 what I mean by that but first let's create our database okay let's open cloud.
1:47:03 mongodb docomo show how to create a cluster
1:47:09 it's really easy but there is something
1:47:11 important here after creating your cluster you
1:47:15 should give a permission to your application otherwise
1:47:18 you will not be able to use it I'm going to come here and create
1:47:23 a new user I already have just givea username and a password and the role will
1:47:31 be read and write any database after that you should come here and click
1:47:38 on network access and add your IP address
1:47:42 you can add here your current IP address
1:47:45 or basically allow access from everywhere we
1:47:49 can use it because it's just a development
1:47:52 mode but after deploying our application we are
1:47:55 going to write here our server address okay
1:48:00 it's going to make the changes and after that we will be able to see
1:48:04 our changes here let's click as you can see this is our previous application
1:48:11 but today we are going to create
1:48:13 let's say dashboard database and in that database
1:48:17 we are going to have our users and products if if you check a post here
1:48:22 as you can see the post table has its ID created adate slack title description
1:48:29 image and other properties so basically we should
1:48:33 create this schema we should Define them first
1:48:37 because it's really important to validate your table
1:48:40 items because in our example when we create a new user for example we should
1:48:46 be able to send only username email password
1:48:50 phone and others nothing else and also we are going to Define our types
1:48:55 for example username will be only string email
1:48:58 should be string again but it should be unique we cannot use the same email
1:49:03 or username again and again and password should
1:49:07 be let's say minimum six characters they have
1:49:11 to be bullan true or false and after
1:49:14 defining all these properties everything will be
1:49:17 much easier but how we are going
1:49:19 to do that I'm going to open up my terminal and install a new library I
1:49:27 will say mpm install mongus and after installing
1:49:35 this Library we will be able to connect
1:49:38 to our database and create our models as you can see it creates a new
1:49:44 schema and it says name should be string size should be string and use using
1:49:50 this schema it creates a new model basically our table here one of these tables
1:49:59 to do that we should connect to our database first let's come here and choose
1:50:04 the connection as you can see it's an async function so we can use try and catch
1:50:13 block like that I'm going to copy this and open up my menu and inside
1:50:22 app directory I'm going to create a new folder and I will say library and inside
1:50:30 utils do JS so let's create our connection
1:50:34 method I will say export const connect
1:50:40 let's say connect to DB it's going to be an async function and I will
1:50:47 paste my function here and let's throw
1:50:51 this error let's import mongus and right now
1:50:58 whenever we want to make an operation like
1:51:02 fetching user or product or adding new user
1:51:06 we are going to connect to the database but if I do that it's going
1:51:09 to create a new connection all the time to prevent this we are going to check
1:51:14 first if we are connected or not if we are we are going to use
1:51:18 that connection if not we are going to create a new one so let's create
1:51:23 here an object and I will say cons DB and if we are connected
1:51:30 for the first time we are going to assign
1:51:32 that connection here and it's going to be
1:51:37 DB connections and we are going to take our first connection and ready State
1:51:44 and if it's not empty if we are already connected we are not going to create
1:51:49 a new connection so let's say if
1:51:53 connection is connected just return do not connect
1:51:59 again okay right now instead of this string we are going to pass our URL
1:52:05 to do that I'm going to come here and I'm going to click here connect
1:52:11 we are going to connect through our application
1:52:13 so I'm going to choose that and I'm
1:52:16 going to copy this URL and after the URL you can write here any database
1:52:26 name let's say dashboard and it's ready
1:52:31 but using your secret Keys like that is not
1:52:33 a good idea when you use GitHub everybody can reach your data to prevent
1:52:38 this we are going to be using EMV file I'm going to cut this and inside
1:52:44 my root directory I'm going to create a new file it's going to be EMV
1:52:50 and let's say and it's going to be this URL so let's open up git ignore
1:52:57 file and add here EMV so when you commit your changes it's not going to show
1:53:03 up in the GitHub repository let's use it here I'll say process EMV and okay
1:53:16 right now we are ready to create our models I'm going to come here
1:53:20 and create a new file and let's create our user schema I will say new mongus
1:53:29 do schema by the way let's import this mongus okay and inside I can Define
1:53:40 my properties the first one will be username and its type will be string I
1:53:47 will say required we cannot create user without username and it has to be unique
1:53:56 every user has different username and minimum character
1:54:01 will be three and the maximum will be
1:54:04 20 let's do the same thing for others it's going to be email again string
1:54:11 unique and required let's delete here I will
1:54:16 say password it doesn't have to be unique
1:54:20 I can remove this and we are going to have user image it's going to be
1:54:25 string it's not going to be required what else we have remember is admin is
1:54:33 active type will be bullan and when we create any user by default it's going
1:54:39 to be false it's not going to be admin so I can do the same
1:54:45 thing for is active volume and by default it's going to be true and let's
1:54:53 see what else we have phone and address it's going to be string again but not
1:55:02 required and address and there is something
1:55:08 important here when we create any new item
1:55:14 I want to see the created adate let's see here as we can see it
1:55:20 gives this created ad dat we don't
1:55:22 have to create this manually instead I'm going
1:55:25 to come here and say time stamps and true so whenever we create a new user
1:55:30 it's going to create created at and updated at time so let's do the same
1:55:36 thing for our product we don't need here I will say product schema we are
1:55:45 going to have a title string required
1:55:48 unique I can it here description again string
1:55:55 but it doesn't have to be unique I'm going to give a price and the type
1:55:59 will be number again required but the minimum number will be zero we cannot give
1:56:07 negative price and again image and it's going
1:56:11 to be actually let's remove here I will
1:56:14 say color size and I forgot St let's create stock here again it's going to be
1:56:23 a number and the minimum number will be zero okay that's all so let's export
1:56:31 them and use inside our application so I will say export const user mongus do
1:56:39 model and the table name will be user and we are going to Wate our items
1:56:44 using our schema let's say user schema
1:56:49 but there's something important here if we already
1:56:53 have user table we shouldn't create a new one instead we should use the existing
1:56:58 one to do that I will say check the models and if user exists use
1:57:05 it if not create new one and I will do the same thing for products like
1:57:17 that okay right now every is much easier I'm going to close everything and let's
1:57:24 create a new file and it's going to be data.js basically we are going to fetch
1:57:29 our data using this file let's create the first one I say export con fat
1:57:38 users of course it's going to be an Asing function I will say try catch
1:57:47 if there is an error show this error and also throw that error I'll say
1:57:54 Throw new error and I'm going to pass this error here or directly let's give any
1:58:01 message fail to fatch users okay let's use our model and fatch all the users
1:58:11 I will say const users it's going to be user model and I will say find
1:58:20 and of course it's going to be a wait after fetching our users we are
1:58:25 going to send it of course we are going to add something additional but for now
1:58:31 let's test I'm going to open up my users page here and I'm going
1:58:37 to fatch my data so let's say const users I'm going to use my fatch function
1:58:47 and it's going to return our users of course async let's import and that's all
1:58:57 let's see I'm going to say console log users and I'm going to open up
1:59:02 my terminal I'm not opening my console
1:59:05 on the browser because it's a server component
1:59:08 this is how we can fatch data directly
1:59:10 inside and as you can see there's something
1:59:12 wrong here it throws this error let's
1:59:15 see what happens okay there is something wrong
1:59:18 with our connection let's check our EMV file
1:59:24 it looks okay oh because we didn't connect
1:59:30 I'm so sorry I'm going to come here before fing data of course we should
1:59:35 be connected first I will say connect to DB and let's check and again we
1:59:47 have a problem let's open up up this function and let's check what's wrong if
1:59:52 connection is connected we are not going
1:59:54 to do anything if it's not a wait mongus
1:59:57 connect process EMV and we are going to assign our connection here and I'm going
2:00:04 to console lock this error oops it's
2:00:16 undefined because I said connection is to be
2:00:22 connections finally there is no problem and as you can see it returns an empty
2:00:27 array because we don't have any user yet let's come here and create a new one
2:00:34 by the way if I refresh the page you are going to see our database
2:00:37 and our table it's here and as you can see we have products and users
2:00:48 let's add a new one the username will be drone email password and let's give
2:01:04 any image to do that I can use
2:01:07 pexels.com let's choose any image here doesn't matter
2:01:15 like that and let's say is admin is going to be false of course it's
2:01:20 going to be aoon and again is active it's going to be true okay we don't
2:01:32 have to add phone and address I'm going to insert and it's here let's check
2:01:39 again I'm going to refresh the page and as you can see it returns our user
2:01:47 let's add one more I'm just going to duplicate this and change the name let's
2:02:00 actually add more because I'm going to show you how to use pagination of course
2:02:14 we shouldn't add this manually we can use our ad page but I'm going to show
2:02:19 that later because we don't know nextjs
2:02:21 server actions yet first I'm going to explain
2:02:25 and after we are going to add our own data and let's add one more
2:02:34 and it's going to be enough okay let's refresh the page and see them okay
2:02:46 perfect right now I can use all these users in our page let me close
2:02:55 here and using our array I can add different rows so I'm going to say users.
2:03:03 map and for each user show this row like that there is a warning
2:03:14 because we don't have any unique key and yeah is going to be user.
2:03:21 ID and right now as you can see we have
2:03:24 six items let's change their names and images it's going
2:03:30 to be user do username and I'm going to write here
2:03:34 a condition I will say if user has an image show
2:03:39 it if not show no Avatar PNG and as you
2:03:44 can see there's a warning here because it doesn't allow us
2:03:48 to use any other image source to prevent this we
2:03:51 have to add this host name to our configuration to do
2:03:55 that I'm going to open up my menu and find
2:03:59 next config and inside I'm going to add images we
2:04:04 are going to add a different domain let's say remote
2:04:08 patterns you can specify here your protocol it's going to be
2:04:12 https only for the security and the host name will
2:04:17 be pexels.com okay let's see I'm going to refresh and perfect
2:04:28 let's remove one of them I'm going to edit and delete
2:04:31 this image okay awesome it works let's change others user.
2:04:49 email user.
2:04:51 created at time and we can write here
2:04:55 our condition if the user is admin right here
2:05:00 admin if it's not let's say client and I will do the same thing for is active
2:05:08 let's remove this one and it's going to be is active if it is it's going to be
2:05:13 active if it's not passive and finally instead
2:05:19 of this test I can update my link here
2:05:24 and I'm going to pass here my user id like that okay perfect as you can see
2:05:36 there is something wrong with created adate because
2:05:39 we don't have any created adate let me copy
2:05:43 and paste from my previous data for example I
2:05:50 can copy this and created at dat and I'm
2:06:00 going to paste it here and its type will be date let's see as you can see
2:06:11 there is something wrong because we are sending
2:06:14 a date we cannot show it as a string
2:06:17 to prevent this I'm going to come here and say to string if there is created ad
2:06:25 convert it to string like that and it's going to show you the full date but I
2:06:31 want to get only this part so I can use a slice method and I'm going to take
2:06:38 from the fourth character and 16 like that so
2:06:46 what about this search function ality when we
2:06:49 write any name here we are going to search
2:06:51 for our users normally in react you can create
2:06:55 a use State hook and store whatever you
2:06:58 write here and you can create a user fact
2:07:01 hook and whenever it changes you can trigger
2:07:05 the search functionality but we don't have to use use
2:07:08 State we don't have to use use effect
2:07:10 so let's open up the search component and I'm
2:07:15 going to store my input inside my browser
2:07:19 URL so when we search for John for example
2:07:22 we are going to add it here like query and John and using this query we are
2:07:28 going to reatch our users to do that we
2:07:31 are going to be using next navigation we are
2:07:34 going to need our path name and also
2:07:37 the search params basically whatever after this URL let's
2:07:41 use them and you are going to understand better
2:07:44 firstly of course it should be a client component
2:07:48 use client and I will say const search
2:07:55 params and use search params hook as you can
2:07:59 see it comes from next navigation and path name
2:08:08 let's see what we have inside I'll say console
2:08:11 lock search params and path name I'm going
2:08:17 to refresh open my console as you can see
2:08:21 this is our path name we already know how to use it and this is a function
2:08:27 that we can create a new URL and pass inside any query we want let me show
2:08:33 you how to do that I'm going to close here and let's create a new URL I will
2:08:38 say const perms new URL search parms and I'm
2:08:46 going to pass my search parms here and after
2:08:49 that I can set any query perams do set let's say test and the value will be
2:08:56 let's say value and using these new perms I can change my URL to do that we
2:09:03 can use replace method I'll say const replace it's
2:09:08 going to come from use R hook again next
2:09:11 navigation and using this method I can change
2:09:14 my URL I'm going to use my path name
2:09:19 remember it's dashboard and users and additionally I'm
2:09:23 going to add my search params here let's see
2:09:27 but before there's a mistake here we should
2:09:30 call our function okay and as you can see
2:09:36 it automatically adds this value so what can I
2:09:39 do when I change this input I can take this value and add as query let's do
2:09:49 that I will say on change method that's call
2:09:53 a function handle search let's create our function so
2:10:02 I'm going to take the event and create new
2:10:06 PRS let's move them inside and I'm going
2:10:09 to set search query and its value will be
2:10:13 un Target and value let's try I'm going
2:10:21 to remove here and try here JN as you can
2:10:28 see it's immediately here if I change it's
2:10:33 changing perfect so right now in this page using
2:10:37 this query I can refetch my users let's come back and I'm going to take my query
2:10:44 to do that we can use search params and and you can get any query you want
2:10:50 in our case it's going to be C let's do that I will say const query it's going
2:10:57 to be search parms do query and by the way it can be empty so I'm going
2:11:03 to put here question mark and if it doesn't
2:11:06 exist it's going to be an empty string so let's pass this query into our F users
2:11:14 function I'm going to take it here and I'm
2:11:17 going to write my condition the username should include
2:11:20 this query if you write here directly your query
2:11:23 you have to write the exact name but we are going to search every single letter
2:11:28 to do that we are going to be using
2:11:30 rejects const rejects I'm going to create a new
2:11:37 expression and it's going to include our query
2:11:40 and I can give here a new Option and it's
2:11:42 going to be I and it means it's going to be case insensitive so if I write
2:11:49 here any capital letter it doesn't matter they
2:11:51 all are going to be lowercased and let's use
2:11:55 it here rejects will be rejects okay I'm
2:12:01 going to do one more thing here I'm going
2:12:03 to write a condition if event Target and value
2:12:09 exists we are going to set this perms if
2:12:12 it's not we are going to delete that query
2:12:19 because when we write here anything and delete it
2:12:21 shouldn't show this query anymore let's try I
2:12:25 will say John it's here but if I delete it's gone but it's not fetching I said
2:12:34 John but it's not here let's see what's wrong
2:12:39 let's open our console let's remove those users
2:12:51 and those console locks and let's come here and check
2:13:03 if we have query or not okay it's empty because I said query it should be Q
2:13:25 okay it's here and our user okay perfect if I say Jane Just J as you can
2:13:36 see John and Jane okay awesome but searching users
2:13:40 for every single letter is not a good idea
2:13:43 because anytime I enter new item here it's
2:13:47 going to search for for users and this calculation
2:13:50 will be expensive to prevent this you can write
2:13:53 here a condition and say if it's less than
2:13:56 three characters don't search let's do that I'm
2:14:00 going to come here and I will say if
2:14:04 event Target value more than two we are going to set this query let's try I say
2:14:14 j o as you can see it's not searching but if I I say of course length
2:14:25 let's try it's not here if I say h and perfect what else you can do you can
2:14:33 add debounce functionality and you can wait user
2:14:37 to finish typing to do that we can use
2:14:40 use debounce Library let's say mpm install use debounce
2:14:47 and I'm going to write right here my version
2:14:50 okay right now using this Library I can wait for my users to finish their typing
2:14:57 to do that I'm going to come here
2:14:59 and rub my function with use debounced call back I'm
2:15:06 going to rra this like that and I'm going to add the time period let's say 300
2:15:14 milliseconds let's import this from our library right now
2:15:26 if I write quickly as you can see it's not searching but when I finish it weighs
2:15:32 300 millisecs and search for users and this is
2:15:37 how you can prevent abusing your database requests okay
2:15:42 so what about this pagination I want to see
2:15:46 here only two items only two users to do that again I'm going to add here
2:15:51 a query and it's going to be Page by default it's going to be one and we are
2:15:56 going to search for our users if there are
2:15:59 more than two items we are going to enable
2:16:01 this next button and when I click here
2:16:04 we are going to update this query it's going
2:16:06 to be two and when I click here one again let's do that by the way we
2:16:14 are going to use exactly the same functionality
2:16:16 for the search component so let's add here a new
2:16:20 query I will say perms set page and it's
2:16:27 going to be one because whenever we change
2:16:29 our input it's going to show the first page so even if we are in the second
2:16:36 page or third page or whatever when we write
2:16:38 anything it's going to reset here and in our users
2:16:43 Page by default it's going to be one let's say page if there is no page
2:16:49 it's going to be one and again I'm going to pass this page here let's take it
2:16:56 in our function let's remove this console lock
2:17:01 and I'm going to create here how many users I
2:17:04 want to see so let's say const item per page let's say two of course
2:17:11 in a real world example it should be five or 10 but we don't have that much user
2:17:17 for for the task purpose it can be two and I can write here limit and using
2:17:23 this item per page I can limit my query
2:17:27 in this case it's going to patch only two items
2:17:30 but how I'm going to see the others it's
2:17:32 really easy I'm going to come here and say
2:17:36 skip item per page multiply by Page minus one
2:17:41 so what this does is it skips a certain
2:17:45 amount of items for example when the page is 1 1- 1 will be 0 0 multip
2:17:52 by anything it's going to be zero again so
2:17:55 it's not going to skip any item it's going
2:17:57 to show us the first two items but if we are in the page two it's going
2:18:02 to be 2 minus 1 1 2* by 1 is going to be two it means it's
2:18:08 going to skip the first two items and show the other two items so if I change
2:18:14 here if I make this page two as you can see Harold Jane page three John and Mike
2:18:24 so using this page query I can update
2:18:28 my pagination component let's open again it's going
2:18:34 to be use client let's take them again I'm
2:18:41 going to copy here and paste and I'm going
2:18:47 to going to import them okay right now I
2:18:51 can create a new search params like that and again
2:19:00 I'm going to need item per page because
2:19:02 I'm going to make some calculation item per page
2:19:07 again it's going to be two if you want to you can store this in your em
2:19:11 view file but it can stay like that let's take our page by the way const Page
2:19:18 search params get and the page if it exists we are going to store this if it's
2:19:26 not it means we are in the first page
2:19:30 and right now we can make our calculation I'm
2:19:33 going to create two variables first one will
2:19:37 be has PR and the second one will be
2:19:41 has next if we have the previous page we will be able to click on this button if
2:19:46 it's not yeah are going to disable that's right
2:19:49 here if we don't have previous page and I
2:19:53 will do the same thing here disabled and we
2:19:55 don't have any next page okay so let's make our calculation I will say item per
2:20:05 page multiply by Page minus one but remember it's
2:20:11 a string we should convert this so I will say par in and if it's more than
2:20:22 zero let me explain let's say we are in the first page 1- 1 is going to be
2:20:29 0 0 multip by any number doesn't matter it's going to be zero again and it's not
2:20:35 bigger than zero it means we cannot click
2:20:38 on this button it's going to be disabled if
2:20:41 we are in the second page here is going to be 1 1* by 2 is going
2:20:47 to going to be two and it is more than zero so we can click what about here
2:20:53 again item per page multiply by our page minus
2:20:59 one it's exactly the same but also I'm going
2:21:02 to add here item per page and it should
2:21:06 be smaller than the total number of our users
2:21:10 in our case it's six of course we are going to take this as a probe
2:21:15 but let me explain for the second page here is going to be 1 1* by 2
2:21:21 it's going to be 2 2+ 2 it's 4
2:21:24 and it's smaller than six smaller than total number
2:21:28 but when it comes to third page here is going to be two two multiply by 2
2:21:34 4 4+ 2 6 so it means we don't have any other user we are at the end
2:21:41 of the page so it's going to be disabled so instead of six let's take our count
2:21:50 as a prop and I'm going to pass it
2:21:55 here you can directly say cons count equals users.
2:22:03 length but it's not a good idea because
2:22:05 remember it returns only two items it's not
2:22:09 returning the total numbers of users so we
2:22:12 cannot use it like that instead we should use
2:22:15 our database here and hatch all the user numbers and send it as a response
2:22:21 with these users so I'm going to create
2:22:24 a new query I'll will say const count await user
2:22:29 dot find again I should use this rejects
2:22:33 because we are going to use pagination for search
2:22:36 functionality also and I'm going to say count
2:22:41 and this function is less expensive it's not
2:22:44 actually get any user information it's just going
2:22:47 to find and count so let's use it inside
2:22:50 an object count and users oops count and let's
2:22:56 take it here it's not returning users anymore
2:23:00 it's returning count and users and I can send it to my pagination okay and what
2:23:16 else whenever we click on previous or next
2:23:19 button we are going to change our URL we are going to set new page and change
2:23:26 the url using replace method let's do that I
2:23:30 will say on click event and let's call
2:23:33 a function handle change page and I'm going
2:23:38 to pass here my type and it's going to be previous let's do the same thing
2:23:42 for the next button and the type will be
2:23:46 next next let's create this function const and it'll
2:23:53 change page I'm going to take the type and I'm going to write my condition if
2:23:59 the type equals previous params do set page
2:24:07 and I'm going to take the previous one previous page
2:24:12 number and I'm going to decrease and if
2:24:18 it's not I'm going to increase this number
2:24:24 it's that easy and finally using this page
2:24:30 number I can replace my URL question mark
2:24:38 and parms let's see I'm going to delete
2:24:43 this page as you can see at the beginning
2:24:46 it's disabled when I click here page will
2:24:50 be two so we can click on previous let's click again we are in the first page
2:24:59 second and third and right now it's disabled
2:25:04 and if the calculation is confusing for you
2:25:07 don't worry you going to use this calculation thousand
2:25:10 times and once you learn it it's going to make more sense okay let's do the same
2:25:16 thing for product let's open up prly I'm
2:25:20 going to come here and copy them and I'm
2:25:24 going to open up products page here that's
2:25:32 paste I will say async let's import this next
2:25:44 navigation and it's going to be patch product
2:25:47 of course we didn't create yet let's create
2:25:50 I'm going to come here duplicate this and change the name and instead of user we
2:26:01 are going to be using product model and instead
2:26:08 of username we are going to be using
2:26:10 the product title let's say products okay we
2:26:20 can use this function right now let's open up
2:26:23 our page and import and it's going to be
2:26:27 products and using this products we can show
2:26:31 different rows map for each product show this TR
2:26:44 by the way it's the wrong place it's our hat it should be body okay let's
2:27:01 give our unique key it's going to be product.
2:27:07 ID and I'm going to write here if product has an image use
2:27:13 it if not no product of course slash here and it's going to be
2:27:21 product title description price date but remember
2:27:39 we are going to convert this to string
2:27:44 and take fourth and 16 characters and this is going to be what's
2:27:52 that stock and I'm going to change this H dashboard products and the product
2:28:06 ID as you can see we don't have yet but if we create it's
2:28:24 going to be a number and stock that's create two more of course we
2:28:48 don't have created at but let's test as you can see there's a problem if
2:28:57 it exists and perfect and when I click here it's going to show
2:29:05 the product ID it's that easy guys and if I search for any item oops
2:29:13 there is something wrong here it's not updating and also we cannot see
2:29:18 the next button because we didn't send here count okay it's here but what about
2:29:31 this it's not updating oh because I said minimum three characters so I'm going
2:29:40 to search for test three and again it's not here let's check search PRS
2:29:49 query okay we are sending this query and Page query and Page let's see
2:30:01 again okay it's not showing because I'm
2:30:06 using navigation it's a page we should take
2:30:11 this as a prop okay it works okay perfect okay guys right now you
2:30:21 know how to Fat data how to search them how to use pagination right
2:30:26 now let's learn how to use NEX js14 server actions after this new feature
2:30:33 we don't have to create any API by the way I still prefer creating apis
2:30:38 it's more reliable and testable but I want to show you how you can
2:30:43 do this without any API layer let's close everything to test server actions I'm
2:30:52 going to create a test page let's say test folder and Page Insight let's
2:31:03 create a component and I'm going to create here a form before actions we were
2:31:08 not using this action remember what we were doing if there's an input we
2:31:14 were creating here comp input set input
2:31:18 use State and we were making this component
2:31:21 a client component and using use State we were updating our input using
2:31:29 this set method let's say on change event Target and value and using a button
2:31:39 we were creating on click event or unsubmit event in the form and we
2:31:45 were sending our data to database but after actions we don't need use State
2:31:53 we don't need client components we don't need any listener here we are able
2:32:00 to send everything inside this form using
2:32:03 server actions so let's say action and I'm
2:32:07 going to create any function here handle
2:32:11 form and let's create this function and here
2:32:18 I'm going to use use server directive
2:32:21 and it means everything inside this function
2:32:24 is going to run on the server let's say console lock hello and let's
2:32:31 open up our console Let's test and as you can see there's a warning
2:32:39 here server actions must be async functions because we are going to make
2:32:46 some post requests and let's see I will say John and I will send
2:32:55 and as you can see our text is here but the best thing is
2:33:00 we can reach any input inside this form I'm going to write here form data
2:33:05 and let's see what we have inside but we cannot see our input
2:33:14 because we didn't give any name here let's say username I will send again
2:33:23 and as you realize in this form data object we have our input object
2:33:28 and it includes the name and its value so using this object I'm able to use
2:33:34 this name so if I say const username it comes from from data
2:33:40 and I will use the get method and write here the name of the input
2:33:44 and its username right now I can use it here and if I click
2:33:51 right now it's undefined because I D
2:33:54 structure this of course it should be without
2:33:58 object and it's here and it means inside the server actions we can take
2:34:05 any input value and send it to our database and right now we can
2:34:10 turn back to our users page and add new user page and here we
2:34:16 can collect all the data from this form and send it to mongod DP
2:34:21 using server actions and the best thing is after sending our data to database
2:34:28 we can actually refresh this data here let me show you how we can
2:34:32 do that I'm going to close here and inside Library I'm going to create
2:34:38 new file and it's going to be actions let's create our first action I will
2:34:44 say export const it's going to be add user Asing function let's get
2:34:52 our input values the first one will be username form data of course we should
2:35:00 get this from here get and the input name username and I can do
2:35:08 the same thing for email passwords phone
2:35:10 address and others but instead of writing them
2:35:13 one by one I can directly D structure them I will say username email
2:35:20 password phone address is admin is active
2:35:27 and remember the form data is an object
2:35:30 to D structure our items I can use object from entries and form data
2:35:40 right now using all these data I can create a new user and add
2:35:45 it to my mongod DB so I'm going to use try catch block if
2:35:50 there is an error firstly we are going to console loog and after throw
2:35:55 this error and let's say failed to create user let's create our user here
2:36:07 using our model const new user new user model and I'm going to pass
2:36:18 my items here let's save it to database I will say await new
2:36:26 user and save that's all of course we should be connected to mongodb like
2:36:34 that so let's use this action by the way we didn't write here use
2:36:39 server directive don't forget that otherwise it's
2:36:42 not going to work so I can open
2:36:45 my ADD user page and inside my form I can call my action and it's
2:36:53 going to be add user Let's test by the way it's not the design
2:37:01 part anymore so let's come here and I'm going to give username I'm going
2:37:11 to give some password phone number his admin will be false is active will
2:37:18 be true and let's give some test I'm going to submit let's see I'm
2:37:26 going to refresh this page and as you can see our user is here
2:37:36 so what actually happens here is let's open up our Network Tab and write
2:37:43 another user and they are not required they can stay like that and when I
2:37:55 submit as you can see it's actually making a request and the end point
2:38:00 is dashboard users and add it's just like an API request and it returns
2:38:07 to 100 successful let's check our payload as you can see we are sending
2:38:13 username and other user data here and there is something important here you have
2:38:18 to validate your inputs without sending data
2:38:20 to database because even if you write
2:38:23 here required and type should be email or any other validation users can send
2:38:30 different data using this endpoint what we should do is validating our data
2:38:36 in this action but remember we are already
2:38:39 using models here so even if different data
2:38:43 comes in it's not going to work because our schema accepts only those items
2:38:48 with some types and other requirements so we don't have any problem right now
2:38:54 and also don't use your entries like that let's say data and directly send
2:39:01 a data instead D structure every single items in this case you can make sure
2:39:07 which data you are using and I'm going to come here and I will
2:39:12 say revalidate path and I'm going to write the path which has the data
2:39:18 that I want to refresh so it's going to be this path I'm going
2:39:22 to copy and paste here so as soon as you create a new user it's
2:39:28 going to refresh this data in our example we are using different page
2:39:32 but imagine you have your data and also you have a form here and thanks
2:39:37 to revalidate path as soon as you click to add new user button you'll
2:39:43 be able to see your user here so you don't have to use usequery
2:39:47 you don't have to use S WRR everything is much easier right now
2:39:53 and in our project when I click here I want to redirect my users
2:39:57 to this page and again I'm going to use same path I will say redirect
2:40:06 and paste my path that's import it's
2:40:10 going to come from next navigation don't use
2:40:13 anything else and let's see and a password here and let's send and it's
2:40:28 here of course our password is to week let's come here and our user
2:40:35 is there okay but there is something wrong here let's check our database
2:40:42 and as you realize when we send any p password we are storing it
2:40:47 in a plain text but you should never ever store your passwords like that you
2:40:52 have to Hash it first and store it like that so when user enters
2:40:57 their password Here we are going to Hash this also and after we are
2:41:01 going to compare them if they are equal it means it's the correct user let's
2:41:07 do that I'm going to Hash my password to do that I'm going
2:41:11 to use a library and it's going to be bcrypt mpm bcrypt and I'm going
2:41:17 to write the version let's see how we can use I'm going to zoom
2:41:26 in as you can see we are using the hash method and passing here
2:41:30 our plane text and we are passing the generated salt here and after it
2:41:36 returns us the hashed password let's do that after this connection I will say
2:41:43 const salt a bcrypt generate salt you can give a number here by the way
2:41:52 let's import this and after that I'm going to Hash my password hash password
2:42:05 again await bcrypt do has method I'm going to pass here my password comes
2:42:12 from user and I'm going to use this Sal and it's going to generate
2:42:17 a new password and right now instead of this plain text I can use
2:42:23 it let's see I'm going to create new user secure user again from 1
2:42:38 to six I'm going to submit let's check I'm going to refresh and as you
2:42:50 can see the password is hashed right now it's much secure so let's do
2:42:56 the same thing for the product I'm going to duplicate this and it's going
2:43:01 to be add product and we are going to take title description price stock color
2:43:11 and size we are not going to need that we are going to be
2:43:17 using product and I'm going to paste my data here by the way
2:43:30 if you are using multiple server action by the way let's remove here you
2:43:37 don't have to write them inside every single action you can just use it
2:43:43 at the top of the file like that so we don't need this okay
2:43:51 let's import product model and I will do exactly the same thing I'm going
2:43:57 to open up add product and form action will be add product and if everything
2:44:06 is okay we are going to revalidate and redirect to products page let's see Ikea
2:44:22 task any price stock and description I'm going to submit there is an error
2:44:30 because I had splice is going to be slice let's open up products
2:44:42 and it's here okay so let's do the same thing for this delete action
2:44:49 so what I'm going to do is creating here a form and when I click
2:44:53 on this button I'm going to send my product ID to action and we
2:44:58 are going to delete this from our mongod DB let's do that I'm going
2:45:02 to come here let's duplicate this I will say delete product and inside form
2:45:14 data we have we're going to have only ID and I will say product find
2:45:22 by ID and delete and I'm going to pass here my ID if there's
2:45:27 a problem we are going to throw this error and in this action you
2:45:31 are going to understand this part better of course we are not going
2:45:34 to be redirected to anywhere and let's open up products and before this button I
2:45:43 will say form and the action will be delete product here and of course
2:45:53 we are going to need an input it's going to be text and I'm
2:45:57 going to pass here product ID and in this case we are going to see
2:46:05 this input here but I don't want to do that so I will make
2:46:08 this hidden perfect and when I click on this Buton button we are going
2:46:15 to send this ID don't forget this name and we are going to take
2:46:20 that ID from this form data and we are going to delete that product
2:46:26 let's do that and let's remove this Ika desk I'm going to click as you
2:46:34 can see it's gone let's delete perfect it works it's that easy guys let's
2:46:44 do this the same thing for product sorry user and I'm going to open
2:46:53 up users page and I'm going to do exactly the same thing here input
2:47:09 is going to be hidden name will be ID and the value will be user
2:47:19 ID okay right now you know how to use server actions you can
2:47:24 do exactly the same thing for update page let's open up ID page users
2:47:32 and ID and firstly I'm going to fatch my data we are still using
2:47:38 our design here to do that I'm going to open up my data and if
2:47:42 you remember we are fetching our data using this file file right now I'm
2:47:46 going to fatch a single user fatch user we don't need rejects or pagination
2:47:56 I'm going to delete them actually let's delete here and I will say const
2:48:01 user await user model find by ID and I'm going to pass here the ID
2:48:08 comes from our client and right now I can return this let's say F
2:48:18 user and I'm going to do exactly the same thing for products okay that's
2:48:33 all let's open up our page right now using this function I'm going
2:48:37 to fatch my user of course it's going to be async const user P user
2:48:49 and I'm going to pass my ID here it's really easy to take
2:48:53 this only thing I should do is write here params and I'm going to take
2:49:02 the ID from this params I can do that because remember the page name
2:49:08 is ID if you write here slack or something else it has to be slack
2:49:14 or and other things I can pass this ID here and user do username
2:49:24 and again let's copy this if there's an user image show it if not
2:49:31 show no AAR okay and after that we are going to update our user
2:49:37 let's open up our action and copy here sorry this one and I'm going
2:49:47 to paste and this time it's going to be update user in this case
2:49:54 I need my ID also and I can delete here right now let's say update
2:50:04 so what I'm going to do here if you remember those inputs are empty
2:50:08 right now if you don't write anything here when I click on this button it's
2:50:14 going to send an empty string and if we are sending empty string we
2:50:18 shouldn't update that part we should update only whatever we change here to do
2:50:24 that I'm going to need a condition firstly let's create our Fields const update
2:50:33 Fields it's going to be username email
2:50:37 password phone address and is admin and is
2:50:44 is active right now I'm going to check those inputs if they are empty
2:50:50 or undefined I'm going to delete them from these update Fields if they are
2:50:54 not empty I'm going to use them and update my user so let's say
2:51:01 object Keys updated fields we are going to check every field here so I'm going
2:51:08 to use for each I'm going to take the key and I'm going
2:51:12 to check if update field key equals an empty string or undefined I'm going
2:51:24 to delete that key I will say delete that key of course it's ending
2:51:33 here okay so using these update fields we can update our user so I will
2:51:41 say await user find by ID and update and I'm going to pass here
2:51:49 the user ID and after update Fields Let's test I'm going to save here
2:51:58 let's change those placeholders by the way it's going to be username user email
2:52:09 we don't have to write here phone and address let's see by the way why
2:52:21 it's not fetching let's see our ID okay it's here but oh I
2:52:42 didn't say await okay so let's try of course we are going to need
2:52:50 our ID let's close here and create an input and it's going to be
2:52:58 hidden name will be ID and the value will be user ID and let's give
2:53:07 our action update user let's see and as you can see all these data
2:53:15 is here let's update this username and as you can see it's here and others
2:53:28 are still the same actually it's changing
2:53:31 this role because by default it selects
2:53:36 the first value so I can write here a condition if user is admin it's
2:53:45 going to be true and is not admin I will do the same thing
2:54:02 here let's see this one it's client and active so it's going to be
2:54:07 false and true false and true okay let's change here for example phone I'm
2:54:20 going to update and perfect it's here okay this is how we are using actions
2:54:32 you can do exactly the same thing for products just duplicate this and say
2:54:45 update product and change here like that if they are empty it's going to delete
2:54:59 and after product find by ID and update if there's an error it's going
2:55:07 to be update product and after that we are going to revalidate our products
2:55:16 and our users and products are ready we can add delete update and fch
2:55:23 data so let's take care of authentication for the authentication we are going
2:55:31 to be using OJs let's get started normally to use next off we should
2:55:43 create an API route and write all the configuration inside the API folder I also
2:55:50 prefer this method it's much easier but since we focus on server actions
2:55:55 and handling data without an API layer let's do it without creating an API
2:56:01 and this is what the nextjs documentation recommends us as you can see it uses
2:56:10 next off but be careful here you
2:56:12 should install the beta version because this version
2:56:15 is compatible with NEX js14 let's install I'm going to open up my console
2:56:22 and I will say mpm install next off and beta actually let's write here
2:56:29 the exact version number in order to prevent any possible errors so the version
2:56:34 will be 5.0 and beta and after that we are going to need to create
2:56:43 all secrets and URL basically this script is used for creating session tokens
2:56:49 and this is for creating authentication Pages like our login page so let's copy
2:56:55 this and paste to EMV file I'm going to open up EMV and paste
2:57:02 it here you can write here any secret key it doesn't matter you can use
2:57:12 this command on your terminal and create a if secret but it doesn't matter
2:57:16 it can stay like that and after that we are going to create our configuration
2:57:23 let's create a new file I'm going to create it here and it's going
2:57:27 to be config.js I will say export const off config I'm going to write
2:57:37 here my login page Pages the signin page will be the log L URL
2:57:45 this is important because if we are not authenticated we are going to be
2:57:48 redirected to this signin page after that we are going to create a callback
2:57:54 that we can write the authorization logic because if we are not logged in it's
2:57:59 not going to allow us to see this dashboard it's going to redirect us
2:58:03 to the login page and also if we are logged in we are not
2:58:06 going to see this page it's going to redirect us to the dashboard let's
2:58:11 do that I will say callbacks authorized and it's going to take our session
2:58:20 and also the request so we can check the request URL so firstly I'm
2:58:27 going to check my session I'll say const is logged in if there's a user
2:58:34 inside our session it means we are logged in right now we can check
2:58:39 if we are in the dashboard or any other page I'll say const is
2:58:44 on dashboard so we are going to check our request URL and the path
2:58:52 name and if it starts with dashboard it means we are on the dashboard
2:59:00 right now I can write my logic I will say if is on the dashboard
2:59:06 and if it's logged in we are going to return true so user can
2:59:13 stay on the dashboard but if it's not logged in we are going
2:59:17 to return false and it's going to redirect
2:59:20 unauthenticated users to login page and else
2:59:25 if is logged in so we are not on the dashboard but we are
2:59:30 logged in we are going to be
2:59:32 redirected to dashboard so I'll say return response.
2:59:40 redirect I'm going to create a new URL and it's
2:59:44 going to be dashboard and I'm going to pass
2:59:46 here request and next URL and finally if we are
2:59:53 not on the dashboard we are going to return true
2:59:56 and in this case users can stay wherever they
2:59:59 are so right now we have to run this function
3:00:03 for every request to do that we can use nexj
3:00:06 as middleware let's check the documentation as you can see we
3:00:16 are going to pass our configuration here and it's going
3:00:19 to run this function on every request except of this matcher
3:00:25 and it includes our API and static files we
3:00:29 should write this otherwise we won't be able to see
3:00:32 our images so let's copy this and paste here
3:00:37 of course I should change here it's all config
3:00:43 by the way it's here I'm going to move
3:00:46 this to app folder okay right now we can create the login
3:00:52 function let's check the documentation as you can see
3:00:56 we should create here our provider and it uses
3:00:59 the GitHub provider but in our application we are going
3:01:02 to be using our username and password so I'm going
3:01:06 to use the credential authentication in OJs the recommended
3:01:10 way to login is using social accounts or email codes
3:01:15 but most of the websites are still using username and password
3:01:19 credentials and for this kind of dashboard application it's not
3:01:22 a good idea to log in with Facebook or something
3:01:26 so we are going to be using our credentials so
3:01:32 I'm going to create providers and inside credential provider
3:01:36 and finally we are going to hatch our user but there
3:01:39 is something important here if you remember we are using
3:01:42 BP to hash and compare our passwords but we are
3:01:46 using this configuration in the middleware and the problem is
3:01:50 the bcrypt library is not JS dependent so I'm not
3:01:53 going to write my providers here instead I'm going
3:01:57 to create a new file let's say OJs and after
3:02:07 I'm going to create my provider let's copy this and paste
3:02:13 and and I'm going to remove here we are
3:02:15 going to fatch our user outside of this function let's
3:02:18 say const login we are going to take the credentials
3:02:26 and it's going to be an ASN function and we
3:02:28 are going to fatch our user compare our password if
3:02:32 everything is okay we are going to return our user
3:02:35 here but before let's spread everything inside our config let's
3:02:43 import like that and instead of export default I can
3:02:55 destructure my sign in and sign out functions that we
3:02:58 can use in the login page I will say const
3:03:04 sign in sign out and also I'm going to destructure
3:03:10 all session so using this function we can fetch
3:03:14 our user and use it in the sidebar okay let's
3:03:19 fetch our user I'll say try catch if there's
3:03:26 an error console lock this error and throw and new
3:03:31 error and I will say failed to login let's connect
3:03:36 to our DB and after I will say const user
3:03:45 await user model and I will say find one
3:03:50 because we are finding only one user and I'm going
3:03:53 to write my condition here and it's going to be
3:03:57 username should be credentials username and I'm going to write here
3:04:04 a condition and I will say if there is no
3:04:07 user in the database with this username we are going
3:04:10 to throw an error and let's say wrong credentials
3:04:19 and after if there's an user we can compare our passwords
3:04:23 I will say const is password correct and we are
3:04:30 going to be using bcrypt let's import this and we
3:04:39 are going to use the compare method and we are
3:04:42 going to pass here our plan password which is credentials.
3:04:46 password it comes from the login form and we are going
3:04:50 to compare this with the user do password basically the password inside
3:04:58 our database this hashed password so if they are not equal again
3:05:04 we are going to throw an error if it's not correct I'm going
3:05:10 to throw exactly the same error and finally if everything is okay
3:05:16 we can send our user return user let's call this function here
3:05:26 I will use try catch again if there is an error we
3:05:32 are going to return null in this case the login process will fail
3:05:37 let's say await login and I'm going to pass my credentials
3:05:42 and finally I'm going to take this user and return this user so
3:05:49 next off is going to take this user and pass it to session
3:05:54 let's see okay we are still in the dashboard there's something wrong
3:06:04 with the middle R okay it's not running if I move this here
3:06:19 okay right now it works but there's something wrong with our configuration
3:06:24 because we didn't add here any provider I'm going to leave it
3:06:28 empty because we passed our providers here inside OJs and right now
3:06:37 as you can see there's a typo here starts with and as you
3:06:43 can see it redirects us to login page that's try dashboard
3:06:49 and I cannot see that page okay and right now we can
3:06:53 log in don't forget to create your middleware in the root don't create
3:06:58 inside app directory or Source directory it has to be inside root
3:07:05 okay right now using this form we can complete the login process
3:07:10 let's create an action and take those fields and try to log
3:07:16 in inside library and actions I'm going to say export const let's say
3:07:27 authenticate we are going to take the form data and we are
3:07:33 going to fatch our user let's say async so let's just structure
3:07:38 our username and password remember how we are doing this object from entries
3:07:48 and form data I will say try catch block if there's an error
3:07:58 throw this error and I'll say await sign in function remember it
3:08:06 comes from next off and I'm going to write here the provider
3:08:13 name it's going to be credentials if you are using any social
3:08:18 media it's going to be like Google GitHub or whatever but we are
3:08:22 using the username and password and I'm going to pass my username
3:08:27 and password here let's say console lock error and throw this error
3:08:38 okay let's use this action in our form I'm going to open
3:08:41 up the login page page and pass it here but don't forget
3:08:48 writing your names it's going to be username let's import this and let's
3:09:02 try so let's say user one I'm not sure have we
3:09:07 created this user or not that's login and as you can see
3:09:13 we have an error because we didn't create that user we are going
3:09:16 to handle this error and show it somewhere here but for now
3:09:20 let's complete our process this is correct one test user I'm going
3:09:29 to login and as you can see we are in the dashboard
3:09:33 so if I try to go to the login page as you can
3:09:37 see it doesn't let me to go okay perfect right now let's
3:09:42 use our off function and Patch our image and username and after we
3:09:48 are going to handle our error remember we have this function let's
3:09:53 use it in our sidebar I will say async const session await off
3:10:11 function that's see what we have inside I'm going to open
3:10:16 my console as you can see it has the expires at date
3:10:21 and a user and this user includes only email but we are going
3:10:26 to need this image and username by the way there is an error
3:10:31 here there is something wrong with our images it's probably because
3:10:36 of this middleware and mature we are going to handle this but for now
3:10:41 it can stay like that that let's try to add our username
3:10:45 and image to our session to do that I'm going to open
3:10:52 up OJs and write different callbacks when you log in by default
3:11:01 next up is storing your email address into JWT token but we
3:11:06 can change it we can store something else like username and image
3:11:11 to do that we are going to be using J WT function I
3:11:14 will say async JWT and it has the token and the user
3:11:21 and I'm going to check the user first in any case and I'm
3:11:25 going to pass some other information to my token so token dot
3:11:31 username will be user do username and the image will be user.
3:11:40 image and after I can return my to token but to reach this data inside
3:11:49 our component we should pass the token
3:11:52 information to session to do that I'm going
3:11:56 to create another function and it's going
3:12:00 to be session and it includes the session
3:12:05 and the token it's exactly the same thing we are taking the data from user
3:12:11 and passing the token and we are going to do exactly the same thing here
3:12:15 we are going to take the data from the token and pass it to session
3:12:21 so let's a token and it's going to be session and finally we are
3:12:33 going to return this session so let's see right now I'm going to log out
3:12:39 and try again by the way we don't have our functionality here let's use
3:12:44 our log out function remember it's here we can use it where is our sidebar
3:12:53 here and what I'm going to do is creating here a form and wrap
3:13:00 my button and when I click on this button we are going to call our function
3:13:06 of course we are going to create here a server action to do that I
3:13:10 will say asnc remember server action should be async and I'm going to write here
3:13:18 my directive and await sign out function
3:13:25 let's import and that's all let's see I'm
3:13:30 going to click as you can see we are not logged in anymore what was
3:13:35 the name test user I'm going to log in and let's check our console
3:13:45 here and right now before this image error you are going to see that we
3:13:50 have username here but we don't have image because in our database as you can
3:13:56 see it doesn't have any image let's add actually I'll say image and let's choose
3:14:05 an image here this one I'm going to save by the way there was something
3:14:22 wrong here because we should pass it inside user object let's do that I'm going
3:14:29 to come here instead of directly session I will say session do user okay let's
3:14:40 see I'm going to log out test user and perfect right now we can use
3:15:06 them let's take our user directly and and I will say user do username
3:15:19 and if user has an image we are going to use it if not we
3:15:24 are going to use this image okay it's here so let me check this middleware
3:15:42 okay this is the correct one you can find it in the GitHub reposit story
3:15:46 as you can see there is no error right now we can login but if
3:15:53 you remember there is something wrong here
3:15:57 if I write any wrong credentials it shows
3:16:01 up this error component but I want to show my error somewhere here let's say
3:16:07 after button but if you are using your form inside the server component it's not
3:16:14 possible to catch the error and show it here so what you can do
3:16:19 you can come here and create an error layout of course it should be use
3:16:29 client and show your error inside this component okay we can see our error
3:16:38 but this is not what we want because user has to go back and and write
3:16:42 the credentials again to prevent this we should use a client component so I'm
3:16:48 going to take my form from the login page and create a new component let's
3:16:54 do that inside login page I'm going to create new component let's say login form
3:17:02 let's create our function and CSS and I'm going to take my form style here
3:17:21 from the parent and paste it here and right now let's open up the login
3:17:35 page I'm going to delete this form instead I'm going to call my component login
3:17:41 form right now we don't need this action here and let's paste our form
3:17:55 for now let's leave it empty okay there
3:18:00 is something wrong because I forgot dot here
3:18:08 okay as you can see it's exactly the same right now now I'm going
3:18:12 to convert my login form component to client
3:18:19 component and create here a new function handle
3:18:26 login we are going to take the form data and we are going to call
3:18:31 our action here so it's going to be async and I will say const data
3:18:38 is going to be our server action and we are going to pass this form
3:18:45 data let's open this function and instead of throwing error I'm going to return
3:18:51 let's say error equals wrong credentials let's
3:18:57 close everything and open up login form I
3:19:02 will say if data do error set an error so I will say const error
3:19:10 set error use State hook and I'm going to set my error here and if
3:19:21 there's an error I'm going to show it here let's use this function here
3:19:31 and let's try I'm going to write some different username and password and login
3:19:38 and as you can see wrong credentials but there is is one more way if you don't
3:19:44 want to use use State and this function you can use use form State hook
3:19:51 this hook allows us to update our state based on the form action let me
3:19:56 show you how it works let's check the example as you can see we are
3:20:01 creating this hook and we are passing here the initial State and when we click
3:20:06 on this button we are calling this form
3:20:09 action and it triggers our increment action
3:20:13 and this action is taking the previous state and returns a new state so we
3:20:19 can use this state inside our component after
3:20:22 this button for example so in our case
3:20:25 what we can do the state can be our error message at the beginning
3:20:30 we can Define this as undefined and when we call our action if there's
3:20:35 an error we can update our state and show it after our button let's do
3:20:40 that and you are going to understand better I'm going to copy this and paste
3:20:46 here I'm going to delete this use State
3:20:49 let's import okay let's import manually from react
3:20:58 Dom and we are going to pass our form action here and it's going
3:21:02 to trigger our server action and at the beginning
3:21:08 our error will be undefined and I
3:21:12 will say if there's a state show that state let's open up our server action
3:21:20 right now we are going to need one more parameter and it's going to be
3:21:23 previous state and right now if there is an error I can directly send
3:21:29 this error let's try I'm going to refresh
3:21:39 and let's give some username and password
3:21:42 and login and as you can see it's here and the best thing is even
3:21:47 if you disable the JavaScript it's still going to work and this is one of its
3:21:58 awesome features okay let's log in again
3:22:07 and right now we can authenticate fat users
3:22:12 products add new one or update by the way you can do exactly the same
3:22:17 thing for those forms you can make them client components and show the error
3:22:22 here I'm not going to do exactly the same thing again and again and that's
3:22:28 all this is how we are using NEX js14 I'm going to explain every single
3:22:33 thing about nextjs 14 in the next video but for now you know the basics
3:22:42 so let's deploy our application okay before
3:22:47 the deployment I'm going to build my application
3:22:50 for the test purpose let's check if everything is okay or not I'm going
3:22:55 to say mpm run build as you can see there is no problem right now
3:23:06 we can upload our files to the server and after we can build and start
3:23:11 our application let's open our project I'm
3:23:15 going to select everything here but we don't
3:23:17 need do next git and not modules I'm going to take the rest and I
3:23:24 will compress and we are going to upload the zip file to our server
3:23:30 let's open up our hosting panel this is our server it's up and running let's
3:23:36 come here this is the cloud panel URL let's click and remember our username it
3:23:45 was admin and we created a password I'm going to login and right now we
3:23:55 can create our website I'm going to click here we are going to create
3:23:59 a not JS application because nextjs is using not JS under the hood and here you
3:24:06 can write your domain name for this project I'm going to be using dashboard Lama
3:24:13 Dev and this is our username we are going to use this later but don't
3:24:18 worry you don't have to memorize everything
3:24:20 is inside your hosting panel let's create okay
3:24:27 let's manage our website and I'm going
3:24:29 to install the SSL certificate so our application
3:24:34 is going to use https connection I'm
3:24:38 going to come here and choose this certificate
3:24:42 let's create and install okay it's ready as you can see everything is much
3:24:51 easier thanks to Cloud panel and by the way
3:24:55 don't forget to redirect your website
3:24:58 to this IP address if you don't know how to do that you can search
3:25:02 for changing DNS records it's really easy
3:25:05 there is nothing complex and let's come here file manager and this is the main
3:25:13 directory of the application I'm going to choose
3:25:16 my website and right now I can upload my zip file here I'm going
3:25:21 to take this and upload let's extract it's going to be the main directory okay
3:25:34 right now we can connect to our server and build our application let's get back
3:25:40 to the hostinger let's click here and using this command we are going to connect
3:25:47 to the server but to do that we have to add our SSH key I'm
3:25:52 going to come here SSH keys and I'm going to add my key here let's
3:26:00 create a key I'm going to open up my terminal and create my key okay
3:26:12 it's ready so let's copy this key using
3:26:15 this command by the way all these commands
3:26:18 will be in the description below don't worry about them and let's come here
3:26:24 and paste our key and let's give a name it doesn't matter and it's going
3:26:32 to take a while and after that we will be able to connect to our server
3:26:37 okay it's ready let's come here and copy
3:26:43 the connection command I'm going to paste
3:26:47 it here I will say yes and we are connected the First Command I'm
3:26:54 going to write here is sud sudo 2 and llama dashboard let's get back
3:27:02 to the main folder and let's see what's inside as we can see this is
3:27:12 the folder that includes our websites let's get
3:27:15 inside HD docs and inside this folder you
3:27:20 are going to see our website let's open CD and our website and if you
3:27:27 check inside you are going to see that all the files we uploaded are here
3:27:32 let's install our libraries I will say mpm install okay we can use this command
3:27:44 because remember we have created a not
3:27:46 JS application so everything is ready to use
3:27:50 let's build our application I'm going to open the production mode and I will say
3:27:54 mpm round build as you can see there is no problem it works as expected
3:28:08 but I forgot something remember in the EMV file our authentication URL is still
3:28:16 Local Host let's change here otherwise we
3:28:19 cannot login so I will say dashboard l.
3:28:23 Dev of course it's going to be https I'm
3:28:27 going to save and let's build again during this process
3:28:36 let's update our mongod DB remember in the network
3:28:41 app access we are not using any specific IP
3:28:44 address and it allows everyone to access our mongod
3:28:48 DB to prevent this I'm going to write here
3:28:51 the server IP let's come back and copy this IP
3:28:57 and I'm going to paste here and right now only
3:29:02 our server has the access right now it's much
3:29:06 secure and it's ready to run I'm going to start
3:29:09 my app and let's see I'm going to refresh
3:29:18 my page and as you can see our homepage
3:29:24 let's try to open dashboard it doesn't allow because
3:29:30 we are not logged in let's log in okay wrong
3:29:40 credentials I forgot what was the user test user
3:29:47 or let's see and it's ready let's check our users
3:29:57 okay they are here let's check the pagination perfect
3:30:03 I'm going to delete this one and this one
3:30:08 perfect let's try to add new user test from website
3:30:22 I'm going to submit it opens to users page
3:30:26 and let's check and it's here perfect it works
3:30:37 we have only one product and let's try to log
3:30:43 out okay all functionalities work and that's all guys
3:30:48 I hope you liked it remember the next video will
3:30:51 be the complete nextjs 14 tutorial and if you
3:30:55 have any questions if you didn't understand any part
3:30:59 of this tutorial I highly recommend you to watch
3:31:01 the next tutorial okay if you learned something new today please
3:31:06 like the video you can support Lade using the link
3:31:09 in the description below or by joining the channel
3:31:12 don't forget to follow lad's social media accounts I
3:31:16 hope I will see you in the next tutorial goodbye