LongCut logo

✈️ Build & Deploy Full Stack AI Trip Planner NextJs App Using React, Typescript, Arcjet, Convex

By TubeGuruji

Summary

## Key takeaways - **Build a Full Stack AI Trip Planner**: This tutorial guides viewers through building a comprehensive AI trip planner web application from scratch, integrating technologies like Next.js, React, TypeScript, Convex for database, Clerk for authentication, Mapbox for maps, and Google Places API for location data. [00:00], [45:00] - **Leverage Shadcn UI for Rapid Development**: The tutorial emphasizes using Shadcn UI, a component library built on Tailwind CSS, to accelerate the development of a professional and visually appealing user interface, reducing the need to write extensive CSS from scratch. [01:23:36], [01:44:43] - **Integrate AI for Trip Generation**: The project utilizes AI models to generate personalized trip itineraries based on user inputs such as destination, duration, budget, and preferences, demonstrating how to implement generative UI for a more interactive experience. [01:36:16], [02:14:15] - **Implement Real-time Database with Convex**: Convex is employed as a real-time database solution to efficiently store and manage user data, trip plans, and other application information, ensuring data consistency and seamless updates. [58:47], [01:01:16] - **Secure App with Arcjet and Clerk**: Arcjet is used for rate limiting and security, protecting the application from abuse, while Clerk handles user authentication and simplifies the integration of subscription billing models with minimal code. [01:19:13], [04:43:41] - **Visualize Trips with Mapbox 3D Globe**: Mapbox is integrated to provide interactive 3D global maps, allowing users to visualize trip locations and destinations, enhancing the user experience with dynamic and engaging map features. [04:15:27], [04:26:48]

Topics Covered

  • Introducing the AI Trip Planner: Your Personal Travel Assistant
  • Interactive AI Trip Planner with Generative UI and Maps
  • Securing Your App with Arcjet and Implementing Subscription Billing with Clerk
  • Rendering a 3D Globe Map with Custom Styling
  • Adding Markers to the Map: A Step-by-Step Guide

Full Transcript

Tired of spending hours researching

destinations, hotel and activities? Our

AI trip planner does it all for you in a

second. Just type in where you want to

go, your travel duration, budget, if you

have any preferences and watch our AI

power assistant instantly build a

personalized trip itinary for you. It

completes with the hotel, restaurant,

attraction, any hidden gems tailored

just for you. So today we are going to

build an AI trip planner fullstack SAS

application which give you a day-by-day

travel plan interactive maps with the

pins and smart recommendation. This is a

fullstack application which we are going

to build it completely from the scratch

with the help of React NexJS TypeScript

and many other popular text stack we are

going to use to build this full stack

SAS application. If you are a beginner

and don't know how to code, this AI trip

planner web project is perfect for you

in order to get started. Let me walk

through the application first and then

we'll talk about the all the text stack

which we are going to use to build this

application. If you see we have this

beautiful landing screen for our AI trip

planner web application where we have

the hero se hero section in order to

directly start creating a trip. We have

video tutorial section along with this

beautiful scrolling corrosal that also

we are going to learn how can we build

this landing screen. Next we added the

email and password authentication.

Simply log uh to your account and then

you'll find an option to create a new

trip. Simply click on that and then you

will jump onto this page where you can

directly start chatting with an AI trip

planner agent. On the right hand side

you will see this beautiful interactive

map. Obviously you can switch between

your trip information and then this map

as well. Now once you start uh charting

with an AI agent depends on your

personalized preference it will generate

the personal trip for you. So let's get

started. So over here I want to start

creating a new trip. We'll add an source

and destination. So we'll say New York

to London.

Then we we also added a gender to UI.

And here if you see we got an gender to

UI option to select. So just select the

option for you. And obviously depends on

your answer. It will ask the next

question. How cool it is.

You're going to learn how easily we can

add this generative UI into your u text

conversation. Now you can even select

the dates and once you confirm it, it

will generate an complete itonary trip

for you. Now we'll wait to finish this.

After finishing this uh trip generation

here on the right hand side you will see

all the details the trip itonary from

your source to destination. Then all

your select uh selection uh which you

made it and here you'll find the hotel

recommendation. If you see how easily

you can scroll it and then you will find

a daybyday uh trip planned for you. Here

you will find a best time to travel, the

beautiful attraction along with the

ticket pricing and when uh the best time

to travel at that particular location.

You can even see this on Google map by

just clicking view on map and here we

have how cool it is right next you will

see the day second day the third day it

depends on how many day you are planning

to travel now most interesting part on

this one you can switch this to the

globe and boom if you see we have this

beautiful map animation where you can

directly jump on to that particular

location and here you will find all the

location which is from your itonary. You

can see where it actually uh placed on

the map. This is how easy it is and

that's everything we are going to build

in this particular project guys. Okay.

Next, you can even go to the my trip

section where you will find all your

trip plan. Click on that and then you'll

jump on your itinary with the same

details on a different uh screen. Next

with the help of arjet we added an extra

security for our our application. We

also put a rate limiting for the free

user. So user cannot create more than uh

one

itonary per day and that is possible

with the help of arjet. Then we also

added the subscription billing model to

our application where you can easily

subscribe and uh start paying monthly

basis which is possible with the help of

clerk billing within just single line of

code. You can easily add the pricing um

subscription model into your

application.

Obviously uh you don't need to integrate

a big chunk of code in order to

integrate payment gateway with the help

of clerk billing. It is possible within

a second. Everything is getting saved to

our convex database which is a realtime

database. And here if you see all the

details if you never use the convex

don't worry because in this particular

project I'm going to tell you how easily

we can set up this convex and easily

connect to your application. This is a

fullstack SAS application which we are

going to build it completely from uh

from scratch. Now if you see all these

places and their photo as well that also

we are going to learn how can we fetch

it and display it on the screen. Now all

the resources uh services which we are

going to use in this project to build

this application is free. So you don't

need to pay a single penny to build this

application. So guys, if you are new to

this channel, don't forget to subscribe,

press notification bell icon so that you

will not miss any update and you did not

join our tube guruji pro membership.

Just go ahead on a tube guruji.com where

you will find an exclusive courses and

the source code for each of my project.

Not only that, but you'll get an special

uh technical support on a discord

channel. Just go ahead on tube pro and

join the membership just under $15.

So guys without doing any further delay

let's start developing this AI trip

planner fullstack SAS application with

the help of React NexJS TypeScript and

many other text stack.

Now in order to create this React

application we are going to use a NexJS.

NexJS is a React framework to develop

the web application. It provide many

inbuilt feature like built-in

optimization, React server components or

even client server rendering as well.

Not only that but most important the

routing. NextJS contain a folder based

routing. So you don't need to manually

configure the routing inside your React

application and that's the reason we are

going to use a NexJS. Now in order to

create this React NexJS application,

this is the command in order to use it

which is npx create next app at latest.

So we'll copy this command.

Go to the folder where you want to

create this project and then open a

terminal at that folder. If you are

using Windows then make sure to uh open

a command prompt at that folder and

simply paste this command. Now at latest

will install the latest version of the

NexJS application. But if you want to

use a specific version just provide that

specific version number. Now 15.4.4 is

the latest version of the NexJS. We'll

click install and then it will start

installing. It will ask do you want to

proceed? Say yes and then give the

project name. So here we'll say AI

trip

planner.

Then it asked do you want to use

typescript? Now in this particular

project we are going to use a typescript

and if you are new to the typescript

don't worry because I'm going to teach

you everything step by step. Typescript

and the javascript is quite similar

except 10% of changes and that's I'm

going to tell you how to uh do it. Then

say no to the es say yes to the telvin

css no to the source directory and yes

to the app router. And then we'll say no

for the remaining questions.

If you see it start installing some

dependency like react, react and some

div dependency for a typescript and

tailwind CSS as well.

And once done you are ready to go. Now

we'll close this window. Simply open a

VS code and inside the VS code you have

to open that particular project inside

this VS code. Hello

and here we have if you see on the left

hand side we have some files and folder.

Let's walk through the walk through each

of these folder. Now the very first

which is the app folder which contain

all our pages routing APIs. Now very

first file which is a global CSS which

contain a globally apply style or CSS to

your application. Now whenever you want

to apply some style throughout the

application you can mention inside this

global CSS the layout.tsx file which is

the root layout of your application

which contain a font the metadata which

is helpful for SEO purpose and HTML body

tag as well. through this body. If you

see the children are rendering, it means

all our pages are going to render

through this children. Now this

layout.tsx file is on the server side

and we want to keep it on the server

side all the time. Then we have the

page.tsx which is the default page of

our application and if you see we have

some default code as well. Now each page

we need to mention with page.tsx. Now

once we run the application you'll get

to know much better. Then we have this

node module folder which contain all our

packages. Obviously we are not going to

touch this folder any time. Then we have

a public folder which contain all the

images, logos, whatever the assets you

want to use from your local project, you

can keep it inside this public folder.

Then we have next doconfig.ts file which

contain the nextjs related

configuration. Then we have package.json

JSON which contain the name version of

your application along with the script

to run uh to start or to test your

application the dependency along with

their version and some dev dependency

along with their version as well and

then we have post CSS and tsconfig.js

file as well. Now in order to run this

application simply go to the terminal

click new terminal

inside this simply type a command npm

run dev and click enter. Once you run

this command you will see your

application is running on a port 3000 on

localhost. Simply open this inside the

browser and then you will see the

default landing page. Obviously this is

the default page when you created the

NexJS application getting rendered

inside the browser. Now let's consider

we'll go to the app inside the page.tsx

and we want to remove everything and

we'll simply add empty div. Now if I

save this one and go back you will see

empty screen. Now over here we'll add a

h2 tag and we'll simply say subscribe to

tube guruji. So guys, if you did not

subscribe to our channel, please do

subscribe. Once you save this file, you

will see this simple text. As soon as

you save the file, it automatically

render to your uh application and

getting display on the browser as well.

So you don't need to refresh manually.

Okay. So that's how guys you need to run

your application and create your

application.

Now the next step is we want to uh

install the shad CN. So simply go to the

shad CN. Now, Shaten is an UI based

component library which is based on a

tailwind CSS obviously and we are going

to use this library in order to develop

our UI uh pages which help us to build

our application and design our

application much uh faster and

professional way. So in order to install

this simply go to the ui.shadcen.com

click get started and make sure to

select the correct framework to install.

Then you have this command. Just copy

this npm command in order to initialize

this shad scen. Open a terminal. Make

sure to add a new terminal and play

enter or paste this particular command.

Then say do you want to proceed? Say yes

to that. And then you can select the any

base color whichever you want. Okay. And

once you select the base color you will

see this CSS variable is updated inside

the global CSS file. Okay. with the

tailwind CSS version 4, we don't have

dedicated tailwind.config.js

file. Everything move to this global CSS

file.

Now once you save it, your shad cen is

now ready to go. Now let's install this

button component from the shad cen.

So again we'll paste this command and

then this button component will install

to the shad c. Now whenever you want to

use any components from the shad CN like

let's say you want to use popover right

like this then you have to make sure

that component need to be installed

every time okay now once you install you

will see uh this new file get added

called component js json which contain a

configuration related to your shad cen

then you have component folder which

contain the whichever component you

install from the shaden that component

will be added to this u component folder

Obviously you can customize this

according to your need and then we have

li folder. We are not going to touch to

this particular folder at all. Now once

you add this button component you can

easily use it. So I will say button and

if you see it's importing from this

component folder and then you can write

any text. Let's save this one. We'll go

back to our application and this is how

it look like. But that's weird right? If

I go to the shadian button component,

it's supposed to look like this, right?

So sometimes it happens. So what you

need to do with the inside the global

CSS, remove this twwan animate CSS file.

Save it. Go back to your application and

boom. Now it come to your uh original uh

style. Now obviously you can

you can paste this again. Okay. So I

will sorry

I will paste this and save it. And

obviously you will not find any issue.

Now so that make sure you have to fix

this issue. If you uh face this issue uh

while adding this button on your screen

now once you add this button you will

see this button and inside this button

component if I go to this component UI

button.tsx file you can see different

different variant like default

destructive outline. Now if you want to

use this variant just type variant and

you can select the whichever variant you

want you want. Once you select that you

will see that change. How cool right? So

that's how easy it is. So you don't need

to write the tailwind CSS classes for

these basic components.

Now the next thing before move to the

next chapter that we are going to update

the font for our application. Currently

this is the default font that we are

using. But if you want to use any other

font simply go to the layout.tsx and

currently they are using this default

font. So I will remove this font.

completely because we don't want that

and we want to use our own custom font.

Now in order to use the custom font you

simply go to the Google font

and once you are on the Google font you

can select any font which you want to

use for example in my case I like to use

this outfit font okay and if I want to

use this font simply make sure to

remember this name then if you see this

next font.google Google here I will

remove this font and just type outfit

you will find this suggestion called

outfit then initialize this font so

we'll say constant outfit is equal to

outfit

then inside this we need to write

subsets and then we'll say latin and

then this outfit font you need to

provide to this body so we'll say outfit

dot class name and then save it and

boom. If you see now font uh style or

font family is now changed. Okay. So

that's how you need to update the font.

You can use any font guys. Okay. Just

you need to make sure to import that

font and then initialize that font as

well.

Now it's time to add a landing screen

for our application. If you see this

mockup, we have this header section.

Then we have this hero section and then

and after that we have this video

section in which we are going to

demonstrate how it works, how our

application works. That video

integration we going to add and then

some popular destination.

Each of these component we going to add

u with the help of some UI component. So

it will be very easy. You don't need to

write a lot of code. Okay. And that's

what we are going to learn in this

particular chapter as well. Also in the

header along with this logo and this

button we are going to add some more

option in the middle. So let's go back

to our application. And remember one

thing that this complete page we are

going to divide into a small small

components like header hero section and

this popular destination section. So

inside our application, let's close all

of this tab. And inside this app folder,

we are going to create a new folder

called components or underscore

components. When you start your folder

name with a underscore, then this

component or this particular uh folder

will not consider as a route. Okay. Then

inside this we'll add header.tsx

file. Let's add a default template. Now

if I if you see once I just type RFC and

click enter it automatically add the

default template for me and this is

possible because I added the VS code

extension called react redux snippet

tool. So this one okay so make sure to

install this VS code extension also is

it will be best if you also add this

Telvin CSS intellisense um extension as

well. So which help us to write the

Telvin CSS classes much faster. Once you

add this header tsx, we have to make

sure that this particular header will be

throughout the application, right? So,

we want to keep it inside the um root

layout. Obviously, we want to keep this

layout.tsx file on the server side. So,

we'll create a new file called

provider.tsx.

And we'll keep this file on the client

side.

Now once you add the provider we have to

make sure you will render this children

through this provider. So I will copy

this and simply we'll paste it here

and then I will render this children.

Now inside the layout I will wrap this

children inside the provider so that it

will render through this provider. Okay.

Now obviously if you go back to our

application you will see no changes

right but now inside the provider.tsx

now we can add the header

that's because all our pages are going

to render through this children and

header will be constant throughout the

application. Okay now if I save this one

you will see this header text that is

nothing but this header component is

rendering. Now inside the header first

we want to show a logo

right then we want to show

the menu options

and then get started button. So these

three section we want to show. So first

in order to uh show the logo I will just

use some logo placeholder. So just

search logo placeholder something like

this and it you can copy the SVG file

from it. So you can search whichever you

want. Okay. So in this case I will use

this particular logo or maybe

let's search a little bit

uh we'll use this one. Okay. So just

copy this SVG. Once you copy we'll go to

the public. We'll create a logo SVG file

and simply

paste this and then save it. Once you

save, you can use that directly inside

the image. So we'll add this image from

the next / image. It help us to optimize

our image. Then provide the file name.

Now you don't need to provide a complete

path. We'll give the alt name. We give

the width and height and then save it.

Now once you save, you will see this

logo is rendering on the screen. How

beautiful.

Along with that one, we also want to

give the application name.

So we'll wrap this image inside the D.

So we'll add H2 tag. And here we'll say

AI trip planner. For this one, we'll add

a class name. We'll say font bold and

text to Excel.

Something like this. See? And then let's

bring everything in one line. So we'll

say flex gap to let's say two. And then

item to be in the center. Perfect.

Uh I will just remove this content.

Okay. So you will not get confused.

Perfect. Now this is our logo. After

that we want to add a menu options. So I

will define this menu option over here.

We'll say constant

menu options

and then we'll say name as home

and obviously we want give the path for

that one.

Then name which will say pricing. the

path

we'll say pricing

and then the last I will say

contact us

and the path for that one we'll say

contact us as a path now this option

once you define you can just iterate

those options

so over here I will add a div then we'll

say menu option dot map we'll say menu

index and the arrow function

Inside the S2 tag, we'll say menu dot

name and then save it. Obviously, make

sure to wrap this in a link tag. Now,

once you wrap this in a link tag is

similar to anchor tag, you need to

provide an H reference. Okay, on the

click where it should go. So, provide

the H reference and inside this we'll

say menu.path.

Now, let's save this one. We'll go back

and if you see these are the three

option now displaying on the screen. Now

let's bring everything in one line. So

we'll say class name flex gap to five

and item to be in the center.

I will give gap more gap. And for this

H2 tag, we'll give font not font but

we'll say text larger. Once you hover on

this one, we want to also scale this to

105. And for smooth animation, we'll say

transition all. So if you click hover on

this one, you will see that change.

Perfect. Now let's bring everything in

one line. But before that I also I'm

also going to add a button.

Oops. Sorry.

And here we'll say get started.

Perfect. Now I want to bring everything

in one line. So for this parent div

we'll say flex. Then we'll say justify

between and make sure to provide item to

be in the center. See? Then for this div

we'll so we'll give a padding to four

something like this and now everything

will be in the center I'll show you our

on this one the color get changed

now currently the primary color is kind

of black color and we want to change it

to this our logo's color right now in

order to change the your shadian

component primary color simply go to the

global CSS file inside this if you

scroll down under the root you will see

this primary color and this is provided

ated with this okch color format.

Obviously, I also don't know what is

this color format is but you can provide

your hex color as well. But uh this

particular shadian variable does not uh

support the hex anymore. So you in order

to convert your hex code to this that

particular format simply go to this site

called oklsch.com

here paste your hex code and then you

can copy this particular color format

and simply paste it here and then save

it. Once you save we'll go back and boom

you will see that change. How cool. Now

our primary color changed to that

particular logo's color. How easy it is

right? So make sure to do that also for

this um menu option. Whenever you hover

on this one, I also want to change text

color to primary. See something like

this. How beautiful. So make sure to add

this all the small detail which give

your application more attractiveness.

Next part is to add this hero section

where we have this content then this

input box and then the suggestion

options. Okay, obviously we also have

this hero section. So let's go back.

We'll I will close this header and then

I will add a new component under this

component folder and we can call it as a

hero tsx. Let's add a default template.

Once you add this hero component

obviously we want to show it on the home

screen. So inside this page tsx I will

import this hero component save it and

then we'll go back over here you will

see this hero uh component is loading

perfect now let's go to this hero

component first thing inside the class

name

um I will give margin top to let's say

24 also we'll make it flex item to be in

the center and then justify between if

needed But right now I will just make

item to be in the center.

Then we want to show a content first.

Then input box

then suggestion list

and then video section.

Okay. Everything will be in the hero

section. Now for the content we'll

simply add a div. Inside this div we'll

add an H1 tag or H2 tag what doesn't

matter. And inside this we'll say hey

I am your

personal

trip planner.

Now for this trip planner text I'm going

to wrap this

inside the span tag.

something like this and then for this

pan I will add a text to be primary.

Okay. Now for this H1 tag we'll say text

excel on medium screen we'll say text is

of 5 XL

font bold and then save it. If I go back

this is how it look like. Obviously we

want to bring this in the center of the

