10 hours 19 minutes 31 seconds
๐ฌ๐ง English
Speaker 1
00:00
Learn how to create a fully functional hotel management site with Next.js 13, React, Sanity IO, Tailwind and Stripe. Larry Bright created this course. He will help you understand how to fit all of these technologies together in a real world full stack project.
Speaker 2
00:16
Hello friends and welcome to another project video where we are going to be building and deploying this hotel management system. So let's have a demo of the application we are going to be building. This application is going to be using the sanity CMS.
Speaker 2
00:35
So if I copy over this URL and I open a new tab in my browser and I just go to slash studio you see that we load our CMS. So our CMS is embedded inside of our front-end code here And we have this navigation section. We have the header. We have the user profile.
Speaker 2
00:54
And we can also switch between the light and dark theme here. And our application is fully responsive for mobile devices and also for desktop devices. All right, so let's have a demo here. So over here, we can search through a room.
Speaker 2
01:14
And we list out a room. So let's actually start in our CMS here in our content management system. Let's try to create a hotel room. So we can click on this hotel room section and here we click on this tab.
Speaker 2
01:29
Alright, So we need to give this hotel room a name. I'll just call it Test Hotel for now. And I'm going to generate a slug. And for the description, I'm just going to copy and paste this description in here.
Speaker 2
01:44
And for the price, we can give this hotel room a price of 1,000 and say we are currently on a 10% discount. And for images I will click here and I will just fast forward and add some images from Unsplash here. Okay so once we have added these images for the cover image I'm also going to copy this other URL from Unsplash or you can as well add a file and you see by default the room type is basic we can choose the different room types I'm just gonna choose luxury and we have the special notes I'll leave the dimension for number of beds I would just say 2 and for all 5 amenities we can choose an amenity for the icon the icon has to be a font or some icon so I'm just going to come here and add this icon FA bird and for the amenity I would just say king king sized bread like this and that should be it so it's saved we can obviously add more all right so after this I'm not gonna make this is not booked so by default a hotel room isn't booked and I'll not make it to be a featured hotel room. And we can go on to publish this hotel room.
Speaker 2
03:11
So we gave this hotel room name of test hotel. And if we come over here to the application, we come over to our rooms section, we see that we have our hotel room here in real time. So as we make changes to our sanity studio, You see it reflects in our application and we can go on to book this hotel room. So I'm going to click on this book now and these are the images that I uploaded for this and we have this nice looking model over here for the different images so that the user can swipe and see it in full screen.
Speaker 2
03:49
Alright, so you see what we chose here, the king-size bed, the city view, and the coffee maker with the respective icon. I just happened to choose the wrong icon for that city view. We see the description, we see here they offer the amenities, safety and hygiene and this hotel room doesn't have a review. So let's go and book this hotel room and you have to be authenticated.
Speaker 2
04:11
So if we click here you see this comes to the user profile page And we can obviously sign out of the application and we are redirected back to the home page. And we need to authenticate. So we can authenticate via email and password, or we can use GitHub. Or we can also use Google.
Speaker 2
04:31
I'm going to click on Google over here and I'll sign in with my Google account and I should be redirected back to the application. Great. So let's go on and book this our test hotel room that we just added. So you see here we have this filter here and we can filter by luxury and we see the hotel room because this falls under that category and I'll just click on this book now and here I'll choose a check-in date so I can choose today as a check-in date and you see a later day as a checkout date and you say the price of dates accordingly because there's a 10% discount we see that the price here is 900 bucks and if we choose a date that is way ahead of our checkout date we have this error so that the user cannot book, you know, a date that is way ahead our checkout date.
Speaker 2
05:22
Now I'm going to choose this check in date, and I'm going to go on and book this hotel room. Now once this loads up Stripe, because we are going to have Stripe for payment. If we come over here, so we see sessions that we have used now because this hotel room is following a payment first approach. A booking is only going to be made if payment is successful.
Speaker 2
05:44
So I'm going to fast forward through and fill out these details over here. And once you fill out these details, you can go on and click on Pay. And this is processing payment. Now on successful payment, we can just come back to our Stripe dashboard and let's reload these sessions that we have here.
Speaker 2
06:02
I'm just going to reload this. And you should see our new webhook. Now this webhook is called because so this is our new webhook that we just triggered now. Now because this event is called we go on to create a booking.
Speaker 2
06:17
And if we come over here to our Sanity Studio, and we come over to our booking section, you will see here that we just booked this hotel room. So this test hotel room here, the number of days, and all the details that we filled out while we were booking this. Now, if we come back to our hotel application, you see here that we are redirected to the user profile page. And here, the user can see the current bookings, and the user can also see the amount spent.
Speaker 2
06:45
So this is the test hotel, which was the highest amount spent at 900 bucks. So if we come back to the current bookings and we click on rate, we shall be able to leave a rating on this hotel room. So we can say great experience like this and click on submit. Now this is going to go on and submit the review and if we come back to the test hotel room we should see our review here we're just gonna reload this and our review should pop up.
Speaker 2
07:15
So this review that we just gave on this hotel room and you see this hotel room is booked and the user cannot go on to book this hotel room. So we can come back to the user profile page. And here we have this hotel room we just booked. If we want to leave another rating here, and we click on submit and we come back to the test hotel room.
Speaker 2
07:36
So here I'm just going to reload this and you should see that the hotel room you know updates so we have this functionality to leave a review and to also update a review and only customers that have booked a hotel room can go on to leave reviews on the hotel room. So this is the application we are going to be building and the application is fully responsive. Now we have this crazy looking parentheses here because we didn't provide a dimension. So if we come back here to the test hotel room and here, where is it, this test hotel, if we just leave a dimension over here, so we can just say 30 or whatever and publish.
Speaker 2
08:16
And if we come back here, we should see here the updated just below this we should see here 13 so for the dimension so this is the application we have our review and all aspects of this application is fully much responsive as you would expect. And to achieve this we are going to be using Tailwind CSS here. So this is the application we are going to be building together. If you like this project please do go on and leave a subscribe it helps the channel and don't forget to give it a thumbs up as well.
Speaker 2
08:50
And I have already left timestamps in the description so in case you come back for later, you should be able to continue with the project. And the source code is already in the description so you can get it on GitHub. Now, let's get started building out this project together. Let's start our project and I've navigated to my desktop from my terminal and I'm going to run the command to create a new Next.js project.
Speaker 2
09:17
The command is mpx create-next-app, And I'm going to be using a template of TypeScript. So I'll zoom out a bit so you see the entire command. So npx create next app with a template of TypeScript. I'll execute this.
Speaker 2
09:32
We are prompted to give our application a name. And for this project, I'll just give it the name of Hotel Management, like this. So I'll just add the E, so Hotel Management. And say yes to all these prompts and say no to customizing default inputs.
Speaker 2
09:53
Now once Next.js CLI is done building our project, I'm going to cd into the created project which I called Hotel Management and go into Visual Studio Code. This is the default files and folders that we get by default. If we run npm run dev so that we can just preview the application that we get from Next.js. As you can see, we are running on Next.js 13.5.4.
Speaker 2
10:26
This is the current version of Next.js we are working with. If we come over to the browser and we just go to localhost 3000, you'll see the file or our home page, so localhost 3000. So let's go on and make changes already to our application. And I'll get started in our layout.
Speaker 2
10:50
So our layout.tsx which controls the entire layout of our Next.js application. And for the title, I'll give it the title of Hotel management app and also update the description. You can give this any title or any description of your choice but in this case I'll just say discover the best hotel rooms like this And this is going to update our header title and description. For the font, I'll be making use of font poppins.
Speaker 2
11:23
So I'll import poppins from next font Google and use it over here. We have an error. But before we come to that, the intact variable here, I'll change it to poppins. All right, poppins with a lowercase p.
Speaker 2
11:39
OK, so configurations we can pass to this poppins font is the font weight. So it can be a string. In this case, I'm going to pass an array of strings for the different font weights we are using in our application. So we're going to make use of a font weight of 400, also a font weight of 500, And also a font weight of 700.
Speaker 2
12:02
And lastly, we're going to make use of a font weight of 900. Okay, so just type 900 like this. And for the styling, I'm going to give this a style of italic, as well as a style of normal. So this style over here, normal.
Speaker 2
12:21
And lastly, we need to pass also a variable. Okay, so we're gonna pass a variable. And the convention is to go with double hyphen like this, and then font on the hyphen. And I'll just go with font poppins as the variable.
Speaker 2
12:35
And to fix the error that we have in our body tag over here, right and go with interclass names, we're going to go with poppins dot class names like this. So poppin dot class name. All right. And I'm going to cut these children here.
Speaker 2
12:55
And I'm going to wrap our layout in a main tag, like this, in the main tag. So here we have a main, which we can give className. And the className I'm going to give to this main tag is font-normal, so font-normal like this. Later in our application, we're going to have a header component as well as a footer component.
Speaker 2
13:21
Here, I'm going to have header. So this is a placeholder, and I'll comment it out. Just after it, we're going to have children, and after which we are going to have our footer components. But before we go on and have our header components, so before we go on and have the layout for our header components, I would just like us to discuss briefly about the meta description.
Speaker 2
13:48
Let's go over to the browser. Here in the browser, if I just reload, and you see here we have Hotel Management app. If I open the Elements tab over here, so here where we have the Elements tab, and I just collapse the head. Here, if you check down, you see here that we have the meta, so the description, and we have the content, and the same for the title.
Speaker 2
14:15
This object that we have over here, so this metadata, we just have the title and it renders it as we normally have in HTML in our head tag where we have the title, and there we just write out the title of our application. This is the work of this metadata. We can pass these headings that we would normally have in HTML. OK, so I'm just going to revert to the changes that I made here.
Speaker 2
14:46
And we can go on and create a header component. So in the source folder, I'll create a new folder, I'll call components and in here, so inside here, I'm going to create a folder, I'll call header and then another file, which I'll call header.tsx. Okay, so I'm just going to bootstrap this header component and remove the React input. We can already import this header component in our layout.
Speaker 2
15:19
Here we have the placeholder. I'll go and import header. Header will be coming from components header, slash header like this, and I'll just rearrange the order of inputs here. For HTML semantics, rather than use a div, I'll be making use of the header tag.
Speaker 2
15:43
Obviously, I'll be starting this header. I'll give it a padding on the y-axis of 10, padding on the x-axis of 4, give it container, and to position the items in the center I would use mx-auto, text-xl, flex, flex-wrap, and on medium devices, I'm going to go with flex-null-wrap. So flex-null-wrap here. After that, we're also going to use position the items in center and justify between.
Speaker 2
16:19
I'll zoom out a bit so hopefully you can see the entire class names, styles that we have applied here, and I'll zoom back in. Inside this header tag, we're going to have a div. 2 sections actually, sorry about that. I'm gonna have a div, and I'm also gonna have an unordered list.
Speaker 2
16:41
So let's start with the div. And this div, I'll give it a class name of flex, give it item center, width full. And on medium devices, we won't take the full width. We're just going to take 2, 3 of the width, like this.
Speaker 2
16:58
All right, and inside this div, we are going to have a link. So this is where we are going to have a link that we point into our home page. So this link component we are going to go and import it from next link. Okay and for the href we are going to go to slash which is our home page.
Speaker 2
17:23
And for the class name I'll give this a class name of font black and also text let's say this hex code this color. I provided this hex code before now, so F27405, which is more like an orange color. Here I'll just give you the name of hotels like this. After this link, we are going to have another list where we will have the icon to take us to the authentication page and also another icon to toggle the theme.
Speaker 2
18:00
So here I'll give this another list, a class name of flex, item, center, and margin left of 5. For the icons, we are going to be using React icons. So npm install react-icons, like this. So I'll wait for it to install, and I'll restart the application.
Speaker 2
18:18
So npm run dev. All right, so let's use the, Before we can apply the icon, we're actually going to have a link. This link will take us to the user authentication page to the auth page and for the icon I'm just going to use fa-user-cycle. So fa-user-cycle and for the href of this link I'll just take this off.
Speaker 2
18:47
And for the href, this link is going to be pointing to slash auth. So let me import the FAESA circle, and let me give it a class name. So for the class name, I'm just going to give this a class name of course, a pointer. So allow the IDE helping with this input.
Speaker 2
19:06
Nope, it doesn't. So I'll have to import it manually. So let's import, boot the structure FA user circle coming from react-icons for slash FA. Great.
Speaker 2
19:20
Actually, this link that we have here, we need to wrap it in the list item. So in an ally and this ally needs some class names. So I'm going to give this class name of flex-items-center. And then we're going to have another list item.
Speaker 2
19:38
And the idea is for this other list item to hold the toggle. So it's for our lights and dark theme. So I'll just give it the margin left of 2 to have some space from the user circle. And for the icon, I'll use this MDDarkMode like this.
Speaker 2
19:57
Okay. And I'm just going to duplicate this so that I will destructure this coming from React Icons MD, okay, for material design. And also give this a class name. So I'm going to give this icon a class name of CursorPointer here.
Speaker 2
20:21
All right, and for this other list items, which would hold links. So I'll just give this a class name of flex over here. Also give it a class name of item center, justify between, give it a width full and on medium devices, I'll give this a width of 1 slash 3, 1 third, and imagine top of 4. And then we're going to have list items and for this li I'm also going to give this some animation on hover so I'm going to translate this on the y-axis so negative 8 pixels and I'm also going to give this an animation duration of 500 and I'm going to transition all like this.
Speaker 2
21:11
Okay and inside this list item we are going to have a link so We already have this link components in Perfect which will go to home. The href is going to be pointing to slash. I'll bring this down, let's say 2 more times. We are going to have a link going to slash rooms.
Speaker 2
21:33
We have this rooms here, and the href will be pointing to slash rooms. This will just go to the homepage is contact. We'll just have the link contact. We don't have any contact page, so we'll just leave it to go back to the home page like this and we're going to save this file and then we can visit the browser and I will just quickly reload our application So that we can see our styling Take chain our changes take place already Yeah, so we see our changes we see our link and we see our different icons You know and you see the animation that we have on this section.
Speaker 2
22:20
Let's come back to the IDE. I'll just remove this so that we can take the full room. Let's configure Tailwind CSS. I'll come over to Tailwind config.ts file.
Speaker 2
22:39
I'm going to get rid of this background image. We're not going to be configuring the background image. We are going to configure first the different colors that we'll be using in our application. Okay, so we are going to have our primary color and our primary color is going to be this hex code so F2C641 and then we are gonna have our tertiary color and our tertiary color we are gonna have different variants so I'm gonna have the dark variant and also the light variant and the dark variant is going to be this hex code so F27405 And the light variant is going to be this hex code, so F2C641.
Speaker 2
23:59
OK, so this for our colors. And Apart from the color, we are also going to be configuring our font family. Here we are going to use Poppins name. We have this array, and this variable has to match the variable we define in our layout.tsx.
Speaker 2
24:24
So this variable, I'm going to copy it, come over to our layout, it has to match this variable over here. So come back to the table in config and we also need to spread out the font family. So I'm going to import the font family using the require statement. So const fun family is equal to require.
Speaker 2
24:53
And this will come from the win CSS and default team. So Here we are going to spread out the font family and access the sans property. Great, so we can come back to our header.tsx and where we made use of the tertiary color. So I'm just going to copy this and if we come over to our header.tsx I'll replace this so this is going to be you know text and now we can use text testiary dark and you see this yellowish color this icon or we can use text testiary light here we don't get the icon that means there should be you know a typo somewhere And we forgot to actually add the hash here.
Speaker 2
25:51
So add this hash, and there we see the preview. Great, but I will go back to the DAQ variant, which we are using in this case. And we see everything works as fine. So up next after the header, we are going to be working on our footer component.
Speaker 2
26:11
So I'm gonna create another folder, which I'll call footer, and then another file for our footer.csx. Okay, so I'll get rid of the header and the tailwind.config. So I'll bootstrap a footer component and remove the react input. And rather than use a div, I'm going to make use of the footer tag.
Speaker 2
26:40
And let me style this footer, give it a class name. And the class name is going to be margin-top-16. Okay and here we are going to have a div with the class name of container and mx-auto. And for padding give it a padding of 4 on the x-axis.
Speaker 2
27:03
And then we're gonna have a link which will import from next link and this link will still take us to the home page so the href is going to be slash and the class name is going to be Font Black. And for the text, we're going to go with text, tertiary dark here, and we'll just have the makeup brand name, Hotels. And then we're gonna have a h4 a h4 that will say contact like this and for the class name of this h4 I'm gonna give it a class name of font let's see font semi bold and a text let's see I'm actually looking for 40 pixels do we have no so I'm gonna use 40 PX like this and padding on the y-axis of 6 here. OK, so after this h4, we're going to have a div.
Speaker 2
28:08
And this div, I'll give it a class name of flex, and give it flex-wrap, and give it a gap of 16. Position the items in the center and justify between as well. Inside this div, we're going to have another div, which we're just going to give flex1 with different paragraphs for this made up address which I will give 123 road and then we are going to have this div with the class name of flex and item center give it a py of 4 and this div is going to have this icon so this icon BS field send field okay and after the icon we are gonna have a paragraph and This paragraph would have a margin left of 2, and I'll just say code with Larry here, and quickly import this BS send field, BS field send field from React icons, forward slash BS here. OK, so after this, I'm actually going to copy and paste this 2 more times.
Speaker 2
29:35
We're gonna have, get rid of this py4. And for the icon, we are going to use in this case, another icon, which is bs-telphone-out-bond. And I'll just have this made up phone number here and after this we are going to have this And we'll still keep the brand name code with Larry, but we are going to use a different icon. So here we're going to use BI message detail.
Speaker 2
30:13
And we need to import this from react icons for slash BI. And I'll remove this bs send field send field okay and get rid of this py rather use a p padding top of 4 So after this div with this flex 1, we're gonna have another div. And this other div, we are still gonna give flex 1, and we are gonna give for medium devices and above, we're going to position the text to the right. So align the text to the right.
Speaker 2
30:52
And we're going to have a pattern, a paragraph with a pattern bottom of 4. And here we say our story. And I'll just bring it down and say get in touch. And next we're going to have our privacy our privacy commitment, I'll bring this down.
Speaker 2
31:12
And next we are going to have terms of service. And I'll bring it down 1 last time. And here we are going to have customer assistant without any class name. So this last 1 is not going to have any class name here.
Speaker 2
31:32
Great. Okay, so after this div, you are going to have another div, which we are going to give a class name of flex1. And on medium devices and above, we're going to go with text right like this. And this div we have different paragraphs.
Speaker 2
31:54
This paragraph we're going to give a padding bottom of 4. And we'll just go with text of dining experience. And next we're going to have another text with wellness. Bring it down for fitness.
Speaker 2
32:08
And next we're going to have another with sports. And we're going to have another 1 with events without any class name. Okay, so after this div, we are going to have another div. This div actually is going to be a self-closing div because we are not going to have any content inside.
Speaker 2
32:29
It's just for styling. So I'll give this a background of background tertiary light. Give this a height of 10. And on medium devices and above, I'll give this a height of 70 pixels.
Speaker 2
32:44
And give it a margin to the top of 16, a width full and I'll give it a bottom of 0, left of 0 and we come over to the layout I'm just going to import the footer component here okay so Footer from our components, footer, footer. Go on and save this file and we'll visit the browser. We see our footer over here. Let's see if our application is responsive.
Speaker 2
33:20
I'm just going to test this out to see if it's responsive, and use the responsive points that we have here. We don't see our text, that's because come over to our app and our page.tsx I'm going to get rid of everything we have here. Okay so for now I'll just return empty fragment with the text of home. So I'll just type home in here and remove the input from next image.
Speaker 2
33:58
And I'm also going to use an arrow function. So const home is going to be equal to this arrow function. So I'm going to save this. And if we come back, we have an error, because we are not exporting this home component.
Speaker 2
34:14
Actually, we have to export it by default. So export default home like this. And if we come back to the browser, we see our application. And let's test out the responsiveness of the application.
Speaker 2
34:30
And we see that our application is responsive. We can just test this out here. I would also love to get rid of this background color that we have here. To get rid of it, let's come over to our global.css and I'm just going to remove these predefined stylings that we got by default.
Speaker 2
34:56
And yeah, we have our white background. Up next, we are going to be working on our teaming feature. I'm just going to close all. Let's work on our teaming.
Speaker 2
35:09
In the source folder, I'll create a new folder, I'll call context. Here I'm going to create a new file for our team context. So a file, call it teamContext.ts, and let's import dispatch from React. We're also going to import setStateAction, And we're also going to import that create context.
Speaker 2
35:35
To create a context, we're going to have this constant over here. And we're going to call it team context. And this is going to be equal to create context. So to create a context, we make use of createContext from React.
Speaker 2
35:49
And for TypeScript, let's define the type that we are going to need for our context. So the type for our team context type is going to be equal to this object. So we're going to have that team, which is going to be of type Boolean. And we are also going to have set that team.
Speaker 2
36:10
And set that team is going to be of type dispatch. So the type of action we're going to dispatch is a set state action, which is of type Boolean. And I'm going to pass this type to create context. We're going to have errors, because now we have to define some default values.
Speaker 2
36:29
So for that team, by default, it's going to be false. And set that team, The initial value is going to be this function that returns nothing. All right, so let's export our team context. So we're going to export default, this team context here.
Speaker 2
36:47
So this is the first step. We create our context. And in the components folder, I'm going to create another folder, which I'll call team provider. So we're going to wrap this team provider with our entire application.
Speaker 2
37:04
Here we have our team provider.tsx. First, I'll be making use of the use client directive that we get from Next.js, and I'll import useEffect, and I'll also import useState from React. And I'll also import the themeContext. I actually want this to be an uppercase T, so I'll rename it here and also rename it in a themeContext file.
Speaker 2
37:34
So This const, I'll use an uppercase T here and also export default team context like this. Then I'll come back to the team provider. Here let's have our component JSX. I'm going to have this const team, not context.
Speaker 2
37:55
So team provider, which is going to be equal to this arrow function here. Okay. So for props, this is going to receive children. And the prop is going to be of type object where we have children and children is going to be of type React dot react node like this.
Speaker 2
38:20
OK, so first we're going to have this const where we set our state, so dac team, and set dac team, which is going to be equal to uState like this. And uState is a generic type that is going to hold a Boolean value. And for the initial value, we're going to get this from local storage. So we can call this team from local storage.
Speaker 2
38:47
And first, we need to check that we have local storage So we're gonna check if type of local storage is not equal to undefined Okay, so if this is the case that local storage is set Then we are going to get an item from local storage. And local storage dot get item, the item we're going to get would have a name of hotel team. So hotel team like this. And we're going to check if we successfully get an item.
Speaker 2
39:18
So if we have a value there, then we are going to JSON dot pass that value. Okay, because it will definitely be a string because we say string in local storage. So we're going to pass JSON dot get item hotel team. And I'm just going to have this exclamation sign here to tell TypeScript yes, we are sure we're going to have this.
Speaker 2
39:42
Otherwise, we are going to be using false. Okay. So if local storage is defined, we get the hotel team, and then we're going to JSON dot pass. And once we JSON dot pass, we if we get it, otherwise we use false.
Speaker 2
39:59
So I'm going to pass this team from local storage. And for TypeScript types, this team that from local storage is going to be of type Boolean. I'm going to pass this value as our default value to use states here. This is the first step in achieving our teaming.
Speaker 2
40:20
After this, we are also going to go on and have our JSX for our TeamContext. Now TeamContext, we access.provider. For values, remember our TeamContext will be holding a dactim value, which is the value from our set state, and set dactim, which will be referencing this value from our use state. And in here, we're going to have a div.
Speaker 2
40:49
A div, and we have Some conditions for the class name. So we're going to be using Brackets and then back tick so we're first of all gonna check if that team so if that team is true Then doing CSS gives us this dark variant. We are going to append it to this dact variant. Otherwise, we are just going to use an empty string.
Speaker 2
41:15
And then we're going to give this a minimum height of screen. So in here, we're going to have another div and this is the div where we check if dark team is true. We are going to use apply some class names. So here we're going to check if we have dark team, we're going to give have a text white.
Speaker 2
41:35
And if we have dark theme, so we have this dark variant, we're gonna give this a background of black. And for the text by default is going to be a black text. Okay, so for the white team, a case where we don't have the black team, there's going to be 1A1A1A. And then in here, we can just go on to return children that we received from the props.
Speaker 2
42:04
This team provider, let's go and export this as a default. Export default team provider. We're going to add another state. I'm going to have another state here, and we're going to call this state RenderComponent.
Speaker 2
42:22
And this is useful so that we know we have some condition here for the class name so that Next.js will be able to pick this up on the client. So we have RenderComponent, set RenderComponent is going to be useState of false. Okay, and I'll just close this off here. And we're going to have our useEffect.
Speaker 2
42:44
Okay So in our useEffect, we are sure that our component has been mounted to the screen. We are going to go on to setRenderComponent and set it to true. So we're having this error because we forgot to have our return statement. So we're going to return this.
Speaker 2
43:05
And back in our useEffect, we're going to set a render component and set it to a value of true like this. So we can check over here. If our component is not yet rendered, we are going to go on and return and empty fragment. Great.
Speaker 2
43:24
We have our team provider. Now we are going to make use of this team provider in our layout. Come over to the layout.tsx. In our app, and here we have layout.tsx, we are going to wrap our entire application with this team provider.
Speaker 2
43:42
So I'll cut this. And here we are going to have our team provider and we are going to return our main tag. Okay, so if we come over to the browser, we would expect everything to work as not intended, but actually, it's not going to work. Okay, I'll just reload the page.
Speaker 2
44:03
And, you know, if we click on this button, you see nothing happens. So let's come over to our header. Because we haven't wired up the events yet, so in our component, header.tsx, here we are going to be importing the DAC team and set that team from our context. To make use of our context, we use the use context, and here, we are going to make use of our team context.
Speaker 2
44:31
I'll just bring this down here. And we're going to destructure dark team, and also set dark team here. Great. So dark team, we can use this to configure the icon.
Speaker 2
44:49
We're going to show. So this icon here, I'm going to cut this icon. Here, I'll first of all check if that team is true. So if that team is true here, I have the question mark sign.
Speaker 2
45:05
So if that's the mystery After you want to return a different icon, so we are gonna go on and import this icon And the icon is this MD outline light like this so light mode so I'll copy this and if that's true I'm gonna paste this otherwise I'll use this okay so we're actually gonna use this as a self-closing tag like this. Okay, so next we're going to give this class name of cursor pointer. I'll just paste this class name over here. Next, we need to wire up the click events.
Speaker 2
45:48
So on click, we're actually going to do 2 things. So I have this callback function. You can outsource it, but I'll just write it in line here. So on click, we're going to first set that team to false.
Speaker 2
46:04
And we also want to go on and remove the from our local storage so we're gonna remove item from our local storage hotel team okay And I'll just copy this click event here. On the DAC mode, we are going to do 2 things. But this time around, we're going to set DACTheme to true. And rather than remove item, we are going to be setting item.
Speaker 2
46:29
And with this key of HotelTheme, and the value will be true, but not like this, as a string. And to make our main feature to work we just need to go on to make this header component use client component because now we are making use of context and not to have errors. And lastly, in Tailwind config, we just need to do 1 last thing. So come over to Tailwind config.ts and just right above the content here, we're gonna set DAC mode.
Speaker 2
47:05
Yep, so the DAC mode, we're gonna set it to value of class. Okay, so now if we come over to the browser. So just come over to the browser and if we click, yep, you see our teaming feature works as expected. Up next, if we click on this icon here, you see that we are directed to slash auth.
Speaker 2
47:31
For now, this leads us to a 404 page. So let's work on this page and in our app I'll create a new folder which I'll call auth and then I'll create a file for page.tsx. So in here I'm quickly going to bootstrap this component and I'll change from page to off and Remove the react inputs and next I'm going to give this some class names and I'm going to give it a class name of container and then imagine on the x-axis of auto and I'll change this div to a section tag. Okay and in here we are going to have a div and this div is going to have a class name of padding 6 and also a class name of space y4 and the medium devices this is going to have space y6 and then a small devices is going to have a padding of 8 like this and we're also going to give this a width of 80 and on medium devices I'll give this a width of 70% and make sure that I also go with MX auto so that the form is in the center.
Speaker 2
48:55
And next we're going to have a div and this div is going to have a class name of flex, a margin bottom of 8, Give it flex call and on medium devices I'm going to give it flex row, items center and justify between and this div we are going to go on to have a h1. Now this h1 I'm just gonna say create an account and let's start this h1. I'm gonna give it a class name of textXL and also fontBold, leading tight and also give it a tracking tight like this and the medium devices I'll give it a text of to Excel now just after this h1 we are going to have a paragraph which is going to say or. After this paragraph, we're going to have a span.
Speaker 2
49:53
For the class names of the span, we are going to give it a class name of inline-flex-item-center. In this span, we're going to have 2 icons. First is this for GitHub, so AI-fill-github. We're going to give this a class name.
Speaker 2
50:10
The class name of this is gonna be margin to the right of let's say 3 and then I'll just give this a text of 4XL and a cursor of pointer and then text black like this. And then on dark mode we are going to give it a white text. So here we are going to go and have this pipe, which is going to differentiate it or separate it from the Google icon. So here we're going to have this FC Google with the class names of margin to the left.
Speaker 2
50:47
So margin to the left of 3 and also give it a text of 4xl give it a cursor pointer and next we can import these icons so first I'm going to import this AI field GitHub which will come from react-icons forward slash AI and next I'm going to import FC Google which will come from react-icons forward slash FC alright so next we are going to reload and if we check the browser, and you see that we have this create an account and we have everything working as expected. Alright, great. So after this div, now we are going to be having our form. So our form but without any action.
Speaker 2
51:35
Okay so I'm going to take the action and provide it to the class name and the class name is going to be let me see so the class name is going to be space y4 and the medium devices I'm going to give this a space y6 like this and inside this form we're going to have different inputs so for the email password and also for the name so this input is going to be of type email and then we are also going to give this a name and the name is going to be email and we're gonna give it an ID. The ID is also going to be email and for placeholder you can just go with name at no company dot com and we are also going to make this required like this okay I think that will be all for this inputs okay so that'll be all And let's just style it for the class name, the class name is actually going to reference a variable. So we're going to call this input styles. And we can define this input styles here, which is going to be this constant.
Speaker 2
52:47
So input styles is going to be the string. We are going to go with border and also give it a border gray of 300 and on small devices give it a text SM and a text black like this and we're gonna give it rounded LG I'm just gonna fix this yep so rounded LG and give it block and also give it a width of full a padding 2.5, and on the focus states, I'm just going to take off the outline by saying outline none. There'll be no outline on the focus states. This input styles, you can see the complete class names and that's the input styles we are passing to this input over here.
Speaker 2
53:40
Alright so we're gonna have more inputs so actually I'm just going to you know copy this 2 more times so we're gonna use this for password so that'll be the type and the name of this input field is going to be password the ID as well is going to be password and for placeholder the placeholder is also going to be password so let's have password here and for validation apart from making it required we're gonna give it a minimum length so this password is gonna have a minimum length of 6 like this and this is going to be for the name. So it's going to be of type text. So this other input over here, and the name is going to be named for the username, The ID is also going to be John Doe and for placeholder so actually the ID is going to be name okay and then placeholder. You can give it any placeholder.
Speaker 2
54:44
I'll just go with John Doe like this And I will change the placement of these inputs. So I'll cut this for the name and just place it right above the email like this. And if we reload the browser, you see we have different inputs and it also works fine with our teaming. Okay great so after this input we are going to have a button to submit the form So this button is going to be of type submit like this and it's going to have the text of sign up.
Speaker 2
55:27
Okay and let's dial this button So I'm just going to bring this quote, a single quote back. And for the class name of this button, this button is going to have a width of full like this. And this button is also going to have a background texari-dark. And on the focus state, so we're going to give this button outline none and also front medium rounded LG text SM and also padding to the x-axis of 5 which I think is 20 and Py 2.5 and also give it the text of Center Like this.
Speaker 2
56:11
So this is the class name that we have on this button Okay, And just after this button, I think that should be after this form, we have another button. And this button is going to have a class name of text blue. So we're going to give it a class name of text blue 700. And on the line, And the text should just say login, like this.
Speaker 2
56:39
So we'll come back to the browser, you see that we have form and everything works fine without seem, We can also check the responsiveness on how this form adjusts to the different viewports. Okay. So everything seems to be working fine so far. And you see how the form adjusts.
Speaker 2
57:01
Great. So next let's make sure that we are able to retrieve the user inputs from this form and at least log it to the console for now. So for us to do this on the different inputs, Okay, I'm actually going to, let's see, I'm going to go and make this a use client component because now we are going to be managing states. Okay, so here, we are just going to define a state for the form data.
Speaker 2
57:34
We're going to have const formData, and then set formData. This is going to be useState like this. We're going to define a default value. Here I'm going to have this const, which I'll call default form data, which is going to be equal to this object.
Speaker 2
57:57
The email is going to be an empty string by default, and also the name is going to be an empty string and then the password is also going to be an empty string by default and I'll pass this over to this useState over here. Great so next we can go to our different inputs and wire up the value. Okay so we can start with our email, get rid of the id since we're using name so get rid of the id on all inputs and wire up the value. So the value for the email is going to go to our formdata.email.
Speaker 2
58:34
And I'll just copy this and use this for our name. So I'll change this from email to formdata.name. And also for the password. The password is going to be formdata.password.
Speaker 2
58:46
You can also have an onChange. And onChange, we're going to call this function, which we have not defined yet. So handleInputChange. And I'll pass this function to other inputs that we have, sorry this onChange And we can go up and define this handleInputChange function.
Speaker 2
59:06
So somewhere around here, we're going to have this const, which we call handleInputChange, which is going to be this arrow function. This function is going to automatically get the event, which is going to be of type ChangeEvent, and it's a generic type, which is going to be of type HTMLInputElement. So here we're going to destructure some properties from the event's target. So remember, we have the name,
Speaker 1
59:32
so we're
Speaker 2
59:33
going to destructure name. And we're also going to destructure value from events target. So with these, we can go on and update our form data.
Speaker 2
59:43
So we'll call set form data. And there's an object where we spread form data. So I'm just going to spread form data. And we're going to use square brackets so that we can dynamically update the name with the value of the object.
Omnivision Solutions Ltd