Car rental app in NextJS 13, Tailwind, GraphQL and TypeScript
In this article we are going to create a nice looking Car rental app in NextJS 13 with Tailwind CSS. We are also going to use GraphQL endpoints through an amazing application of HyGraph. And we are going to code it all in TypeScript.
This post has been inspired by this awesome tutorial by TubeGuruji.
Now, open up the terminal and give the below command to create a NextJS 13 app. We are sticking to this particular version. Also, make sure to give the answer same option as below.
Once the app is created, change to it and then open with VS Code.
Next from the terminal give the command npm run dev and it will open in localhost:3000
Our app starts from page.tsx file and we will remove everything from here and only put a h1.
In the globals.css file, we will remove all styles as below.
Now, we will use the awesome free to use app of clerk for authentication. So, register using google and head over to https://dashboard.clerk.com/
Here, click on Add application.
Now, we will give our app a name and then click on CREATE APPLICATION button.
Next, move to API Keys and copy the keys.
Now, head over to documentation of clerk to know the install command.
So, head over to the code and create an .env.local file and add your API keys. Also, from the integrated terminal, we are installing clerk for nextjs.
Now, in the layout.tsx file which wraps all the components, we will add ClerkProvider and wrap it.
Next, we need to add a middleware.ts file in the root directory with this content.
Back in layout.tsx file we will use the in-built SignedIn and SignedOut components from clerk.
Now, head over to http://localhost:3000/ and we will be re-directed to a nice Signin page.
Once, we login through a google account, we will be taken to http://localhost:3000/
Next, create a components folder in the root directory and here a NavBar.tsx file. Inside it we are creating a simple component with image and other navbar text with tailwind css classes.
Now, include this NavBar component in layout.tsx file.
Back in http://localhost:3000/ we will see out Nav bar been completed.
Now, we will create out Hero component. So, in a Hero.tsx file we will add some h2, button and image using tailwind css classes.
Back in the page.tsx file, we will add our Hero component.
We can easily change font in NextJS in layout.tsx file. Here, we are giving a google font.
Now, we will create the SearchInput.tsx file in components folder and add the below content in it.
Now, include this component in the page.tsx file, below the Hero component and we will see a nice looking search bar.
Now, we will go to Daisy UI where we get in-built tailwind css components for NextJS.
Now, we need to add the daisyui in tailwind.config.ts and also install the package.
Next, we will create a CarsFilterOption.tsx file in the components folder and add the below content in it.
Now, we will add this component in page.tsx file.
Back in http://localhost:3000/ we see a nice filter component.
Now, we will use Hygraph in our project. It is a CMS which also gives us GraphQL endpoints.
After logging in click on Add project button.
Give the project a name, description and region.
Now, in the dashboard click on Schema and then +Add button.
In the pop-up give the Display name as CarList.
Now, click on Single line text from right side.
In the pop-up give the Display name as Name and also check the checkbox for title field.
In the validation tab, we can also make this field mandatory.
The next field will be a Asset picker and here the Display name will be image.
Next, a Number field called Price.
And we will create another Number field called CarAvg.
Now, click on Dropdown and it will ask to create enumerations.
In the next pop-up it will ask us to Add Enumeration.
Here, give the Display name as CarBrand and add some values.
Now, again click on Dropdown and then give Display name as CarBrand and also choose the enumeration as CarBrand.
Now, add another enumeration called CarType and two values in it.
Again create a dropdown with Display name and Enumeration as CarType.
Our CarList schema now have these fields.
Now, click on Content and then Add entry button.
Here, we will fill the data in various fields and also add an image.
We have added some cars with data in our CMS.
Now, head over to API playground and we will see the query after selecting from left menu. We are also running it to see the result of our graphql query.
Now, go to the Project settings and then Environments and we will see the api endpoint.
Back in our project, create a services folder and index.tsx file in it. Here, we will create a function getCarsList and add our query from hygraph. We are also using the url here.
Beside this we are also installing the package of graphql and graphql-request in our project.
Now, go back to hygraph and click on API Access and then Yes, initialize defaults.
Now, we will get Read access to all endpoints.
Even with these permissions it was giving some errors, so add the below dependencies and devDependencies in package.json file.
Now, in the page.tsx file we will first add “use client” which is required if we use react hooks in NextJS project. Next, we are calling the getCarsList() from a function carList(), which is in-turn called from useEffect.
We are saving result in carsList state and then sending it to CarsList component.
Next, create a CarsList.tsx file in the components folder and add the below content in it. Here, we are calling a CarCard component and passing each object to it.
Next, we will create a CarCard.tsx file in the components folder.
Back to http://localhost:3000/ we will get all the name of the car and also all data in console.
Now, we will update our CarCard.tsx file and add more data in it including props.
Now, all the images and other details of cars are shown correctly in http://localhost:3000/
We were using normal img tag in the CarCard.tsx file, which we will convert to Image tag from NextJS.
But in http://localhost:3000/ we got an error which shows our image path.
To solve this issue we need to add this domain in the next.config.js file.
We have also added some more data in CarCard.tsx file, which includes some react icons.
Back to http://localhost:3000/ we get more data and everything works fine.
Now, we will add the Rent Now button with an svg image in CarCard.tsx file.
It will show the nice Rent Now button, when we hover over a car.
Now, we will add filtering logic in our project. Here, in the CarsFiltersOption.tsx file we will add brandList state. In a useEffect we are calling the filterCarList().
We are using Set to filter out duplicate entries inside it. Also, we are converting back the Set into array.
Next, we are looping the brandList inside return statement to show each brand.
Now, we will be able to see all unique brands in http://localhost:3000/
Next, we will add a props of setBrand and a onChange which will change the setBrand in CarsFiltersOption.tsx file.
Now, back in page.tsx file we will send the props of setBrand, where we are calling a filterCarList with the value. Based on this we are filtering all the cars which brand matches to one passed.
Now, our filtering logic is working fine in http://localhost:3000/
Now, we will add functionality to Price in CarsFiltersOption.tsx file. Here, we are again passing a prop called orderCarList and onChange of price sending the data.
Back in page.tsx file we will again use this props and sort our cars based on the price.
Now, our sorting is working perfectly.
Next, we will add the Booking modal in our project. It will be shown when we click on the Rent Now button. We are creating a new state of selectedCar and when we click on a car, w are passing the selectedCar to the BookingModal component.
Now, we will create a BookingModal.jsx file in the components folder. Here, we are getting the car and sending it to a new CarCard component.
Now, click on any car and a pop-up will show it’s details.
Now, in the BookingModal.jsx file we will call a Form component with the car props.
Now, we will create a Form.tsx file and here, we will have a Tailwind form with different inputs.
Now, in http://localhost:3000/ we will see a nice form with two buttons.
Now, in the Form.tsx file we will add the states, handleChange and handleSubmit with a console log.
Next, we will add the onChange handler calling the handleChange in all input fields in Form.tsx file.
Back in hygraph we need to create a new Schema for Booking.
The first field will be User Name which will be a Single line text.
Next, we have added seven more fields and all of them are Single line text.
Now, we need to create a relation with the CarList model. So, we will create a Reference. Here, we need to choose the radio button as shown and also refer to the CarList model.
Next in the Configure reference, we will add the Display name and API ID.
Now, our CarList reference is created successfully.
Next, we will go to the API playground and choose Mutation from bottom.
Now, we will choose the appropriate things and click on play button and we will get the id.
Now, we will also add this id in our mutation.
Now, we will go back to the index.tsx file and create a new function createBooking. Here, we will take the formValue to create our mutation.
Now, in the Form.tsx file we will set the formValue through an useffect hook.
Now, when we submit a details of a car we will get it in the console.
No, we will pass the formValue to createBooking function from handleSubmit in the Form.tsx file.
We have only read access in hygraph. To update it to write we go to Projec settings and then API Access. Here, we will select Read, Create, Update, Delete and click on Add.
Now, we will see all the permissions.
Back in http://localhost:3000/, we will click on a car and submit some data.
Now, we will see the data in hygraph been created.
We will also see all the details with the correct Car name been captured in the system.
This completes our Rental app. You can find the code for the same here.