screen. So we'll class name flex and

we'll say

item to be in the center justify

let's

basically instead of this one what we

can do we can provide a maximum width to

3 excel okay and then we'll also make

sure to wid is full and take to be in

the center

let's save this one and uh I don't know

why it's not coming in the center of the

screen

and here as well we'll make justify

center perfect now once you done this

one done with this I will also make sure

to wrap this everything inside the div

okay not only this content and then

we'll add a p tag inside that we'll say

tell me what you want and

I will handle the rest Okay. So like uh

flights,

hotels,

trip planning

all in seconds.

So some text like this obviously uh once

you add this I'm also going to add space

Y

to six. to some space and for this P tag

I will add a class name

um text larger

something like this see

then we want to add an input box okay

now make sure our input box will look

like this uh inside that we have this

text area from the shadian and button at

the corner so in order to add that text

area I will go to the shadian

go to the text area component. Make sure

to copy this. And then we want to import

that. So I'll paste it here. So this

text area component will get add.

Then we'll define a div. Inside the div,

we'll add one more div. Inside this

we'll say text area component.

Okay. And then inside the placeholder

we'll add a create a trip for

Paris from New York. So this is just a

uh placeholder. Okay. So this is how it

look like. See

now obviously we also want to add a

button. So for this text area I want I

don't want that particular border.

Right? So here first we'll say width to

be full. Then I will also provide an

height to 28. I want a transparent

background. And then we'll say border

none.

Okay. So if you see but when you click

on this one we also don't want that

particular border line. So here we'll

say focus

uh visible

then oop sorry the ring I don't want

that ring. So we'll say ring to zero.

See? Perfect.

Uh also we'll add a shadow

none.

Okay. So you'll not see any shadow. And

we don't want this particular resizable

things. So we'll say resize none. See

now it's gone. Perfect. Now for this

particular div you can add border. Then

we'll make round it to let's say 2 XL.

And then we want to add padding to four.

See? And now we have this beautiful

border as well. You can add the shadow

to this particular um text input box or

you can remove it either way. Next thing

we want to add a button. So we'll say

button. Inside this button um you can

provide a size

icon and in that we can add a send icon

button from the lucid react. Now once

you install the shad this button also

get in uh the icon library also get

installed. So this is the icon library

currently we are using. Okay, you don't

need to install manually because it's

auto install once you install the shad

cen components. So once we have this u

icon you can even provide height and

width for that particular icon and then

save it. We want this icon on the right

side. Right? So simply for this button

we'll add a class name. We'll make

absolute.

Then we'll add a bottom to let's say six

and right because we want a right side.

So we'll say right to six.

Let's save this one. And it's going at

the bottom. That's because we need to

provide or mark this particular div as a

relative. So we'll make this relative.

And now it is inside this particular

text input box only. How beautiful,

right? So that's how you need to add

this input box. How easy we added.

Right? Next is the suggestion list. Now

we need to provide the suggestion list

first. So at the top

we want to add a suggestion list. So

we'll add a constant suggestions.

And inside this we'll add a title. Let's

add a first title. Let's say create new

trip. For that one we also going to add

an icon. So we'll say globe to icon. To

this one we'll add a class name. And

let's make text blue.

400

and along with that one just provide the

height and width over here. Okay, same

thing you have to do and add few more

options. Now once you added these all

the suggestion you just need to iterate

those. So inside the div we'll say

suggestion dot map inside this we'll say

suggestion comma index and then arrow

function.

Then inside this we'll add a div

and simply add this suggestion dot icon

first. Then inside the h2 tag we're

going to show suggestion dot title and

then save it. For this do let's add a

key as a index. And then you will see

this suggestion. Beautiful. Now for this

do let add a class name because we want

to add some style. So we'll make flex

item to be in the center. Gap to two.

Then we want to add a border. We'll make

rounded

full and then save it. Make sure to give

some padding. So we'll give padding to

two. Perfect. And then we want to bring

everything one line. So for this div

we'll add a flex gap to five.

Perfect. Um, also for this H2 tag, we'll

add a class name text to access.

And then we have this. Let's make it

small. I think that's much better. See?

And now our suggestion is ready. Now,

whenever you hover on this one, we want

to change the cursor. So, we'll say

cursor

pointer. Then

this is how it look like. Um when you

hover on this one we want to change

background color. So on hover we'll say

background to primary and on hover you

have to make sure text should be white.

See something like this right? Um I

don't know whether we want to change

this icon to white. I think let's do

that too. So over here we'll say on

hover um

we'll change this to white.

And let's see how it looks.

I don't think so that's affecting

anything. Uh we'll keep as it is.

Okay. And when you hover I think that's

look much better. See

now next thing as you know that we want

to add this hero section. Right now, in

order to add this video section, sorry,

the video section I wanted to say uh you

can use the one uh L UI component called

magic. Sorry, that not this one. It's

magic UI. Okay. Now, magic UI is based

on chat. So, you don't need to install

anything. But inside the component, you

will find a bunch of different

components. Okay. You can explore more.

But inside this component section, you

will find this hero video dialogue. Just

click on this one and this is what we

want. Once you click on it, it will open

the dialogue in order to play that

video. How cool. And that is inside your

application only. Now, in order to use

it, make sure to select the CLI. Copy

this npm command. And if you see this

command is in from the shadian only,

right? And then once you install this,

you can use any code. So this is how it

comes. I will go to the code and or you

can even see the usage how it actually

works. I will copy this usage. I will go

to this video section. Simply paste this

section. Make sure to import that. And

then you have to replace this thumbnail

source. Okay.

Need to use thumbnail source. So you can

copy this thumbnail source. I'm proing

inside this uh documentation. Just paste

it. Save it. And if I go back, boom, you

will see this beautiful video section.

Once you click it, it will open the

dummy one. Right now, we don't have that

YouTube URL ready, but once we finish

this application, you can provide that.

Now, next thing, make sure uh just

before this, I'm going to add an H2 tag.

And inside this, we'll say not sure

where to start. And inside the span tag

or we'll say strong tag. Basically,

we'll say see how it works. And then I'm

going to add

down arrow or we'll say arrow down.

Now for this H2 tag, we'll add a class

name. We'll say margin Y to 7, margin

top to 40, and we'll make flex gap to

two. Save it. I want in the center of

the screen. So we'll say text to be in

the center.

I think that's fine. I don't know why

it's not coming in the center

but maybe because

so here we can make flex column and now

it's come to the center but this

text input getting broken. So just

remove that

then and you can keep like this only. If

you want really in the center what you

can do

you can wrap this inside the div

and then you can provide a class name

flex item to be in the center justify

center

and make flex column that is very

important. Okay. And now beautifully it

look showing this um video section as

well. So that's how guys uh our hero

section is now ready. Okay. So until

this point if you have any question any

doubt let me know in the comment

section. The next thing we want to add

is this

corrosal. Okay. Which is a popular

destination that we want to add and it's

very easy. So for that one uh go to this

UI. certainity.com similar like this

magic UI this particular UI component

library also u use the chaten only go to

the components over here you'll find a

bunch of different components and for

our case we're going to use this apple

carts corroser okay now if you see this

is how it looks obviously you can change

this content which however you want and

then simply in order to use it go to the

CLI copy this npm command go back to

your application

and simply

we'll paste it here. So we'll clear this

paste it so that you can use. Now make

sure I will close all of this tab and

here I will create a new component for

that one and we can call it as a popular

city list.tsx.

Let's add a default template or let's

simply copy this example code. So this

is the uh code we want. So we'll go to

the code, copy everything, paste it

here. Now we'll replace this

uh component name to we'll say popular

city list and then save it. Once you

save, make sure you need to add inside

the page.tsx file. So we'll say popular

city list component. Once you save,

we'll go back to our application and

boom. If you see how beautiful it's

looking now, we have these beautiful

components as well. Now in order to

replace with our own um destination all

I already added this list. Okay, simply

copy this data information and we'll go

back inside the popular list. Here we

have demi content but inside this data

you can replace with your own data. So I

will paste it here. Okay. And then over

here you can obviously edit it. So we

have category, title, source and

content. Now if I go back, refresh the

screen. Oh, I think I forgot to save it.

And boom. If you see, we have this

beautiful destination,

right? And that's how you can add this

corrosal into your application.

I'm going to make some small update. I

don't want this particular text this

much bigger. So I will make it 3XL.

And then um we give the uh padding I

think so padding y so here I will make

just to five

and uh not five we'll keep as it is

we'll say padding top to 20

or we'll say padding y actually um the

this particular distance is too much so

maybe because of this corrosal

but for Now we'll keep as it is. Okay.

And then save it. You can just rename

this to we'll say popular

destination to visit.

Okay. And then we have all of these

destination. Perfect. Now if you have

any question, any doubt on this

particular uh landing screen, let me

know in the comment section.

Now it's time to understand the workflow

of our application so that we can

implement each of the feature step by

step. Once user come to our application

and want to create a new trip, we'll

check if user is already sign in or sign

up to our application or not. If user is

new user and not sign in or sign up,

then we are navigating user to the login

and sign up screen. And once user is

sign up or login depends on that one we

are going to save user information to

our database and for that one we are

going to use a convex database. Convex

is a real-time database and it's very

easy to integrate and easy to use as

well. After that uh if user is

successfully authenticated to our

application we are going to check if

user is a free user and has any

subscription. It means user is paid or

free user. If user is a free user means

user did not subscribe to our any

pricing model then we're going to check

uh users daily usage limit. We are going

to give user two to three credits where

he can uh generate two to three trips in

a day and that particular logic going to

handle with the help of this arjet. ARJ

is a model where it help us to restrict

user in order to limit uh our AI trip

generation. There are lot of different

feature that we are going to show and we

are going to implement with the help of

ARJet. If user is a free credit and user

has a free credit lift then obviously we

are going to navigate user to this uh

create new trip planner application

where user can create a new trip with

the help of AI or obviously if the user

is a paid user means user is a subscribe

to our any pricing model then user have

option to uh navigate to this trip

planner. So this is the basic workflow

initial workflow for our application.

Once user on this particular um screen

where user have option to create a new

trip then there are a lot of different

feature that we are going to implement

later on but for now in order to

implement all of this feature we have to

go step by step. So very first thing

that we need to add is the login signup

screen. So for that one I'm going to use

a clerk. Clerk is one of the best

authentication service provider in the

market. Not only that but we are also

going to use clerk for our billing.

Clerk provide the subscription billing

model. You don't need to integrate any

payment gateway. Clerk will take care of

everything. Just you need to add one

single line of code which is the pricing

table component and then boom it will

give you the all the pricing table which

you want and with the help of stripey it

also integrate the payment gateway

directly to your application. How easy

it is and that's the reason we are going

to use clerk for our application. Clerk

is so powerful that it also protect your

application from unauthorized user. It

has a different different pre-built UI

component. So you don't need to build

everything from the scratch. And the

most important thing it provide a lot of

different feature like multiffactor

authentication, session management,

email, SMS, onetime passcode, a magic

link or social sign in signup as well.

Everything is packed under one uh

provider. So that's why uh make sure to

go to the clerk.com create a new account

if you don't have and then navigate to

the dashboard.

Once you are on the dashboard here you

have option to create a new application.

Give the application name.

Then you have option to enable different

signin like email magically uh

authentication or Google Facebook and

there are many more. Simply

uh click create application. On the

right hand side you will see the UI

component how it actually look once you

integrate that and then I will create

this application. Once the application

is created you have option to select any

framework which you want. Obviously in

this case we are building an NJS

application. So I will select the neckj

copy this clerk neckj npm command in

order to install into your uh project.

So inside the terminal just paste this.

So it will install the clerk inside the

neck.js.

Then you need to copy this environment

keys. So we'll copy those and then we'll

create a new envu file. Inside this

we'll paste this both the keys.

Then we'll copy this middleware.ts. Now

middleware is very powerful feature

inside the NexJS application and clerk

will you clerk is using that one in

order to protect your pages from

unauthorized user. So obviously copy

this middleware.ts

file obviously we'll create a file first

inside the root directory and then we'll

copy all the content as it is and then

save it. Then we have to make sure that

our application is need to be wrapped

inside this clerk provider. Okay. So

what we'll do, we'll go to the lay sorry

the layout.ts file. So we'll close all

of this tab

and inside the layout.tsx we'll wrap our

application

inside the clerk provider

something like this

and make sure it is cler provider is

importing from the cler/ neckjs. and

then you can run your application. Now

if I go back and run our application,

you will not see any changes. Right now

we did not implement our own custom

signin and signup page. So click the

link in the description so you'll jump

onto this clerk authentication. Here you

can continue to the NexJS guide.

On this one you have to add custom

signin and signup page. So this is the

route at which you need to create this

signin page. So I will copy this

complete route as it is. Then we'll go

back to our app folder. Inside that

we'll create a new folder start with

this circular basis called O. And inside

that will click on this plus sign file

icon. Enter it and it automatically

create you the folders and file. So you

don't need to create the folder or file

one by one. Then copy this content and

simply paste it here. Same thing you

have to do for the signup screen as

well. But before that uh make sure that

you will make the sign in as a public

route. So I will copy this middleware

now this code and I will replace the

current middle file content with this

new one.

Okay. So it basically make the route as

a public and it avoid that if the route

is public you don't need an

authentication. Right? Similar way you

have to implement. Make sure to save

that. Next you need to copy this all

these uh lines inside the env file

and again you need to add a custom

signup page as well. So same thing we'll

copy this. You can click the link in the

description about the clerk. So you will

get the documentation link inside this

art folder. We'll add this file and then

we'll copy this content and we'll paste

it here.

Then make sure inside the middleware you

will add this

as a public route.

Okay. And you need to add this

environment variables as well.

And that's all. Now if I go back to our

application, let's say local 3000. And

then if you see it's redirecting me to a

sign-in screen. Now remember that our

landing screen need to be a public

right. So you don't need an uh

authentication for our landing screen to

uh visit right. So for that one what

we'll do we'll go to the middleware

and we'll tell that okay along with the

sign in and signup script this home

screen is also an public route. Now if I

go to the local 3000 see I'm able to

access it right but if I go to this any

other route it asks me to sign in

correct now I will just redesign this

particular page sign in and sign up page

and it's very easy so um simply we'll go

to the sign in page tsx file

inside the div we'll add this and we'll

then say sign in

for this div we'll add a class name

we make it

flex item to be in the center justify

between and height to screen

and we'll say width to full oh sorry uh

this need to be justify center

something like this see okay same thing

I'm going to add for a signup screen as

And if I user want to sign up, he will

navigate to the signup screen as well.

Okay. So I will refresh this. We'll go

to the sign up.

So make sure oops sorry. So this need to

be wrapped in a circular braces.

And now I can able to see sign of screen

as well. Beautiful. Right? So make sure

to implement in such a way that user can

see this sign in and signup screen. Now

make sure on the click of get started

you have two option either you can

navigate to sign in or signup screen or

you can show a popup inside your uh home

screen directly. Let me show you how. So

we'll close all of this tab for now and

then go to the header. Inside that we

have this get started button and here

we're going to wrap this button inside

this signin button component from the

clerk next. See something like this and

then save it. Now if I click on this get

started it navigate to the signin page

right but as I say we can show a popup.

So here you have option called mode and

inside that you can say a model. Once

you say model, click get started and

boom, it open a popup for sign in and

sign up screen. See how cool, right? So

this is the second way that you can

implement it. Next, once you enter the

information and click this send button,

you have to make sure that user is sign

in or not. And depends on that one, you

should navigate to the uh new screen. So

for that what you can do inside your

hero.tsx tsx file

I'm going to add constant here we'll say

user

and then we'll use this use us user hook

from the clerk now once you import this

hook make sure you have to mark this

component on the client side now once

you have the user it means you have the

all the user information which is login

and then

on the click of send button we'll check

if user is sign in or not. Right? So

basically

I will add on click method

and we'll say on

send. So I will call this on send

button. Sorry. So we'll create this

method

constant on send

and this method will check if not user

then we'll return nothing and then we

want to navigate to this sign-in screen.

So basically in order to navigate you

need to add the router.

Okay. So make sure to add this router

and then we'll say router dot push

and we want to navigate to the new

screen which is the

obviously uh we'll say sign in. Okay

otherwise

uh we'll navigate

to create trip planner web screen

or web page. Okay. So let's save this

one now.

If I click button say it navigate to

sign in because user is not signed into

our application. Now let's sign in. So

you have two option. You can either sign

in with the email and password or you

can sign in with the Google.

I will select the account

and then you will see that I am able to

sign in to my account. Now boom. Right

now if I type anything and click on this

button see I should able to navigate it.

Right now obviously it's not showing me

sign in and we don't have any logic to

navigate to the tip planner web page.

But for now I hope you understand how

easily we added this Gmail password or

Gmail and email password authentication

into our application. Obviously there

are lot of feature the clerk will

provide for you and you can explore it

by clicking the link in the description

so that you can check all the

documentation and the all the features

as well. Later on we are also going to

add a clerk billing model so that you

learn how easily we can add a payment

gateway and subscription model based uh

feature into our app.

Now next we will learn how we can save

this new user login or sign up to our

database.

Now it's time to save the user into our

database and for that one we are going

to use a convex. Convex is a open-source

reactive database for the developers. It

provide a lot of different features like

realtime update, type safety, framework

integration along with the chrome job to

schedule uh some uh background jobs or

even you can have option to store some

files like um convex provide you the

file storage as well.

Uh convex is available to a different

framework. So it's very easy even though

if you switch from one framework to

other convex uh can help you to do that

as well. So click the link in the

description. So we'll jump onto the

convex and their documentation. Simply

login. Once you log to the convex,

you will jump onto this dashboard

project. Here you have option to create

a new project. Give the project name. So

here we'll say AI

trip planner and simply click create. If

you see I already have a lot of project

created with the convex. Convex also

provide you the development and uh

production mode as well. So it will be

easy to switch between the development

and the production mode.

Then on the left hand side you will see

some of the features like function file

schedule logs and many other option.

Now once you created the database

simply jump onto the convex

documentation. I will put the link in

the description. Select the correct

framework and here you need to

initialize the convex. Very first thing

that you need to install the convex. So

we'll copy this command. Go back to your

project.

Inside here I will paste this. So it

will install the convex for us.

And once the convex is installed, you

can run the convex development. So over

here you can use this npx convex dev.

Now we already created the project. So

make sure you will select this choose

existing project and then you can simply

select the project which you just

created. So in this case we created this

AI trip planner. So we'll select that

one and boom. Now your convex function

is ready and running locally. Now once

you run this particular um mpm command

you will see inside this env.local file

get created and inside this you have

this convex deployment key and then the

convex public convex url as well. Okay.

Along with this, you'll see the new

folder get added called convex. Inside

here, these are some uh some files under

under this under underscore generated

folder. You don't need to worry about

this one right now. Okay. Now, we'll

head back to the documentation again and

you need to wrap your application inside

this convex provider. So, we'll copy

this convex provider something like

this. Okay. We'll go back to our app.

So uh we'll create this file called

convex client provider. So simply inside

this app we create this convex client

provider.tsx file. Inside this we'll add

a default template and then make sure to

uh render the children. So we'll simply

copy everything as it is

something something like this. Okay. So

you don't need to export because we are

already exporting. Make sure to import

this convex provider. And here uh we

also need to add this convex URL. You

need to initialize this. So we'll copy

at this top. Okay. Now make sure to

import this convex react client.

Uh we have to add react node. I think

that's all we needed. Now here we are

already rendering the children, right?

So what we can do? We will render

through this provider

something like this and inside the

layout.tsx file where we are rendering

from the provider instead of this now

we'll render it from the convex client

provider

and then save it. Now you have to make

sure your application running smoothly

and don't have any issue. Right now if

you see your application has some issue

it's saying that uh you need to define

that in a use client. So inside the

convex client provider mark this

component as a use client

and boom now if we don't have any error.

Okay and that's all you need to do. Now

the next step is you need to create the

table inside the convex database and in

order to create a table convex use a

schema structure. Now once we when we

say the schema it nothing but that you

need to define the table and the column

name. So in order to do it simply go to

the convex and inside the convex folder

we need to create a schema tsx file or

you can just say ts

over here um in order to refer that how

to create a convex table and all you can

simply go to the documentation

inside the documentation

uh you can go to the database and then

just go to the schema section here you

will you will see how to define a schema

for any table. Okay. And let's implement

it. So here we say export default

I will just

and make sure to define the schema. So

we'll say define

sorry

define schema. Inside this you need to

provide a table name. So we'll say user

table.

And inside the do you you need to define

as define table

and then just provide a column name.

Okay. Now if you want to provide an id

you can provide the ID but convex is

automatically adding a unique ID for

each of the record. So you don't need to

define that one but we will define a

name. So name is of type uh string or

var. So here you need to define a value.

Make sure to inputting from the convex

slash value dot

here we'll say string

then image URL

which is again of type string

uh then the email of type string here we

say subscription

now subscription again of type string

and we are provide uh you can even

provide the credits if you want. Okay,

it's completely optional thing. If later

on if we needed you can easily update

that and then simply save it. Once you

save, you can just see the convex

function. You don't have any error and

it's showing currently the convex

function is ready. Now if I go back to

our app and refresh this uh database,

you'll see the new table get added

called convex table. Currently we don't

have any record. But if I click on add

here you will see all these fields that

you can add it. How cool right now if

any of the field if you want to make it

optional you just need to wrap it like v

dot optional

currently obviously we want to make this

subscription as optional field. So you

can simply wrap this and now that

particular column is now optional. Okay.

Inside this

schema you can see the current schema.

Okay. So you can easily check whatever

you added inside the schema file. And

that's how you can add a table. Once the

table is ready, let's insert a record.

So we'll go to the app inside the

provider.tsx file

over here. Uh first we'll write a method

called constant create new

user as a method.

And inside this we'll first check if

users is already exist or not.

So either you can directly define or

write a um method over here or you can

create an API endpoint in order to

insert a new record. Simply we need to

check or we need to make sure to uh call

or save you new user if not exist. Okay.

So in order to do that obviously we need

to write a convex API endpoint. So go to

the convex inside this we'll create

user.ts

file and inside this user.ts file we'll

simply create a mutation because we want

to insert a record. So here we say

export constant create new user is equal

to mutation and if you see this mutation

is importing from the generated server

from the convex only and then uh we need

to accept the arguments first okay which

are the field you want to add it so

first we'll say name of type string make

sure you are importing this v

then email of type v dot string string

and then image URL of type v dot string.

Once we have these three value here

we'll we need to define an handler.

We'll say async and inside this we'll

have ctx,

arguments and then error function.

Here you need to write a logic in order

to save the record. So here we'll check

if user already exist. So first we need

to check if it already exists or not. So

we'll say constant user is equal to

await

ctx

dot db dot query because we want to

fetch the record. Here you need to

provide a table name. You can see this

suggestion. So table name will be the

user table.

Then we have to add a filter. It means

the wear clause. Here we'll say query.

So query dot

equal to and then Q dot fill is email

matches with our arguments

I don't okay so this need to be

arguments so here we'll say arguments

dot email if that matches then we have

to collect that means we have to select

those all the record now here we'll

check if

user

of zero

we'll say user dotlength if the length

is greater than zero or maybe we can say

if length is equal to equal to zero it

means we don't have any record it means

we need to insert the record so we'll

say constant user

data and whichever the field you want to

insert you can just define that so here

we'll say arguments dot name for email

we'll say arguments dot dot email and

then

image URL arguments dot image URL. So

these three field we want to add right

and then we will say if not then create

new user.

So over here you say constant result is

equal to await ctx dot db dot insert and

then the user table and we whatever the

field you want to add that field which

is nothing but the user data which we

already define. Once it is insert you

can return the user data as it is

something like this. Okay. But if you uh

user is already exist then you can

simply return that user information.

So we'll say user of zero. Okay. If user

is already exist as simple as that and

then save it. So that's how you need to

define the convex function. Okay. This

is very important because all your logic

are returning on the server side. Convex

is running on the server side. So don't

need to worry about that. And all your

logic is also running on the back end

side. Now once you have that inside the

create new user first you have to define

the uh this particular mutation. So

we'll say constant create user is equal

to use mutation. Inside this mut

mutation define that API endpoint. So

we'll say API dot user dot create new

user. Okay. And simply inside the create

new user you need to call it. So we'll

say constant

result is equal to

await

create new user. And obviously you need

to provide uh all the fields. Okay.

Oh, this need to be create user only and

inside this we need to provide the

arguments. Okay. email image URL and

name. Now in order to get those

argument, you can simply get it from the

use user hook. So here we have this use

user hook.

Uh make sure your provider is on the

client side. So we'll define use client.

And then once you define the user, now

make sure you'll pass this value like

email. So we'll say user oop sorry

user dot primary email address dot email

address then the image URL. So we'll say

user dot image URL and the name user dot

full name

here I will make this as a async and

here you can add a condition as well if

user okay because that's the reason it

give us this uh error as well sometimes

or you can add

some default value to it. Okay. Now this

particular method we need to call only

when the user information is uh

available and also whenever this

component get load. So inside the use

effect when whenever the user is

available we will execute this use

effect and then we'll also execute this

create new user method something like

this. See

oh so this need to be double question

mark. So if full name is not there it

will save it as a empty string. Okay and

then save everything. Now if I go back

to our application you will see already

it inserted the record into our

database. Now even though you refresh

many times it doesn't matter because uh

it only check whether the user is

already exist or not and depends on that

one it will save the information. So

that's how you need to create a new

user. Okay. Now before moving to the

next chapter make sure once the user is

sign in you have you can change this

button to let's say create new tree.

Okay. So what we can do we'll go to the

header first

and inside the header once the user is

sign in. So over here we need to check.

So we'll define a user is equal to use

user

and I will mark this component on the

client side

and then we'll if not user means user is

not sign in then it will show this sign

in button or get started button

otherwise we'll add a button

here make sure it's a turnary operator

and here we'll say create new trip.

Okay. Now we'll show this particular

button. See, and we obviously want to

navigate that. So we'll wrap this in a

link tag with a h reference.

Create trip and we'll say create trip as

a new route

and then save it. Okay, perfect. Right

now user is login. So you have option to

create a new trip. If I click on it,

obviously we don't have that particular

page or route. So that's the reason it's

showing 404 error. But uh make sure to

update this particular uh button logic.

Okay. So that's all uh I hope you

understand that this is very important

to set up a database because whatever

the information now we are going to uh

save it, we want to save inside the

convex database. It's very easy guys.

Very uh first time it might be seem

difficult to you but once you implement

it will be easy.

Once we have the user information and

user detail after sign in it is very

important to share that information

across the different of different

components so that you don't need to

fetch it every time and in order to do

that we are going to use a context.

context is very powerful react hook in

and it's not a just a hook but it's a

state management uh functionality inside

the react application. So in order to

create the contact simply we'll create a

new folder outside uh or maybe inside

the root directory and inside this we'll

create a user

detail context tsx file. Now in order to

create a context simply you need just

need to write export constant user

detail context is equal to create

context. Make sure you will import this

create context from the react. Now as

this is a simple one so I will I'm

giving the type any

then you need to wrap your application

inside this context provider. So go to

the app inside the provider.tsx file.

I'm simply going to add a user detail

context dotp provider to this provider

you need to pass the default value that

value are going to share across the

application. The interesting part about

this context that you can update this uh

state value from any components and it

automatically reflect to all the

components as well. Now in order to pass

the default u state first we'll define

that state. So we'll say user detail

comma set user detail is equal to use

state. Now uh I hope so you know this

use state hook. Okay which help us to

set the value and to get the value for

the specific uh variables. Okay. Now

once you define this over here we'll set

the user detail with the result and

here I will provide a type any because

uh we keep the context as type any only

and then you can simply pass this user

detail information to this context. Now

whichever component which you are going

or pages which you are going to render

through this particular children are can

access this user detail information. Now

later on you will get to know how we can

use this

also. Um in order to avoid writing the

complete context here I'm going to also

write one more method called constant

user

use user detail. So we'll say use user

detail

and inside that we simply return

use context and then user detail

context. Now you don't need to worry

about this for now. Okay, this is just a

simple way uh to use this use digital

context.

Now it's time to add a feature in order

to limit the access to our free trial

plan. As you know that this is SAS

application and we want to add a free

trial as well as paid subscription model

into this application. Inside the free

trial obviously user can create only one

trip per day. Okay. So he can plan only

one uh one trip and then we want to also

give the limited access to the certain

features. Obviously we are going to

reset this limit every day. It means

next day he can again create a new trip

but he has to wait a 24 hours in order

to generate a new trip plan. But in in

the case of paid user, you don't need to

wait it. You user can create unlimited

trip and he can access have all the

features. But the question is how can we

add this limit? Obviously if you try to

write a logic it will be very

complicated. But what if I told you that

we have this best feature that can help

us to add this um limit to our u free

trial. Okay. So that's where the arjet

comes uh and play very important role.

Arjet is the developer first security

platform for a web application. It offer

a protection rule for automated board

detection, rate limiting, email

validation, protect a signup form and

there are many other feature can uh you

can add with this help of arjet and it's

very easy to integrate it provide a very

light SDK which you can easily add it

and within a u few line of code you can

easily integrate it with the help of

arjet we are also going to add email

validation so that when you want to send

um the trip plan to your user, you can

send it to the email but before that

obviously we are going to add a

validation whether that email is correct

or not and the rate limiting which is

quite easy and quite interesting. So

that's what we are going to see. So

first thing first uh we'll go to the do

uh documentation you can check the uh

link or click click the link in the

description. So you'll jump onto the

specific website and the documentation.

Here you need to select the correct

framework. So in our case we are using

NJS. So make sure to select the NJS. Uh

it also provide a tutorial. So you can

go ahead and watch if you want. Now

first thing we need to install the

arjet. So we'll copy this npm command.

We'll go back to our application.

I will close all of this tab for now.

And inside the new terminal we'll simply

add this arjet.

The next thing we are going to set the

key. Obviously we need to add this arjet

key and we need to obtain it from the

arj account. So uh before that I will

just paste this key over here. Okay. And

then we'll create an arj account. Now

interesting part is free to use. Okay.

So you have the free trial. So you can

use it. Um, you can add up to five rules

and no expiration. So, it's up to you.

You can even go with the starter plan if

you want to add a multiple sites.

And I will simply log in with my

account. Once you log in, you will jump

onto this uh home screen where you have

option to add a new site. Give the site

name. So, in our case, we'll say AI trip

planner. We'll create this site and then

you'll get this arjet key. Just copy it

and paste it here.

Once you copy it, we'll go back to the

documentation again and then you can

simply add the rule. Now in this

particular example, you will see uh it

help us to protect your application from

SQL injection which is very important.

Then you can even uh detect the board

and token bucket which help us to limit

or rate limiting features and there are

many others. But if you want to uh use

or integrate specific feature go to this

features and just click that example. So

if I click quick started and scroll down

you will see this example. Let's copy

this example as it is for now and then

we have to add it inside the arjet/

route.ts.

So I will go to this API first. So

inside the app we need to create an API

folder and inside this API folder we'll

create arjet folder and then inside this

we have route.ts file then copy the

content as it is and simply paste it.

Now let me walk through this code. It's

very interesting as we initialize this

arjet and passes this arjet key. Okay

which we already generated and save it

inside our env.lo file. Then we need to

define the rule. Now currently we said

it's a in a live mode and we define the

characteristic as well where you can

pass a user ID as a unique ID. Okay.

Then you can refill the rate. Okay. So

after 10 second it will refill with the

five tokens and each time it will deduct

five tokens from the account. Okay. And

that's I'm going to tell you how. But uh

currently it just have the 10 seconds of

interval. Okay. So after every 10

seconds it will fill with the five

tokens. And the maximum capacity of that

particular bucket is just 10 tokens.

Okay. So obviously it will not store

more than 10 tokens. Then whenever you

make a request you just need to add this

particular line which will protect your

application or protect our request. Uh

to that request you have to pass a user

ID. Okay. So it will be a unique user ID

for for this example it uses this user 1

2 3 and then uh for every request it

will detect five tokens. You can change

this to two it's up to you. Okay. And

then we'll check if the is decision is

denied. It means there are too many

request otherwise it will return the

hello world on a successful request.

Okay. Now once you save it let's test

this out. So simply what you need to do

just go to the local host once you run

application I will go to this local host

/ ai/jet

as our application is already running so

I will go to this and you will see we'll

get the hello world say if I refresh it

again again I got it but if you refresh

it again it's saying too many request

and then the maximum capacity remaining

one the reset the window size and

everything if I refresh it after say 10

second it again fill it but if If I

refresh it back to back see I'm not

getting right because it will add the

tokens every after 10 seconds. Okay. And

now you got the result. Now that's how

you can limit your API request as well.

Okay. Now instead of 10 seconds

obviously you can add for a 24 hours

duration. You just need to convert uh 24

hours to seconds and you can add that

interval. So basically for 24 hours I

will say 86 400.

Okay. So it will now refresh it every

after

uh 24 hours and the maximum capacity

just 10 and refill rate is five. Okay.

So that you can easily handle this one.

Later on you going to learn how easily

we can protect each request with the

help of this arg.

And we also going to implement the email

val validation later on in this

particular project. But for now I hope

you understand. Now you can even access

this rate limit for each of the user and

you can see the analytics inside your

arj dashboard. Over here you will see

that the rate limit is uh trigger and

whenever it allow it's saying it's

allowed. See how cool right? You can see

this analytics as well. How many times

it get denied? how many times it allow

everything you can see inside your arj

dashboard and that's why it quite easy

for a developers to protect it and you

don't need to write a bunch of code to

limit the API access

now the next thing is uh we want to

navigate user to the create new trip

screen on this screen we are going to

divide the screen into two sections one

for the chat box where user can enter

the information in order to generate u

the trip planner and on the right hand

side we are going to show eternary and

the map. Obviously we need to show a

complete trip information uh the hotel

list the places to visit daybyday and

everything timeline basis and also want

to give an option to show a map.

We are going to show a 3D map so user

can interact directly with that

particular map and we are going to also

show all the location on that map. Then

on the chat box section we are it's kind

of question answer format chart box. But

the interesting thing about this that we

are going to add a generative UI to

select some option. For example, if user

want to select uh the um how many people

are going right or budgets. So where we

are obviously giving option to select

from the UI. You user don't need to type

it. It automatically give us that

option. So that's how we are going to

add generative UI feature to our app. So

let's go back and let's create a new

route called create new trip.

So inside the app folder

we are going to create a new route

called create new

trip as a new route. Inside this we'll

create a page tx file and then we'll add

a default template.

I will rename this to create new tree

and then save it. Now once user is

logged in to our application

and on the click of create new trip

button we want to navigate to this

particular screen. So let's go to the

header component where we have this

create new trip and here we already have

this create trip option. So I will add

it as a create new trip and then save

it. Now once I click on create new trip

it should navigate to this create new

trip. If you see something like this.

Okay. So this is very important. Same

thing you have to do once user click on

send button. So on send we want to

navigate it. So over here we'll say

router dot push/cre

new trip.

So on the click of this button as well

it's navigate to this create new trip.

Now let's divide this screen into two

section.

So we'll go to this over here. We'll add

a class name. We'll give grid grid

column one when the screen size is

smaller. And when the screen size is

medium, we'll give grid column 2. We'll

also give gap to five.

Then uh let's add some padding if you

want. So we'll give padding x to 10 or

let's give complete padding to 10 only.

And inside this we'll add two section.

One for the chat box

and other for the map and trip plan to

display

something like this. See so one for chat

box and one for the map and trip it. Now

next thing for each of these we are

going to create a separate component. So

we are going to create a new folder

called underscore component under this

create new trip and all the component

related to this create new trip we're

going to keep inside this folder. I

think we need to rename this to

components

and inside this we'll say chatbox tsx.

Let's add a default template and then

save it. Now make sure to import this

chatbox component.

So you will see this chat box.

Now inside here uh obviously we want to

add the text area section at the bottom

inside the chat box. So first thing

first we'll add a section two section

basically. So this one for the display

messages

and other section

uh for user input.

Okay. Now for this particular display

section uh I'm going to add some dummy

message. Okay. So here we'll say due. Uh

inside the due we'll add another due.

Over here we'll add a class name flex

justify and margin top to two. And for

this do we'll simply add a maximum width

with a class name maximum width large.

Then background

primary

text white padding X to four padding Y

to two and rounded

large.

Okay. Um and inside here you can write

user message for example. Okay. Same

thing I'm going to do it one more time

but and here we'll say AI agent message

or AI message and in this case instead

of justify in we'll say justify start.

Now if I go back here this is how it

looks. Uh obviously for this AI agent

message we want to give a gray color. So

we'll say grade 100 and text black.

Something like this. See? Okay. Now once

you have all the message list you can

just start displaying it. But for this

particular uh section we'll add a class

name and we'll make it flex one and

overflow y auto.

So you can able to scroll it. Okay. So

we'll say overflow y auto and padding to

four. So this is the message list. Now

at the bottom where you want to add a

user input. we want to add similar input

that we added inside the hero section.

So I will just copy that particular

uh input. So inside the hero we have

this input box. I will copy as it did

and we'll paste it here. Make sure to

import this text area button component

and then this send icon.

So everything is look correct. Okay. So

on send method we need to call it.

So this onsen method we are attach we

already attached to that send button

right. Uh so I think everything is

correct. So here we have an header

issue. It's weird.

Okay. So basically uh if you see we have

that error that we we are using a

function. So our hero need to be or not

hero but chat box need to be on the

client side. So at the top make sure to

add that and if you refresh it now if

you see it don't have any error. So

currently we have this beautiful input

boxes but it's coming at the top and we

want this at the bottom. So for that

one, for this particular div, you can

add a height. Let's say 90 vertical

height. And we'll make it flex flex

column. And that's all we needed.

Something like this. See, instead of

this one, we'll say 87 vertical height

or maybe 85.

Perfect. Okay. So here you have option

to enter the um input on the click of

send it will send the message and then

it will go to the AI. So that's how you

need to create this UI. It's simple

right on the right hand side obviously

we'll implement the map and trim planner

once we have all the information in

order to display it.

Now after implementing the UI for the

chat box, it's time to connect our

application to the AI model so that you

can ask the question and AI will return

the answer for us. But in order to uh

plan the trip there are couple of things

that we need to keep in mind. The very

first thing that obviously you um we

need to get the source and destination

for the trip from the user. After this

we need to get a group size whether it's

a solo trip, couple trip, family trip,

all the friends. Then we need to get a

budget whether it's a low, medium, high,

trip duration, how many days user want

to uh make this trip and if there are

any special requirements or travel

interest everything uh when you can get

it from the uh users and obviously AI

will uh our AI need to be asked this

question one by one and that's the

reason I created this beautiful prompt

which will help us to get this uh ask

this question to the user one by one. So

make sure that user of this AI will not

ask the question um or multiple question

at once so that user can enter each

questions answer one by one and in order

to add a generative UI made sure that

our response will be in the form of

JSON. Okay. And obviously in the JSON

format we have the response and the UI

uh whether it is a budget UI or we want

to show or group size UI we want to show

everything I already mentioned inside

this prompt. Okay. So once we have this

prompt we can use this one. I will also

share this prompt with you. You will

find the link in the uh description for

this documentation where you will find

all of these flowchart and um diagrams.

Now uh let's go back and very first

thing that we need to do is to create an

endpoint for our AI model. So I will go

to this API. Inside this API we'll

create new folder called AI model.

Inside this we'll create a route.tsx

file and then simply add

a post request. So here we'll say a sync

function as this is a post request. So

we'll say post

and then next request. Now to this post

request we need to get a messages list.

Okay. Obviously this messages list we

need to send to the AI model each time

so that AI will know what all

information he already has. Right. So

we'll say request.json

and then save it. Now in order to use AI

model there are bunch of different AI

model you will find on the internet like

Gemini open edge chat GPT uh deep sync

and many others but I'm going to use a

free AI model which you will find on the

open router.ai.

Open router will give you all the AI

model at one place. Many of them are

free to use. So if I go to this model

section and if you see now this new

model came which is a free model.

Obviously you can just switch this

pricing to free and boom you'll find all

of these free model which you can use

like deep sync R1 model or Mistral

Google Gemini model and many others.

Okay but uh it's up to you how you want

to go. I will use the chat GPD's uh AI

model like 4.0 mini. Okay, I think that

is sufficient for us. Once you click on

this, go to the API section and inside

this we can create an API key. Now if

you don't have an account, make sure to

create a new account. I'll go to this

create API key and then we'll select

create API key. Give the API key name.

So here we'll say AI trip planner.

Then you can limit the credit as well

and simply click create. Once you have

this API key, make sure to copy it

because otherwise you will lose it. it

will not display it again and then

inside your env or maybe env.lo you can

simply paste it. So here we say open

router API key is equal to and paste

this key and then your application name

will display over here. Okay, as simple

as that.

Next I will go back to that particular

model and if you scroll down you'll find

with the help of open um go make sure to

select TypeScript and with the help of

open router HDK you can easily make an

call but if you want to use open AI HDK

instead of open router select this

framework documentation if you get this

page not found select return home and

over here you'll see the TypeScript

option where you can use the open AI SDK

now in order to use this open AI SDK.

First thing you need to install the open

AI. So I will simply add npm I open AI

and make sure to in uh install this.

Once you install simply copy this first

few lines of code which initialize this

open AI see now you can even export this

one so that you can use it in some other

API routes. uh we don't need this

default header. So I will remove that

and instead of this API key I'm going to

use our API key from this env file.

So we'll go to this env file open router

API key something like this and make

sure to pass it. Okay, now you have the

open AI initialize and then you just

simply need to call this method in order

to get the response.

Okay, as simple as that. Now for the

model, make sure to update the model

which you are looking. So in this case,

you want to use this model. So you will

see this copy button. Make sure to copy

that model name and then simply paste

here and then save it. Okay. Now under

the messages here, you can you need to

pass all the messages. Okay. But before

that I'm going to add a system prompt

that is very important. So inside the

role I will pass it as a system and then

for the content I'm going to pass a

prompt. Now I already have prompt inside

the eraser doc. Simply copy this prompt

as it is and we can paste it at the top.

So we'll say constant

prompt is equal to and then paste this

prompt.

Okay. Once you have this prompt you this

prompt you need to pass to this system

and then for the user role you can

simply say dot dot dot messages because

we want to send all the messages list

then you'll get the response. You can

get this response over here inside the

message is equal to

completion dot choice dot message.

Okay. And then in return

we can simply add next response dot

JSON. And here we'll say JSON dotpass

messages dot contain because you will

get in the form of string might be. So

make sure to pass. If the content is not

there I'll pass it as empty. Okay. Now I

also make or wrap this line of some few

all this line of code inside the try

catch block.

So in case it fails, it will return the

empty response.

So right now I will pass it as error e

only and then save it. Okay. And that's

how our initial AI model is ready. Okay.

So over here make sure it's not string.

It's a prompt that we need to pass.

Okay. And if I go back, obviously

nothing will get changed. Now, whenever

you enter something and on the click of

this send button, we need to make sure

to call this particular API endpoint.

So, what I will do, I will go to this

chat box inside here we are on send

method and then we need to make an API

call. Now in order to make an HTTP API

call you need to add an AXIOS okay AIOS

HTTP client library which help us to

call an API endpoint. So over here now

we'll say constant result is equal to

await axios dot get

or not get it's supposed to be post and

then we'll say / ai ai model and inside

the body we need to pass a messages

right right now we don't have messages

list so we'll define a state

which hold all the messages

now Um you can even provide the type for

that messages. Okay. So I will add a

type

message message

and in that one we have role as a string

and content as a string

and here we'll say messages of array

list and initially it will be empty.

Then

whenever user enters something we need

to get and save it in a state called set

user input

and which is of type string. So inside

this text area

maybe we can add on change method which

will emit the event and then we'll set

the messages with the event dot target

dot value

and default obviously we going to pass a

default value called user input as well.

So if there is a no value uh we'll pass

an empty string. I don't know why we are

getting this error.

Oh, sorry. So, this need to be

an user input, not messages. So, that's

the reason we got this error.

Okay. And then save it. Perfect.

Now, on the send, we have to make sure

first thing first, we need to set the

user input

uh as a empty one. Okay, you can say

null. Then we want to add that message

inside this messages list. Okay, so uh

we're going to simply add constant new

message

is equal to uh we'll define a message

type first and then we'll say role as

user and then content

as user input. Okay. So this is

important so that you can pass this.

Now obviously we have uh error that user

input need to be there. So if the user

input is not there

will return nothing.

Okay. So this need to be a not user

input dot trim.

So it will return nothing otherwise it

will go to this page and then we have

this user input with a new message. And

then over here we can set the messages

saying uh add a previous message.

And then we have the previous message

with new message

make sure to wrap

something like this. Okay. Now once we

have the messages just pass this me uh

over here actually we need to pass uh

the messages list first. Okay. So we'll

say all the messages

comma the new message. Now you might

have a question why we are doing like

this because when we update this message

state it's not updating immediately

right. So that's the reason I kept this

new message as a different constant and

then I'm passing the all the previous

messages with a new message. As we are

using await, you need to make this as a

async.

And then once we have the result, you

can set the messages

with the previous over here. We'll say

previous colon messages.

And then inside the arrow function,

we'll add previous message. Make sure is

a three dot is a se uh

spread operator. Okay. And then we'll

say role as assistant

and then content as result

dot data dot response. Okay, because

we'll get the response um if you see our

schema schema contain the response,

right? So that's that field I just

mentioned over here. And then save it.

Later on we might need to update this

but for now I think we are okay and then

save everything

over here I will just console the result

dot data in order to check whether we

are getting the result or not so let's

head back obviously we are not iterating

the list but inside the inspect panel we

can verify it

now here we'll say hi first we'll pass

this and we are waiting right now if you

see we did not get any response from the

AI model.

So also make sure to check

the terminal

if you have any error or if we miss

something. So basically we have an U

response. So if you see we have the

content and then inside the content we

have this UI as a source but it's not in

the correct format. So right now we are

getting the content as a string and

that's what we don't want it. So

basically you can mention over here

saying response format and then we have

to provide a type with this JSON object.

Okay. And then save it. Now I will say

hi. We'll send this one. Go to the

inspect panel inside the console. Now

we'll get an object. Okay. Let's try

this again maybe.

And boom. If you see now we have the

response and the UI as well. It

mentioned which UI you need to render.

But obviously for some of the uh field

we are going to show a generative UI as

well. But for now I hope you understand.

Now once you have the response and uh

all the information from the AI simply

we have to iterate those information.

Okay. Now in order to iterate inside the

section

I'm going to add the or we just going to

reiterate these messages comma map here

we say message comma index and the arrow

function message need to be type message

and then we'll add this both the div.

Obviously we don't need to show both the

div. Okay but before that what we can do

we can add a condition. So we say

message

dot ro is equal to equal is equal to

equal to user then we want to show

uh only this first div okay otherwise

we'll show this second div which is then

ai agent view message right now the user

message we need to replace with the

message dot content and this one also we

need to the message dot content

uh we can provide the key as a index

at the both the place and once you save

this one let's refresh this over here

we'll say hi send the message

and boom if you see we got the response

how cool so you can just now start

chatting so for example we'll say okay I

want to traveling from the Charlotte and

then AI will ask the next question then

now we will Okay. New York.

Boom. See how cool it is. So that's how

you need to um

uh attach and integrate the AI model.

Now next couple of things that we need

to update. For example, the loading when

you send and response, we need to show

some kind of loading indicator. Right?

Second, we need to replace this

placeholder. So first I will replace

this placeholder because that's quick

thing.

So we'll say start typing here.

And uh in order to add a loading

indicator that's quite easy. You need to

maintain a loading state

and initially it will be false. Once you

start asking question we'll set the

loading as a true and once it is

finished we'll set the loading as a

false. Now whenever there is a loading

we can simply show that indicator. So

over here inside the div right inside

the content basically we can add a

condition

if loading

then we can show a loader icon

otherwise you can show the message

content. For this loader icon I will add

this animate spin. So it will spin it

and then save it. Now let's try this

out. So I say hi

and somehow it doesn't work. Let me

refresh this.

Oh, so that's might be not working as

expected.

Basically instead of showing this

loading over here, I will just undo

everything. Okay. And what we can do we

can simply add the loading indicator

after these messages every message.

Okay. So simply I will copy this due

because in place of that D we need to

show uh we don't need this index and

instead of the message content we'll

show a loading indicator. So we'll add a

loader icon

and to this loader icon you can animate

that using animate spin teleps class and

we want to show this div only when there

is a loading when the loading is true.

Okay now once you save we'll say hi send

it and boom if you see we have this

beautiful loading indicator

and then you will start asking question

see how easy it is. So that's how guys

you need to uh add these details.

Now whenever there is a empty state

right so once user land on this one it's

showing a blank and that's not look

good. So you can replace that with an

empty state. So basically I will add a

new component. We'll say empty state

or empty box state we'll say box

state.tsx.

We'll add a default template and then

save it. Now whenever the message length

is empty, so we'll say messages

dotlength

is equal to equal to zero. Then only we

want to show this empty state box.

See something like this. And inside this

empty box state you can add some

heading. So we'll say

start planning new trip

using AI

and obviously you can't wrap this with a

strong tag

and I will add a class anime sorry uh

text primary

for this H2 tag I will add font bold

text

excel

and text align in the center.

Perfect. Um we'll give some margin top

and this text you can just add 3xl

large. Okay. Um you can add some head uh

sub description as well. So I will just

paste it. I already have. And then once

you save, we'll go back to verify how it

looks.

Uh maybe you can add a class name text

to be in the center. Then text gray

and margin top to two.

Perfect. And also you can give the

option to select uh some information.

Okay. But I think that's a easy way if

you don't want to add too much things

into your uh chart area.

You can simply bring this those option

that you added inside your hero. So I

will just go to this hero.tsx file.

These are the suggestion option we have.

So I will copy that or we can simply

export this. So you don't need to copy.

And then

this is the suggestion list. Right? I

will save this one. We'll go to our

empty state box

and simply paste it here. Now make sure

you import you can import this

suggestion because you already exported

it right. And if I save this one this is

how it look like but we want in a

vertical format. So don't if you make

this flex make it flex column

and I will not make rounded full. I will

say rounded excel and we'll give more

padding. I will add Excel as a text.

Perfect. Excel is too much. Let's make

it large and padding to three. Let's

see.

I think that's much better.

And here you can select those option as

well. Now instead of making the

background primary, I will just make

border

primary.

See? And don't want to make this text

white. I will make it as a primary as

well.

Something like this. I think that's look

much better. See,

now once you click on any of these

option, we have to make sure uh that

particular option you will pass it. So

basically uh you can add on click method

to this particular div and you need to

pass back to the chat box. So we'll say

on click

on select option and then you need to

pass that option. So we'll say

suggestion dot title. Now this on select

option

I will pass and type any and then inside

the empty box state we'll

think we need to get that

and we'll say on send method. So inside

the onsign method we need to call but uh

we need to make sure

we'll set that input. So over here we

have the value of type string

and along with to make that onsend call

we also need to set it as a user input

with this value v. Okay. And then save

it and let's test this out. So I will

say create a new trip. See it's coming

over here.

Right? And once you send this, you can

uh AI will start uh working on your

request as simple as that. So that's how

you need to uh implement it so that uh

you will not see that uh empty box and

here or not empty thing but you can see

some content when you jump initially on

this particular page.

Now it's time to display the generative

UI where if you see this mockup along

with the AI's response we are also going

to show an UI component which help us to

directly select the option. Now this

component obviously we need to build it

but AI will tell us that which component

need to be rendered for that particular

message and that's why in our um prompt

we added that particular

um line if I scroll down little bit up

inside our prompt where you'll find that

uh the generative UI these are some

types that we are going to build it okay

and also So under this UI field, it will

return that particular type. So first

thing first, I will just update to small

F for now.

And then let's close all of this tab.

And first thing first, we'll go to our

uh create new trip chat box. And inside

here, we're going to add a new field

inside this message called UI. Okay?

because we also need to get that UI

string. So that's the reason I'm adding

this. Then make sure you will set that.

So over here we'll say UI with

result dot data. So we'll say result dot

data dot UI so that we can easily

uh use that in order to render that

particular UI. Now in order to render

the UI we say constant render generative

UI as a new method and this will accept

the UI of type string

and depends on which UI for example

let's say we want to render the budget

UI right and that's what AI response

return to us then we have to show a

budget UI component right same thing if

the UI compi is equal equal to

group size then we have to render

uh group size UI component

something like this. Okay. Now the

question is obviously we need to build

this particular components and this

method we need to call. So this need to

be a generative

render. This is just failing mistake.

So once you create this method, you need

to render this method over here. And

make sure to pass message dot UI.

Oops. Message.

Make sure it's not empty. So I'll pass

an empty string. And over here as well,

we'll say undefined. I don't know. I

think we don't need to show undefined

uh obviously but over here we need to

return something right so that's the

reason we is throwing an error now let's

implement for the group size component

so what we can do we can go back over

here we'll create a new component called

group size

UI dot tsx

then we'll add a default template. Now

inside our eraser do I already added the

list of group sizer we can use it. So I

will just copy that and then I will

paste it over here

so that we can easily iterate it. So

we'll add we'll just iterate that. So

we'll say selected travel list dot map

here we'll say item comma index and the

arrow function inside this we'll add a

div

and first we'll say item dot icon that's

a simple emoji icon that we are going to

show and then we have item dot title

here we'll say key as a index then for

this due we'll add a class name we'll

say padding to three we'll add a border

we'll make a rounded corner to 2 XL

background to white on hover.

I want to add a border to be primary

and we'll make cursor

pointer as well. Okay, I think that's

all we needed

and then save it.

Now this group size UI over here, I will

just return this particular component.

Make sure to import this component and

then save it. Now if I go back, I will

just refresh this once here. We'll say I

want to travel from

Charlotte

to New York. Okay. And I will send this

one.

And boom. If you see, we have beautiful

UI now rendering on the screen along

with the question from the AI response.

Right? Obviously we will just uh add

some styling. So over here I will mark

it as grid grid column four or we'll

make two and on medium screen size we'll

make it four. Then we'll give gap to

let's say two item to be in the center

margin top to one and then save it.

Boom. See how beautiful. Now once you

select any of this option obviously we

have to make sure that we will pass back

this uh user selected response to the

chat box and then we need to call this

on send method. So for this one

uh let me bring this down. Here we'll

add on click method and to this onclick

method we'll say unselected option and

we'll call this okay over here we'll say

item dot title plus along with this one

I'm going to add how many number of

people are there right so that

particular count I'm going to say same

people and title as well and obviously

make sure to pass it you can pass type

any and inside the chat box I will

accept that. So

I will get this on selected option

and then simply you can call set user

input. Now make sure to accept that

particular value

so that you can set it and also call on

send method. Okay. And then save it. Now

if you select any of this option and

boom if you see we got the user input

response as soon as user select any of

this option and then after that AI

returning are asking us the next

question same way now you have to build

this UI component for the budget uh as

well so let's go back to our app and

let's create a new component for budget

UIT tsx Over

here we'll add a default template. Then

I'm going to get these particular budget

options which is available inside the

eraser doc. And once you add simply you

can iterate iterate those in the same

way.

So I will simply copy this same

structure as it is

and instead of this one I'm going to add

this selected budget option.

then make sure to return the same uh

method. Okay. And instead of this title

now we'll pass as description

and save it. Now if I go back to our

application

uh okay so make sure inside the chat box

you will add this. Okay.

So same return statement but different

component now. So here we will say

budget UI and boom. Right now if you

want to add more uh styling to this one

you can add it and let me show you how

you can do it. So for example for this

div

uh you just want to add

some kind of background. So we'll add

this as a div. Then inside the class

name we'll say text is of 3 XL. Then

padding to three and rounded

full.

Then we have the H2 tag. For this one,

we'll say text large

and font

semi bold margin top to two. And also we

can add a description. We'll say item

dot description. For this description, I

will add text smaller and text gray 500.

I think we can add some color

combination as well. Okay. So, we

already have I'm already providing the

colors. So, I will add that.

So, maybe over here

we can add the colors. So, let me put it

inside the curly braces with this tag.

So we can dynamically add a color.

So we'll say item dot color. See

something like this. But we have to make

sure it will be in the center.

So for this div we'll say flex flex

column item to be in the center and text

to be in the center.

See

uh obviously you don't need to provide

this uh obviously make sure it's a three

now

perfect and now we have this different

UI from the previous one right so it's

up to you how you want to provide okay

and give the better look each time

next uh obviously once I select any of

these right if you see it's

and and then it now AI will ask the new

question. So guys that's how you have to

do and add the general UI for each of

this question.

Now I will pause the video and I will do

it for the uh number of days. Okay. And

I will implement that. Now here I also

added the number selection that how many

days user want to travel where user have

option to select these days and then and

once after this we have this final

things where we are showing that your

plan is getting uh generating in the

background and then we are show we are

going to show this beautiful uh message

or loading message uh only inside this

final view I'm going to add class name

with a margin in top to two and also

we'll provide a width full okay

something like this and once we have the

uh trip information then user can view

this particular trip on the right hand

side and then we'll enable this button

as well so that he can able to view the

trip okay so this is how we are going to

generate uh the UI in the runtime with

the help of generative UI tech okay so

if you any question any doubt let me

know in the comment section before going

uh to the next chapter let's test this

out one more time okay so here I will

say hello

I want to travel from

New York

to Mumbai okay and I will send this

message now obviously we only provide

the source and destination so obviously

AI will not ask this question again and

again that is smart that's how smart it

is now we are try with. So I will try

alone. Okay. And uh what your budget so

I will select moderate.

And then it will ask how many days you

are planning. When it ask me how many

days. So I'm planning for 7 days. Okay.

And then it will ask any other question

if I any. And now if you see now it's

saying that your uh inform uh with that

current information um the trip is now

generating. Okay, it takes some time

obviously but whenever we have uh this

final step right that's why we have the

UI component UI field with the value

final then we have to make an API call

in order to generate the final uh result

that is very important. Okay, that's

what we are going to see next. But until

this point I hope you have understand

everything. If you have any question any

doubt let me know in the comment section

because there are lot of different

feature that we are going to add in this

particular uh project.

Now it's time to generate the final

itenary of our tree depends on user

provided information with the help of

AI. Now once user uh reaches at this

place where UI is a final and currently

if you see we are getting this generated

UI because we set it whenever the UI

field is mentioned as a final right. So

in that case we have to send another API

call in order to generate the final uh

trip details. So to do that we are going

to simply check whether the last message

contains the UI field as a final or not.

Okay. So we'll go back to our

application

and inside this we have this chart box

and inside the chat box I'm going to

use the use effect. Now this use effect

will execute whenever the messages

uh is updated. Okay. And once the

message are updated then we say constant

last message is equal to messages of

messages dotlength minus one. So it will

contain the last message whichever last

message there. And then we'll say if

last message dot UI is equal to equal to

final. Okay, then only we'll set is

final as a new attribute or new state.

Okay, so what we can do? We can just

mention that state. So over here we say

is final comm, set is final is equal to

use state.

Initially it will be false. And over

here once there is it's final then we'll

set it as a true. Okay. And once we set

it as a true

we are going to call on send method as

well. So this method now we have the on

send correct but in this case we are

going to send is final as a parameter

over here. Okay. Obviously initially it

will be false. Now let's go to this AI

model

uh under this API and then we are going

to accept that

is final. Okay. Now whenever there is is

final is true then we need to update

this prompt. We need to change this

prompt so that uh it will generate the

final

uh trip information. So to do that I

already have this particular prompt

ready. Okay. Now this prompt will

generate the all the information which

you need the trip planning plan the

hotel information the eternary day wise

and everything. Okay. This is a schema

and this is the prompt. So I will just

copy this as it is and then I will paste

it inside the route just below this one.

So this is how it look like. So now we

have this final prompt and this final

prompt we wanted to

show. So over here we'll say is final.

If it's final is true then we'll u pass

as a final prompt. Otherwise we'll pass

the simple prompt. Okay.

And I think that's all we needed for

now. And now if I go to the chat box uh

wherever there is is final you don't

need to set the message. So make sure

that

okay. So if is final is not true then

only we are setting the message

otherwise we will not set the message.

Okay but I will just console

over here

so that we'll get to know whether we are

getting the correct data or not. Okay

let's save it for now and let's test

this out. So we'll go back to our

application

and we'll refresh the screen. Now before

test this one just make sure to add one

quick change. Whenever you set it as a

final also set the user input with some

value will say okay great okay because

if you see inside our on send method the

user input need to be there say this one

right so that's the reason it is very

important that you will set some user

input and uh that is uh important okay

now let's test this out so we'll say

create a new trip Okay. And then we'll

simply say we want to Mumbai to Goa

trip.

Okay. So it will ask uh

with whom you are traveling with then

budget

and I will uh set the date as well. And

if you see it start generating.

So only thing that it's uh if you see

it's not make any call yet. Okay.

Because uh maybe it let me check the

issue. So once we set the final we'll

set the user input and then we'll click

on on send button. So that's good. Um

let's make sure that you are getting a

final one right. So that's what we

needed.

So I think we need to test this again.

So that's weird.

Maybe we can just hide this one. Okay.

And uh then we'll test this out. So

right now I will just say okay.

And now if you see it start generating

and inside the payload you will see is

finally is true. So it once the loading

is completed you will see that output as

well. Okay. See now we got the trip plan

and inside that we have hotel

information we have it turnary

information the all the details see okay

so that's how we need to do it I think

um you can test this out again okay and

hopefully it will works so only thing

that when you update the user input

right it's not updating immediately and

that's the reason uh it's not going

inside this ons so sometimes it happens

So the another option is to fix it. I

will just commented this on send and I

move this to an use effect. When this

use effect will execute whenever there

is final is true and the user input is

there then we have this on send method.

Okay. So now if I test this out here we

say um

Mumbai

to Kova 3 days. Okay. Now once I ask it

will not ask me then again the how many

days right so we'll say that I want to

travel with the friends with a moderate

budget and then if you see it start

generating as well okay now inside the

console we can just test this out right

now it's still loading because it's a

big chunk of data that we are expecting

to get it so that's why it's taking time

and boom if you see we got the trip plan

information how cool right now whenever

uh you we we got the information we want

to enable this view trip button. Okay.

So simply

um over here we are going to save this

trip information first. So we'll say

constant

trip detail

comma set trip detail is equal to use

state. Okay. And uh obviously we need to

define the type for this one and make

sure once you get the data. So over here

we'll say is final if it's oh sorry

we'll say inside the if

uh is final is true. I will just move

this block of code

just below this one. Okay. So we'll say

is final is true.

Then we'll set the trip detail

with the result dot data dot. And if you

see our information inside the trip

plan. So I will save it inside the trip

plan.

Okay. So let's move this up. Something

like this.

And whenever the trip detail is there

then we want to enable the button.

So simply what we can do

uh okay so the button is inside the

final UI right. So over here we'll say

disable this button only when the trip

detail is not there. Okay. If trip

detail is not there then disable it and

we'll go to the final. over here we'll

say uh trip detail

or we'll say disable

I think that's what we route right so

disable correct and then we'll pass this

disable

whenever the disable is uh true then

only it will disable that particular

button but once we have the uh trip

information then it will not disable

perfect now uh one last important thing

uh because we already saving it. We need

to define a type that is very important.

So I will define a type over here. We'll

say trip info

and inside the trip info we need to

write a budget destination everything.

So we'll say budget is of type string.

Destination is of type string. Then we

have the duration group size.

So make sure to copy everything as it

is. That is important.

Then we have origin.

Okay. And then we have hotels and

itinerary.

So right now hotel contain the list of

array. Right. So for now I will give the

type any. And then last we have the

itinary

that is of type any only.

Okay. And this strip information

I will set it here

something like this. Okay. And then save

it.

So I hope you understand this particular

um functionality that is very important

in order um to go to the next chapter

because once we have this all the

details then we are going to display it

on the screen.

Once you create this trip, it's very

important to save it to our database so

that next time whenever uh user want to

fetch the trip details, he can fetch it

from his dashboard. Okay. So to do that

simply uh we need to create a table

inside the convex. So we'll go back to

our application and inside the convex

schema file we'll add it. So go to the

convex schema.ts.

Inside this we'll create

trip detail as a new table. So we'll say

trip detail table. Then we'll say define

table.

And inside this we need to define it. So

first thing we want to add a trip ID

which will be the unique ID. So we'll

say v dot string. Then the trip detail

is of type JSON. we say v dot uh I don't

think so we have JSON but you can put it

as a any and then the user ID right now

the user ID we already have inside our

context we just need to pass it so over

here we'll say B dot string

instead of string we need to pass an ID

because this is id and then you need to

refer it so we need to refer with the

table name which is

user

table

I think something like this okay because

this table name need to be here I think

that's all we needed and then save this

one once you save obviously uh the

created by and everything will be there

but make sure the user table is now

added uh to your convex see perfect now

let's go back

to the uh we'll create a new convex

function actually in order to save it.

So we here we'll say trip

detail.ts TS file and inside this trip

detail. TS similar like a users right we

need to create a mutation. So we'll say

export constant trip I will say uh

create trip detail

is equal to mutation.

Inside this mutation we need to accept

arguments like trip id

which is of type string. Then the user

ID of type

make sure to input V of type ID

and here we'll say user table

and then last we want to accept the trip

detail information

which is of type any.

Now once you add we need to add a

handler

uh handler is of type async. So I will

just verify that. Yeah that's correct.

And inside that we have ctx

comma arguments and the error function.

Then we'll need to save it. So we'll say

constant result is equal to await ctx

dot db dot insert.

The table name is um trip detail table

and then we need to add the value.

So if you see the the same way that we

added the user you need to add the trip

detail information. So first thing trip

detail. So we'll get it from the

arguments dot trip details. Then the

trip ID again from the arguments dot

trip id and then user ID which is also

from the arguments dot user ID something

like this. Okay. And then save it. Once

you save you can return the data if you

want. Okay. Or you can leave it as it

is.

Now our trip detail convex function is

ready.

Now I will go to our chart box. inside

this chat box we need to

uh initialize that mutation. So we'll

say constant

save trip detail is equal to use

mutation and then we'll say API dot trip

detail dot create trip detail and this

save trip detail we need to call so we

already have is final right inside this

we'll say save trip detail or we'll

something write something like this is

equal to await save trip detail and

inside is we need to pass a trip detail

information. This this trip detail

information you can get it from this

result. The trip ID you can get the trip

ID from the or obviously we need to

generate this one. And then we have the

user ID. Uh user ID you can get it from

the context. So we'll define a user

detail context over here. So we say

constant

user detail

user detail comma set user detail is

equal to use user detail. See this

particular hook we can directly use it.

You don't need to mention the context

and then the what which context you want

to use. Okay. From here you can directly

use that and then we'll say user detail

dot ID because the field is saved as a

underscore id. Okay, here you don't need

to mention the result. You can uh left

it as it is and then save this one. So

this will also save our trip. Okay, if

you want to notify user with the toast

message that trip is saved, then you can

mention that one as well.

Now in order to pass a unique trip ID, I

will search for this UU ID V4. Okay, not

this one.

Uh just search UID V4 package. Okay, so

it will jump onto this package. You just

need to install. So I will copy this

and inside the new terminal. Make sure

to install that. Once it installed you

can directly use it with the help of

this UU ID v4 function.

So maybe we'll say constant trip id is

equal to uid v4. Make sure to import

this statement and it will generate a

unique global identification number.

And now just pass this trip ID.

Okay. And then save it. As simple as

that.

Now obviously you can test this out. So

I will create a new trip.

Now I will just say Mumbai Tune I want

to travel. So with the family then

moderate budget

confirm 3 days.

So I think there is some problem. Uh

let's see what's the issue.

I don't see any issue over here.

It was still working. So that's the

reason. Okay. And now if you see the

trip is generating. So we have this

final and we'll wait to finish this.

Once it finished, we got the trip

information. I will just make sure

inside the trip details. You will see

the new record get added with the ID.

The trip detail obviously which contain

a complete JSON. Then we have the trip

ID as well. the user ID uh obviously

which is connected to that particular

user. Okay. So that's how guys you need

to save the trip information to your

database. Now with the help of this uh

trip id you can easily fetch the trip

information directly.

So you don't need to uh f uh do

anything. Also just wanted to uh tell

you that this view trip button is now

enabled. Okay. And obviously uh on the

click of that one we can show that

particular trip.

Now it's time to display the trip

information. Now we want to display in

some modern way that it looks much

attractive. Now in order to do that

first what we can do we will just copy

some dummy information. So from this uh

network tab we'll check this one. So

we'll say uh make it 2 days. I will just

getting the trip detail information.

Right now if you see it generating this

trip detail information this we are

going to save as a dummy data in order

to display it. And once our UI is ready

then we can simply uh uh replace it with

actual information. So I will copy this

response as it is. We'll go back to our

page. And inside this one, we are going

to create a new component.

We'll name it as a iternary

tsx. And then we'll add a default

template. Now this itenary we need to

add it inside the page.tsx file.

Something like this. And then save it.

Now first make sure that is displaying

on the screen. See something like this.

Right? And on this side we want to

display that trip information.

Now inside the itinary

I'm going to add that demi data. So

we'll say trip data is equal to and

paste this. Make sure we don't want this

trip plan as a field. So we'll remove

that

and we'll only keep what we need. Right?

Obviously it contains all the

information. So this is the first step

that we wanted to display it. Right?

Next thing

uh we'll close this one. We want a UI

for it. So for that one I'm going to use

this assert assertinity UI uh which is

based on shad. So you don't need to

worry about this. Simply go to the

components and then scroll it to the

component called timeline. Now this

timeline component will give you this

particular uh UI component. See how cool

right now obviously we will replace this

particular information with a day one

day two and on the right hand side we

can show an actual information the place

information and that's how we are going

to use this particular component. So in

order to install go to the CLI, copy

this npm and then simply install it

using this command prompt.

Once it is installed,

it will available inside your component

folder under the UI timeline.tsx file

where you can customize completely.

Okay. And now we'll copy this example as

it is. Inside this example if you see we

have the data and I will copy everything

and then inside the timeline we will

just simply passing this data. So in

same way I'm going to replace this

return with this information. Make sure

to import this timeline

statement

at the top. I will close this and then

save it. Once you save and if I head

back to our application, boom, you will

see this beautiful change, right?

Obviously, there are lot of things that

we need to customize it before

displaying all the data.

Now, first thing first, um obviously we

don't want this ugly scroller, right? We

just want to make sure that uh it will

not scroll complete screen. So, similar

like the chart box. So if I go to the

chat box if you see the maximum height

which is height 8 85 vertical height

same height we are going to give it to

this itonary. So over here I will say

height to 85 vertical height. Now if you

see if I refresh this screen

it's still scrolling right. So maybe we

can say overflow

auto and then save it. And now if you

see it's scrolling only that particular

part. Cool, right? I will just make sure

to 83. I think that's much better. See

now it's completely fixed.

Now next after this uh we need to update

all of this content this particular

empty space and lot of other things. Now

for that one I will go to this timeline

component. Inside the timeline component

it has a dummy data. See this one.

Obviously we need to replace this data

with an actual information. So over here

we will just uh say something like your

trip itinary

from and then we want to add a source to

destination is ready. Okay something

like this. So over here we we want the

information from this trip data because

inside the trip data we have the

destination and the origin right now in

order to pass this trip data we can pass

this complete trip data to the timeline.

So over here we'll say trip data and

then pass this trip data. Obviously

inside the timeline

you need to accept this trip data.

Sorry. Over here you need to accept it

and you can provide a type or make sure

it's a trip data

and the the type will be trip info and

then save it. Perfect. Right now next

over here we'll say trip data dot

uh origin and here we'll say trip data

dot source sorry destination. And if I

save this one, you'll see this change.

Your trip itary from Mumbai to India.

Okay. So, oh this need to be an

destination.

Yeah. See your trip it from Mumbai to

India to Goa is ready. Now you can even

wrap this in a strong tag

and change the color. So I will change

this to primary.

And same thing I'm going to do for the

destination as well.

Here you can customize completely

everything you can customize in this one

right and this is how it look like. Next

thing instead of this P I am going to

replace with the some uh uh user

selected options. So over here I will

add a D. I will add a calendar and then

inside here I'm going to add the

duration. So we'll say trip data dot

duration

and this is how it looks. We want

everything in one line. So I will add

flex gap of two item to be in the

center.

Perfect. Same thing I'm going to copy it

few more times. Secondly after this I

want to add a budget.

Here we can add a wallet icon

and here I will say budget. Then group

size and here we'll say people or I

don't know users.

I will just get that per perfect icon

for it.

So we want many users. So maybe users we

can say users.

And if I save this one, this is how it

look like. Obviously, we want everything

in one line. So, we'll say class name

flex gap to five item to be in the

center. And boom. How cool it's looking,

right? Perfect. So, that's how you can

modify it. You can add more text if you

want. You can add more styling as well.

Now, again, uh we want to we don't want

that much space at the top. So, we can

remove that space as well. So here

instead of padding Y to 20 we can give

padding Y to let's say seven. So it will

move up. Then we don't want this empty

space as well.

So after this we can scroll down

and I will just make sure that there is

no margin or padding from the top. So

over here if you see there is padding

top to 40. I'll make this to 10.

And now it's move up. Okay. Also there

is a lot of width between these uh two

section. So that also we can replace it.

So in order to replace that particular

width so instead of this width full

we'll say width 40%.

I think that's much better. See perfect

right? So that's how you can update your

timeline. Now our timeline design is

almost ready. Now we need to replace

this uh demi or um default data with our

demi data and then later on we will

update this dummy trip data with an

actual information whenever the new trip

is generated. Now let's uh display the

list of hotel first. Okay. And I will

also change this size of this particular

text. So inside the timeline

if I go to the title

here we can make to excel

I think let's refresh it and see I don't

think so there is any change okay so

maybe over here we make it 3 excel I

think this is much better perfect

next I will go to the iternary and here

now we need to map our trip data with

this particular format where we need to

provide a title which is nothing but

this particular left side uh title and

then the content whichever the content

you want to display on the right hand

side in any format okay so first thing

first uh

I will just remove everything so we

don't want this one right we'll just

keep this title and the content for the

reference

and u first we need to show and hotels

so basically Then in the title we will

say

recommended

hotels. Okay. And uh after this if I

save this one let's go back. I don't

know why it's gone but now it show

recommended hotels. Perfect. And inside

the content

I will just clean everything.

And inside here we'll say

trip data dot

hotels

dot map

and then we'll say hotel, index and the

arrow function. Right now we don't have

a type called hotel. Okay. So you can

mention that type. You can mention

inside the

our chat box only because that's where

we define the type for the t info. So

over here we'll say export

type

hotels.

Here we will say hotel only.

So here I added for the hotels activity

and day plan and then I'm going to

replace this with the

uh we can say day plan I don't know or

we can call it as a iternary

instead of day plan and then I have

going to replace this with an itturnary

and here need to be an hotel.

Now hotel need to be if you see the

hotels need to be a list right. So I

will make sure that's a list only

and then save it. Now if I head back to

our itinary in order to map this one

we'll say simply say trip data hotel

here. Here here you can provide a type

and then you can map it one by one. So

over here we'll simply say a div or you

can just iterate those. Inside the div I

will show an image first. So image

source tag for now I'm going to use a

placeholder image. Okay, which I already

have in my public folder. Here we'll say

uh place image for now. And for width I

will add 400 height to let's say 200 and

then save it.

key as a index. Now if I save this one

here you will see the place image that's

where that it's not showing maybe it's a

JP image.

Perfect.

Uh then I want to show some information.

So we'll say inside the height sorry H

s3 tag we'll say hotel dot um

hotel name

and that's how the hotel name cames over

here we'll say font

semi bold

um then we can add text large

perfect after this I want to show and

hotel address.

So we'll say hotel dot address

inside the class name we'll make this

text gray 500

text excess

and we can keep the text as it is that

also good

and if you want to show a rating you can

also show a rating along with their

budget. So over here you can add hotel

dot price per night.

Over here we can add

wallet icon

and let's see how it looks. Then let's

bring everything in one line

and you can change this color as well.

So we'll say text gray or we can make it

green

something like this. See

after this

if you want to add a rating for the

hotel because we already have that

rating. So I will add a star icon. Then

I will say hotel dot rating.

And I will change this color to yellow

500.

Let's bring everything in one line. So

we'll make it flex

gap to two.

And we can bring this

together if you want.

So basically

you can say flex justify between item to

be in the center.

So this is how it look like. Perfect.

And if you want you can add a

description as well. So hotel has the

description. So we'll say hotel dot uh

description over here. We'll get class

name and we'll clamp the line to two.

We'll make a text gray 400

something like this. Or let's keep

make it 500.

Now for this div I will add a class

name. We'll make it flex flex column and

gap to one.

So some spacing between all of these. Uh

for the image I'm going to add some

styling. So over here we'll add a class

name.

Uh we'll add rounded corner. So we'll

say rounded to

Excel.

Then you can add little bit of shadow

and object cover. Okay. Can add margin

bottom to two. Let's see how it looks.

And we want those in uh in the form of

grid. So we can show two items in one

row. So we'll say grid grid column one

when the screen size is smaller on the

medium screen you can make it grid

column two. So something like this. See

perfect. Now another problem with this

one right uh this charts box is quite

bigger. So you can even change the size

as well. So in order to change instead

of giving a two column I will assign

three column over here. And then for

this itonary I will give the two column

and one remaining column to the chat

box. Okay. And then you will see the

change. See. So that's how also you can

u modify it. Okay. It's up to you how

you want to uh show it.

Now after this this is how it look like.

You can add some more space. It's

description is optional actually. Even

though you did not add it that's

completely fine. only thing that we want

to add a button and we'll say uh

view details. So we can say view just

we'll say view we'll say font not font

but we can add a variant if you needed

so I will add a variant outline

perfect and inside the class name we'll

give margin top to one

uh we give the gap two here I will make

gap four some more gap okay now if you

want

Now this is just a hotel recommendation.

Now as you know that we are just testing

this out. So that's the reason I want to

remember this one. Okay. You might have

question without any uh chart with the

AI how we are getting because it's a

dummy one dummy data. Right now the next

part is we want to show itterary right.

So if I go back to our application and

over here if you scroll a little bit

down after the hotels we have the

itonary uh day by day and inside that

again we have the activity list.

Now in order to display that one we have

to add the spread operator. So here

we'll say dot dot dot trip data dot

itinary

dot map. Inside here we'll say day data

and the arrow function.

Now over here we'll add a title first

and for the title we'll simply say

uh day

and inside the dollar we'll say

what this need to be

and we'll say day data

dot day. Okay. So it will give you the

first day, second day, something like

this. Then the content that we need to

show. So inside the content

we'll add a div. And over here we'll add

a p tag.

Inside this we need to mention that best

time

and then we'll say day data dot best

time to visit

uh day right because this field will be

we already have now if I save this one

until this point uh okay so we have an

issue so inside the trip data if you see

uh maybe the format is not the correct

one after save if you see we have the

day one and then we have the day two as

as well right perfect uh then next part

I don't know why this is showing okay to

be frank uh this particular error uh

we'll fix that in a moment but before

that now let's show the activity list so

over here we'll say data dot activities

dot map and inside here we'll say

activity

oops sorry

activity, comma, index, and the arrow

function. Then inside here we'll add a

div.

Uh inside this div we'll add a key as a

index and then we want to add a place

name here. First we'll add a image that

will be good option. So inside the image

I will add a source tag. For now I will

add a placeholder.

Then width we'll say 400. Height to 200.

All tag as let's give the

activity dot place name.

And inside the class name we'll say

object cover

and rounded to Excel.

If I save this one and let's see how it

looks. Perfect. See then for this

particular div I'm going to add

a class name or not here but we can

maybe

wrap this inside the div

so that we can make it grid grid column

one on the medium screen size we can

make grid column two with a gap of four

something like this see beautiful right

so So that's how we can display after

this u place image. Obviously we are

going to replace this place image with

an actual image of that particular place

later on. But now let's add an H2 tag

with an activity place name

place name. Uh for this one I will add a

class name font semibold

and text larger.

Then

inside the P tag, we'll add some details

about this place. So we'll say activity

dot place details. Uh for this one, I

will add a class name

text gray

500

and I will clamp the line to two only.

After this, we'll add a ticket pricing

if there is any ticket pricing. So

inside the H2 tag we'll add activity dot

ticket pricing

and over here

we'll add a ticket icon as well

and let's see how it looks. See now

let's bring this in one line flex gap of

two

and also we'll change the color to let's

say 500.

I will change the color. So let's say

blue

for ticketing.

And if you want you can add light clamp

to one. Okay, you don't want too much to

display.

Then

after this we can add the

travel time for that location.

So we'll say activity dot

time travel for um each location. Maybe

that's the correct one. Over here I will

add a clock icon

and inside the class name

we say flex text

uh orange maybe I will give and then

gap to two.

Perfect.

And here we can show the best time to

travel as well.

So I don't know which icon uh should I

use over here.

Maybe

you can use timer icon. And here we will

set activity time best time to visit. So

maybe if you did not show uh the about

time that's also fine. So instead of

this one I will say activity

best time to visit instead of this one.

Okay. And let's see how it looks. I

think this is much better. Uh you can

add a line clamp to one.

Okay. Somehow it's not get applied.

Okay. But we can leave as it is. That's

fine.

And I think that's all we needed. You

can add a button to view it. So we'll

say button.

I will add a size small.

And uh I will also add a variant to

let's say outline.

And inside this we'll say view.

Let's add a class name. We'll say width

to full margin top to two.

Perfect. Where user can view that

particular location.

Over here we'll say

link open. I don't know how we can

show that. So over here

I will use this external link tag

external link icon. Okay, I think this

is much better. See,

and that's how we have this day one and

then day two information. How cool it

is, right? So that's how guys you need

to display the result. Now on the click

of this view, obviously we want to

navigate it. Now on the click of this

view we want to navigate to the Google

uh page where the detail will found. So

for that one I already have this link

which you can use it. Okay. Uh it's a

free just it will navigate to that

particular link. So I will wrap this

button inside the link tag

then h reference and then I will just

hardcoded this link

obviously. Uh oh that's weird. We don't

want this unwanted text. And instead of

this place name obviously we'll replace

with our activity dot

place name something like this. Okay.

Also make sure to wrap it this button

inside the link tag.

Remove this unwanted text

and I will just make sure here we will

add https

and then google.com the place name and I

will open this link in a new tab. So

we'll say inside the target blank. Now

if I go back click on this view button

let me refresh the screen once

and if I click on this view button see

it navigate to that particular place.

How cool right same thing if I go to

this BA beach. If I click on this one

you will see this BA beach and that's

where the Google map also redirect you.

Okay same thing you have to do it. So I

will copy this link for the uh hotel

placeholder. So for hotel we have this

button

and then I will wrap this link tag but

instead of this hotel we'll say hotel

dot hotel name.

Okay now once we added hotel name. Okay.

So over here

we need to add a class name with width

to be full.

And if I click on this one, it jump to

that hotel. See the bucket list hotel.

The bucket list hotel Goa. Okay. So

that's how you need to navigate. Now one

more important thing that we need to

update that we are going to replace

these all the um items into a separate

components right independent components

because it will be easy for us later on

as well. So first for the hotels we are

going to remove all of these bunch of

code and we'll keep it in separate

component. So here we'll say hotel

card item dot tsx let's add a default

template for that and from the itinary

I will cut it everything from here I

will go to the card item I will paste it

and then we don't need to provide an

index over here make sure to import the

image tag

and here we need to accept the hotel of

type hotel.

Now, if you did not exported this hotel

type, okay, so from the chat box, make

sure to export this hotel type.

Okay. And now if I go back to this hotel

card item, either you can import this

otherwise uh you can direct define

props. Here I will say hotel

as a hotel and then I will pass it as a

props. Okay. So it destruct this hotel

and now you see we don't have any error.

Make sure to import this link tag and

then button as well. Let's save

everything. Uh okay. Make sure to import

this wallet icon and star icon as well.

I think that's all. And then we will

simply replace this with a hotel card

item and pass the hotel information as

hotel. Let's save this one. Refresh it.

And then you'll not see any change.

Okay. Now later on I will tell you why

it is important. But for now I hope this

understand. Same thing we need to do for

the trip information.

Inside the trip information

we just need to replace this activity

info. So this particular card. So I will

cut it from here. I will create a

separate component for that and we'll

call it as a place card item dot tsx.

Add a default template and then simply

replace it. Now over here obviously we

need an image tag. So add it. Remove

this index.

Oh, we need an image tag from the next

last image. the link tag

then the ic all the icons we need to

import

the external link icon as well and the

last is button then we need to accept

the activity

right and we'll define a prop for this

one so we'll say type props is equal to

activity

and is of type activity right now you

have to make sure From the chat box the

activity is exported right so that you

can use that particular type.

Oh so inside this one

from the chat box and then simply show

the props. Okay something like this. I

think that's all. uh now go to the

itonary and here I will add that

particular component and then simply

pass the activity as activity

let's save it all the pages and now if I

refresh you will not see any change but

now we have different component for each

of these card item

now in it's time to replace the

placeholder image with an actual Google

place photo and it's very

straightforward First in order to

generate this Google place photo you

need to search the place detail with the

help of Google place API and then from

that Google place detail information you

will get the place ID that place ID

information we need to pass to the

Google place photo URL. Now just follow

the step-by-step guide that help us to

get the Google place photo. Now very

first thing uh there is a documentation

about the how to do it. So first we need

to search the that particular place

right with the help of this text search

and this is the endpoint that we need to

uh send it or make an call. So I will

copy this endpoint

and let's close all of this tab for now

and we'll go to this API here. We'll say

Google place detail as an endpoint. Here

I will add route.tsx file. Let's add a

default template. not default template

but over here we need to make an post

API call.

So I will say post

request next request something like

this. Okay. Now once we have this uh

we'll simply

call an method. So we need to add

constant

base URL and then we'll keep this base

URL. Now we also need to send some

configuration. So we'll say constant

config. Inside this configuration we

need to send an headers

and inside the header we have the

content

type. Here make sure it's an

application/json

then x

dash google api key that you need to

pass.

Now all of this you can even find this

on uh over here right. So if you see

this Google API key we need to par field

mask and all the information.

So that's what I'm writing. So over here

we just need to add the environment key.

So I will say next not next but here

we'll say Google

place API key. Okay. Now we'll replace

this key in a moment but I will just add

it over here and then we need to add

this XG Google field mask

and inside this we need to provide which

things you need it. So we'll say places

dot

photos then we need a display name. So

we'll say places dot display name and

then places

do id. Okay. So once we have all of this

config ready now simply

we'll make an API call. So we'll say

export

uh result is equal to await

exos dot post then we'll pass we'll send

this base URL then we need to pass the

information okay uh to this place so

over here we'll say text query and for

this one we need to pass a place name so

we'll say place name. Now we need to get

this place name from the body of so

we'll say place name is equal to aait

request dot

JSON. Okay. And that place name we are

going to pass and along with this one we

need to pass the configuration. So

whichever configuration we have that

configuration we need to pass and then

save it. Once we have the result

we'll return this result. So we'll say

result dot data.

Make sure we'll pass this inside the

next response dot JSON.

Now I will also make sure that I will

wrap everything in a try catch block. So

over here

I will add try catch block

with an exception E and here we'll say

return

next response dot JSON

E with an error E. Perfect. Here we'll

say error. So that's how you need to uh

said the post API call for your Google

Play API. Now in order to generate the

API key simply you have to go to the

uh Google cloud console. Inside the

Google cloud console here you have

option to create an API key. But before

that make sure you will search on this

Google place API right. So make sure you

will enable this places API new and make

sure to you you might have enable

button. Make sure to click on enable. In

my case it's already enabled. So I don't

need to do anything right. Uh also if it

doesn't work make sure you'll also

enable this place API which is old one

but make sure to enable that too. Once

you enable you can create an API key

and once you created that API key I will

copy that API key. Then we'll go back to

our env file. Just paste it here. And

for the security purpose, um I will just

rename this to AI trip planner place API

key. You can add a resting to your

website only. Okay. Right now I will

keep as it is and then I will save this

one.

Once you save uh you can ready to use

this API key because that we already

added. Now I will go to the

hotel card item. Okay. And instead of

this placeholder now we want it to show

but we need to make an call to this

particular place Google place API

endpoint.

So to make an call right so here we'll

say constant

get Google place detail

something like this. And uh inside here

we'll say constant result is equal to

await exos dot post / API/ Google

I will get that API endpoint which is

Google place detail Google

place detail

and uh that's all we have and inside

this we'll say place name as

hotel dot hotel name.

You can even pass more attribute if you

want to get an exact result. Make sure

it's a sync. And here I will just

console the result. So we say result dot

data. Now this particular method we need

to call inside the use effect whenever

this component get load and when the

hotel information is available. So here

we have hotel and then I will call if

hotel is there

then get Google place data something

like this and then save it. Now if I go

back to our application,

go to the inspect panel,

go to the console here, I will refresh

this screen

and we obviously we are getting error

because we need to make sure this

component is on the client side

and refresh it. Now if I refresh this

screen then you will see we got the

place information. Inside this we have

three different uh info. So I will just

extend this

and if you see we happy homes Goa happy

home there are lot of different option

cames out and for each of them you will

see the photos right and here we have

the uh

and from this one we just need this name

in order to pass to the Google uh photo

URL uh with this information right but

along with that one you'll see more uh

things over here like Google Maps URI,

their width, height and all of this

info. Now sometimes you might get a

three different results. See inside this

in this case we got places with the

arrow of three. So in order to avoid

that and to get only one place you can

pass the address as well and which will

uh limit and we'll get an exact result.

So now let's gohead back and once we

know that we are getting result over

here. Now we are going to update

the things. So over here we'll get the

place uh reference name I will say is

equal to result dot data. From the

result dot data we got the places. So

we'll say places of zero. Then we have

the photos. Then we'll say photos dot

and then we just need our first element.

And from there we'll get a name. So

we'll say photo of zero dot name. Okay.

So like this we'll get the photo

reference name. Now after that once we

get this one I will go to the

documentation and click on this place

photo doc over here. it will explain how

to get the

photo. Okay, because this particular URL

we need to render in order to display

it. So basically we'll copy everything

as it is. Okay, so this example we'll

copy. We'll go back to our application.

I will say constant photo reference URL

is equal to and then I will paste this

URL. This particular key nothing but

the environment variable key. we'll say

process dot environment dot and we'll

paste this key

variable. Okay. Then instead of this

place name

now we'll add a place reference name. So

we'll say place reference name. And then

for media you can provide a maximum

height and width. So we'll say max

height pixel is equal to 1,000 and max

width

pixel is equal to 1,000 and and then we

have this key. Now this photo reference

URL we need to write

okay because we are doing everything on

the server side. So you don't need to

worry and on the card item now we'll get

only that particular result. Now if I

head back, let's refresh the screen. Now

we are expecting just a URL. Now if I

open this URL, boom, it opened that

place information. If I open this one,

you'll get that place info. How cool? It

means it's working perfectly fine. Now

simply once we have that URL, we'll save

in a state. So we'll say constant

photo URL comma set

photo URL is equal to use state

which is of type string

and then here we'll say set photo URL

with the result of data and then here

we'll say if photo URL is there then

show photo URL otherwise show

placeholder

okay and uh also I'm going to write if

result

dot data dot e if there is any error

then return nothing and then save it.

Right now uh we have an error. So

obviously this particular endpoint we

need to set. So this particular host

name we need to add to our next

doconfig.js because we are trying to

render from the third party URL. So

simply go to the next doconfig.ts file.

Inside this we'll say images then we'll

say domains and then we'll white list

this particular domain. Once you add

this domain make sure to refresh your

application manually. It will not

refresh automatically. And then here we

go. And boom. If you see now the actual

image is now rendering. Perfect. Right

now same thing you have to implement. So

I will copy everything as it is and I

will implement for the place card item.

Once you add I will I need to make this

as a client. Then make sure to import

the use state and the use effect. Here

we have this activity right. So once we

have this activity info then only we'll

make a call. Uh obviously make sure once

we have the activity we need to send a

place name and along with that one

you can add

the activity dot place uh address okay

so which is helpful to get an exact

details now once you add I will refresh

this screen and okay so still I'm

waiting for this one uh let me see

what's the issue do.

So we'll go to the inspect panel. I

don't know why it's not rendering. So

we'll go to the console. I don't think

so. It's get call.

Okay. So that's because we did not set

the value. So over here we forgot to add

a photo URL. Then show photo URL

otherwise placeholder image. And boom.

If you see all the images from the um

that particular tree. Sounds good,

right? So that's how guys you need to

add it. Uh let me know if you have any

question any doubt because this is the

easiest way that you will find on the

internet that how to do it. Okay. And

most important the Google Play API is

free. You might need uh to add a card

credential sometime depends on the

country

but if you search on Google Play API

pricing.

So you will find let me go to this

pricing and billing section. Here you

will get some uh free credits every

time. Okay, so you don't need to worry

about this. Uh if you see it's

completely for zero dollar. You don't

need to pay any amount. Okay, and you

can use for a small business for your

development purpose as well. Uh same

thing if I go to the places you will see

everything for the $0.

Now it's time to uh render the actual

result on the right hand side. Right now

we are showing the demi data, right? in

order to make sure our UI is working

perfectly fine. But whenever user

generate the final response, we want to

display on this particular component.

Now there are couple of way that you can

do it. You can pass your generated trip

data from one component to other and so

on. But the best approach we can do it

that with the help of context and we

already use the context. So we'll create

a new context called trip detail context

dot tsx. Whenever later on we want to um

fetch the user already created trip info

that time also trip detail context quite

helpful over here we'll say export

constant trip detail context is equal to

create context and make sure it's from

the react you can mention the type any

and here I will put it as a null and

then save it now inside your provider so

we'll go to the provider tsx I will wrap

this So we'll say um

trip detail context dotp provider. Here

we need to pass a default value and make

sure to wrap this children inside this

provider. Now let's define the state. So

here we'll say trip detail, set trip

detail

and then we'll pass this trip detail as

a default state.

and then save it. Now you can also uh

add the shortcut for this one. So we say

use trip detail is equal to arrow

function and simply return use context

trip detail context.

Now let's close everything and go to the

uh chatbox component. That's where we

are generating the final trip. So first

I will use that context. So we'll say

trip detail, comma set

trip detail is equal to use trip detail

something like this. Right? So already

we are using this trip detail uh state

over here. So what we can do

uh I will replace this to trip info

instead of detail inside the context. So

inside the provider

instead of div detail info I will say

and here while passing make sure you'll

update this to trip detail info.

So this trip detail info. Okay. And now

I will say trip detail info and trip

detail info. Perfect.

And this need to be set trip detail

info. Now once you set this whenever we

get the detail information about the

trip we'll set the trip detail info with

the result dot data dot trip plan. As

simple as that. And then save it. Right

now I will go to the

our component and inside this eternary

we'll use this context again. So I will

copy it from here. Go to the iternary

and here I will use that something like

this. Okay. Make sure to import it and I

will just comment this

over here.

Uh we have this trip data. You can

replace this with the trip detail info

if you want.

But if you see for the trip detail info

obviously at many places we have to

provide a type right because we are

using a typescript. So best way to do

that instead of providing type for each

of them you can add a type to your

context itself. So if I go to the trip

detail context so inside this we'll

provide a type for it. So we'll say

constant or we'll say type

trip context type is equal to and then

we'll say trip

info as trip info we already have and

then set trip

detail info actually. So here we'll say

trip

detail info. Okay, then here we'll say

react dot

dispatch and then react dot set state

action with the trip info

and then here now you can provide a type

as a trip detail context type and it

might be an undefined so you can pass it

as undefined

here as well I will pass it as undefined

by default okay now let's save it. Let's

go to

uh provider because that's where we also

need to update. So inside the provider,

we have this trip detail info. Now I

will replace this with the trip info

and we also have an error over here. I

think we need to pass some dummy data.

So over here I will also pass a null

because we can keep a null as well,

right? And once you pass over here along

with the trip info I will pass it as a

null and here as well we'll pass it as a

null and then save it. Now if you see we

don't have any error inside the context

and the provider. Now inside the chat

box we have to make sure that the it

will return these two value. So I will

just update the provider as well.

And here inside the trip detail context

I will export it. So I can use this

context type inside the provider when we

return this. So over here we are

returning right. So

we'll add this particular type

and uh

and undefined. So over here I don't know

why we are getting this error.

So right now I just ignoring this error

because it's saying that you're also

trying to save it as a undefined. So

just ignore that thing. And uh I think

that's all we needed. And over here I'm

setting this value. Now let's go to the

itonary. And over here let's add ts

ignore. And here we have trip detail.

And after adding this one I will say

trip data, set trip data is equal to use

state is it? And I will pass it as a

null by default. But I will add a type

trip info

and null. Okay. Now this trip data I'm

going to pass everywhere.

Something like this. Now also along with

this one

uh we need to add one more condition to

verify whether the trip data is actually

there or not.

So basically here we'll add a condition.

If trip data is there then it will

render this trip data otherwise it will

pass an empty value. And now if you see

we don't have any more error right so

make sure to follow the step-by-step

guide if you face any issue you can

always refer the source code anytime

okay and I think that's all we needed

let's go back to our application

and as you are using the uh hook so I

will make this component on the client

side

so we have still have error so it's

saying the trip data is not defined okay

that makes sense because inside the

timeline we need to pass now this trip

data.

Uh I think I I forgot one more thing

that whenever

we have the trip detail info context

then we need to update. So here we'll

say trip detail info and I will say trip

detail info is there then we have to set

the trip data with trip detail info.

Okay, that is very important. Right now

if you see we don't have anything and

that that's why it's not showing any

value whenever there is no trip data.

Okay, it doesn't make sense to show this

timeline. Okay now right now if you see

it's completely empty obviously we are

going to replace this with a different

value but for now I hope you understand

up to until this point. So here we will

say uh create

trip from Charlotte to New York for 3

days. So I will pass this one. Now AI

will generating it. So it will ask who

is traveling. I will say couple.

We'll say moderate.

And then it start generating the uh trip

for us. And boom. If you see the trip is

generated as soon as uh it's there and

wow if you see all the details the

images also generated and now all the

images are directly from the Google

place API and that's a 3 days it turnary

right every day you got all the details

along with the hotel information depends

on your budget and here you will see all

the basic info that you selected

previously how easy it is now

interesting part if I click on this on a

view map it will navigate to the Google

map and if you see it jump to that

particular specific location where you

can learn or access more details.

Uh not only that but in advance um if

you want to add affiliate link to these

hotels you can add that too which make

you the real money along with that your

pricing and subscription model. Now

whenever there is a blank space we want

to show some image over here some travel

image right. So basically

over here we already have this trip

data. So I will add a question mark and

then

if the trip data is not there we'll add

an image

source over here. I already have this

travel.png file u inside my public

folder. So I'm going to use that local

image. All tag I will say travel width I

will say 800

height to let's say

800 and then inside the class name we

will say width full height

to full then object cover and rounded to

3x okay let's save it if I refresh the

screen now you will see that particular

image on on the blank screen. Boom. See

how cool. Also, on the top of that, I

want to add a text. So, I will wrap this

in a do tag.

Inside this, we'll add an S2 tag. Here,

we'll say getting to know you to build

perfect

trip here.

And then below that I'm going to add or

maybe we can add an arrow over here.

Left arrow or arrow left I think.

Perfect. Now this particular heading I

want to keep on the top. So I will say

absolute. We'll say bottom to 10.

Let's save this one. Okay. So it's

coming over here.

I will just move this and I will put it

on the top of this image.

And uh I will say 40. Not 40. Let's say

20. I will say text 3XL

text color to white.

I think that's much better. And then

we'll say left

to 20.

Perfect. Okay. So it's just showing this

direction that okay you can start from

here. Uh just last uh minute change that

I want to make inside the chart box.

Okay I'm just trying out that what if

you wrap this particular UI inside the

border. Okay. So over here we'll say

border rounded to 2 Excel

and we'll obviously give some padding to

five. I think this is much better. Or

instead of border you can add a

background. Let's say secondary.

I think secondary is too dark. Let's say

gray

50.

I think I will just add a border. That

would be good. And with the shadow.

Okay, perfect. And obviously on the

right hand side we have this image.

Now it's time to limit the free user to

just create only one trip each day. As

you know that we already integrated the

arjet into our application. Now it's

time to use that in a real time. So

we'll head back to our application. Over

here we already have the arjet API

endpoint and we also tested this get

request which is the example that how it

actually works. Now basically we need

this particular line in order to verify

whether you uh uh the access is need to

be denied or not and depends on that one

we are going to send a response. So

basically let's copy this line

and this AJ I'm going to export it so

that we can use it in any of the uh

file. Now go to the AI model route.tsx.

I will just collapse this prompt because

we don't need it for now. And at the top

we are going to check. So first I will

add this line of code here. Make sure to

import this AJ. Now instead of this user

ID we are going to use a user email the

login user email which you can get it on

the server side using this await current

user from the clerk neckjs and that's

how easy it is with the clerk once you

have the user you just need to pass user

dot

so over here this need to be an user dot

so pass user ID as user dot primary

email address dot email address okay so

So you have to pass this field called

user id.

Uh over here if it's empty then

obviously we have passed empty string

and then requested to five. So obviously

every time the five token uh it will

check whether the five token is

remaining or not for that particular

user. Then next thing we need to check

if access denied. So this line of code

we're going to use. Now after this one

we need just console the decision to

check all the fields that is available.

So over here we'll say decision save it

and we'll check this out. So I will

refresh the screen. When you make any

API call it will return the decision for

us. And if you see inside the decision,

so let me go up here. We have the

decision. Inside the result, we have

this information, right? Then we have

the IP. Then we have the conclusion.

Then we have the reason inside the

reason we have the remaining field. And

that's what we needed. So I will just

say if decision dot remaining

or we can say decision dot reason first

dot remaining

and then decision dot remaining. So it

will give us a count. So if it's equal

to equal to zero okay means there is a

no uh token left then we are going to

return next response

dot JSON inside this we'll say uh

response as

your

daily limit

reach or we say

no

free credit remaining

and the UI will be limit

as simple as that and then save it okay

and also inside the decision we have to

make sure whenever is final is true then

only we'll request five otherwise

will only pass as a zero

okay and I think I don't we don't need

to do anything let's refresh this and

let's take this out so I said create new

trip. So it's generating. That's weird.

Okay. Now if you see it's saying no free

credit remaining because we don't have

any more credit. But if I increase this

capacity to 10 for example, right? And

let's try this out.

Okay. So maybe I need to increase little

more because I already

um use many times

and now it if you see it start working

as expected. Now it only limit it or it

will only deduct whenever there is a

final when once you generate the final

output then only limit that uh and

deduct that particular amount. Okay. So

that's how you can add the arjet rate

limiting feature so that um your API is

secured from an uh free users.

Now it's time to add a pricing table

into our app. Obviously, if you see this

is how we want to add a pricing table.

Integrating the payment gateway is a big

headache, but it's no longer because

clerk providing you the billing feature

and within just one line of code you can

add this pricing table. How beautifully

looking, right? And that's what we are

going to integrate in this particular

chapter. So simply go to the clerk and

obviously you can go to the dashboard on

in which under the configuration you'll

find brand new option called billing.

Click on the setting section and here

first thing you need to create a plan if

you don't have any plan. Now I will say

create plan and under this plan section

we don't want to show a free plan. So I

will just hide this one. So you can open

that and simply say public vable to

false and then save it. But we want to

add some paid plan as well. So I will

add a new plan over here. And then give

the plan name. So here we'll say

monthly.

Then you can set the base price how much

you want, right? So I will say 9.99. And

you can even give the annual discount.

So let's say on annual discount the

pricing will be just $7.99.

And here you can add a feature, right?

for example unlimited

trip planner

then I will add this feature and same

way you can add a multiple feature by

providing a name and the value once you

add all the feature simply save this one

and then we'll go back currently we are

under the development mode right so it

clerk itself use a testing credential in

order to test it But once you move this

to a production, make sure to connect

your actual stripe account because clerk

use a stripe payment gateway in order to

uh receive a payments. Now once you done

with this plans just enable this billing

and then your billing is now enabled.

Now simply with this particular uh

component you can add your pricing

table. You can read the billing guide in

order to get more details. I will put

the link in the description so you can

go ahead and check this out. Now once we

create the plan here you will see how

easily and uh we can show this. So I

will copy this just pricing table

component. We'll go back or simply

create a new route under the route uh

app folder and we can say a pricing.

Inside this we'll create a page tsx file

and then we'll add a default template

saying pricing. over here. I will paste

this. Make sure to import this pricing

table and then save it. Now, inside the

header tsx, we already have this pricing

at route attached. So, we'll go back. I

will refresh this screen and then make

sure to click this pricing and boom. If

you see, we have this pricing uh table

is showing on the screen. Currently, we

only u add one plan, which is a monthly

plan, but you can add number of plan.

It's totally depends on you.

Next,

I will add some text over here. So, for

example, we'll say first I will give

margin top to 20 and then we'll say S2.

Let's

we'll just add some text over here. I

will add a class name font bold text 3

XL and margin Y to five.

And if I go back to our app over here,

boom, this is how it looks. Obviously,

we have to make this in the center of

the screen. So, we'll say text to be in

the center.

Okay. Now, we don't want to add a lot of

plans over here. Okay. Uh but that's the

reason we added the only the one single

plan. Now when you want to subscribe you

will find in in app only you can able to

uh go to the development mode. Here you

can make a payment and obviously you can

test this out with this uh test card as

well. Okay. And once you make the

payment you can manage this using a

profile section. Currently we don't have

profile section so we can add it at the

top. So basically inside your header.tsx

tsx.

I will wrap this in a do tag

maybe outside of this one

and then we'll simply say user button.

Now this user button component we are

importing from the clerk right and

automatically add all the UI all the

necessary UI for you. Here I will make

flex gap of file item to be in the

center. Now if I go back you will see

this profile icon. Just click on it and

then you will see this beautiful

drop-down option where you will find an

option called manage account. Click on

this manage account and then here we

have the new billing option. Click on

it. Currently you we are you are on the

free plan that's why it's saying zero

but under the statement you will see the

statement payment section everything but

you have option to add a new plan as

well see how easy it is right so with

the help of clerk you can easily add all

of these feature guys now once you have

the pricing model and uh all the details

right now it's time to check the limit

because currently we set the limit but

we have to check if the user is paid we

don't need to uh add that limit feature.

So in order to do that simply from the

documentation you will find how to do

it. So we'll check whether the user has

a premium access or not. So we'll copy

this line of code. Go to your uh AI

model route at the top. I will simply

paste this. Make sure to import this

has.

Obviously in order to import it you need

to write like this has

is equal to and you have to import from

the O actually await O and then we have

has now in the plan make sure to give

the plan ID. Now in order to get this

plan ID simply go to your plan in this

case is a monthly and if you check this

key that key you can pass. So I will

just copy this key and I will pass it

here. Okay. And now it will check if

user has the premium access or not along

with this. So this condition I will add

if premium access is not there. So I

will say not there then you can send

this particular message. Okay. Here I

will just console this so that you can

easily check this out.

So I will go to the create new trip.

Here I will say create new tree for me.

Inside the console

if I go to our console here we will say

has premium access to false right.

Perfect.

Now I will in order to test this right I

will just go to this arj route and

instead of this 30 I will again make

this five. So that obviously uh I will

get the message that no free credit

remaining. But if I subscribe to our

plan then obviously that limit will go

away. Now I will say subscribe I will

pay with the test card and once I make a

payment you will see this particular uh

table u pricing is activated. Now if I

go to this manage account under the

billing you will see the current

pricing. Perfect. Now let's create a new

trip. I will say create new trip. And

now in this case it allow me to create

it because I already subscribed to my

plan.

I hope you understand this particular

scenario. Right? That's how easy you can

uh manage it. I hope you understand this

pricing table. If you have any question,

any doubt let me know in the comment

section or you can also reach out to me

on my discord channel.

As you know that we already saving the

all the trip information for that

particular user into our database. So if

I go to the database here you will see

the trip detail, trip ID, user ID and

all the data. Now we need to create one

button over here instead of this create

new trip on this particular page and we

say my trip. On the click of that my

trip we are going to navigate to that

new screen on which we are going to show

the user uh generated trips. Okay. So,

first thing we have to check depends on

the route inside the header we need to

uh replace this particular button.

So, I will go to the header.

Inside this header tab, we'll get the

current route. So, we'll say constant

params is equal to use

or this need to be a path name actually.

So, we have instead of param we'll say

path. Okay. Now this particular hook is

very powerful. It will return us the

current URL. And let me show you how. So

if I save this one, refresh this screen

and if I go to the inspect panel, you

will see the /create new trip as a route

is rendering or it's displaying inside

the console. Now

um here we'll create a new method not

method but here we'll just use this path

actually in order to uh change this

create new trip. So over here we'll say

if path is equal to equal to / create

new tree

then we want to show a different button

otherwise so here we'll add a turnary

operator

otherwise show create new button so I

will just copy the same and we'll paste

it here and here I will say my trips

and I also want to navigate to my trips.

and then save it. Now if you see it's

showing a my trips but if I go to the

home screen then it will show the create

new trip. Okay so that is very important

to update this. Now on the click of my

trip obviously we should navigate to

this my trip screen. Currently we don't

have that particular route that's why

it's showing 404 error. So inside this

app we'll create my trips folder. Over

here we'll create a page.tsx tsx file

and simply add a default template saying

my trips and then save it.

So right now it's still executing and if

you see now we have the my trips list.

Over here we'll give a class name

padding x to 10 padding to 10. Then

we'll give on medium screen we'll give

padding x to 24 and on large screen

we'll give padding x

x2 48. Okay. So, some distance. Then we

want to add a text called my tricks.

For this one, we'll add some styling.

And if user don't have any trip that

condition also we need to handle. So I

will create constant my trips comma set

my trips is equal to use state

and over here we'll say

if not my trip so we'll say otherwise my

trips dotlength is equal to equal to

zero then simply we want to add a div

inside This do will say you

don't have any trip plan

created

and then below that we'll simply add a

button

create new trip.

Obviously I will wrap this in a link tag

with a h reference saying it will

navigate to the create new trip screen.

And I think that's all we needed. Then

over here we say padding to seven,

border

and rounded to 2 Excel

as we are using a state so we need to

mark this component on the client side.

Okay. So that's good. part over here I

will make it flex flex column item to be

in the center and justify content center

gap to five

and then we'll also give margin top to

six something like this right and on the

click of new trip it's navigating

perfect now we need to write a convex

function in order to fetch that

particular user information

so go to the convex folder inside that

we already have the trip detail Now in

this case we want to fetch it right so

we'll write we'll write a query so we'll

say export constant get

user trips

and here is equal to we'll say query

and obviously we need to pass an

argument in the argument you need to

pass a user ID which is of type ID and

then you need to provide a table name

which is user table

then pass an handler.

Inside the handler, we say async ctx,

arguments, and the arrow function. Here

we say constant result is equal to await

ctx dot db dot

query and then you need to provide a

table name. Here the table name is trip

trip detail filter dot

sorry u trip detail table and inside the

filter we need to add equal to

so here we'll say q dot

equal and then q dot fill the field name

is user id matches with our arguments

dot user ID and again select all that

records. So that's the reason we have to

say collect. Once you add this, we

simply return the result.

Okay. And then save it. As simple as

that. Now once you have uh once this

getting the user convex function is

ready, let's head back to our page.tsx

tsx file

and inside this we'll write a constant

get user

trips

and here we need to define a convex

first. So we'll initialize the convex is

equal to use convex.

Now we are using the convex because uh

we need to execute the query. So we'll

say constant result is equal to await

convex dot query and inside that we need

to pass a query. So we'll be it inside

the API dot trip detail dot get user

trips and then we need to pass an

argument. So in this case the argument

will be just a user id. Now in order to

get a user ID you already know that we

have this user detail

uh context.

From that you can get

the user ID. So we'll say use context

was not context user detail context

actually.

Oh my bad. Uh I will just undo

everything here. We just need to write

user detail

because that's the context we have to

use. U use detail. Use user detail

context. My bad. Okay. Then from it you

can get user detail

dot id. Okay, here I will make this as a

async. Then inside the console I will

just write a result and I will call this

method inside the use effect

whenever the user detail information is

available.

So here we will say get user trip.

Now once you save everything head back

to our application. I will go to the

inspect panel. Go to the console and

boom. If you see we got the nine

records. Okay. Now obviously this record

will be in ascending order. So here I

will add one more condition dot collect

dot. Here we already have I think we

have order by order. Here we need to add

descending.

Here you just need to provide whether

it's a descending or ascending. So we'll

say descending. Okay. So we don't need

to provide any other things. And most

important we are getting the result. Now

save this result in a state.

So

inside the page tsx we already have this

my trip section. We'll just set that. So

set user detail with the result. Okay,

you can define a type over here because

we only have the trip ID, trip detail

and UID. Now from it obviously we need

to iterate the trip detail in order to

display the each trip information.

So over here I will add a div. Inside

the div we'll say

trip.

Oh, so what is this? Uh my trips sorry.

So we'll say my trips

dot map here we'll say trip, index and

the arrow function.

Then we'll add a do

and inside this do obviously we need to

iterate this trip detail.

So let's uh show the origin and

destination. So over here we'll say H2

tag inside this we'll say trip dot uh I

think it's better we can provide a type

for this one. So here we'll say type

trip

is equal to and uh we mostly concerned

with

let me uh u trip id so here we'll say

trip

ID of type any then we have trip detail

so we'll say trip detail of type trip

info

and

underscore id if you want So underscore

id of type string. So these are the some

parameter we are fetching. Um I will set

this over here

so that we can directly use it. So here

we'll say trip dot trip detail dot

um origin or we'll say destination

first. Okay. Here for the key we provide

index. I will save this one. I just want

to see whether it's working or not.

Right now we got an error. So that's

where okay there is one small mistake

instead of the setting the user we have

to set my trips okay so make sure you

set the correct one and once you set my

trips if you see we got the list of all

the destination

so this is the destination so here I

will put a source as well so we'll say

trip dot trip detail dot

destination and over here we'll add

arrow So I want arrow on both the side.

Okay. So something like this.

Okay. And for this H2 tag we'll say

class name flex gap to two. I think

that's much better. Also we'll make font

semimedia bold and text to Excel.

Now just above this one we also want to

show an image. So we'll say image tag

with a source. Currently I will add a

placeholder.

Um so for a placeholder we'll say slash

dot slash placeholder dot jpg

and

for the alt tag we'll say trip dot trip

ID.

I think that's all we needed.

Make sure to provide a width and height.

Then inside the class name, I will make

a rounded corner. So rounded to Excel.

Then object

cover.

So we have an error. So we'll say what

is the issue.

Oh we don't need to provide this dot. So

that's the reason we have that error.

And if you see we have the placeholder

for each of them. Perfect. Now instead

of putting writing the code over here I

will create a new component under this

my trips

and under the components we'll create

uh my trip card

item dot tsx file. Let's add a default

templates. Save this one. I will cut

everything from here and I will paste it

inside this my trip card item. Obviously

here I will accept the trip as a data.

Okay.

And uh for the props I will say type

props

is equal to

here we will say trip and then we want

to export this type

so we can use it.

Perfect. And then we don't need to

provide a index over here. Make sure to

import the image and save it.

Uh, okay. I think we forgot this.

Importing this icon.

And now inside the page.tsx, you need to

add this my trip card item. And to this

one, you need to pass a trip. You can

add a key as a index if you want. And

then save it. And boom. Right now over

here, I will add a grid. grid column 2

on the smaller screen on medium screen

or maybe on large screen we'll say grid

column 3

gap to five

perfect I will also give margin top to

six

and that's how it looks like now

obviously we need to add lot of other

things um here we can write a text

something like H2. Here we'll say how

many how many days of trips. So we'll

say trip dot trip detail dot

duration

and and over here we'll say let's save

this and let's see what is the result 3

days

trip

with and then we need to write a budget.

So we'll say trip dot trip detail dot

budget. So 3-day trip with a moderate

budget

something like this. See okay and uh

I will add margin top to two text grade

500

and save it.

Then

you can add

padding to three. We'll add a shadow

rounded to 2 XL.

Here we'll add more padding.

Okay. So user can able to see it. Now

once you add all of this detail,

you can also show that particular image.

Okay. So in order to show you the image

you can use the same logic which we used

for other cards. Um just the things I'm

going to add margin top to two over

here. So some space now uh I will go to

the previous card. Let's say place card

item. I will copy everything as it is.

We'll go to the card item and we'll

paste it here. Now make sure to import

this all the hook first.

Now whenever the trip information is

there we want to execute this get Google

place import the exio as well and

for the place name we'll say trip

so I will remove everything dot trip

detail

dot

um you can add that

information from the itinary

of zero dot

activities

dot okay so from the activities I think

we need to get first activity and then

here we'll say place name okay so that's

how I think we can get the place

information of place name so that you

can

replace with this particular placeholder

with the image

And boom. If you see, we got the

eternary. How cool, right? So that's how

guys, you need to uh create this

alternate. Obviously, that's not look

good. So instead of this one, you can

just place a destination name. Okay. So

what we can do? So we'll say trip detail

dot destination.

And if I refresh this now, you'll see

the destination. I think that's much

better. Now, uh, another important thing

you need to do is to, uh, give the

specific height and width. So, here we

say width to full, height to 200 pixel.

Okay. So, everything will be in one

line. I think we can give 270.

I think that's much better. Say

and on the click of that itonary we want

to navigate to the new screen where we

can show or use existing uh timeline uh

structure where we are showing the

itinary or trip details.

Now once we have this my trip details

information right and on the click of

that we want to show all the details of

that particular trips. Obviously, we are

going to reuse the component. But before

that, let's create a new route. So, I

will close all of this tab for now.

Inside this app folder, we'll create

view trip. Inside this view trip, we

need to add a trip id that is very

important in order to fetch uh or view

the trip information dynamically. Okay.

And inside here, we'll create a page.tsx

file. Now let's add a default templates.

Here we say view trip

and then save it. Now in order to get

this trip id we'll say constant

trip id is equal to use params and

that's how you can get the trip

information. Make sure the this field

name will match with this folder name

which you gave. Okay. And whenever you

want to make a dynamic route, you can

start with the folder name with the

square bracket. Now once you have the

trip ID, obviously we need a convex

function in order to fetch that

particular trip information. So I will

go to the trip detail uh inside the

convex and here we'll say export

constant. Let's copy everything as it

is. Actually

only thing that we need to add get here

we say view trip

or get trip by id then

uh along with the user id we also want

the trip id

so which is of type string

and here we are filtering out right also

we need to add one more conditions. So

we'll say Q and Okay. And then the first

condition which is equal to and the

second condition. So let me bring this

down.

Second condition will be Q dot equal Q

dot fill

matches with this trip ID and our

arguments dot trip ID. If that matches

uh obviously we don't need order by over

here then we need to return only one

record because it will only return the

single record and that's how you can get

the t by ID. Now inside this first we'll

get the user

detail comma set user detail is equal to

use

uh user detail context and then we'll

create a method to get the trip by

get trip we'll say just and here we'll

say constant instead of before constant

let's define a convex X

and then we'll say constant result is

equal to await

convex

dot dot query pass the query. So API dot

trip detail dot get trip by id and then

we'll say user id as user detail

dot id and then the trip ID nothing but

the trip ID which we already have

here I will make as a async.

So if there is a note trip ID we'll pass

it as empty. Oh here we have an error.

So it's saying string is not assignable

of type string.

So over here we'll say to string maybe

that will help or

we can add it something like this. I

don't know why it happens but let's see.

And then inside the console we can write

the result. Okay. Now this particular

method we need to call inside the use

effect.

So over here um whenever the user detail

is available we're going to call this

method.

Perfect. And save it. Now in order to

test this first we need to

uh go to the

trip not but we'll go to the

my trip inside the card item. on the

click we want to navigate. So I will

just use a link tag.

I will replace this due to link tag and

in the ha reference

we'll navigate to slash

view trip slash and then trip id. So

we'll say trip dot

trip id. Okay, let's save this one and

let's test this out. So if I click on

this Mumbai to whatever. So if you see

it's navigate to this view trip. I think

we have incorrect name. So it need to be

a view trips. I will rename this to view

trip only.

And if I refresh this now we have uh the

view trip. We got an error. That's

because we need to make sure that

particular component on the client side

we use the hooks. So here I will make

this as a client side.

And if I refresh I will just make sure

And if you see we are we are on the view

trip. The most important thing if you

see this route right because inside this

URL only we are passing the uh trip id.

Now inside the inspect panel make sure

you are getting the result. See and we

have this particular result. Cool. Right

now once we have this result uh

I will make sure to go back first and

then we'll define a state inside this my

inside this view trip. So over here

we'll say constant

trip data comma set trip data is equal

to use state and the type is trip. So

make sure to import that

and over here we'll set the trip data

with the result. Okay. Now we already

have the component called itterary.

Right? So here we say itterary

make sure to import and then to this one

if I go to the iternary u uh we need to

just display that. Right? Now obviously

it will not display anything except this

empty value. Right. Uh but

we need to set the trip information. So

if I go to the itinary component, you

will get to know that we are using this

use trip detail context and that's where

we are setting the trip. So I will

go over here make sure to import this

use trip detail

and I will ignore this for now. And once

we have this trip detail info,

I will set this detail info with the

result dot trip detail. And boom. If you

see the result, how beautiful, right?

And we don't need to do anything.

Everything is here. Uh if I go back,

come to this new one. Let's say

Charlotte to bone. And boom. Perfect.

Right

now it's time to add a 3D map on our

application.

On this particular page, obviously we

are giving one option to see the view

trip details and other option to view

the places directly on the map which is

a completely interactive 3D global map.

That's what we are going to add with the

help of mapbox. Mapbox provide a best um

map which is the best alternative for

the Google map as well and Mapbox is

free to use. You can start with the free

trial and if once you reach certain

limit you can uh buy the with the extra

credits but uh for a development and for

a small business the mapbox is free to

use. Simply sign up to the mapbox. Once

you sign up uh you need to create an API

key. Sometimes it autogenerate for you.

So once the key is ready or token is

ready just copy that go back to your

application and then inside your envu

file just add this. So we'll say mapbox

API key is equal to and then paste this

here I will add next public because we

want to use on the client side. Then I

will head back to this mapbox

documentation. here it help us how to uh

install the SDK for the mapbox. So I

will put the link in the description so

you can also go ahead and check it out.

So inside the mapbox do documentation

under the get started here you need to

select the modular bundle and then copy

that go back to your application

and inside the terminal

make sure to install this mapbox. In

meantime, we can go to the

create new trip screen. Under the

component, we create global map.tsx

file.

And then I'm going to add a default

template and then save it. Now, this

global map we wanted to show on the

screen. There are a couple of way that

you can uh show the map. Either you can

add a tab or you can add a floating

button in order to switch between the

trip and the map. So we are going to use

a floating button. So basically in order

to add that button

we can first go to the page.tsx file.

Under this we have the iternary right.

So I will define one constant called

here we'll say uh active index comma set

active index is equal to use state and

initially it will be zero. Now whenever

the active index is zero

we need to show itterary otherwise we

will show a global map.

Okay. Now here this is turnary operator.

Make sure and once you save it right now

if you see the it's showing the iternary

but if I switch this to one then it will

show the map. See the global map. Okay.

Obviously we will add a button later on

but for now I will keep this active

index one so that we can test this

global map and we can implement it. Now

once the mapbox is installed

you need to add this CSS file. So you

can add simply inside the same component

and then you need to import this maxboxg

gl as well. Okay then this is the

example where you can initialize the

mapbox. So I will add this

initialization inside the use effect.

So we'll define the use effect over

here. We'll add this. Now obviously you

need to refer this mapbox token.

So we'll say process

dot environment

and then this mapbox environment key

something like this. Okay. Then inside

the container obviously we need to

define it. So I will define a reference

called constant map container.

Reference is equal to use reference

and by default I will provide it as a

null. Then inside uh the HTML side

obviously we wanted to show it. So I

will just add a reference to map

container reference. So it will

automatically render our map inside this

particular div. Also don't forget to

provide a style that is very important.

So here we'll provide a width. Let's say

95%.

Then the height I will add 85 vertical

height.

And if you want you can add a border

radius. Let's say 20. Okay. Now once you

define this inside this container you

have to refer that container reference

current something like this okay

and if it's not there I will pass it as

a empty now style you can put this style

URL this is the current uh street v12

style but you can create your own and uh

save this one go back to your

application right now if you see the map

is getting rendered how cool right at

least our map is rendered But we want

the map in some different way. We want

to show a complete global. So here I

will pass it as a projection. And here

inside the projection you can add a text

called globe. The zoom level. I will

change this to let's say 1.7. Save this

one. And then you will see the magic.

Make sure to refresh it. And boom. Now

we have this proper global where you can

easily manage it. You easily you can

change this. Not only that, but you can

easily zoom it as well with your keypad.

Cool, right? So that's what we wanted to

add within a few single line of code or

few lines of code. Obviously, we added

this um map box map which completely 3D

like structure. Okay. So I hope you

understand this how to do it. Obviously

what whenever the trip is generated, we

want to show the markers as well. Now

before moving to the next chapter, we

want to add the floating button at the

center. So I will go to this page.tsx

file

over here. I will add a button.

inside this button. Uh let me

add as a globe

global.

Okay. Yeah, this one. Maybe not this

one. Uh

global two icon. This one. Okay. And

obviously again I I I want to add a

condition

if active index is equal to equal to

zero then I want to show a plane

otherwise I will show the global.

Okay here this need to be a turnary

operator. Save this one. And if you see

this button is at the bottom. Obviously

we need to add a position as absolute.

Then we'll say bottom to let's say 20.

Then we want a lift

to let's say 25%, I don't know whether

it will work or not.

And I will make this as absolute

or not absolute u the relative.

Okay, let's make this 50.

I think this is much better. And instead

of bottom 20, I will make 10. I will add

a size

large. Perfect. Now on the click of this

one, we want to switch uh this one.

Okay. Uh the it turnary to map, map to

itary. So over here, I will add on click

method

and we'll set the map index or set

active index.

If it's zero

then we'll show one otherwise zero.

So obviously this condition need to be

if at index is equal equal to zero then

we'll show one other way zero. Now if I

click on this one see now if I check

again see okay so that's how we are

going to change it.

We can change the color let's say

background black.

I think this is much better. And on

hover we can add background gray.

Perfect. Okay. So that's how we need to

add it. So I hope you understand this

one. Okay. Uh on how you can add some

kind of toggle tip. Okay. So if I go to

the share CN

and go to the components we have tip or

talk I think tool tip we can say. So on

hover this is how the tool tip will look

like. Obviously in order to add it first

you need to install

the npm package from the shad cen and

then simply import the statements

and then you need to wrap your button

inside this tool tip.

And here we can add switch

between

map and

trip

and obviously uh

this class name maybe we need to now

attach to this tool tip.

Oh my bad. Um,

this button need to be here inside the

trigger. And for the content,

we'll add this text.

See?

And obviously, uh,

I think that's all we needed. And also

cut the class name to this button

trigger. And make sure to add a rounded

to Excel. And if you hover on this one,

you'll see the change. Perfect. For this

button um

where is this button? Yeah, over here I

will add a class name background black.

See, something like this. Obviously,

we'll change this hover effect as well.

Perfect. Okay, so that's how we are

going to add it.

Now it's time to show the places on the

map with the help of mapbox marker.

Marker is a concept where you can show

the location with the help of latitude

and the longitude and then it will show

that particular marker on the map. Now

obviously you need to create a trip and

at the final stage uh we will get the

data which we can show it. But u in the

testing for the testing purpose we are

going to use my trip section inside the

my trip I will go to this uh any of the

trip okay you can select any trip

literally and then once you select the

trip uh we can show map on the right

side okay so let's go to the my trip

first and in that one I'm going to

import this global map

so I will go to the view trip inside the

view

I will divide the screen. So we'll say

grid column span

uh five out of this column. Okay. So

over here we'll say grid grid column

span five. Out of the five column I'm

going to assign three column to this

iternary and two column for the map box.

So here we'll say global map and we'll

say glo column span three and then save

it. Once you save, if I go back to our

app, let refresh this screen.

You will see on the left hand side we

have this uh map and on the right hand

side we have the uh sorry itonary on the

left map on the right. Here make sure to

provide a column span two.

I will just refresh the screen so it

will display it on the screen. So it's

coming down. That's where Oh, so this

notable column span

to

perfect. Okay. So that's how a map is

showing on the screen. Now go to the

global map and here we are going to use

a trip detail contact context. Right. So

you already have this trip detail

context. You can get it from this detail

info. I will copy that and simply I'm

going to paste it here.

this trip detail from the trip detail

info

we can easily iterate those markers.

Okay. Now in order to add that first

we need to get all the places. Okay. So

over here we'll say trip detail info

dot.

So let's define the type for the

activity and for the index as well.

Now inside this you just need to add new

map mapbox

G gl dot marker

and by default I will provide a color as

a red.

Then we'll set the uh longitude and the

longitude. So we'll say set longitude

and latitude. So over here we'll say

place not or place activity.

So just a second uh over here we have

this I will say activity only in a

small.

So we say activity dot geiocoordinates

dot um longitude

and then activity dot geoccoordinate dot

longitude. Okay, sorry. Latitude.

Once you provide this one, we'll set the

popup. So, we'll set popup message.

Inside this pop-up, what on the click of

that particular marker what you want to

show that things you can show it. So,

here we'll say mapboxg dot popup

and then you can add the text whichever

text you want to uh show or you can even

add your own component. So for testing

purpose I will just add the text. So

here we will set set

text and then the activity dot place

name. Okay as a simple text. Once we

have that everything is ready here we

have to add it to. So we'll say add to

and then map and then save this one. Now

we'll go back. Here we have an error. So

the use trip detail is not defined. So

make sure to import this use trip detail

and uh if I scroll down I don't think so

uh the

location is is rendering over here. See

actually uh we are not iterating the

activity but we are iterating the

iternary. So basically

here we need to replace this with the

iternary and then we need to iterate

that one. So here we say eternary dot

map and then inside this we need to add

an activity

comma index

and the arrow function and inside this

now we'll add it.

So this need to be an array. Okay wait

um so this is of type number. So here

need to be an internact activities and

then map. Okay, I think that is correct.

Now, now if I go uh refresh this screen

and boom, if you see we have obviously

uh

we have lot of options. Okay, but let me

refresh it again.

So it's not showing it only showing this

uh

places but not the

marker and obviously here we forgot to

push the marker. So once we define the

marker we have to push this marker. So

make sure you define this markers. Okay.

And once you have that marker ready you

have to remove that later on. Okay. I

think that's all we needed. Uh let's

save this one. Let's test this out. So

if I refresh it, I think marker is

showing on the screen. And if you see we

have this marker. Perfect. Now obviously

you need to zoom it in order to see

because that is everything is coming

from the one location, right? So it's

hard to see but once you zoom you can

see each location and on the click of

this you can see the detail as well. Now

to uh programmatically zoom when the

marker is set you can easily set that

too. So

uh if you scroll down a little bit after

this pushing you can set the map

reference dot current

dot fly 2 and then you have to provide

the center coordinates. Okay then you

have to provide a zoom level. So here

we'll say let's say 7 and then essential

we can set it true. Now zoom level you

can adjust depends on how zoom how much

zoom you want. Now for the coordinates

you can set the coordinates. So

basically uh

can get the coordinates

is equal to um activity dot

geoccoordinates dot longitude and then

activity dot geoccoordinates dot

latitude and then simply pass this

coordinate over here.

But don't forget to provide that this is

a number. So here we'll say number

as number,

number.

So let's save. Let's go back, refresh

the screen, and then you will see the

result. Boom. How cool, right?

Obviously, you can do more zoom. It's up

to you how much zoom you want. And now

if you see, it's more zoom. Perfect. So

that's how guys you need to add the map

box with all the features. Obviously if

you want to learn more about the mapbox

you want to more add a more feature you

can put the comment uh in the comment

section so that I can create a uh

completely new project which is

completely based on the map only.

Now it's time to deploy our application

on the cloud so that you can share this

project app with your friends and

family.

Obviously in order to deploy it on the

server uh we are going to use versel but

along with that one we are going to push

all our code to the GitHub and then we

are going to connect GitHub to the

versel. So next time whenever you want

to make some changes you just need to

push to the GitHub and Versel will

automatically get triggered whenever the

new changes are updated. So first thing

first we'll go to the GitHub. If you

don't have account make sure to create a

new account. Then I will create a new

repo. Give the repo name. So here we'll

say AI trip planner app

and then you can select the visibility

and simply create the repo. Once you

create the repo over here you'll find

some command. Right now first thing you

need to set this origin. So I will copy

this. Then inside the new terminal

I will initialize the g first.

Then we'll uh set the remote origin. Now

it is very important to build your

application locally. So just type a

command npm run build. So it will build

your application locally and if there is

any error any issue make sure to fix

that uh before deploying this

application. So if you see right now we

don't have any error but many times uh

your application run smoothly but in the

deployment it fails. So that uh you can

fix it by while running this npm run

build command before deploying it on the

cloud. Now once it is ready you have

option to add this all the changes. So

just we will say get add space dot. Okay

it means all the file are now in stage

mode. Here if you see it's changed to

state. Now you have option to write a

commit message over here and then simply

say commit. So uh we we can say

something like initial

commit and then simply say commit. So

obviously here uh I think in my case is

not configured. So I will just commit it

from here

and then once it commit you need to push

your changes. If you are pushing this

first time to this repo you have to push

with this command. Okay. And later on

you can just type command get push while

pushing the changes. Now right now uh

it's getting push.

Once it push we'll go back to our

application. Refresh this repo and boom

you will see just now we push these

changes. Right now the next step is go

to the versel and if you don't have an

account create a new account with the

versel add a new project and then here

you need to uh connect with your github

repo. Okay. Once you connected, you will

see your project name at the uh top

right. Make sure to click import. Then

you project name will appear over here.

Everything will be as it is. Now you

don't need to make any changes right

now. Okay. But as we are using a convex,

convex need a little bit configuration.

So I will go to the convex and here

we'll say convex versal deployment

and I will go to this deployment se once

you're on this documentation you will

find this build command that you need to

override okay and then you need to

provide this deployment key as well so

quite straightforward so I will copy

this key then we'll go back to this

versel and here we'll say build and

output setting just need to override

this build command and then we'll paste

this build command. Okay, then inside

the environment variable if you follow

this convex I will go to this convex

dashboard first and from the convex

dashboard you need to get this

production deployment key. So I will go

to this production make sure to select

you can even select from here okay then

go to the setting and here we have the

production key which we need to

generate. So we'll say generate

production key. We'll say prod. Save

this one. And then we got this key. Just

copy this key.

And you need to paste it here. Make sure

the variable environment variable name

should match with this one. Okay. So and

obviously you need to deploy it. But

before that make sure from the

environment file and from

environment.local local file you'll copy

all the environment keys and then you'll

paste it here. Okay. So just copy

everything automatically it will assign

all this value. Same thing you need to

do with this local file. We'll copy it

and then we'll paste it here.

Once you add all the keys and updated

this build command just click deploy and

within a few seconds it will start

deployment.

So this variable is duplicate one as

this is a dev. So I will remove this key

because we already entered right and the

empty one as well. And then I will

deploy these changes. Oh so I think we

have duplicate one. So I will just

remove the duplicate. And after removing

this duplicate key because I pasted

uh double time. So that's the reason.

And now if you see the deployment is

about to start. And here we go. Right

now it is building the log installing

all the dependency. You can obviously

check the logs. Then it will uh start

deployment and will assign the domain

for you. If there is any error, any

issue, you can just check this out

inside the deployment logs. Fix that

one. push your changes and it

automatically trigger the versel

deployment for you. So we'll wait to

finish these changes and finish this

deployment

and boom if you see our application is

now deployed without any issue. Now

simply go to the or continue to the

dashboard and here we have the URL. I

will put the URL of this application

demo so that you can test this out. Over

here we have all the things inside the

pricing. Obviously you need to login

first on get started it will ask to

login and then everything will work

properly right and most important this

is completely responsive application so

depends on the screen size it

automatically takes the uh screen size

uh resolution and then design will

automatically get updated.

So guys that's all for this particular

uh project video. Also quick thing

before moving to the uh next video here

um I just move this ARJet export inside

the utils files and open AI inside the

export. So while building it suggested

me to ex uh keep it in different files

right it will not allow sometimes to

export directly from the router AI. So

that's the reason I kept inside this

util files. So make sure to update that

too. So guys that's all for this

particular video. I hope you enjoy this

project. If you have any question, any

doubt, let me know in the comment

section. You can also ask any question

on discord channel with a great

developers community there. And if you

did not subscribe to our channel, please

do subscribe. Uh press notification bell

icon so that you will not miss any

updates and press like button. Share

this video with your friends and family.

So guys, we'll see you in the next

video. Until then, happy coding.

Loading...

Loading video analysis...