Introduction
In today's competitive job market, having an outstanding resume and the skills to ace interviews is crucial. Enter Sensei, an AI-powered career coach designed to take your career to the next level. This powerful tool integrates multiple features to offer personalized guidance and support throughout your job search process. In this article, we will delve into the key features of Sensei, including its AI resume builder, interview preparation tool, and more.
Transform Your Resume with the AI Resume Builder
Sensei includes an AI Resume Builder that automates the process of creating an impressive resume. This tool tailors your resume based on current industry standards and the specific job you're applying for. Some highlights of the AI Resume Builder include:
- ATS Optimization: Generates ATS-friendly content to increase the chances of passing initial screenings.
- Customization Options: Fully customizable templates to reflect your personality and professional style.
- AI-Powered Content Suggestions: Helps you improve your resume descriptions based on the job description and market trends.
How It Works
- User Onboarding: Sign up with your email and select your industry.
- Skill Analysis: Sensei analyzes your skills and compares them to current market demands.
- Resume Generation: You can choose to generate a new resume or upload an existing one for optimization.
- Mock Interview Preparation: Evaluate your interview skills with role-specific questions.
Navigate the Interview Process with Confidence
The Mock Interview Feature of Sensei is designed to prepare you for upcoming interviews. It simulates real interview conditions by asking role-specific questions and analyzing your responses. Key features include:
- Performance Tracking: Records your scores and progress over time.
- Customized Questions: Generates questions specific to your desired job role.
- AI Improvement Tips: Provides personalized advice based on your past performance.
Preparing for an Interview
- Begin with a warm-up session to get comfortable.
- Answer questions honestly and reflect on your strengths and areas for improvement.
- Use the feedback to refine your answers and boost your confidence.
Stay Informed with Industry Insights
With Sensei, you're not just crafting resumes and practicing interviews; you also gain access to invaluable industry insights. The platform provides:
- Market Outlook: Understand how your selected industry is performing and identify in-demand skills.
- Salary Trends: Get detailed breakdowns of salary ranges for specific roles within your field.
- Continuous Updates: This data is updated weekly to reflect the latest market trends.
Intelligent Cover Letter Generation
A standout feature of Sensei is Intelligent Cover Letter Generation. By analyzing job descriptions, the AI-powered tool crafts customized cover letters that enhance your application.
Key Functions
- Job Description Analysis: Automatically identifies key elements and skills from the job post.
- Tailored Content Creation: Generates personalized cover letters that resonate with potential employers.
Beautiful User Interface Built with Next.js
Sensei is designed with a beautiful, responsive interface using Next.js and Shad CN UI to ensure optimal performance and user experience. Key features of the user interface include:
- Modern Landing Page: Captivating scroll animations with calls-to-action buttons.
- Interactive Dashboard: A centralized hub displaying your generated resumes, insights, and interview results.
- Seamless Navigation: Easy-to-use menus enhance user experience, allowing for quick access to all features.
Conclusion
The future of job searching is here with Sensei, your AI-powered career coach. By integrating AI tools for resume building, interview preparation, and market insights, you can confidently navigate the complexities of job applications and excel in your career journey. Embrace the future of job searching today with Sensei!
this is that AI powered project that will take your resume to the next level by building this full stack AI career
coach called Sensei with features like user onboarding to generate interactive dashboard displaying in demand skills
and salary Trends in your industry which is updated weekly an AI Resume Builder that generates ATS optimized content
based on your industry and skills and it is fully customizable as well this awesome mock interview feature with role
specific questions to prepare for your upcoming interviews which also displays your performance over time and gives AI
generated Improvement tips as well an intelligent cover letter generator that analyzes job descriptions and creates
tailored content accordingly along with this fully responsive and beautiful user interface that we will be building using
nextjs and Shad CN UI so right of the bad we have this professional and modern looking landing page with this beautiful
scroll animation which I'll teach you how you can Implement as well if you further scroll down we have the list of
features that our app contains like interview preparation industry insights AI powered career guidance smart resume
creation and much more we have all of the statistics related to our app how our app works and also some testimonials
from our users along with some frequently asked questions right here so we have included all of the important
elements that a modern SAS website contains and a call to action button at the bottom and as I always say a modern
landing page like this can play a huge huge role on if you'll be getting a call back from that HR or that company or not
so so let's click on get started and we are on the login page now we can go on and login with Google or email address
and password so let me just quickly go on and login with Google and there we go we have successfully logged in and it
has presented us with this user onboarding page where we can select our industry so let me select technology and
I'm a software developer years of experience let's say four let's select our skills for example if I select
JavaScript react postgress nodejs we can enter some professional bio and click on complete profile and here we go we are
on industry insights now this is our dashboard page and over here you can see on the top left we have a user drop-
down with options like manage account or sign out if I click on manage account we can see more details about our user we
can update our profile over here like first name last name or email addresses Etc if you go to security you can see
different different places where the user is logged in right so we have all of these production great features
implemented inside of our app let's close this and over here you can see there's another drop down which will
display all of our AI tools we will come back to this very soon but here in the industry insights you can see it shows
us The Market Outlook based on what we have selected on the user onboarding screen how fast our industry is growing
how much is the demand or you know jobs inside of our industry what are the top skills over here and it shows different
different job roles with minimum median and Max salary for each and every one of them right these are all the top job
roles in the industry and if you further scroll down it will tell you the key trends that are going on right now in
the industry and the recommended skills that you can learn learn and all of this data is updated constantly right every
single week you can change it if you want as well and it will be updated in next six days and to implement this
feature we will be setting up a background job a crown job which will be running every single week and not a lot
of tutorial teach you this kind of features and that is what makes this project different now let's go to this
growth tools dropdown and let's select Resume Builder and we are on this form right here right we can select our email
addresses let me just select Anish over here some random mobile number we can enter our LinkedIn URL our Twitter
profile we can enter professional summary along with the skills as well now when it comes to work experience
let's say you're entering something in the description right let's say worked on an Ecommerce website and now you're
St what am I supposed to write further in this right let's say an e-commerce websites selling clothes so you can
click on this improve with AI button and notice it will generate a complete description
ATS friendly description with all of the analytics and everything as well right using Gemini Ai and I will show you
exactly how you're going to go on and Implement a feature like this you know so you can build any type of AI
application we can also enter over here our title our company from which date we started and if it's a current experience
you can click on this else you can select the end it over here as well and you can click on ADD entry button over
here and this will be successfully added and similarly you can add more experience if you want to add education
if you want to add projects it supports links and everything as well right and after you have built this rume
successfully you can go to this markdown tab over here and your complete rume will be rendered right over here so let
me just fill this form completely and let me come back and there we go I have created my complete resume right over
here now obviously you want to download this resume as well right so click on this download PDF button and this will
allow you to download this rume as a PDF let me click on Save and there we go our resume is successfully downloaded
awesome if you want to save this markdown rume in your uh you know database you can click on this save
button over here and if you want to directly edit this resume you know how to edit markdown right so you can click
on edit resume and you can change anything directly over here and then you can click on Show preview and it will be
updated over here and you can click on save button and to manage all of the forms inside of our app we will be using
react hook form along with the Zod validation Library so that you are following all of the latest industry
standard practices as well all right now let's go on to the interview prep page and over here you can see we have the
data related to the users's performance over the time what is their average score how many questions that they have
practiced what is the latest score and if you scroll down you can see all of the latest quizzes that user has
attempted if you click on it you will see the result for that particular quiz as well along with the Improvement tip
as well so let me just go on and start start a new quiz there we go it tells us that this will have 10 questions let's
click on start quiz and it's loading our quiz it has generated 10 questions using Gemini API so let me just go on and
randomly answer these questions for now and you can see we have this show explanation button like if you're not
able to think for any of this question if you on show explanation it will show you and give you the idea of the right
answer so let me just click on next question and randomly select all of these and we are on the last question
let's finish the quiz and we will see the result right over here so you can see I have scored 20% and it's given me
this Improvement tip that I need to focus on solidifying my understanding of core JavaScript concept asynchronous
programming blah blah blah for every single question it will give you the summary of your answer and the correct
answer and along with the explanation of the correct answer so these are the Enterprise grade features that you see
in the big applications right and if you go back to the interview preparation see it showed me my latest performance which
was 20% so the chart died and we will be using recharts for rendering all of these charts inside of our application
and you can see inside of our postgressql database we have all of these data stored like related to our
assignment our resume you can see the complete resume stored in the content in the markdown format the industry
insights for every single user right so that all of this data is persistent now let's check out the AI cover letter
Builder so you can see I have already created two cover letters over here if you click on create new it will ask you
the name of the company enter job title for the job description obviously you can copy it from the job portal and
stuff like that but let's say for now I'm going to say nodejs and mongod DB required right let's click on generate
cover letter and this should generate a proper cover letter that we can provide to that particular company to you know
apply for that job so you can see it has given us this empty columns to fill our name address phone number email and the
complete cover letter over here as well right it has mentioned the back end develop at roadside coder and stuff like
that amazing let's go back to the all cover letters and also I would like to mention this is not a spoon feeding
course I will also give you some assignments to do as well along with this course right because on this
channel We Believe taking action and building projects yourself is what makes you a better developer so before
starting up let me know in the comments down below from where you watching this video and what is the best feature that
you like about this app let's get started all right so open vs code over here and let's quickly open our terminal
and initialize a new nextjs app so I'm going to say npx create next app at latest and I'm going to press enter it's
going to ask us to proceed yes what is your project name now if you name our project anything it will create a new
folder over here but we are already inside of this Sensei folder I'm going to press Dot and press enter would you
like to use typescript no would you like to use es lint yes yes Tailwind CS says yes of course would you like your code
to be inside of SRC no we're going to be using App router right so yep that's exactly the next question yes we're
going to be using App router turbo pack yes comes from nextjs 15 would you like to customize import allias no and there
we go it is going to be initializing a brand new nextjs app inside this folder right here there we go let's go on and
run this so I'm going to say npm run Dev and it has started a brand new server let's
click on over here there we go our nextjs app is running now where can we find this code so if I go back and if I
go inside this app folder right here we have two files one is layout. JS which basically contains the code that wraps
all of our app so if you see over here we have HTML body and then the children and this children is this page.js file
inside of this you can find the complete code that we just saw so let's remove everything inside this return right here
and I'm going to have a Dev over here which will say subscribe to Road Site coder which you should if you haven't
yet so yep you can see this is what is being rendered over here all right now next what I'll do I'll go on and install
shat CN UI so just quickly go to Google and search Shad cnii there we go and shat CN UI is not a component Library
this is basically a beautifully designed components that you can copy and paste inside of your app so this is basically
pre-built components that are built on top of Tailwind CSS that we can fully customize right right the ones that you
can see right here so let's see how we can install it if I click on docs over here and click on installation and by
the way this library is super popular noways click on nextjs and let's go and use npm so I'm going to copy it up and
I'm going to go back to my terminal let's open a new terminal over here and paste it right here so npx Shad C in at
latest in it and it's going to ask us few question base color Yes keep it neutral CSS variables yes and it's going
to ask us this question how would you like to proceed it's because we are using react 19 right and some libraries
are not yet fully compatible with react 19 so we have to choose this use Legacy pair depths option so that it works fine
with our application all right now next let's go and install some component over here so over here you can see they've
given the example of button so if you go to a button right here yep you can see we have different different types of
components over here right so for this button to install it we simply have to run npx shat CN at latest add button so
let's just copy and paste it right here and I'll show you how Shad scen UI helps us so basically it will create a
components folder inside of our app but before that we have to choose Legacy Pier depths again so you can see it has
created this components folder over here and it has created this UI folder which is reserved for the Shaden UI components
and it has created this button component over here and you can see This is highly scalable component with uh you know
multiple different variants and sizes of the but so we can better see it over here so if you scroll down this you can
see this is a primary button secondary color destructive color outline variant Etc right similarly we have ghost and
multiple different sizes for this button over here as well and if you want you can customize this here and you'll be
good to go so you see how easy it makes our job so if I you know let's just add a br tag to add a line break and I'm
going to add a button from Shad CN UI make sure to import it from this/ UI folder only and I'm going to say hello
and let's save it and let's go back and check yep you can see we can see this Hello message right here now as you can
already see inside of our app we are using this button in multiple places we are using this card component this is
also from Shard CN UI we are using um let's say this accordion component which is also from shat CNU right so we're
going to be using bunch of different things inside of our app bunch of different components from shat CN so
what I'll do let's just go on and install them one by one so you can see accordion right here we just simply have
to copy this lineup and go back to our terminal and paste it right here the other things that we will be needing is
a badge component button we have already installed we're going to be needing a alert dialogue for you know asking user
confirmation or cancelling some action right we have to use the card component a dialogue component for displaying
models like in our case we were displaying result after the quiz is finished right a drop down menu input
comp component from chat CN UI label for those inputs or you know some other places as well progress for showing our
progress in the dashboard we would be needing a radio group component a select component a sonor component for all of
the toasts that you saw on the bottom left side of the screen the tabs component and at last text area right so
press enter and this will successfully install all of these components right here inside this UI folder oops
something went wrong I believe I misspelled something oh I think it was the radio group so it has to be g r o u
and we will also be fixing this text area right here and yeah I think uh that should do it let's press enter would you
like to proceed use Legacy paer deps all right so you can see it's installing all of these dependencies right inside this
UI folder and it's asking us the button already exists let's let's override it and and yep there we go we can see all
of our components right here and we don't need to touch this unless we need to customize it and we don't need to
customize it right now right cool then now out of the box shaten also provides us with the light and dark mode and as
you can see our app is in complete dark mode right so let's implement the dark mode as well so you can click on over
here in this dark mode and click on nextjs and it's pretty simple you don't need to understand what's going on over
here so just install this next themes over here so I'll just copy it up and paste it right here and it's going to
provide us this code which will be used for you know handling our themes so just copy it up and inside of components we
have to create a component called theme provider. TSX so I'll say theme-
provider. TSX and in our case since we're using jsx we have to say jsx right so paste it right here and let's get rid
of these types we won't be needing them Yep this looks good and after this we just have to wrap whole of our app using
this theme provider object right here or sorry theme provider component right here right so I'll just copy it up and
go to our layout. JS file as I already told you this layout. JS file is responsible for wrapping h of our app so
instead of this children I'm going to put this theme provider right here and let's import the theme Provider from
this/ component / theme provider and I'll put the default theme as dark and yeah that that is all we need to do to
set up shat CN UI great let's work more on this layout page over here so inside of this let's plan what all the things
that will be inside of our app so we will have a header component okay then we will have a main component which will
contain all of the children components so I'll put children inside of it then below it I'm going to have a footer
component right let's just create this footer right away and for this main tag I'm going to give the class name of
minimum IM um height to be screen and this footer let's just have a footer component over here inside this I'm
going to have a d inside that I'm going to have a paragraph tag which will say made with love by roadside coder let's
go back and see yep we can see it right here and you can see our app is now in the dark mode as well great let's give
it some styling so if you have not work with Tailwind CSS is pretty similar to bootstrap you just have to say class
name over here and you can start giving the class name which are inbuilt in typescript and you can refer to
typescripts documentation and I will also show you how you can use it right here so like for example if we have to
add a background color of muted and by the way these colors are predefined in shat cnii so if you go to this global.
CSS you can see we have different different types of colors that are defined over here for muted it's this
muted foreground you can you know check more about these in the shats and UI documentation about what these colors
are exactly so I'll say background muted and SL I'll provide the 50 opacity I'll say padding vertical so py and if you
hover on these Styles you're going to see we have padding top and padding bottom to be 48 pixels you can see the
exact values right similarly for our da as well I'm going to provide the class name of container now what is a
container class so basically container provides us with some break points like for example in the smaller screens we
have Max width of 640 pixels in the you know medium screens or screens less than 768 pixels we have Max withd this and
different different things right so this helps make our websites more responsive so I'll say MX Auto so that we can
display it at the very middle some padding horizontal of four text is going to be in the center and text Gray is
going to be 200 let's see Yep this is exactly what we wanted amazing for our header right here let's just quickly
create a header component as well so I'm going to create a new file called header. jsx R A fce and I'll say
header over here let's import our header over here make sure to import it from slash
components let's see yep we can see the header over here as well now before moving forward before doing anything
else let's start working on our user authentication so click the link in the description down below and you will land
on Clerk and this is the most comprehensive user manager platform as you have already seen in my previous
videos I love to use cler because it provides us user authentication and user management right out of the box so let's
click on start building for free and let's go on and log in with Google and you will see a similar interface now
here we can add the name of our application so let's say Sensei we can choose what are all the authentication
types that we are going to be adding inside of our app like for example we can add email password we can add Google
login as well or like username phone number bunch of different things right and I'll show you how easy it is to
implement inside of our application so let's just choose both email and Google and click on create application and we
are in amazing and you can see it tells us exactly how we can go on and add clerk inside of our application so I've
chosen nextjs over here so all we need to do npm install at clerk / nextjs okay I'll copy it up and go back to my
terminal and paste it right here now what's next we are supposed to set up our environment variable so that
app can connect to clerk so okay let's copy it up and instead of our app I'm going to be creating a new EnV file this
will contain all of our secret environment variables and which we are not supposed to share with the world
right and obviously if you try to use my environment variable they won't work because I would have deleted them after
the video okay after that we have to create this middleware DJs file now what is this file all about so this file runs
before our application is run right so before our application starts we need to figure out some things like for example
in this case user authentication so you can see it is going to initialize the clerk before our application is accessed
so I'll copy it up and I'm going to create a new file middleware do JS and paste it right here
just like this then next we are supposed to wrap our app inside this clerk provider function okay let's see so if
we go to our layout. JS this whole thing this whole app is supposed to be wrapped in clerk Prov provider so let me just
move it to the very bottom and let's import clerk Provider from at clerk SL nextjs like this and also by the way we
don't need both of these fonts right here so I'm going to remove them and we would be needing the font
enter and let's just add this font right here so simply you have to do const enter equals we have to import enter
from next SL font / Google subsets Latin so this is basically just for changing the font of our application if you don't
want to keep it that's fine you can use some other font so over here in the body I'm going to remove this let's remove
this class name and over here simply I'm going to say enter do class name this is just a onetime configuration don't worry
about it we're just adding the fonts inside of our app and let's just change the title to AI career coach or you can
also say Sensei AI career coach and you can add your description according to you right all right now let me show you
how easy it is to set up the user authentication using cler so what I'll do over here you can see we have this
example over here so I'm just going to quickly copy it up and I'll go to my header. jsx and inside of it I'm going
to paste it and import all of these things from clerk so clerk / nextjs signed in component user button
component all of them right now you're going to notice if I go back to my app we are getting this warning right here
hydration warning oh so this is actually H this happens because like when we add this theme provider inside of our
application to so you can check the shat scen U documentation as well they have recommended that you can simply add
inside of the HTML this thing suppress hydration warning and you won't see this error so what's going on over here so
basically we're saying that if the user is signed out then show the signin button and if the user is signed in show
the user button let's see you can see we have this signin button over here or sign in text if I click on it what's
going to happen it takes me to a completely separate login page amazing and we didn't even do anything right we
just took that code from Clerk and obviously this is highly customizable as well so if I click on continue with
Google it's going to allow me to sign in and let's see we are in you can see we have this user drop- down button right
out of the box coming from cler right click on manage profile you can see we can update our profile over here as well
update our profile picture like for example if I go back inside this configure tab in clerk you can add some
options over here like for example I want users to be able to change their name as well right so I'll enable this
and now if I go back I'm going to click on update profile and now I'll be able to change my name right here amazing and
you can also go to this security tab to see where you are logged in and you can delete your account as well right so
yeah all of these things comes right of the box from clerk let's go on and properly design our header for our
application so you can see see inside of our deployed app we have this logo right here right Sensei AI so you can get this
logo from my GitHub repository so just click the link in description down below and you will land on this GitHub
repository right here and if you go to public folder over here you can find different different things like for
example this logo that I've kept apart from that I have three different types of banner so that all of you know all of
you building this app don't have same types of banner images inside of your app right so I'm going to go on and
download both of these there we go I've downloaded them and kept it right here in my public folder let's get rid of
these SVG files we won't be needing them so delete all right so right here in the header component let's above it I'm
going to change it to header inside this I'm going to have a nav tag over here which will contain all of the navigation
items of our app like for example first of all I'm going to add a link tag so link tag in nextjs basically helps us to
navigate between different different pages so this link tag takes a h riff just like our anchor tag in HTML right
so this will be let's say slash for our homepage and to add any image inside of nextjs we use this image tag which comes
from next SL image and the reason for this is this optimizes our images in the server right and sends it to our client
so let's say SRC equals SL logo.png let's save this this and see we cannot see anything over here in fact we
have an error over here that missing required width property so yep this takes a width and height property over
here as well and we will also give this the alt tag that is the description of the image so let's just say Sensi logo
and width and height let's just give this some class name of height to be 12 so this is basically the resolution of
the image right and here I'm going to provide the Styles like padding vertical to be one
width is going to be Auto and object to be contained so that it doesn't get deformed let's see now yep that is
exactly what we wanted below this link let's add some action buttons right like for example to be able to navigate to
our dashboard or industry insights or the d drop down menu uh displaying all of our AI tools and you can see so
inside of this div we will display all of those things only if our user is signed in right so I'll say signed in
and insert this I'm going to first display the link tag to our industry insights right so I'll have a link tag
which will have a button which will obviously be coming from Shad Cen UI so make sure to import it from / ui/ button
inside this we can add an icon over here as well along with the text so you don't need to worry about the icons because
Shad CN UI contains Lucid react package which you know contains all of the icons so just say layout
dashboard and you can see we're able to import it from Lucid Das react and let's give this some class name of height to
be four width to be four and below this I'm going to say industry insights let's see how this looks oh of course we need
to give the link tag a HF let's just call it dashboard if you want to call it something else again that is up to you
yep that looks good we need to obviously this a little bit more so what I'll do I'll go to this header right here I'm
going to say class name and our header will be fixed on the top right I'll say top to be zero and width is going to be
full let's give it some border bottom and some background color to the background from shat Cen right as
already told you these things are already defined in the global. CSS file you can go and check it out and I'll
keep the opacity to be 80 I'll say back drop blur to be medium so that if anything comes behind our header it is
you know it has the blurry effect I'll say Z index to be 50 so that this remains on the top and I'm going to say
it supports backdrop filter right and then I'll give it the background of sorry BG to be background color with the
60 opacity let's see how this looks like this looks pretty good and you can see I think whatever behind this I think there
was a button right it went behind this header now and we'll come back to this to fix it right now for this nav button
right here I'm going to give this some class name to be container I've already told you what container does mx Auto
said everything is in the middle padding horizontal to be four height to be 16 and I'm going to give this some display
Flex so that everything is in one single line and items to be Center so that we vertically align it and horizontally I
want justify between so that they are on Far ends of each other let's see yep that is what we wanted now one thing
that I want to do over here is make this website responsive out of the box right so when this becomes smaller we don't
want to show this whole button right here so what I'll do let's just put it into a span tag right here and over here
I'm going to give this class name of hidden by default and when it's more than the medium screens I'll say display
to be block so now you will see if it's less than medium screens yep that is exactly what we want to do great now
after this we're going to be showing a drop- down button which will display all of our growth tools right so after this
let's go back to shat ceni documentation and over here we have to find the drop down menu component and we already
installed it so if I click on it you can see this is how it will look like okay so let's take this code right here I'm
going to copy it up and paste it right here so let's import them one by one and make sure to import it from from /ui
folder and not the radx UI right so sometimes we make this mistake and then it won't work so let's import all of the
separator and yeah I think they would have been imported now oh I think I did not import this drop down menu item now
it would be important yep if I click on open yes we can see the drop down all right let's uh configure it according to
us we would need the three items over here and we won't be needing the separator and the label okay for the
trigger here I'm going to Simply add a button just like we have done right here so I'll just take this button and paste
it over here instead of this layout icon I'm going to add the Stars icon over here and instead of this industry
insights let's just say growth tools and below this let's add an icon for you know indicating the Chevron down key you
know indicating a drop down over here so let's see um yeah that is exactly what we wanted let's create some gap between
both of these so over here in the div we would need to give some class names so I'm going to say display flex and items
to be centered so that they are vertically in between and some space X tob2 so that they have some space
between them and when the screen size is bigger we will add Space X to be 4 yep that is what we wanted all right so now
over here for each and every one of these I'm going to add a link tag which will take us to that particular you know
growth tool like for example Resume Builder cover letter Builder or you know interview preparation page again inside
the link tag I'm going to have two things one uh icon and the name of the growth tool so over here we just going
to get rid of this class name inste of this Stars icon I'm going to say file text icon so import it from Lucid react
and I'll say build resume let's see if I click on it oh yeah of course this again needs the HF tag which will be slash
resume and I'll give this the class name of display Flex items to be Center and some gap of two between them so now we
should see this if I click on it yep build resume similarly I'm going to do for both of these as well so let's just
copy it up and paste it right over here and then we will change it for the cover letter I'm going to add a pen box icon
and for the interview prep page we're going to add a graduation cap icon so let's just import both of these and now
let's see yep that is exactly what we want let's change the link so for this one I'll say AI cover letter and for
this I'll just simply send it to the interview page okay now after this we need to display our you know login
button and user button so let's move this back inside of over here inside this div and when the user is signed out
we don't want to show this sign in button instead this will have some children inside of it where we will
render the button from Shad cnii so I'll say sign in also by the way we want to differentiate between both of these
variant right so for my dashboard or the this uh industry insights let's just say variant to be outline and let's go back
and Y that looks much better and for this thing right here okay sign in button I want this to have the variant
of outline as well so if I go now and try to log out let's click on sign out over here you can see just the sign in
over here and growth tool wise it's showing up over here I think we need to move it inside of this signed in so just
take this signed in from over here and put it right here now it should not show up just the signin button okay now for
our user button over here if we quickly go on and sign in again there we go you can see it is very small right the
circle is very small so we can customize it actually over here in the user button we have a appearance prop inside of this
let's just say elements we can choose the element and we need to choose the Avatar box which will be width to be 10
and and height to be 10 user button pop card is going to be Shadow Xcel and user preview main identifier is going to be
font semi bold so you will see this will have some Shadow and some font to be semi bold okay and we can also Define
when we click on sign out where this page goes right so for now I'm going to keep it slash only if you want to keep
it something else I've kept it right here looks like this is deprecated but don't worry it will still continue to
work all right now let's try to uh click on this industry insight we're going to click on it and this will take us to
the/ dashboard page and again this page does not exist but still we are logged in right now right if we log out you're
going to see it took us to the slash page right that's fine but now if I try to go to slash dashboard page it should
not allow me to land over here because we are not logged in right now right even though this page does not exist it
should us it should route us to our home page right or maybe our signin page where we can sign in so let's add this
protection to our app so I'll go to the middle .js file and over here on the top I'm going to say cons is protected route
and we can add the different routes that we want to add over here so we'll import create route matcher inside this we will
give an array and we can Define all of our routes right over here so our routes will be dashboard resume interview AI
cover letter on boarding right all of these and I've added dot asteris over here that means anything that comes
after it will also be a private route okay now after it inside this export default
clerk middleware we're going to be adding a call back and this will be an asynchronous call back which will take
the Au and the request object and we will work with these to you know add the production to our app first of all I'm
going to say await o and this will give us our logged in user's ID so const user ID then after it right that is user is
not logged in right now and is protected route that is this thing right here we're going to pass the current route so
I'll pass this request object if request object does not contain any of these then we will route them back to the Lo
login page right so I'll say await or and this will give us something which will be redirect to sign in and we can
simply take this and in the next line I'm going to say return redirect to sign n that's it we're going to call this
function and this this will continue to work this will reroute us back to the signin page and then in the end I'm
going to say return next response. next that is whatever comes next we can continue our app after this and make
sure to import it from next SLS server okay now let's try to do this again if I try to go to/ dashboard you can see it
sent us back to this signin page but wait you might be thinking what is this URL over here this is a weird sign-in
page right I want the sign-in page to be inside of my application and and not go to some third party URL right and that
is exactly what we will be implementing next But first you can see our app is in dark mode right and this is light mode I
want this to be in dark mode as well so what I'll do I'll go to my layout. Js and in the clerk provider I'm going to
say appearance and inide of this it takes a base theme and this will basically be dark so I think we need to
import it or probably install it from uh some package let me me just check inside of the clerk Yep this is what we want
npm install at clerk SL themes you can find it in the docs right so I'm going to paste it right here and P install at
cl/ themes and this will install it and from here we can you know get a lot of themes like for example you can see we
have different different types of themes right here and this is what I need all right so this has finished installing
let's try to import it yep from at clerk / themes and now if I go back to my app looks like it won't work on this page
but it will work on the component when we go on to add this signin component inside of our app right so okay let's
try to do that and how are we going to do that we have to define the custom uh you know signin page for our application
and to do that we have to go to the EnV file and we have to add four environment variables over here actually two
environment variables other two are going to be for something else so first one will be next public clerk signin URL
this will Define the signin URL for our app and the second one will be sign up URL sign up right now what will happen
when the user signs in or signs up so I'll say next public clerk after signning URL to be SL onboarding and
after signup URL to be/ onboarding as well all right now you're going to notice if I go back to my local host
3000 I'm not dashboard I mean just the Local Host 3,000 if I click on sign button this will take me to/ signin but
this page does not exist so what should we do inside of our app now we going to be creating a brand new route right and
don't worry I'll show you very soon the in-depth ways to create you know routes inside of our next CH but for now just
try to understand what I'm trying to do over here if I want to create a new route I have to create a new folder
that's all if I let's say sign Dash in this is now a new route inside of our application like if I say new file page.
jsx and this very important you have to create a file called page. jsx for it to be recognized as a route so I'll say
page and um let's say sign in right let's see if I refresh this now I think this is in like behind our header right
now if I just remove my header from over here let's get rid of this header y you can see the sign in is behind this
header let's take care of this as well we don't want things to be uh you know overlapping our header so what I'll do
over here I'll create a sign up folder over here as well sign Dash up and I want to provide some common styles to
both both of these so what will I do I want to grip them somehow right and to grip them I'm going to create a new
folder called o but this won't work right this will create a new uh route and I don't want to Nest another route
like / signin so what I'll do I'll wrap it inside of parenthesis and this will essentially ignore this folder as a
route right so if I move both of them inside of it move now this won't be considered as a route right here and I
can provide it a layout. Js file and whatever we write inside of this file will directly affect
both of these right so I'll say R A fce let's say o layout and I'll take the children over here and I'll render them
right here so this sign in and sign up will render right over here and I can Pro now provide some common Styles like
for example I'll say class name display Flex justify to be Center and padding top to be 40 let's check it out if I go
back and ref refes this yep you can see sign in right over here now instead of this sign in I'm going to display the
clerk's signin component right so if you go to the clerk's documentation you will find that there's a convention on
creating these signin pages right what you have to do you have to create this signin route first then inside of this
you have to create a new folder which will contain a catch all route and we will discuss what this catch all route
is basically you have to write two square brackets inside of it dot dot dot sign Dash in and this is basically an
optional route if you have anything over here it will catch it like for example if you go back you can see we have all
of these options over here right so these are for clerk to be managed so that's why you have to create this scat
all route over here and let's move this page. jsx inside of it move now inside this page. jsx simply all we have to do
is to import a sign in component from clerk that is all let's get of this import Port react and now let's see yep
you can see such a beautiful sign in form right here and this is right inside of our application if I go back and try
to click on sign in yep you can see we are landing on the signin page great let's do the same with our sign up page
as well so inside of the sign up page I'm going to get a new folder and I'll add a catch all route for sign Dash up
inside of this I'm going to add this page. j6 file so I'll create a new file page. jsx paste it instead of sign in
I'm going to say sign up right let's remove this sign in over here and let's see if I click on sign up it should take
me to sign up page all right we can you know fill up this form and create a new user all right great so we have
successfully set up our user authentication and now let's go on and connect our back end or you know set up
our database basically so click the link in description down below and you will land on neon and this is a postgress SQL
database and you already know how important it is to be knowledgeable working with a post SQL database right
so I'll tell you everything about how you can get your database set up and also use it alongside with Prisma orm
which again is a super trending technology nowadays right so click on get started and let's log in with Google
and we are in now we're going to create our project so let's name our projects and say database name we can just keep
it empty and click on create project there we go we are in let's go on and set up our database so all we need to do
we need to go to this overview tab over here and this roles and databases and click on ADD roll let's add rule of
roadside coder that I'll be the one managing this database create and then below it we need to add our database
right if you want you can copy this password over here as well let's click on ADD database and let's name the
database Sensei and the owner will be roadside coder let's click on Create and yeah
with that we have created our database successfully let's go to our dashboard over here let's choose the database and
the owner and we can simply copy this connection string from over here right and then go back to your app and inside
of EnV file I'm going to create a datab basore URL equals and I'll assign it right over here so basically this
connection string will enable us to connect our project and to communicate with neon DB using something called as
Prisma omm which I'll show you in just a moment but let's set go on and set up the service which we will be using for
managing our background jobs like you know fetching the industry insights every single week so click the link in
description down below and you will land on inest and click on sign in over here quickly I'm going to sign it with Google
and there we go we are in let's click on take me to onboarding and you can see over here they've given us this command
so just copy it up and go back to your terminal just run npm install injust first so that it installs the injust
inside of our application and then we can run npx in/ CLI at latest Dev proceed yes there we go it has
successfully ran inest on our local machine and click on this Local Host link right here and there we go our
inest server is running in our Local Host okay so let me just open the injust docs over here real quick so we have
already ran this Command right here and we can see our injust running now we have to create an inist client and to do
that we have to do new inist and provide the ID of our app okay so what I'll do I'll go back and insert this lib folder
over here I'm going to be creating a new file and actually new folder for inist and I'm going to be creating a new
file called client do JS andert this I'm going to Simply paste this code so I'll just copy it and paste it right here
right let's name our app Sensei and this will also take the name so I'll just say Sensei just like that and this will take
more things like for example later on we will go on and configure our credentials for the Gemini API key right so yeah we
will come back to this later let's go to the docs and see what else so now we have to set up this/ API SL inest route
inside of our application now how does inest actually works so in nextjs we have something called as this API folder
right and inide this we can as the name suggest build our apis right it can be public API can be private API so we have
to build a public API for inest to connect to our application right so you can see we just have to say/ API SL
inest so I'm going to say new folder inist and so that this AP works we have to create a route inside of it route
file so I create new file route. JS inside this route. JS file we have to add this code right here so just copy it
and paste it right over here and also we're going to remove this because our inest client will be coming from at lib
slin client so what is going on over here so we have created this API with get post and put requests and this serf
function which also comes from inest / nextt and now over here we can Define our functions which will be running in
the background let me show you how you can quickly go on and create the function so over here they've given this
example in the code of a simple hello world function right let me just copy it and explain you how this works so um
let's say I'll go insert this inest folder and create a new uh like file called functions do JS and paste it
right here now this function takes an ID of hello world and the event of test/ hello. world now this event right here
is something which will trigger this particular function over here right so this is very important over here this
first object takes more things like for example if you want to add the retries that is how many times this function
will retry before it fails in the background it also takes things like rate limiting throttling ability to bash
the events debouncing and much much more right so you can find all of these things in the official NES documentation
and learn more about it okay so now what we are doing inside of it we're simply saying that make this function wait for
1 second and then we will return a message called event. data. email which will be provided by us right so this
takes the event and the step so injust functions are executed in different different steps over here right and over
here we just have added a step of sleep so now if I just take this and where did it go I'll go back to my route. ts and I
can import this right here right so import hello world from in just SL functions and now if I go back to over
here in in my development server inside the app you can see it has all autod detected it inside of the functions we
can see this hello world function and we can manually invoke it from over here right obviously inside of our app we
won't be manually invoking it and you can see it's asking us for some data if we want to provide let's say email and
and let's say example at gmail.com click on invoke function it will wait for 1 second and yeah you can
see it has already completed the function and provided us this message hello whatever the email was and you can
see we have this wait a minute step run over here right we can see the data that we have sent to inest yep right here
email so this is a very basic example of an injust function again we will be coming back to this and build our
industry insights function which will be fetched every single week right so let me just um get rid of this for now and
we will come back to this very soon and if you're someone who's preparing for frontend interviews you can definitely
go and check out my front-end interview preparation course this is the only thing that you will ever need to prepare
for your fronted interviews and not only this I've covered every single topic of reactjs like react router D Redux all of
the hooks class based component function based component react even the performance optimization
which is asked from senior developers a lot tons of machine coding questions as well and obviously in-depth interview
preparation course on JavaScript as well and not just this along with this course you get an active Discord Community
where you can ask your doubts whenever you get stuck and we will be there to help you so click the link in
description down below because right now we're having the biggest sale of the year for a very limited time so don't
forget to check it out or you can also scan this QR code on your screen to go directly to the the course page and now
let's go on and build our beautiful landing page right here as I've already told you having a beautiful landing page
like this plays a huge role on if you'll be getting that call back from your recruiter or not right and you can see
this looks super professional with all of this you know grid background and everything with all of the FAQs provided
over here as well so cool then let's get started we have already imported this banner. jpeg from my GitHub repository
which we will be needing while building our app right all right so I've opened my page.js file over here let's remove
everything inside of it and let's see what are all the things that we will be adding inside of it so first of all
obviously we have a hero section this hero section right here then we will have the feature section the statistics
how it works what our users say and obviously frequently asked questions okay so let's first add this background
that you can see over here right this grid background to our app so I'll go to my Global start CSS file and right on
the bottom I'm going to create a class name called grid Das background inside this I'm going to add a position fixed
top to be zero left to be zero width and height to be 100% for our page right because this is going to be fixed and
we'll be inside whole of our app okay so to create those lines I'm going to be adding this background property over
here of linear gradient so basically what we will be doing we will be creating a line of one pixel with the
opacity of of 10% or 0.1% right and it will go from left to right similarly we will create another
line or linear gradient which will go from top to bottom right and we will do it with the gap of 50 pixels right so
I'll say background size to be 50 pixel and 50 pixels I'll say pointer events To None because we don't want to select it
and Z index to be minus one so let's take this grid background and go back to this page. jsx I'll add a div over here
let's actually rename this file to page. jsx and give this the class name of grid background and let's see yep that is
exactly what we wanted let's add a radial gradient over here right if you notice this is fading on the sides but
it's visible in the middle so I'll go back to global. CSS and below this I'm going to say dot grid background and
I'll add before sudo element and inside of it let me just quickly get the Styles and I'll explain you so content is
nothing we don't want to display anything the position is going to be absolute for this gradient top zero left
Z width 100 and height 100% right that's like covering the whole page but we're saying add a radial gradient property of
circle and transparent and it will be 9% opacity right so now you will see yep just like this this is exactly what we
wanted and you know don't stress much about this in real world you will most probably be searching in chat jpt or
Google to find a property like this right you won't be having to create this from scratch anytime soon all right so
coming back to this page. jsx we will first be having the hero section so right below it I'll have a hero section
component now one thing that you need to understand in nextjs is there are two types of components a server component
and a client component like for example this page this does not have any flag on the top so this is a server component if
I were to make this a client component I would have to add use client now what is the difference between both of these so
client component can have logic like hooks right and which which cannot work on our server right which cannot work on
our back end so that's why we have to make them work in our front end right that's why they are client component and
the server component are basically those component which generally are rendered on a server and contains the information
which is crucial for probably the SEO let's create this hero section component um over here so I'll get a new file
called hero. jsx or afce hero section okay let's import it right here just like this now uh over
here let's just wrap it in a section tag and start this I'm going to have a Dev which will contain another Dev which
will have our H1 and we will simply say your AI career coach for professional success and this section right here will
have class name of width full some padding top of 36 right we can see this and in Media medium screens like screens
more than medium screens we're going to have padding top 48 and padding bottom to be 10 let's see Yep this is what you
wanted below this H1 we are also going to be having a paragraph tag which will say Advance your career with
personalized guidance interview prep and AI power tools for job success now below this div over here we will display the
two buttons for getting started and watching the demo of this so I'll have a d which will contain a link tag which
will contain a but Buton from shat cnii which will say get and the link will have the hrf of/ dashboard when we click
on get started okay for this button let's just provide the size of large and class name of padding horizontal to be8
Let's duplicate this link just like this and if you have any demo video you can add the link to it over here I'm going
to Simply add the link to my YouTube channel is that because that's is the place where this tutorial exists and
this button will have the variant of outline that's all let's see link is not defined okay let's import link from next
SL link and there we go we can see it now below it we will add that Banner image that we copied from GitHub right
so below this div right here I'm going to have another div which will contain another div which will contain the image
and the reason why I'm creating two divs over here is because we will be adding the logic to this uh image right here so
if you notice when we scroll down see it tilts forward right so so this is the logic that we would be needing to add
and I'll show you how you can add that as well right so but first of all inside this image I'll say SRC let me see if I
have imported image from next / image yep so SRC will be/ banner. jpeg I'll provide it the resolution of 1280 to 720
and the all tag of dashboard preview oh you know instead of that let's just say Banner Sensei below it I'm going to have
the class name of rounded large Shadow tob2 XL and some border with margin horizontal to be Auto and let's just add
the priority tag so that it loads first right yeah like this all right now that we have created the basic structure of
our app let's just add some stylings over here first of all this div which contains both of these things we will
add some gap between them so I'll say space y to be six and text to be Center and for this particular div I'm going to
say space y to be six and margin horizontal to be Auto let's see yep that is what we want now for this particular
title we will be adding some uh gradients and all if you notice just like this and we will be using this
gradient throughout our application so we want to create a custom Tailwind style for this so what I'll do I'll go
to global. CSS I'll say add layer utilities and inside this let's first create a gradient class so I'll say
gradient inside this I'm going to say add apply and I'm going to apply a background gradient so I say BG gradient
which goes from from top to bottom right so I'll say gradient to bottom and we can assign either two colors or three
colors so I'm going to say from Gray 400 via gray 200 to gray 600 if you want you can remove this from the middle over
here as well but I want three different colors over here right now similarly we can reuse this class over here so I'll
create a gradient title class over here or style over here and I'll use the whatevers that we have added over here
gradient font extra bolt tracking tighter text transparent background clip to we text you know so that we can show
this background and clip it inside of our text just for our text some padding bottom and some padding right right so
we're just going to take this gradient title and provide it to this H1 so I'll say class name to be gradient title and
now you will notice which I don't think you can notice because we need to provide some uh size over here as well
so let me just add it so over here alongside it I'm going to add text 5xl font to be bold in the bigger screen
text is going to be 6 XL in smaller screen it's 5 XL and in the larger screens it's going to be 7 XL and in the
extra large screen it will be 8 XEL so right we will we can customize every single aspect of our app using Tailwind
CSS breakpoints right and of course gradient title so now if I go back Yep this looks good for our paragraph tag
right here let's come to over here and I'm going to say margin horizontal to Auto and Max width is going to be 600
pixels so that we can break it down into two lines text muted to foreground so that it's a
little bit lighter and in the larger screens I'll say text Excel okay that looks much better all right now for both
of these buttons right here let's provide some gap between them so I'll say for this D I'll say display Flex
justify Center and Space X to be four like that now for our image over here we need to add that logic off so that you
know this image is tilted and when we scroll down it's going to come forward and tilt to the normal size so for this
div I'm going to be providing a custom class called hero image wrapper some margin top of five in the smaller
screens and in the medium screens it will be margin top of zero yeah we will be getting a reference to this div right
here so that we can provide that logic so for that we will be using a use ref hook so I'll say use ref and import it
from react and I'll show you what use ref exactly does and we will take image ref over here and now you will notice
this will give us error because we are using hooks over here right so it will tell us to use this use client directive
so yep let's just add it on the top I'll add use CL and this will continue to work just like this okay so now what
will we do with this image refi we will take this and say ref equals image refi now through this image refi variable
right here we will get the access to this div's HTML right we can manipulate and we can do whatever we want and by
the way by default we can keep it as null over here and also let's give this the class name of hero image now what
will we do we will first of all take the use effect hook over here right simple use effect hook which will run when our
component is loaded we need two things over here first of all the scroll position where we are currently in our
uh you know window and the scroll threshold that is after this has been cross we want to tilt it back right tilt
the image back so first of all to tilt the image back we first have to tilt it right so we have already added these two
classes hero image rapper and hero image so let's go to our global. CSS and add this so over here I'm going to add hero-
image- wrapper and here I'm going to add a perspective class with 1,000 pixels so now you will see nothing will happen
because we have added just perspective property over here but we have to rotate it now so now I'll say do hero- image
transform rotate X by 15° and scale is going to be 1 now let's see yeah you can see now it has been rotated but if we
were not to add this perspective style notice what will happen see it wouldn't work right so we have to add this
perspectives for this transform to work and when we transform when we perform the transform I want the transition of
0.5 seconds right so that it eases out with the transform and we also need to tell Will Change to be transform
right so this provides a rendering hint to the user agent stating what kind of changes the author expect to be
performed on an element right so we just adding transform animation that's why we have added it over here now when we want
to put it back to normal we are going to trigger another class light over here so I'm going to say dot scrolled scrolled
right so this will simply have this transform actually so I'll just duplicate it and I'll put it right here
but instead of 15° it will be 0° scale to be 1 and Translate Y to be 40 pixels I want to
shift it a little bit right that's all we need to do we just have to add this scrolled class now programmatically so
now in the use effect hook I'm going to say this I'll say if scroll position is more than the threshold position right
we have crossed this 100 pixels of threshold then first of all I'll get reference to this image ref over here so
I'll say on the top over here image element equals image ref do current now we have the access to it so
I'll take this image element I'll say image element do class list and I'll add the class of scrolled and um yeah we
need to wrap all of this code inside of a function so I'll say handle scroll so that we can you know check the scroll
position so I'll add a app Arrow function over here wrap this whole thing inside of it and then after this I'll
say window. add event listener and I'll add the scroll event inside of it which will trigger the handle scroll so now if
I check if I scroll down yep you can see it comes back to normal amazing and also we need to remove the event right when
the component is unmounted so I'll say return window. remove event listener scroll handle scroll and even though it
is working but let's just add the else condition over here as well else I'm going to say remove the scroll if the
threshold is not less than that right so let's see yep amazing this is working flawlessly great so now that we have
created our hero section let's move forward to this feature section over here so I'll go back to my page. jsx and
below this hero section I'm going to have another section right here for the features so I'll add a d and a h two tag
which will say powerful features for your career growth okay now to render all of these features right here we
would need all of this data right and all of this data over here as well so if you want you can create your own data or
what you can do I have added this data inside of my GitHub repo so inside of this data folder over here you can find
these four files FAQ features Industries and testimonials make sure to download all these four files right so let me
just do that real quick all right I have downloaded Ed them and put them inside of this data folder right here right
don't worry about it right now we're going to be using one by one so first of all we would be needing this features
and simply what we're doing over here is we have the icon title and description these three are what we will be
rendering over here right and we will be mapping through this features array so I'll go to page. jsx and after this H2
I'm going to have another div which will render my features so features. map and we will take each and every feature and
the index and inside of this we will render all of these features inside of a shat CN UI card so how do we create a
card in shat CN UI let's see I'm back in this documentation and over here in the card Yep this is what we want so let's
just copy this code right here and I'm going to say return and paste it over here okay we won't be needing this card
header so let me just get rid of it and import this card card content and card footer as well I don't think we will be
needing it this is all we need first of all insert this card content I'm going to have a Dev right here which will
render the feature do icon and I'm also going to be having a H3 tag which will render the feature do title and then a
paragraph tag which will render the feature. description let's save this and see if we can see anything over here
features is not defined okay we need to import it just like this from data folder and if you scroll down yep that
is what we want let's just go on and style it first of all for this parent uh section right here I'm going to say
class name to be width full padding vertical to be 12 in the bigger screens padding vertical is going to be 24 and
in the larger screens it's going to be 32 and background is going to be this BG background color from shat C and UI
right so let's see yep we have some gap between them and yeah it gives us this error each child in a list should have a
unique key prop so that is what we have to add over here in the card I'll say key to be index okay now for this div
right here I'm going to say class name to be container margin horizontal to be Auto some padding horizontal to be four
and in the bigger screens it will be PX to be six for this H2 I'm going to say text to be 3 Exel font is going to be
bold and tracking tighter so that the you know words a little bit closer to each other text is going to be Center
and margin bottom to be 12 so yep that is what we can see over here and now for this D we will be giving a display grid
right here right so I'll say class name to be display grid in the smaller screen The Columns will be one medium screen
columns will be two and larger screens columns will be four we can see all of them right so Gap is going to be six
between them and Max width is going to be six XEL and they will be in the middle so I'll add margin horizontal to
be Auto just like this let's just add some styling to each and every card so for this card right here I'm going to
say border to be2 when we hover on it border is going to be primary color that is we can see the you know border around
them transition color so that when we hover on it we can see the colors transition and 300 millisecond is going
to be the duration so if I H on it yep just like this now for each and every card content over here I'm going to be
saying padding top to be six some text Center display flex and flex to be colum so that they are on top to bottom over
here and items to be Center horizontally for this internal div I'm going to be saying display Flex Flex to be column
items to be Center and justify to be Center so that you can see everything is in the very middle now for each and
every one of them first of all for the H3 tag I'm going to be saying the class name is going to be text Excel and font
bold and margin bottom to two so there's some gap between these and I'll make this paragraph a little bit muted color
so I'll say text muted foreground so like this now we can clearly see them right here all right now after it we
want this feature right here this Statistics feature right so let's build that section so over here below this
section you know what let me just copy this section up from over here and paste it right here and let me remove these
features from here let's also get rid of this H2 right here instead of back BG background I'm going to say PG muted
oops muted to be 50 opacity padding vertical to be 32 let's just remove this in the
larger screens I think this should be enough and over here inside this D we can add four different stats now when I
was building this app I had written the HTML for it and I forgot to create the separate data for it so let me just
bring this in it would look something like this so for each and every D we're going to have the stat and the subtitle
for it right like 50 plus Industries covered we're adding display flex and flex column so that these are on top to
bottom item Center and justify Center so that they are on the middle and space y to be two so that we have some gap
between them right and simply for 50 plus we will have text 4XL and font bold and this one will be muted and similarly
we will have three more stats over here which again if you want you can create your own or you can copy just like I
have written like 1,000 plus interview questions 95% success rate 24/7 AI support right so let's see if we scroll
down yep that is what we want right so after this section uh you know what one thing but while creating a landing page
I would say the development is the easier part the main thing is to understand how you can create the design
right and what are all the elements that you can separate separate elements that you can create to build an app like this
so you can use there there are variety of websites available like behance and dribble which we can go and take the
inspiration of design from right just don't copy it take take some inspiration and add something on your own as well so
below this section let's just again so this is going to be pretty similar to this feature section right so I'm going
to take this section and uh copy it right here and on the top instead of this we can write how it works and we
can also add a paragraph tag over here which will say four simple steps to accelerate your career growth and you
know what let's just wrap this whole thing inside of a d so that this is separate from the below section
and let's remove all of this and I'm going to say margin bottom to be four and for this div over here I'm going to
say text to be Center Max width to be 3XL and some margin horizontal to be Auto and margin bottom to be 12 so let's
see if I go down yep we can see this we just need to change this thing right here and let's remove everything inside
of over here in this features. map instead of this I'll take the how it works and make sure to import it that we
copied inside this data folder over here right how it works. JS I'll take each and every item and the index so I'll
take each div over here and actually since there are I think how many items are there so there are four I think we
don't need to change this grid over here so inside this div I'm going to Simply render my item do icon and let's see how
it looks if we scroll down okay we need to add a key prop as well so key to be index and for this div let's just add
add a class name of width 16 height 16 rounded to be full background color is going to be primary with 10% opacity
flex and items to be Center justify Center and now if you see yep we can see it right here but we cannot see the icon
over here so what did I do wrong it should be icon with the capital I no I think it should be small I over here
that's better now if I see yep we can see the icons let's get this Dev some class name of display Flex Flex to be
columns items to be Center text to be Center and space y to be four so that these are in the middle yeah that looks
good now below this D I'm going to have the H3 and the paragraph tag as well which will contain item. title and item
do description which will be a sem font semibold and text to be Excel and again paragraph is going to be muted just like
what we've been doing up until this point right just like this great after this what do we have we have what our
users say right again this will be very similar to what we how we have been creating this featured section right so
I'll just copy this feature section over here again and go down after this section and I'll paste it right here
right first of all over here I'm going to Simply say what are users say and instead of this features I'm going to be
mapping my testimonial right so I'll say testimonial I'll take one single testimonial over here for this card
simply I'll say background is going to be this background color that we have defined like that shat scene UI has
defined now inste of this card content let me just remove everything and write it from scratch but first of all let's
see if we can see anything over here yep what our user say with three cards of our testimonial let's just first give
this card content just the class name of padding top to be6 now inside of this card component over here I'm going to
have a d and let's plan how we're going to be building this so if you see over here we have this Dev first and then we
have this Dev for containing this uh block code right so inside this div I'm going to have first div for that one and
then we will have a block code for our code right and then inside this div we're going to have two things first the
image and then the information about the user right so I'll have a div for the image and then another div for the info
about the user so first of all for the image so I'll add a image tag over here import it from next SL image and inside
of this I'm going to have the SRC of testimonial. image width and height of 40 and all tag of testimonial. author
let's see if I go back to our app um okay so we're using this random user. me over here right if you go to the data
we're using this image with random user. me API so we need to add this to next. config.js we need to tell nextjs that we
are using this so insert this I'm going to say images and remote pattern I'll say protocol https and host name to be
random user. me so let's see now if I refresh this let's scroll down okay we cannot see the image yet y now we can
see great let's add the class name of rounded full object cover border tob2 and like border color to be primary and
20 opacity so let's see yep like that now after this inside of this T over here we're going to have three paragraph
tags first one we'll have testimonial author testimonial role and testimonial. Company right this will be semi- bold
this will be text small both of them and this will muted and this will be text primary color so let's see yep that is
what we want and for both of these for this parent da over here I'm going to give the class name of display Flex
items to be Center and Space X to be four let's see now sorry I had to give this class name over here not there and
now let's see yeah that's better for this image Dev I'm going to give the class name of relative height and width
to be 12 and flex shrink to be zero so yeah it will take the space available to it for this parent div right here I'm
going to give the class name of display Flex Flex column because the block quat will be in the bottom of it right in
like below it and space y to be four like this okay now you can't see much over here right now but for this parent
Dev of this testimonial do map let's see okay okay I've have given grd columns 2 and over here I think it should be grd
columns 3 because we just have three items over here right so let me just remove it and let's add gap of eight
between them and yeah now we should see them in the middle yep something like that okay so now let's work on this
block code so here simply let me just bring in the code real quick we will just have a paragraph tag which will say
text muted foreground and it will be italic since this is a quote right and position relative and insert this we
will first add this quote Right double inverted commas so to write that you can write something like this and we will
just style them text 3 XEL text primary and Position will be absolute minus top four and minus left to be2 similarly for
this one as well minus bottom to be four and then we'll simply insert our testimonial quote between them like
which looks something like this right so yeah let's see yeah that's exactly what we wanted in the it as well and let's
just add some background to this so what I'll say background muted to be 50 over here okay yeah that looks much better
now I think the only thing remaining is frequently asked questions and this CTA at the bottom let's just build it real
quick this will be very easy just like what we've been doing up until now let me just copy this section above it this
how it works section and let me just paste it right after it let me just get rid of everything inside this map
because we will be mapping through the fa cu's over here this won't be a grid so let me just remove everything over
here in like apart from these two things on the top instead of how it works I'm going to say frequently asked questions
and instead of this paragraph I'm going to say find answers to most common questions about our platform let's see
okay yeah let's just render the FAQ real quick so we have created this fuuse data of question and answer over here so
inside this I'm going to say return and I'm going to return a accordion actually over here not
accordion accordion item we will wrap this with the accordion so let me show you so if I go back to shat CN UI we
have this accordian component right here just like this and to use it this is the code I'm going to take it and paste it
right below it and we will take the accordion item and first of all let me just wrap this with the accordion and
over here is what we will be returning the accordion item right let's go back and see accordion is not defined
obviously we have not imported it so let's import accordion from /ui folder accordion trigger accordion content all
of this has been Tri like imported I guess let's see yep but obviously we have to provide the key as well right
and also it takes this value right here so I'll say key to be index and value to be item and whatever the index of that
item is right so now we can access every single separately and instead of this we will
add the dynamic value that is FAQ do question and over here as well FAQ dot answer let's make it full width so I'll
say class name to be width full so page crashed let me just reload it FAQ is not defined oh sorry FAQ over here not the
item yep just like this this is exact what we wanted the most asked questions about our app and then in the end we
want to have a this beautiful seat here right which most of the SAS companies nowadays have to make the conversion
even better so again let me just um duplicate this section I'm going to copy it and paste it right here you won't be
needing this accordion now let's get rid of this div all together for this H2 I'm going to say ready to accelerate your
career and for this paragraph I'm going to say join thousands of professionals who are advancing their career with AI
powered guidance now obviously we will be changing these Styles a little bit so instead of this section over here I'm
going to say width to be full instead of this div I'm going to be saying margin horizontal to be Auto padding vertical
to be 24 some gradient so if you remember we created the gradient Tailwind CSS class right so we will be
using over here for our background color and rounded to be large so let's see yep something like this we have to enhance a
little bit more for this div over here I'm going to be saying display Flex Flex column so that we are aligning them from
top to bottom items to be Center justify Center so that they are in the middle space y to be four between them text to
be Center and maximum width is going to be 3 XEL which is around 768 pixel right and obviously we want them in the center
so margin horizontal to be Auto for this h2 tag I'm going to be saying in the smaller screens three XL some font bold
and tracking tighter so that texts are closer to each other text color to be primary foreground in the smaller
screens it will be text 4 XEL size and medium screen 5 XEL so let's see yep that is what we wanted let's do the same
for the paragraph tag as well so margin horizontal to be Auto and Max width is going to be 600 pixels text primary
foreground but with 80% opacity and in the medium screens text Excel like this now in the bottom below this P tag I'm
going to be Simply Having a link tag which will take us to the slash dashboard page a button with size large
variant secondary and class name to be height 11 margin top to be five and it will bounce right this is a native
Tailwind class of animate bounce and I'm going to Simply say start your journey today and I'm going to add a arrow right
icon which will come from Lucid react so link is not defined let's import link from next SL link let's see yep there we
go this is exact ex L what we wanted amazing so we have successfully completed our landing page Pat your back
now let's go on and dive into juicy stuff that is designing our database right designing the tables inside of our
database using Prisma so first of all let's just first go on and install Prisma inside of your app and then what
we will do we will go on and design our database so I'll say npm install dashd Prisma so let me show you what
Prisma is all about so if you just Google Prisma right here just open it up and in the documentation let's see this
example right here of create right like if you were to create something using a SQL query it will be super long right
like insert into this table blah blah blah blah it will be a headache but Prisma makes it super easy like you can
see Prisma and let's say if you want to insert into user table do user do create and simply providing our data right here
super easy so the Prisma has been installed I'm going to say and PX Prisma in it and it will initialize our project
with Prisma over here so you're going to notice it has created this Prisma folder with schema. Prisma and this is the
place where we will be creating our tables and you can see it has picked up this database URL that we have added
inside of the EnV file and it will use it to connect to our post G SQL database so this is how our database will look
like so first of all we have a user table where we will be storing all of the information of the user now you
might be thinking we are already using clerk for storing uh the user info right but we will also be storing a copy of
that information inside of our database along with few more uh things like industry bio experience skills Etc right
so that we can access all of these details fast and we can query the other tables along with the user table faster
all right so as you can see we'll be storing the ID like obviously this ID will be generated but we will be storing
the clerk user ID over here and the email the name the image URL and the industry so this industry will be a
foreign key to this industry table right here we'll come back to this apart from that we will obviously have a created ad
and updated ad that we generally do in a database table then we will have the bio of the user so bio experience and skills
these are the three questions that we will be asking the user when user is on the onboarding screen right so we will
also be asking their um you know industry so we will have to uh you know categories for this one like the first
category will be for selecting the uh industry like for example Tech Finance etc etc and then the sub industry like
for example in Tech are you in data science uh front end development backend development Etc right so that is what we
will be storing over here in this industry table and we will be generating the industry insights and storing them
right here and as I already showed you in the intro that we will be updating this uh particular information every
single week right so for for example if there are two users who are uh you know in Tech and they are front end
developers this information will be updated for both of them right along with the salary ranges the growth rate
demand level what are all the top skills that they can learn how does the market look like in the future right key trends
what are the recommended skills that they should be learning right so this is the whole package that is being provided
to the user in terms of the insights when it comes to their industry okay so that's that apart from that the user
table is connected to these three things these two like these three AI tools that we have inside of our app right first
one um let's start with the resume right so we can build our rum we will store the markdown of the rume over here in
the content if we want we can generate an ATS score over here I've just kept this uh field over here even though this
is not the part of our application so that if later on we decide to add this feature we can add this feature right
here right but right now it's not our priority because we are just generating the
and alongside it we can also provide user the feedback on this right so if you want you can ignore these two Fields
over here as well right the major field over here is this user ID that this belongs to and the content that is what
is the markdown content inside this resume and again the updated at and created at now we will also uh like user
will also be taking the mock interview inside of our application so we'll be taking like we can configure it we can
ask them five questions 10 questions Etc right so we'll be storing information about every single assessment like what
are all the questions that were involved in that particular assignment along with the answers what category does it
belongs to the score of that particular quiz if user gave any wrong answers we can ask like we can provide them an AI
generated Improvement tip over here as well and of course the user ID as well right apart from that when it comes to
generating a cover letter we will have the user ID the content of that cover letter that is generated right the job
description from which this was generated the name of the company the job so
basically these three things are the ones that we will be using to generate our cover letter right so yeah this is
the basic structure of our database now let's go on back to our code and let's design all of these database models
inside of our schema. Prisma file right here so to create a model we have to say model and the name of that model like
for example in this case user right so what were the things that we discussed first of all it was the ID which will be
generated uh automatically so let's say string and if we want we can provide it some default value as well which we will
do it over here so I'll say this is an ID you can read the description about it right defines a single field ID on the
model and then I'm going to say add default and we can provide the type of ID this will be so I'll say uu ID so it
generates a global unique identifier based on The UU ID spec apart from that we will also have the clerk user ID as I
already showed you which will be unique we will have the email name the image URL of the user and name and image URL
I'm keeping optional over here then I'm going to have the industry which will be a string and as I already showed you
let's see user belong in the tech software engine like software development industry right so we will
combine both of them that usable from Tech and inside of this we will have the software development then after this we
want to connect this industry to the industry table right so we will be creating a industry table over over here
as well so I'll say industry insights and obviously we'll come back to this later but over here I'm going to say
industry insights is going to be the type of Industry insights table and then we will Define the
relation between this user table and Industry table so inside the industry table we have a field called industry if
you remember this thing right here and we will be connecting this to the industry field inside of the user table
that is this field right here then after that we will obviously have the created at and updated at Fields as well okay
then on the onboarding screen we will ask users some questions right so I'm going to say profile fields and I'll add
bio which will be type of string experience which will be of type integer and the skills which be which will be
array of skills right or string then after that we will also store the users resume and the assignments that they
have uh attempted first of all the assessments the resume and the coverlet and obviously these three will be uh
related to the separate table that we will be creating so let me just um create it real quick over here I'll say
model assessment let me duplicate it twice I'll say model resume and model cover letter so each user can have more
than one cover letter and more than one assignment but a user can only have one single resume all right so let's check
this assignments or the assignment table right so let me just bring it real quick and then I'll explain you what's going
on over here so obviously in the assignments table we will have the ID the user ID that this belongs to and
then we will Define the relation between both of the table so since this is a foreign key I'm going to say inside of
this table we have user ID Fields user ID which references the ID of this user table that is this particular ID of the
user table which we are storing right here then we will obviously store the quiz score that we got after attempting
the quiz the question so this basically be a Json so it it will contain the question answer the users's answer and
what is the correct answer right so all of these information that we'll be storing over here we will have the
category of that quiz that is if it's a technical quiz behavioral quiz Etc what is the you know a generated Improvement
for that particular quiz if any so this is optional and obviously created at an updated ad and then we are saying that
Index this table with the user ID so that this remains unique then comes resume again very similar to what we
have already seen ID the user ID and we are referencing the user table over here the content which will contain the
markdown of the resume we can if you want you can skip both of these right as I already mentioned I've just kept it so
that later on if I want to update something inside this project I can add the atss scoree feature over here as
well right so you can remove that and then we have created it and updated it over here as well right when it comes to
cover letter we will have the ID the user ID again referencing that user table the content of the markdown
content of that cover letter the job description from which this was created company name job title and obviously
created at and updated at and again we are indexing this with the user ID now let's see the industry insights this is
uh you know quite complex first of all obviously we will have two things over here right the ID of that particular
table and the industry that the unique industry like I already gave you the example tech software development right
then we will have the list of all of the users in the industry so we will write them just like this then after this we
will have more things like salary ranges which we will get in this particular format we will get the role that this
industry has like for example data scientist or backend developer then what is the minimum and the maximum salary
and what is the average salary so let me show you something like this so over here you can see we have multiple
different uh information about that particular industry right mobile app developer devops engineer backend
developer Etc then we have the growth rate demand level and the top skills right so again you can see the growth
rate the demand level and the top skills over here right this will be an array so I've added string array growth level
will be in the float format then next we will have the current market condition right and what are the key trends right
now so this can be positive neutral or negative key trends can be array of current industry Trends then we have the
array of recommended skills and last updated and the next update that will be happening for this right so which will
be next weekend so also you can see we have a lot of these enums over here right that this should only have these
many values this should only contain these many values right I mean either of these values so let's create the enim
for this so for demand level and Market Outlook I'm going to say enum demand level and I'll say high medium low and
Market Outlook can be positive neutral or negative right so I can just take this and provide it right here and same
for Market Outlook as well over here right this is much more better and much more robust and yeah I think uh that
should be it let's just open our terminal and I think there's some error over here so industry Insight I think
that should be it not insights and now we have to say npx Prisma migrate Dev and we have to provide the commit
message which let's say create models and press enter so what this will do it will push all of these schemas to our
database that is our neon database and we can see it right there so let's just open the neon database there we go this
is pushed and now if we go back to this tables tab inside of our database let's just select Sensei and uh let's see yeah
you can see all of these tables have been created successfully amazing so now what I want to do first thing first
let's just store our user inside of our database right so to query Prisma inside of our app I'll be creating a file over
here in this lib folder there I'll say new file and I'll name it Prisma do JS and inside of it I'm going to say
export const DB equals new prisas Prisma client and let's import it from at Prisma / client now if we were to use
this uh new Prisma client to query our database every time the nextjs uses hot reloading that is it refreshes our app
it will create a brand new Prisma client over here as well so we don't want that right so what we want to do we want to
store it inside of our Global variable so I'm going to say if process.
env. nodecore EnV is not equals to production right so I'm going to say if we are not on production that is we are
on the development I'm going to say Global this. Prisma equals DB and every time we export this I'm going to say
Global this. Prisma if this exists then take it else we will take the new Prisma client all right let me just add an
small explanation over here for you guys so you can refer it later on cool then so now to store our user inside of our
database I want to run that function every single time my app runs right we have to check if the user is added
inside of our database or not so what I'll do I'll create a new file over here called check user.js I'm going to say
export const check user equals if sync and this will be an arrow function and ins start of this now we will first
check if the user is logged in or not so we will take this current user from at clerk / nextjs SLS server make sure to
import it from this only right so we will take this and then we will check if user is there or not so I'm going to say
if user is not there then return null now we will try to query our database so I'll have a try catch block over here
inste this I'm going to say await DB and import that DB that we just now created do user so we're going inside the user
table and then I'm going to say find unique we want to find one single database which like we want to find one
single entry which is unique to you know particular users ID so we have already like we will be storing uh clerk user ID
right I've already showed you that so I'm going to say where the clerk user ID is equals to user do ID the user ID that
we got from this object user object over here right and and then we will store it inside of the logged in user so
basically we are checking if the user is already stored inside of our database or not so if it is if the user is stored
here inside of our database then we will simply return the logged in user and we don't have to do anything right but if
user is not stored inside of our database then we do need to store it so I'm going to say const name equals user.
first name space user. last name and then to create this inside of our database let me just copy this whole
thing up and paste it right here instead of logged in user I'm going to say new user and I'll say db. user. create
instead of this where I'm going to provide the data that I'm supposed to store so data will be clerk user ID
which will be user. ID the name of the user that we just now created the image URL which will be user. image URL and
the email right so user. email addresses user can have more than one email in clerk but we will just take the first
email address and we will store that inside of our database and then we will simply take this new user and return it
so return new user over here that's all and in the console like in the catch block I'm going to say console log and
log the error do message over here that is all we need to do right now we will just take this check user we will go to
our header component and making sure this is a server component and let me just get rid of this yeah and this
should be an asynchronous function since this is a server component and I'll say await check user right here every single
time we land on our app we will check if the user is like part of our database or not so import this check user and if
they are it will simply return it from over here else it will create it let's go on and check it out so now let's go
on and sign in continue with Google and we are in this should have posted the user inside of our database let's see if
I refresh this uh user table over here there we go we we have the user information inside of our database along
with the email name image URL and all of these things obviously the industry is empty right now and we can also see all
the tables that our user table is connected to over here but we cannot see anything since we don't have any data on
them right now cool then let's go on and um you know create our onboarding page but before that I want to explain to you
guys how routing Works in nextjs so as I already told you guys for every single uh route that we create like for example
over here in the O we have this layout. JS file right so we can have a layout. JS file and we can also have a page.js
file and page. jsx is what makes a route possible right so for example for the internal routes of our app we will have
the main folder right so I'm going to group them in the main folder and obviously this is optional you can do it
without this main folder as well but since we want a consistent layout for our application we will be creating a
layout .js file over here which will wrap all of the routes inside of our main file
like or sorry main folder like for example I'm going to be creating a new folder for on boarding over here and
inside this we will have a page. jsx file let's say r fce on boarding page right simple as that and in the layout.
JS I'll say R fce if I want this on boarding to fall under this layout I want to create it inside of this Main
folder right so I'm going to say main layout and then I'm going to take the children over here that we will be
rendering so I'll be rendering these children right here and then if I want I can provide them some Global Styles just
for this uh routes that fall under this main folder right so I'll say class name to be a container MX Auto so they are in
the very middle some margin top to be 24 so that our header does not overlaps them and some margin bottom to be 20 and
also since all of these are protected routes right I'm going to be adding the logic over here so that when the user is
already onboarded we will check if like we will land on the onboarding page and then we will check if the onboarding
process already completed then we don't need to do it again right so we will redirect user after on boarding right we
will come back to this later on but first so what are the different types of routes in nextjs let's actually go to
next js's documentation so I'm going to say next js. RG let's go to docs and over here we have this project structure
page over here right okay so let's see so since we using App router we are inside this app folder right and there's
something called as Pages router as well which is old next Chase right so we don't need to worry about that so if we
come down you can see it is explaining all of the different different files that we have inside of our folder and
yeah this is the main thing so we have a layout file and the page file we can also have files like loading not found
page right the error page for each and every single route we can also have the nested routes right like for example if
you have created a onboarding page like if I show you inside of our deployed app we have the interview prep right so it
will be slash interview so this can be a page in itself but if you click on start new quiz you can notice it goes to/
interiew SL mock right so this will be a nested page so let me just create it I'm going to say new folder interview and it
can also have a new folder mock right so this will be a uh page now so I'm going to create a new file page. jsx R A fce
I'm going to say mock interview page and they should open that and we can also create a page file inside of this
interview folder so I'll say page do jsx and let me just copy this whole thing up over here and simply instead of mock
interview I'll just say interview page notice this is a route on its own right with the page. jsx and this mock is also
a separate route right okay apart from this we can have Dynamic route segments over here as well right so what is a
dynamic route if I go back to the app and let's go to the cover letter so you can see we have different different
cover letters over here right like we can have the list of cover letters so we I've created this one cover letter so
this is ai- cover- letter if I click on this job like over here in this I button it will take me to one single cover
letter so you can see this is an ID over here right so this is going to be dynamic every single time so we have to
create a dynamic route over here as well so how do we create a dynamic route let's create a route called AI cover
letter and then inside of it if I want to create a dynamic route I have to wrap them inside the square brackets and
let's say ID right so this will be a dynamic route I can create a new file called page. jsx over here let me just
add this same name code and I'm just going to Simply say cover letter and now inside of it we can access that
particular ID by saying params and let's just console log perams do ID over here or you know what I'll just display them
right here I think we need to do a wait params do ID and const ID equals this and this should be an asynchronous
component if you want to do this let's take the ID and I'll say cover letter colon ID right here right so this can be
a page on its own we can also create this AI cover letter page so I'll say page. jsx over here r a f c AI cover
letters page right so this can be a separate page on its own let's try it out so if I go back and I'll say AI
cover letter you're going to notice see we are on this AI cover letters page and if I try to go to some gibberish over
here and press enter you will see we will go to that part cover letter page so cover letter and the ID that has been
entered on this URL right here apart from that we have this catch all route right which like for example if you were
to enter like let me show you if I click on it see we have SL shop SL A/B SL C right we can have multiple different
routes after it but we don't know how many routes are going to be there right so that is where we create this catch
all route so it can catch all of the routes after this particular thing like after whatever this written before this
catch all route right so we not going to be needing that you've already seen the optional catch all route so this thing
right here that we used in clerk right so over here so this is actually optional we don't need to provide
anything over here and it will still work fine then we will have these grouping conventions that I already
showed you we created the O folder the main folder right for grouping the routes but in this case next just
ignores this and goes inside of it but if we create a folder with let's say underscore folder right next just we
completely ignore this folder and everything inside of it so the best way to use this is by creating a components
folder right like for example if I let's we are going to be working on the industry insights right so let's say if
I create a new folder called dashboard we will have a page. jsx file over here like RFC I'm going to say
industry insights page and then if you want to use any components over here I'm going to create a new folder called
underscore components and everything inside fit along with this folder will be ignored and will not be considered as
a route and then we have more types of routes like parallel and intercepted routes metap file conventions right so
we don't need to worry about all of these things this is the major things that we need to worry about for this
particular project right let me show you how you can create a not found page so currently we have a default not found
page right like if I go to some gibberish over here it will show us not found yep you can see 404 page cannot be
found but if you were to create a our own not found page so over here inside this app folder you can create a new
file called not- found and it has to be exactly called this not found. jsx and let like you can create anything over
here let me just give you a quick example this does not really matter so I've created this not found page over
here with simple H1 of 404 H2 of page not found and then I've written a message over here oops the page you were
looking for does not exist or has been moved and then I have a return home button Buton over here which will take
me to the homepage right simple and I've given this gradient title if you remember we created this some time ago
our custom title so if I go back now you can see this looks much more beautiful right so it's a custom 404 page if you
don't want to create it that's fine nextjs is anyways handling it by our default 404 page all right then let's go
on and start working on our onboarding page so if I go to/ onboarding we will just see this onboarding page message
over here so now if I go back over here inside of the main folder we have this onboarding page. jsx and over here first
of all we will check if the user is already onboarded if they are we will redirect them to the dashboard page and
I showed you we have added this condition over here in the layout. JS right so over here basically we will say
redirect to onboarding if user is not onboarded then we will redirect them to onboarding but if they are already
onboarded then the onboarding page will send them back so we will come back to the logic but over here instead of this
div I'm going to have a main tag and inside of this I will be rendering my onboarding form so I'll say on boarding
form so the reason why I've created a separate component over here is because this is going to be a client component
and client components need to use that use client directive right we cannot use hooks inside of This Server component
and the reason why I'm not creating this as a client component is because we will be making a API call over here on our
server which will check if user is already onboarded or not and that will be much more faster when compared to
client component right so to this onboarding form I will send the data of the industries so we have created this
Industries data right inside this data folder yep there we go Industries and now you can see this data so basically
for this data we have the iD Tech name technology and the sub Industries inside of this and similarly for each and every
Industries like Finance Healthcare manufacturing etc etc we have created the industries and sub Industries over
here as well so that all types of users can use our app okay so let's import this I'm going to send this as
industry or you know what industries equals Industries and make sure to import it from at data/ Industries and
obviously this onboarding form does not exist yet so let's just create this component just like I showed you we will
be creating a new folder UND score components and I'll name this file as onboarding Das form. jsx R A fce I'll
say onboarding form over here for this particular component and this will take the prop of the industries that we are
sending from right here okay now before uh building the UI of our onboarding form let's first create the apis for the
onboarding form right so the back end part of these things so where do where will we uh you know be writing our apis
the older way of writing it is in the API folder over here but the new nexj I think it was from nextjs 13 something
version that nextjs has introduced server actions so we have to create a folder over here called actions and
inside this we will be creating the server action this will be like simple functions which will be running on our
server so let me show you so if I create a new file over here let's say user doj yes since onboarding has more to do with
user right and I'm going to create a function over here export async function update
user right this will be our server action and this will take some data let's say onboarding data if will come
from the UI right and also very important you have to write use server on top of this so that this runs on our
server and our server components as well right so before updating our user we need to check if user is logged in or
not right so I'm going to say await o and this Au will be coming from at clerk nextjs SL server right if we get the
user ID then we will check if user ID does not exist then obviously the user is not logged in and we will throw
unauthorized then we will check if user exists inside of our database or not so I'll say const user equals a wait DB
just like we have done earlier db. user. find unique and I'll say where we will will'll find them using the clerk user
ID right so clerk user ID is equals to user. ID pretty straightforward just like we have done over here sorry not
user ID this user ID over here not user. ID and again if user does not exist inside of our database we will throw the
error over here cool then now that we have that out of the way we can make the uh you know connection with our database
over here inside the T TR catch block so we have the data right here right what will this data contain let see inside of
our Prisma schema right here so we will be sending like let's see our user table Yeah we will be sending the bio the
experience the skill set and obviously the details about our industry okay so now after this we will be performing two
operations over here first of all we will find if the industry exists right if the industry exists then we won't do
anything but if the industry does not exist we will create it with the default values for now but later on we will add
the you know AI logic to generate the industry insights right away right and the third step will be to update the
user right so we are performing three API calls over here so this can be a time-taking process so instead of using
just normal API calls over here we will be using something called as transaction that comes from Prisma right so I'll say
const result equals await DB Dot and I'll say dollar sign transaction action right so now what is the uh you know use
of transaction so transaction basically makes sure that all of these three completes if any of these fails the
transaction will fail as well and this will give us the error right so first of all we will take a call back over here
the asynchronous call back and the second thing that we can provide it is the timeout value now this is optional
by default it is 5 seconds but we are providing 10 seconds over here because later on we will be adding this AI logic
right so let me just take this first of all and add it inside of this call back so yeah this is the call back we are
providing it 10 seconds to Pro you know complete this operation to generate all of the AI insights regarding that
industry and then in the end we will return the result. user that's all in the catch block I'm going to say
console. error error updating user and Industry and we'll provide the error. message and we'll throw a new error that
failed to update profile that's all let's dive into this now so to perform a transaction we will take a TX over here
for one single transaction and we will have three transactions over here right so first for this step I'm going to say
cons industry insights or let's just say let over here because we'll be overlapping this value so industry
insights equals await TX do industry insight. find unique we will try to find if that particular industry already
exists right like for example front end developer and I'll say where here data. industry so we'll be getting this
industry from this data object that we'll be getting over here right so I'll check if this already exists and now if
the industry does not exist we will create it with the default value so let me show you I'm going to say if the
industry does not exist the industry insights oops sorry I think it should be industry Insight does not exist we will
simply say await tx. industry insight. create and we will create all the default value that we are supposed to
have in inside of our database right so you've already seen this schema. Prisma file over here this industry inside
right so we are providing all of these values as default so you can see the industry the salary range the you know
empty array growth rate zero demand level medium top skills Market Outlook blah blah blah and this is a temporary
thing for now right again when we later on understand the AI stuff we will be adding the AI generated industry
insights right here cool then after this we will update the user so I'll say const
updated user equals await tx. user. update we will update the user object that is already inside of our
database right so first of all we will try to find that user using the user. ID and then we'll provide the values that
we are getting that is industry experience bio and the skills right all these four values right here then in the
end let's return this updated user and and this industry insights notice I have overlapped this industry insights
variable over here so after this I'm going to say return the updated user and the industry Insight that's all that is
all we needed to do to create this update user server action over here okay and then after this let's just create
another server action for fetching the onboarding status right so I'll just copy it and paste it right here and
rename it to be get user onboarding status we won't be needing any data we are just going to be first checking if
the user is logged in or not so I'll just take all of these things that we've already written and I'll just paste it
over here first and then I'll say try catch block oops try catch and this will be fairly simple right first of all I'll
fetch the user so I'll say cons user equals a wait DB do user do find unique and set this I'm going to say where
clerk user ID is this ID or you can you know also um search using this ID equals user. ID as well from this our database
but this will also work and then I'm going to say select the industry as well because when we get the user object the
industry object might not be populated we just get the ID so we want to populate the industry as well and then
in the end we will simply return is onboarded flag and I'll check if the user industry exists then obviously this
will be true else this will be false and in the catch block we will simply say console. error error checking onboarding
status and provide the error do message and throw new error fail to check onboarding status that is all cool then
this these are the two API that we will be using right here right so let's go back to our onboarding form and let's
start building this but you know what since we have already created uh this get user onboarding status API why not
we just go on and add it to our page. jsx over here right we have this condition so I'm going to say cons
and actually I will say first await get user onboarding status let's take it from over here at action SL user and
over here I'm going to say const this will provid us is onboarded you can see it is suggesting this is onboarded and
this will be an asynchronous function since this is a server component and if the user is already onboarded we will
route them to the dashboard page right that's all let me just copy it and go to our dashboard page. jsx and I'll add it
right here as well and let's make it an asynchronous component and I'm going to say if user is not onboarded then we
will push it to on boarding page right and yeah that should do it let's just import this and import the
redirect and now if we try to go to dashboard yeah you can see we are in the like let's do this again if we go to
dashboard we are directed to the onboarding form great so now if the user is not onboarded we will be redirected
to the SL dashboard page let's go back to this onboarding form over here and now we will be creating the form for
basically onboarding the user so for that we will be using two very popular libraries react hook form and Zod so I'm
going to say npm installed react hook form space Zord and at hook form SL resolvers so this library is for making
sure that these two work fine with each other so I'll press enter there we go it has successfully installed and now since
this is going to be a client component I'm going to be adding a use client flag over here so inside this onboarding form
I'm going to say use form and use form comes from react hook form over here right so this is a hook that we'll be
using and for creating our form we will also be creating the schemas right so schemas that will monitor our form if
the user has entered the correct information or not right so to create the schemas I'm actually going to be
creating a new folder over here called lib and inside of it I'm going to be adding a new file called
schema. JS and here we'll be creating all of our schema right so let's see how do we create an schema using Zod and by
the way if you want to get more information about react hook form and Zord I've created a completely separate
video on this topic as well so you can check it out from Link in description down below so let export const on
boarding schema equals Z and this will be imported from Zod Z doob and this will take an object inside of it right
so first of all the industry I'll say industry and Z do string it will be a string and if it is
not a string we will provide the error to the user right so I'll say requir error and I'll say please select an
industry similarly for sub industry as well if the user has not selected it I'll say please select a specialization
similarly for our bio we'll say this will be a string and Max 500 character vors and this will be optional then we
will be adding the you know inputting the user experience right so experience will be Z do string but we will add some
conditions over here not conditions actually we will transform it so we will be inputting the experience in the
number of years right so it be provided to us as a string let's say four or five right so we will transform it into the
integer value before storing it inside of our database so we will use this transform over here and parse int
function then after this we will add this conditions over here that means minimum it can be zero or 50 years of
experience Max then we are going to be having skills from the users right so z. string and user will be inputting this
in form of the comma separated values right so I'll Transform this into an array over here so I'll say value do
split split it with the comma and I'll map through each and every one of these trim any space around them and I'll say
filter out if there's any you know empty spaces over there so we will have the array of strings over here cool then so
we will just simply take this onboarding schema go back and inside of this use form over here we will have an object
and we will say resolver and inside this we will import the Zod resolver so this Zod resolver will come from the you know
this library that we installed the hook form resolvers so make sure to import it right here Zod resolver from Hook for/
resolvers SL Zod right and this will take our onboarding schema which will come from that schema file that we just
created right here all right so now this use form will return us a few things right first of all register and this
will be very important to connect our form with the logic right I'll show you in just a moment it will provide us the
handle submit for submitting our form the form state which will contain things like errors or is dirty is loading is
submitted Etc right before now we will just take the errors then we will take the set value and watch to watch any
particular field if it changes right like if we are going to be selecting the industry only after that we are going to
be displaying the select box for our specializations right okay uh apart from this we are also going to be having a
use state so use State hook which will be storing our selected industry and this will be null
by default we will also be having a hook called use router which will be coming from next / navigation make sure to
import it from this only and this will help us to navigate to some other page so I'll say router equals use router
that's all let's go on and create our UI over here so I'll WRA this whole form inside of a card right so card comes
from uh Shad CN UI so let's go back to the docs over here and card right here so I'll just take this card code from
here and paste it over here let's import the card card header card title card description we'll need the card count uh
like content and we won't be needing the card footer so let me just remove it let's see if it's working fine yep we
can see it all over here for this parent D let me just provide some class names so display Flex items are going to be in
a center and justify Center as well so that we have the onboarding form in the center of the screen background will be
of this background color defined by Shad CI so let's see yep like that for the card component over here I'll say class
name width to be full and Max width is going to be large which is around 512 pixels margin top is going to be 10 and
margin horizontal is going to be two like this for the card title I'll say complete your profile and card
description I'm going to say select your industry to get personalized career insights and recommendations let's just
provide the gradient title to this card title so I'll say class name to be gradient
title and text to be 4 Excel okay let's see yep that's more like it now inside the card content is where we will be
creating our form let's remove this and I'll have a form tag over here inside this form tag first of all we will have
the industry and then the uh you know specialization select box so we're going to be using a select tag so let's go
back to Shad CN UI and let's use this select Yep this is the select one let's see the code for this this is going to
be the code so just copy it and paste it right here let me just import all of these from at component /ui select
trigger select value select content and select item let's see how this looks okay yeah something like that let's wrap
this select inside of a div and we will also be having a label right here so I'll just say label from shat cnii
inside this I'll say industry label will have HTML for the industry that is this particular select tag let's map all of
the industries so we are getting this Industries over here right Industries array so let me get rid of two of these
and over here I'm going to say industries. map and let's have a call back over here and I'll move this inside
of it return let's take one single industry and right here I'll say industry. name and in the value
industry. ID and and the key will be industry. ID as well let's see label is not defined okay let's import the label
oops not from over here make sure to import it from slash components so let's see okay yeah that
looks good why is this theme over here instead of this let's keep selecting industry and the in the trigger I'm
going to say ID equals industry for this HTML 4 right so let's see yep that's more like it if I select
anything I'm able to select it great for this de let's have class name of space y to two so that we have some spacing
between both of these oops not here actually I want to keep it on the D yep something like this now on our select
tag I'll say on value change I'm going to say set value and we'll change the value of this industry right so we have
taken this set value from over here if you remember right so I'm saying set value and take the current value that is
selected and provide it inside of our form and and then we will have this selected industry updated right so I'll
update the set selected Industries and I'll find the particular industry and provide it inside of it so that we can
you know display the other the specialization select box over here and I'll say set value to be sub industry to
be empty right so we will now display the sub industry form but before that if user has you know not selected the
industry and just press on the submit form button then I'm going to display the error so we have taken this error
from over here right so I'll say error do industry if it exists I'll display a paragraph tag with text small and texted
500 and display the errors. industry. message over here all right pretty cool let's just take this D and I'm going to
duplicate it right below it to display our sub Industries but first uh okay I have some uh mistake over here let's
just fix it okay this will be labeled for sub industry ID sub industry here the value
change will be pretty simple on value change will just be set value to set the sub Industries value and set this
Industries I'm going to say sub industry do SUB industry so sub industry is our state if you remember value can be um so
we don't need to add the ID over here this will just be a simple name right so we can just put indd on all of these
three places so let's see let's select anything let's select technology and yeah now we're able to see it but we
should not be able to see it right away so what I'll do first of all instead of this industry I'll say specialization
and I'll put it inside of a curly braces and also over here instead of Industry it should be sub industry right now
we'll watch this field if it's selected or not and then add the condition there so before return I'm going to say const
watch industry equals watch this industry field over here if it's selected only then we will show it so
I'll say watch industry and over here right so let's see if I just refresh my page now we can just see this if I
select technology only then we are able to select the specialization let's provide some gap between these so in the
form I'm going to say class name to be space Y and I'll also say on submit I'll call the handle submit function that is
provided to us by that use form hook and this actually takes another call back over here so let me just create a dummy
on submit so const on submit like this let's keep it asynchronous and this will provide us the values so let me just
take it and just provide it for now we don't need to worry about it for now right so okay so we have this select
Industries and specialization done now we need to ask user how many years of experience do they have so I'll just
copy this div and right below it let's get rid of this select tag and over here this will be for the experience right so
I'll say years of experience over here and after this I'll have the input tag so input which will be coming from SL
components that is shad CN UI I'll say ID equals experience type is going to be number it can be minimum zero maximum 50
and placeholder can be enter years of experience right and now if you remember we have taken this register from our use
form hook right so we'll be using this now over here so I'm going to say in the curly Braes dot dot dot register and
then provide where like which field does this belong to so if you press double codes over here I'll say experience
experience yep something like this let's take this experience and replace it over here in the errors as well cool
similarly we will do the same thing for our skills so I'll just copy this do and paste it right here I'll replace with
the skills over here I'll say skills as well with the capital S over here I'll just have two things the ID skills and
placeholder can you know denote some skills like python JavaScript Etc and over here as well I'll say skills here
as well instead of experience I'll say skills right and let's just give users some message below it that they should
only enter it in comma separated values right so I'll say separated multiple skills sorry separate multiple skills
with commas and this will be a small text with muted foreground so let's see yep something like this let's copy this
up and again paste it right here now we will add the professional bio field so I'll say bio this ID as well bio
placeholder can be tell us about your professional background let's have a height of 32 so this will not be the
input actually this will be text area from uh shat CN so import that instead of skills I'll say bio over here let's
get rid of this paragraph tag instead of skills again I'll say bio over here then I think that is all we needed to do
let's see our form yep that looks more like it let's add the submit button on the bottom so I'm going to say button
which will be imported from Chad CI type submit and class name will be width full and I'll say complete profile right so
let's see yep that's more like it and now let's try to submit our form right so let's see over here in the onsubmit
let me just console log this simply for now so I'll say values let's see if I go to inspect in the console let's try to
select the industry sub industry can be software development years of experience let's say four skills let's say
JavaScript react etc etc professional bio can be anything right let's click on complete profile and yep there we go we
are getting this object right here let's not provide the years of experience and you can see we are saying expected
number received n if I click on complete profile it won't allow us to complete our profile now if I just refresh it and
just click on complete profile you can see we are getting these errors over here if I just select this we are
getting the error please select our specialization right so this is made possible by using Zod so now we are
getting all of these values over here right in this values object how do we make the API call to our back end so we
have to call this update user API right this is not a server component so we cannot just use the await and call it
directly to use it inside of our client component we have to use a traditional way of you know using using something
like fetch right fetch or axio or something like that and to manage that we would have to manage some separate
states like loading error and maintain data State etc etc right we have to use that again and again so what if we
created a custom hook that will manage all of this for us so what you can do you can create a hooks folder over here
ins start this I'm going to create a new file called use fetch. JS right so this is the custom hook that we will be
creating JS or jsx whatever you want to call it and if you don't know about what you know hooks are these are basically
just like a normal functions but with super power of react right and they are written by using use keyword in the
beginning so let's say for this one I'll say const use fetch equals whatever this is right this is basically a normal
function and I'm going to take a call back inside of it which is going to be basically a API call in this case our
create project call so what will this contain it will contain the three states that I just
discussed data loading and error right all of these three states which we create again and again when we have to
do an API call let's create a FN function over here and this is going to be an asynchronous function which is the
only thing that we would be needing to call in the end when we have to trigger an API call and we will write all of our
logic inside of it which we're going to reuse again and again right right and in the end I'm going to return data loading
error and this function right here and also if you want to you know manipulate this data from outside I'm just going to
send this set data as well and I'll say export default use fetch what's going on over here uh let me just import use
State just like this okay now insert this function over here first of all before fetching our API we're going to
say set loading to true and set error Tel right oops sorry it is export default not export delete yeah so set
loading and set error by default values this will be true and this will be null then inside of this I'm going to have a
TR catch block for handling our errors and all inside the tri block I'm going to say const response equals a wait call
back whatever this call back is and let's if you want to provide it with some extra arguments I'm going to take
this args from over here and provide it inside of this ARX then I'll say set data to whatever the response that we
get from it so I'll say response and set error to be null but what if we do get any error over here then I'll say set
error to be error now after this set error I'm going to be displaying a toast as well to the user right and how do we
do that so I'll go to shat CI docs and we have something called a serer that we installed so if I click on show toast
you can see we are able to show these toast so this is exactly what we will be using
so to configure it we have to first you know add this toaster to the code so inside of our app in the layout. JS
right below main I'm going to add this toaster import it from sonor and this also takes Rich color I believe yeah
Rich colors which will display different different colors for different different types of toasts right warning success
etc etc and now simply over here I'll say toast import it from sonor do error and I'll say error. message and then in
the end finally I'm going to say set loading to false that's all now let's take this use fetch hook and go back to
our onboarding form and let's right before it I'm going to say use fetch oops use Fetch and import it and this
will take our server action that is update user and we'll provide us a couple of things like three things right
data function loading and error so error we won't be needing I'll just say loading and rename it to update loading
function rename it to update user function data update it to update result right these three things are the ones
that we are going to be needing and let's call this update user function inside of our onsubmit function over
here so simply I'll have a try catch block over here first of all we will get two things inside of uh like we will get
multiple things out of this values right so if I show you see we are getting the industry and sub indust industry so what
I'll do I'll combine them to form the ID so what I'll say const formatted industry is equals to value. industry-
value. sub industry and I'll take the sub-industry convert it into the lowercase and replace it replace the
space with the dash so it would look something like this so Tech Das software-development something like this
let's remove this and then after that I'm going to call that function so I'll say await whatever the values that we
are providing and the industry key with this formatted industry variable and in the catch I'll throw the error of
onboarding error this error we actually don't need to handle catch over here since we're already doing it inside of
use fetch but again it depends on you right so cool then that's that after we have submitted the form I'll run a use
effect hook so use effect which will run when the component is loaded but will run when something inside this
dependency array changes so I'll put the update result and update loading these two
things inside of it so that it will only run when these two things change right so first of all I'll say if update
result do success is true or update loading is false right that is it has fetched and we are no longer loading
right then what will we do first of all we will show profile updated successfully and let's import this toast
from soner then we will use this router over here and I'll say router. push it to dashboard and router. refresh right
we will refresh the page and yeah I think uh that this should do it let's just try it out I'll come back to this
and let's say industry technology specialization software development years of experience 4 let's select the
Industries or let's enter the skills over here professional bio I am the best complete profile and oh we have to add
the that loading indicator over here as well right and anyway this failed right here good thing now let's just add the
loading indicator to our button so this button in the bottom whenever this is loading I'll first of all disable it
right so I'll say disabled update loading and over here instead this complete profile I'm going to say update
loading is true show this loader right here imported from Lucid react and I'll spin this loader and show Saving else
I'll say complete profile okay let's see what the error was go to terminal by the way server components will display their
errors in this over here and the client components will display in the inspect so of course this is a client component
so let's just go to our use form hook use fetch hook and uh so we are displaying error. message over here I
think we are not properly handling the errors so in the actions user.js in the update user I'll say fail to update user
profile and I'll also add this error do message message plus error do message let's see now it should give us the
exact reason of failure so if I click on complete profile okay uh what is it invalid value of argument demand level
expected so are we not sending the demand level let's see over here demand level is being provided it is medium
over here instead of I think it should be Capital medium instead of small medium and it should be neutral
something like this probably with respect to our enum also one thing I uh made a mistake over here I realized so
we're returning result. user it should not be this we should be returning success to be true and apart from that
whatever the result is right so now let's see let's select the industry technology specialization software
development let me just open that uh Network tab over here as well years of experience for skills to be these
professional bio and yeah let's just click on complete profile let's see if it works okay profile completed
successfully and now we are routed to/ dashboard page amazing let's go back to our database and refresh on this
industry insights table yep we can see the industry insights have been added those default values have been added for
now in the user we can see in the industry we have this tech software developer and this is connected to the
user table we can see in the end right over here amazing so we have successfully created our onboard cing
flow awesome let's go on and generate all of these industries insights using Ai and we will be displaying them right
here just like this right cool then let's go first of all we would be needing the Gemini API key so just
Google Gemini API key and select this first link and you will land on this page let's click on get a Gemini key in
Gemini studio so yep so click on this create API key and over here just select this Gemini API and click on create API
key in existing project and by the way this is free to use so you can see over here I've been proved my API key I'll
just click on copy over here and I'll go back to my project in this EnV file and I will add Gemini uncore API uncore key
right over here great let's close this en EnV now and don't worry about the pricing and stuff because they have a
very generous free plan as well if you want to see I think you go to ai. gooogle dodev SL prising and you can
find the pricing for all of these models over here we will be using Gemini 1.5 flash so this has 1 million token per
minute limit over here let's go on and create our API first over here so I'm going to create a new file called
dashboard. JS to create our user insights API over here to generate the AI insights so let's first of all create
the server action to get the industry insights from our database right so I'll say use server just like we did earlier
since we're making a server action and I'm going to say export async function get industry insights all right similar
to before we will first check if the user is logged in or not so simply I'm going to copy this thing and paste it
right here let's import o from clerk sl/ server and also DB as well now after it I'm going to check if the industry
insights exists inside of this or not so basically this thing right here what we have done over here right let me just
copy it up and paste it right here oops I'll paste it right here but this will not be as easy as this right so I'm
going to remove everything inside of this and I'll say if user. industry Insight does not exist now we are going
to be generating them using AI right so let's just create a function on top of it export cons generate AI insights
equals and this will be an asynchronous arrow function this will take the industry as an input and this
will generate the AI insights for it so I'm going to take this and I'll come back over here I'll say const insights
and we will say await generate AI insights and we will provide user. industry over here for which we are
supposed to generate the AI insights and after that simply what we have done earlier over here we have done this
industry insight. create right so that is what we will do over here going to say const
industry Insight equals a weit DB do industry insight. create and here we will provide it with the data which we
will be receiving from right here right so first of all I'm going to say whatever the users's industry is so I'll
say industry is equals to user industry I'll take this insights and I'll spread these over here and then I'll tell the
user when the next update is going to be happening over here right so I'll say next update equals new date date do now
and I'll add one week time to it right so after one week we will be having a next update for this thing cool then
after this we will simply return the industry Insight but if let's say we already had the industry insight over
here then we don't need to do anything we will return the user. industry Insight over here also we will be
getting this generate AI Insight right so this is exactly what we will be using over here as well we will replace this
code with this code right here very soon so inside of it let's see how do we make a generative Ai call right first of all
we need to install a package to use Gemini API right so I'll say npm install at Google SL generative d a and press
enter there we go it has installed now on the top I'm going to say new Google generative Ai and make sure to import it
from at Google / generative Ai and this will take our API key so I'll say process. env.
Gemini apore key I'll say cons gen AI equals this okay now that we have this instance
of this generative AI class I'm going to say const model I'll Define what model I'm going to be using over here so I'll
say gen. getet generative model and insert this this will take an object I'll say model and we can choose the
model that we're supposed to use over here so I'm going to say Gemini D 1.5 Das flash so I'll be using Gemini 1.5
flash cool then we will take this model object over here and we will go inside of this function and we will prompt it
right so first of all let me just write my prompt over here real quick just like this and I know it's way too big so if
you want you can go on and you can copy it up from my GitHub repo you can simply go to this dashboard. JS and I've
written the complete prompt right here right so what what is this prompt all about so I'm saying that analyze the
current state of this industry that we have over here and provide insights in only the following Json format right
this is the Json format that we want without any additional notes or explanation so for the salary Rangers
I've already showed you right what are all the types of these things is so so I've just provided over here this for
this one enum of high medium low positive negative etc etc right and in the end we have again mention return
only the Json no additional text notes or markdown formatting we're supposed to include at least five roles for the
salary ranges and the growth rate has to be in the percentage include at least five skills and train awesome now how do
we make use of this prompt so after this I'm going to say const result equals a wait mod model dot generate content
right this will allow us to prompt the model so I'll say prompt I'll provide the prompt over here and this will
return us some response so I'll say response equals result do response okay now that
we have the response we need to fetch the text from inside of it so let me show you how the response will be so
there we go I've opened the documentation for the Gemini and here we go in the response body this is how you
will get the response after the code that we have written and if we just want the text like for example over here you
can see we have the text string over here right if we want this we have to do something like this so over here if I go
to the top see they've mentioned response. text this function is what we will have to use right so if I go back
I'm going to say response. text and I'll call this function right here and this should give
us the text response provided by this uh API now this is actually a little bit weird so it provides us a response in
the following format like for example in starting it will add something like this right and in the end as well it will add
something on the Json so we need to clean this response right so what I'll do I'll say const cleaned text equals
text. replace we'll take this text and replace it whatever this these things are over here and the Json and
everything that is additional things that are written over here I will remove all of them with nothing right and just
keep the normal response normal text response over here and I'll trim it if there's any spaces around it as well
right that's all so then we should get some object like this now all we have to do is to parse it and convert it back to
an object you know right now it's a string so I'll just say return json. pars and clean text there we go and I
believe that that is all we need to do over here and this function should now work this get industry insights function
should now work all right so what do I'll go back to this dashboard page. jsx and actually first we need to create a
layout file over here as well to show the loading indicator and stuff so I'll say layout. JS so I'm going to say r a
fce layout let's take the children oops children over here and I'll render them right here okay but before them I'm
going to have a div over here which will render a H1 tag which will simply say industry insights let's give it some
horizontal padding and this D the class name of display Flex items to be Center justify Center and margin bottom to be
two so this is on the very middle of the screen right and for this H1 tag I'm going to say text to be 6xl font bold
and gradient title so that is is displayed in our gradient format right and regarding this children over here
right we will be making an API call inside of page. jsx so that will be fet that will be fetched on our server right
so we have to something called as suspense that is until that is fetched we want to show some loading indicator
right we will put the children inside of it let's import suspense from react and I'm going to say fall back and over here
we can show some fall back UI which can probably be a loader right so let's import a like let's install a library
over here npm install react Das Spinners right so this will install a bar loader as well which I want to use over here
like let me show you Yep this this thing is what I want we have more types of loaders over here if you want you can
use some other loader that's fine let's close this and if I go back it's installed and over here I'm going to say
bar loader let's import it from react Spinners and I'm going to give it some props like class name to be margin top
of four width to be 100% and color is going to be gray cool then okay so the default export is not a react component
in dashboard / page let's see what's wrong so print page. jsx it is a react component what's going on let me refresh
this there we go it's working we can see the industry insights heading over here great also I forgot to do one thing if
we go back to this user.js I mentioned that we will be replacing this uh with the AI generation later on right so I'll
just uh remove this for now and what I'll do I'll go back to my dashboard. J so we're doing this over here right so
let me just copy it and paste it right here and instead of const I'll just remove the con from here and yeah that
is all we need to do and this will fetch our AI insights let's just import it and now what I'll do let's go back and
delete the industry insights the empty uh industry insights that we kept over here right so let me just go on and
delete one record and now go back to our app refresh it this should take us to our onboarding page yep like this so now
let's select technology I will choose software development years of experience let say four I'll choose the same thing
and professional bio okay let's click on complete profile and let's see if this you know fetches the AI insights or not
okay looks like something failed argument industry might not be null uh let's check okay so over here instead of
user. Industry we're supposed to provide this data. industry right because that is where our industry exists for now so
make sure to replace on both of these places and now let's try it again I'll click on complete profile there we go
profile completed successfully and now let's go back to our database and refresh this page let's see if we have
the AI generated insights or not there we go amazing we can see all of these salary ranges over here for different
different uh roles if I go back uh forward you can see growth rate demand level high top skills let's click on
this yep we have some top skills Market Outlook positive and other things have been populated as well amazing so Yep
this is how easy it is to generate stuff using AI apis like Min let's continue to build this page now I'll go back to my
code inside of this where is it yeah page. jsx now over here first of all I'm supposed to fetch the industry insights
right so apart from this I'm going to say con insights equals await get industry insights this is the server
action that we just now created if I go to it you can see it takes us to the dashboard. JS page right so this is
where we will get all of the insights over here inside this D I'm going to be creating a component called
dashboard view so again we're creating this separate component because we want this to be a client component and this
right here is a server component so I'll say dashboard view insights equals insights okay this obviously does not
exist first of all I'll just give this some class name class name of container and margin horizontal to be Auto so that
they are in the middle okay let's get this dashboard view component so insert this components right here I'll say new
file Dash board- view. jsx r a fce dashboard View and this will take the
insights all right also here we will be using like we will be displaying charts and stuff as well right so if I go to
our deployed app like this right so for this thing we will be using something called as recharts library right so also
I think we have some error over here let's make this component use client first and then we'll come back to that
error also we need to install the recharge library right npm install recharts press enter let's go back and
see I think that error was temporary no it still exists so it's saying that uh unique constant failed on fields
industry what's wrong let's see I think this error is over here in the dashboard. JS file so while fetching the
user from our DB we're supposed to include the inter industry insight as well right so I'm going to say wear this
and include industry insight to be true now this should work this should fetch if the industry Insight is there or not
okay yeah now it's a separate error dashboard view is not defined so dashboard view let's import it so let's
go back to the page. jsx and over here I'll import dashboard view component now let's go back there we go it is rendered
great now let's prepare our data that we are supposed to display right over here like this like Market Outlook industry
grow demand level top scale uh categorizing you know salaries by the role all of these key trends and
recommended skills right so I'll go back to the dashboard view component and inside of it first of all for the salary
data so let's see how we structured it so it looks something like this right roll minimum maximum for each uh you
know role and the location as well so I'll simply over here I'll say const salary data is equals to insights do
salary ranges do map and I'll map through each and every one of them and I'll categorize them in name Min Max and
medium right so the reason why I'm structuring them in this way so that recharts is able to render them let me
show you so if I go to recharts library and over here we would need this simple bar chart so over here simple bar chart
you can see this is kind of similar to our example it's just our example has three values so you can see name and it
has one value second value and the amount right the this thing amount over here so yeah we will come back to this
but let's prepare our other data as well so apart from salary data let's structure the demand level so what about
the demand level so it can be high medium or low right so I'm going to say I'm going to create a get demand level
color function over here which will take the level and we'll have a switch case first of all we'll convert it into the
lower case right so I'll say if it's high it's green medium yellow yellow low red by default it will be gray 500 okay
then after it for our Market Outlook it can be positive neutral or negative I'm going to create a similar function over
here if it's positive it will have the trending up icon from Lucid react for neutral it will have line chart else it
will have the trending down right and respective colors for each and every one of them okay and since Market Outlook
will just have one single value so let's just U you know calculate the icon and color right below it so I'm going to say
Outlook icon is equals to and I'll take this function over here and I'll provide the insights. Market Outlook to it same
with the color as well and I'll take the icon and the color respectively now we want to format the date because we are
also supposed to display this thing over here so if I go to deployed website we're supposed to display this last
updated right and it's optional if you want to add the next updated or not I'm simply rendering it right here next
update in these many days right okay so for last updated I'm going to something like this I'll use the format function
which will come from date- FNS Library which is an awesome Library if you want to manage dates inside of your
application so I'm going to say npm install date- FNS and press enter I would highly recommend you to you know
read more about it from their documentation so they have a few functions that we will be needing inside
of this project first of all the format which will be used for formatting our dates right we have provided this date
of last updated and I'm saying format it in this format right here next to calculate the distance between the
today's date and the date when this will be next updated I'm going to something like this const next update distance is
equals to format distance to now so we will also be taking it from date- FNS and I'll provide it with the first date
that is the next update date and it will calculate the distance from now to this this particular date right so let's just
import both of these so on the top I'm going to say import format and format distance to now from date- FNS great and
also this add suffix basically adds this x ago or X days remaining something like that in our local language right that's
why we need ad suffix over here cool then so I guess we have prepared our whole data let's start rendering them
right over here right so instead of it first of all you can see we have to render this last updated badge so we
have uh already installed badge from shat CN UI if you want to see this you can go right over here in the badge and
this is how you use it right so let me just copy it up and inside of this div I'm going to have another div with the
badge which will simply render last updated to be this last updated date let's just give this the class name of
display Flex justify between and items to be Center and I'll provide this parent Dev as well some space y of six
between everything inside of it right so let's see how this looks okay I have not imported badge so import badge from SL
components folder yep something like this let's add those cards over here for our Market overview and for cards
obviously we'll be getting cards from Shad cnii so in the Shad cnii docs I'll go to card and I'll copy this thing up
copy it up coming back and below this de I'm going to have our D which will contain all of them so let's paste the
first card and we are not going to be needing the footer let's import the header the title not going to be needing
the description let's import this card card content and yeah let's see how does this look yeah pretty cool for this one
the title will be Market Outlook and let's display the icon below it so it will be this Outlook icon and I'll make
it this Outlook color as well so I'll say Outlook icon and class name will be H1 like height to
be four width to be four and I'll give this the color that is according to the Market Outlook so let's see yep
something like that and inside of the card content I'm going to be adding two things first the div which will say how
the market is right like positive negative Etc and the next update so next update distance is in 7 days and you can
see it was last updated today so it shows this thing right here okay for this card header I'm going to say
display Flex items to be Center justify between so that they are in the very center space y to be zero between them
and padding bottom to be two so let's see yep something like that and for the card title I'll say text to be small and
font to be medium and actually I'll say Flex row over here so that this is in one single row okay yeah that looks good
let's make space for four different divs over here right so I'm going to give this display grid for the parent div and
grid columns 1 for the smaller screens in the medium screens I'll say grid columns to be two but in the larger
screens so I'll say I'll say grid columns to be four and some gap of four between them so now you will see yep we
have one single card and we have space for four more cards over here let's just duplicate this card three more times so
1 2 3 Let's see yep something like this now let's start updating each card one by one let me just put some gap between
them so that it's easier to differentiate so for the second card I'm going to render the industry growth and
this will have the trending up icon right to demonstrate the industry growth and I'll render over here the percentage
at which the industry is growing so I'm going to say insights. growth rate. to fix and I'll add the percentage over
here all of these things are already provided to us using the AI insights right and then after this we will render
the progress component so if you go back to shat scen ui's documentation over here we have a progress somewhere around
here yep this one so this is what we will be rendering so let's take this and I'll paste it over here make sure to
import it from SL components and value will be this thing insights. growth rate so I'll copy and paste it over here and
simply I'll say class name to be margin top to two yep something like this let's see how it looks like I come over here
yep this looks good after this for the third card I will render the demand level and simply over here I'll say
insights do demand level and after this instead of this P tag I'm going to have a div over here which will just display
the demand level so let me just bring in real quick so over here I'm going to say a div with the class name of height two
width full rounded full and margin top to be two so we are just going to be showing over here a color right so we
using this get demand level now if you want you can also use over here this progress bar right you just have to keep
the value to 100% and change the color so it would look something like this right and let's change this icon over
here as well instead of this Outlook icon I'm going to say briefcase icon with the text muted foreground let's see
I have not imported it so import it and let's see yep something like this then for the fourth card let's display the
top skills over here so instead of Market Outlook I'll say top skills and here I'm going to going to render the
brain icon from Lucid react and then right here I'll just get rid of it and we will have our div and inside of this
div I will render all of the skills right so I'll say insights. toop skills. map and I will render a badge icon over
here simply like the a badge over here with this skill and variant is going to be secondary and instead of this class
I'm going to say display Flex Flex to be wrap so that they can go to uh you know next line and GAP to be one between them
let's see yep something like this this looks pretty good so far now below this we are supposed to render the chart
right the graph over here so let me just take this card and duplicate it one more time and we are not going to be needing
these class names over here now let's get rid of this insert the card header simply we will have two things right the
card title salary ranges by rule and the card description let's import displaying minimum median and maximum salaries in
thousands right in obviously dollars let's remove everything inside of this card content over here let's see how
this looks okay there we go we are supposed to display the chart below it so let's go to the recharge library and
over here this is what we will be getting this responsive container right so I'll just copy this whole thing up
till this point and insert this I'll have a div which which will have a class name of height to be 400 pixels and to
give it in pixels you have to wrap it in this square bracket and now paste it right here right so import responsive
container this bar chart from recharts this cartasi grid xais y AIS import the tool tip we don't
need the legend but we would be needing these bar component over here right so import the bar component and obviously
I'll come to these one by one so let's see from the beginning so this responsive container is basically to
make sure this is responsive in the smaller screens as well the chart is responsive in smaller screens right so
this would need some data over here the bar chart so we will provide it this um data of salary that we have created
earlier so salary data if you remember this salary data right here we'll provide it in the data field and that's
all let's remove this width height and margin from over here then in the Cartesian grid we will leave it as it is
x-axis data key will be the name y AIS we will leave it as it is in the tool tape yep so over here if you go back to
our deployed app we have this in the tool TI right the name of the role minimum salary medium salary and the max
salary right so this tool tip actually takes something called as insert this we can have a call back function so
something like this and we can take things from our data inside of it which are active payload and label so what is
active active is basically if we are hovering on any one of the bar charts it is true right and if it's false then
tool tip is not displayed okay what is payload payload contains basically all of the data that is inside of over here
in the salary data and the label will basically be the name so this thing right here so this name right here right
cool then let's go back inside of this call back and simply I'm going to check if we are hovering on this that this is
active and payload has something and payload do length has something right then we'll do something inside of it
what will we do I'm going to say return a Dev over here with the label and then after that we have the payload right so
in the payload we have three things the minimum salary the maximum salary and the median salary so I'll render them
one by one the name like the median Max etc etc and the value right in K like in these many k dollars,
right if not I'm going to return null in the very end and obviously we're going to provide them some styles again you
are free to customize them as you want I've just provided some background color and some Shadow to it and some font
medium to this P let's see how it looks so if I come over here okay it's saying page not found I believe we have to do
more over here rectangle is not defined okay yeah of course we have not configure this bar at the bottom so let
me show you quickly what will we do over here so it takes three things data fill and active bar so each bar represents
like min max or median so over here I'm going to display this so first will be data key Min fill you can you know
provide any color I've provided a shade of gray over here all of these are the Shades of Gray and the name me m salary
to be this thing data key is main over here it's important that it is what you have written right here right min max
and median so now this should render yep something like this you can see and when we are hovering on these we can see the
label over here as well this looks beautiful now after this inside of our deployed website we can see we're
supposed to render the industry Trends and recommended skills this will be easy right let's go back to our code below
this card I'm going to actually duplicate this card again and let's remove everything inside of the card
content and for the title and description I'm simply going to say key industry Trends and current trends
shaping the industry and also we will have two cards over here let me just duplicate it and put both of these cards
inside of a d so that we can you know create a grid of these two cards so I'll give this the class name of display grid
grid columns one in smaller screens above medium screens it will be two columns and gap of four between them
let's see if we come down yep something like this now we have the key trends so we should be displaying them in points
just like this right so we'll be using a ul and Li tags so inside of the card content I'll say UL tag let's give this
the class name of space y to be four and inside of this UL tag I'm going to say insights. key trends. map we will take
each and every Trend and we will render inside of a list item right with display Flex items start and Space X tob2
between like both of these three like both of these things right first it's going to be a DOT over here and then a
span we have added this dot because by default chat cnii you know removes all of these styles from CSS so yeah we will
render the trend and if I go back yeah this is our app so you can see it has been rendered right here for the next
recommended skills right so I'll just provide the title and description over here and skills to consider while de uh
developing inside of this card content again we will render the recommended skills array as well everything is like
absolutely the same right we just at this point we just repeating stuff so we're just rendering all of the badge
just like we did earlier for this thing right here top skills so yeah you can see recommended skills has been rendered
and yeah with this we have completed this industry Insight page now one very crucial thing remaining over here and
that is we need to make sure that we fetch it every single week right so now we have to come back to inest and we
have to configure our background job for this so what I'll do I'll go to my let's just compress it and go to this lib
folder inside the inist and client.js and actually functions. JS not client.js and here we will be creating our
function which will be making the use of gini API and fetching the industry insights so here I'm going to be
creating a new function Sol export const generate industry insights equals inest do create function just like we did
earlier similar to this we will be creating a new inest function and you know what let's just go on and run our
injust client so npx inest CLI at latest Dev right so press enter okay let's open this Local Host link and there we go if
you go to the apps you can see it shows no functions registered so never mind we'll come back to this so over here
inside of this create function as I told you the first object takes multiple things like ID name etc etc right so
I'll just provide the name which will be generate industry insights then we will have another object over here where we
will be creating our Cron job now what is a Cron job so cron Expressions look something like this right now you might
be confused what is this all about so this basically means that this job this function will run every single Sunday at
midnight now how do you know what Crown to write over here first of all each and every one of these mean something right
so if I show you I've opened claw AI over here and I've simply asked it to explain what cron is right so this will
be more easier for you to understand so each and every one of these mean something like first one means the
minute then the hour then the day of the month then the month and the day of the week right it can be 0 to 6 like if we
want to run it on Sunday we would put zero over here right like just like they've given this example over here we
can Define exactly on that particular day what minute this will run so I'll put zero what hour I'll put zero that is
midnight day of the month I will put star that means every single day of the month and what which month that means
I put a star over here that means every single month of the year right so this is how you write Chon expressions and
again if you want to you know write cron for anything simply come over here to CLA or you know chat GPT and ask it to
generate a cron expression to you that is much more easier right so coming back to this after this we will have a call
back function right so I'll take the call back function this will be an asynchronous call back function and
again we will take the steps over here so as I already uh showed you earlier we have different different steps for a
particular job right so first of all we will fetch all of the industries over here so we want to refetch all of the
data for the industries right so we want to uniquely fetch the industries so I'm going to say const Industries equals
await step. run so this is the first step that we are running and this is called as fetch Industries and start
this we have provided this call back what it's doing over here it's taking this DB let me just import DB over here
it's saying db. indust insights. find many and we are selecting all of these industries right over here okay so
inside this Industries we will get all the industries cool then we will Loop through all like each and every one of
them so I'll say for const industry industry of Industries right so basically we are taking out this
industry from each and every object of these industries right inside this for Loop now again we will be running that
API call over here so in just actually provides some functions right out of the box for making the uh you know API calls
so let me show you in their documentation yep over here in the AI inference you can see they have this
step. a. RP and step. a. infer these two types of functions what we will be using is step. a. RP over here if we further
scroll down you can see not this one if we further scroll down you can see this is an example of step. a. infer simply
we are providing this unnamed and then we're sying step. a. models this is an example of open AI model but if you want
to use Gemini it also supports Gemini right and we can provide the exact model name for it and then we can provide the
prompt and you might be thinking what uh you know what is the benefit of using these right r or infer so basically
these functions provide us additional information about our API right like metrics data sets and adds the
monitorings to our calls right so it is much more easy easier to Monitor and get the information from these apis so this
is what we will be using so first of all we will be providing it any name you can name it whatever right then we'll be
providing it a call back function we'll be fetching the content and then the prompt right so if I go back now let's
bring our prompt back so we had written it over here in the dashboard yep let's take this prompt from over here and I'll
paste it right here after this we'll be making use of ai. trap right so I'll say con
response equals await step. a do WP and you can read more information about it over here as well now what should we
call it let's call it Gemini then let's have a call back function over here let's make it an asynchronous since
we'll be fetching the API data then the third thing will be our prompt right so how do we get the prompt inside of this
function we'll get it from right over here and inside of this simply we will be using the same thing this await
model. generate content so I'll paste it right here instead of prompt I'll provide p over here and I'll say return
cool so this should give us the response that we need now from inside of it we are supposed to fetch our text right so
after this I'm going to say const text equals r s. response. candidates you you might
remember earlier in the video I showed you what response jini AP provides us so candidates zeroth index we'll take the
content we'll take the parts zeroth index and then we will get the text if you want to get more information about
it you can just you know simply console log and you will realize it's this thing right okay if this is not there we'll
just take it as an empty string and then obviously we're supposed to clean it as well just like we did earlier over here
clean text so I'll paste it right here cons clean text equals text. replace this and trim and yeah that's all after
this we will do json. and provide it with this clean text cool then now all we need to do is need to update our
database right so I'll say a wait step. run in this step we will be updating our database so I'll say update let's keep
it inside of back Tex actually update this particular industry so industry insights and then we will provide the
call back after it so it will be an asynchronous call back it will be a simple API call to our database just
like we have done over here this thing right here I'll just copy it up and paste it right here so db. industry
insight. update and I'll say where industry is this and the data can be I'll say insights and I'll update the
next update so whatever the date do now is and I'll add one week to it and I'll add the last updated as well which is
going to be the current date which I think will automatically generated by our DB as well right so yeah I think
that should do it the only only thing remaining over here is this how do we provide the API key to inest right so we
have to basically go to our client.js and over here after the name I'm going to provide credentials inside of the
credentials it will take Gemini and the API key which is our Gemini API key yep that is all let's go and try it out so
I'll go back to my inest de oh sorry I have not provided it to our API right arang just API so instead of our app the
API route. JS yep let's provide this function over here generate industry insights and now if we go back and
refresh it you can see one function found let's go to the functions yep there we go let's click on invoke and
invoke function and let's see how this is running okay it has fetched the industries but something went wrong with
Gemini let's see what went wrong model is not defined okay let me just cancel this job and see what's the error so
model yeah this one we need to have the model right just like we did over here yeah we need to copy it up and actually
and I realize uh this will get the Gemini API key from here as well but that credentials that I showed you that
we added that can work in you know cases when we are using ai. infer right which uses the model like this like this right
in this case we don't need to create models separately it's just taking it directly from step. a. models right so
yeah let's just copy it up and paste it right over here on the top let's import Google generative AI over here and now
we should uh be good to go let's rerun it let's close this one and open this okay fetch Industries it worked let's
see if Gemini works or not okay looks like Gemini has fetched the data and you can see this is the exact content that
we get in the response and see this is what we were trying to clean from our response and if we go further yep we
have updated all of the industries as well amazing so you see how easy it was to set up a background Cron job you
might have thought I'm pretty sure that this would be something very difficult but see it was a piece of cake I would
say with the help of inist creating a background function is super easy and I have actually uh you know discussed in
just in one of my previous videos of Finance platform as well so you know after you have done following this
project you can go and follow that project as well all right then so we have successfully created our industry
insights feature now this is my most favorite feature that is the interview prep we are going to be creating the
interview prep page which will be this slash interview page right here so first of all I'll go to this actions folder
and create the apis for generating the quiz and saving the results of the quiz so I'm going to say interview. JS inside
of this I'm going to be creating a function called generate quiz the server action and I'll also use the use server
at the top this is very important don't forget it now inside this what will we do first of all obviously we need to
check if the user is logged in or not so let me just take it from right here let me just take it from this server action
and just paste it make sure to import o from clerk sl/ server and I'll also import DB from the Prisma file okay now
after it we're going to have to write the prompt for you know generating our quiz so let me show you how I'll do it
so here it is I'm going to say generate 10 technical interview questions for a user. industry like whatever the user
industry is I'm going to say generate 10 interview questions for this and since we already have the user skills right
then we will say if the user uh skills are there I'm going to say with expertise in whatever the user skills
are right else we will give empty string and then I'm going to say each question should be multiple choice with four
options and we have to return the response in the Json format only no additional text and the format will be
this like the question like the array of questions with the question options correct answer and the explanation of
that answer right so yeah pretty straightforward if you don't want to write it over here you know just you can
go to my GitHub repo and open this interview JS file and copy this prompt from there after this we will write the
same thing that we have done earlier over here I believe in the dashboard JS right y to structure the response I'm
just going to copy this up up and paste it right here so result will be model. generate content on obviously we need
this model as well right so I'll take it from right here and put it on the top right over here and let's import the
Google generative AI from at Google / generative Ai and then over here I'm going to say model. generate content
with this prompt response will be result. response and obviously we are supposed to clean the response as well
right so I'll just copy both of these just like this instead of learning this I'm going to say cons quiz equals json.
bar clean text and then in the end we would get the array of all the questions right so I'll simply say return quiz do
questions and I think we should keep it in a TR catch block so let's keep it in a TR catch block I'll move this part
I'll cut it and move it right after the return and inside of the catch I'm going to say console. error error generating
quiz and throw error fail to generate quiz questions okay now after we have attempted the quiz right we also want to
save the results of the quiz right so I'm going to be creating a new server action called save quiz result which
will take all of the questions that is this array that was provided to us all of the answers by the user and the final
score of the user right we will calculate these things in the front end and then send it to this save quiz
result server action again same thing we will check the user Authentication first so I'm just going to copy it and paste
it right over here now we first of all need to structure what we are going to be sending to our DB right if we refer
back to our schema so right here schema. Prisma we have this assignment right so inside of this we will be storing it
inside of this questions like array of questions answer user answers and what is the correct answer and also the quiz
result so if I go back I'm going to say const question results and I'll take each and every
question like questions do map and we will return an object from inside of it I will take each and every question over
here and the index of that question and this array that we will be forming will contain first of all the question right
so I'll say question equals Q do question then the answer the correct answer that is not the users answer so
I'll say Q do correct answer then I will take the users answer right so we have the users answers array over here so
we'll simply use the index so I'll say user answer equals answers and this Index right here if it's the correct
answer or not so we will compare both of them so I'll say Q do correct answer if it's equals to answers index then this
will be true or false accordingly this will help us to you know render rui even better with less calculations and
obviously the explanation for each and every question and yeah this is what we will be storing inside of our database
but first of all for each and every quiz if you might remember we have this Improvement tip as well right so
Improvement tip will obviously be based on the questions that are answered incorrectly by the user right so we
would fetch all of the answers that are been uh you know like the all of the wrong answers so over here what I'll do
I'm going to say con wrong answers equals questions question results do filter and whatever question is not
correct that is not Q do is correct we will take it from this particular array right and now we will take this wrong
answers and we will feed it to Gemini API so I'm going to say if wrong answers. length is more than zero only
then we will generate the Improvement tip so let's fetch all of the uh you know text from inside of this array so
I'll say con wrong questions text equals wrong answers. map and for each and every child I'll form a text right it
will be question whatever the question is the correct answer and the users answer right three things and this is
what we will be providing for each and every question we will be providing for uh the AI the Gemini Ai and then we will
join all of them so after this simply I'm going to form my prompt and again if you want you can get this prompt from my
GitHub repo as well or you can just watch this video and copy from over here so the Improvement prompt the user got
the following whatever the industry is let's say software development industry technical interview questions wrong and
then we will provide this thing that we generated right here right and then I'm going to say based on these these
mistakes provide a concise specific Improvement tip focus on the knowledge Gap revealed by this wrong answer and
keep the response under two senten right we don't want to keep it longer so that our UI breaks don't explicitly mention
the mistakes instead focus on what to learn and practice cool then I think this will help the user a lot then
simply I'm going to have the TR catch block and we will make the call to Gemini API so I'll just go up here and
just take this just like we've been doing up until this point and I'll come back and paste it right here so result
await model generate content and let's take this Improvement prompt and provide it to it and actually since this is not
going to be a Json so we won't be needing this cleaned text over here and neither this json.parse let's just
simply trim what we get after it right and let's see we should take a variable over here for the Improvement tip as
well right so before this I'm going to take let Improvement tip equals null and I'll update it after it like after we've
got this so instead of this text I'm going to say Improvement tip equals response. text. trim and yeah that's all
uh if there's any error we will just console log the error and then outside of it let's store all of this inside of
our database right so I'll have another Tri catch block and obviously this thing is optional since it depends on the
wrong answers if wrong answers are there only then we will make this Gemini API call so now simply over here we will
feed it to our assessment table so I'm going to say const assessment equals await db. assessment. create and we will
provide the data from over here that is user ID quiz score questions result so if you remember this array that we
created questions result the category and the Improvement tip right cool then after this we will simply return the
assessment and in the catch I'm going to provide the console error that error saving quiz result and fail to save quiz
result and yeah that should do it let's go on and build the UI for it so I'll go to the interview and over here in this
route let's just create a layout. JS file so I'll simply go to dashboard uh layout page probably and just copy it up
and paste it right here let's just get rid of this div on the top and yeah that should be it this will be more useful
when we fetch all of the you know results and the stats in the interview page but let's go on and build this mock
interview page now so over here first of all I'm going to have a div which will contain the link to go back right so I'm
going to have a link tag inside of it which will say hre and this will take me back to the interview page and then I'm
going to have a button inside of it with variant link let's import this button from components and this will have some
class name of Gap two and padding left to be zero because we will have an arrow left and back to interview questions
text over here so let's see so default export is not a react component let me just refresh it yep there we go let's go
to// mock over here and then you'll see that link Arrow left is not defined obviously we have not imported this icon
right here and also uh let's just add some class name of display Flex Flex to be column space y to be two and margin X
to be2 because right below this link we will be adding our heading over here as well so let's see yep there we go
something like this back to interview preparation cool then so below it I'm going to have a Dev over here which will
contain an H1 tag and a paragraph tag just like we've been doing up until this point H1 tag will be text 6 Excel font
Bold and the gradient title class that we created three specific questions and this will be a text muted foreground so
let's save it yep something like this sorry below this div is where we'll be rendering our quiz interview question
opponent folder over here quiz okay let's see oh we have not imported I believe so let's just import it over
here as well and yep we can see this quiz right here all right so this is let's go ins start this quiz. jsx for
each and every quiz let me just first you know let's just have a look at the deployed app and go to the interview
prep section let's start a new quiz so over here you can see we have a box saying ready to test your knowledge and
as soon as we click on start quiz it will obviously make the call to Gemini and will generate five or 10 questions
whatever for us there we go now notice for each and every question how many states would be required first of all
when we are selecting it we need a state to store uh the answer right another state for you know storing whatever the
current question is and also these explanation with respect to each and every question right not exactly the
explanation actually uh if you're supposed to show the explanation over here or not right if it will be a true
or false state so if I go back I'm going to take three states over here and obviously since we're using States we
need to make this a client component so use client let's import use state from react and yeah you can see I've taken a
current question all of the answers array and the show explanation Boolean okay now we would need to fetch
the data right so again we have already created that use fetch hook so I'm going to be using the use fetch hook let's
just import it and this generate quiz server action that we created and we will take the loading rename it to
generate quiz generating quiz and function rename it to generate quiz function and data to quiz data right and
we will use this function right here to call this and you know generate all the questions using AI let's just first
create that UI where we will you know show that box to the user so that they can click on start quiz button and start
the quiz so I'm going to say if no quiz data is present then I'm going to return a card over here right so let's just get
the card from Shad ceni from over here let me just copy it and paste it over here we won't be needing the card
description for the title let's say ready to test your knowledge inside the card content I'm going to say this quiz
contains 10 questions blah blah blah you've already seen this right text muted foreground and in the card footer
let's just display a button saying start quiz and this will be width full so let's see card is not defined obviously
we have not imported all of these three uh things so card header card title card content card footer and is button there
no let's import the button as well and let's see yep something like this let's create some Gap between them or actually
on the sides so I'll say MX to be 2 that is margin horizontal to be two and for the uh page. j6 let me just give some
class name over here which will be container margin horizontal to be Auto some space between these and some
padding vertical to be six so now you'll see yep we have some spacing between them cool let me just close this now
when we click on this button start quiz button we want to call a function right so I'll say on click
generate quck quiz function which you already know comes from right here cool so when we click on it this will
generate the quiz let's just show the loader as well I'm going to say if the quiz is being generated like if
generating quiz then return bar loader let's import this bar loader and same things that we have already given it
earlier and also as soon as the quiz is generated what I'll do I'm going to say inside of the use effect let's just
import the US from react I'm going to say if the quiz data changes then set all of the answers in this set answers
array cool then so let's just work on the UI so first of all uh you can see the current question is zero by default
right so that is where we will be starting our quiz from from the zeroth index so after this I'm going to say
const question equals quiz data and whatever the current question is it's on the zero so that will be our current
question so insert of this div is where we will be writing our UI and instead of this div actually I'll just take this
card and paste it right right here yep and let's update it so for the card title I'm going to say question whatever
the question is 0 + 1 so obviously we're going to start from zero so 0 + 1 of whatever the total length of the
questions is inser the card content I'm going to render my question so I'm going to say question do question and it will
be text large and font medium let's remove this button from card footer we will come back to this card footer and
after this after entering this question we will render all of the four options over here as well right so for that
we'll be using radio group that we have installed so let's see we have this radio group over here yep something like
this so let's just copy this code from over here and paste it right after this so insert this let me just remove both
of these options over here and yeah so radi inside of the radio group we will render the options from inside of our
question so I'll have uh question. options. map over here let's take the call back inside of it we will take each
and every option and the index of that option let's move this div inside of over here and I'll say return let's give
this the class name of space y to be2 and since we're using the map let's just give this the key of index now for this
radio group item we're taking each and every option right so I'm going to say value will be option and the ID will be
option and whatever the current index is similarly for this label as well I'm going to say HTML for and whatever the
ID of this uh radio group so when we click on this it selects the radio group right when we click on the label let me
just import all of these one by one so make sure to import from SL components only radio group item from SL components
and radio group as well let's see how this looks like so I'll go back to our app and click on start quiz so it is
loading the quiz I believe and let's see and there we go our quiz is loaded successfully amazing now we just have to
work on this UI right now right so let's focus on that let's add the logic for selecting a particular option now for
this radio group I'm going to say on value change and I'll call this handle answer which we will just go on and
create in just a moment and the value will be answers of the current question so if you remember this is an array
populated with null so on value change we will provide the users answer to this handle answer uh you know function so
let's just go on right below this use effect I'm going to say const handle answer equals
whatever the user's answer is I'm going to take that and notice in start of it first of all I'll just make a shallow
copy of the state of the answers right so I'm going to say new answers equals whatever the existing answers is then
I'll take this copy and for that particular question for like whatever the index is right I'll update the
users's answer and then I will update the array back right this state back to this simple enough then after this I'm
going to be adding the Logic for you know displaying the explanation as well so after the radio group actually I'm
going to say show explanation so if the show explanation is true only then we will be showing the explanation so let's
take a div over here andert this I'm going to have a P tag which will say explanation and then another P tag which
will show the question do explanation oops explanation let's keep it font medium and for the explanation
keep the color as muted foreground for the div containing this I'm going to say margin top to be four padding four
background muted and rounded large so let's just make it true so that you can see what are we getting over here oh
sorry I think I lost the UI uh you know what let's just um let's just do it again let's click on start quiz yep you
can see we have the explanation right here let's give some spacing between both of these so I'll go to this card
content and I'm going to provide the class name of space y to be four okay now in the footer and by the way let's
just R it back to show explanation now in this card footer right here we will display the button for you know for
triggering the show explanation only if the user has selected any option and also the ability to you know go to the
next question so pretty simple UI if the show explanation is not true I'm going to display a button over here with
onclick set show explanation to True when we click on it it will be true variant will be outlined and if that
particular question has not been answered I will display like disable this button right and after this I'm
going to have a button for going to the next question so I'm just going to copy this button and paste it right here so
it's going to say if the current question is less than the last question right if we are not on the last question
we will show the next question else we will show the finished quiz and this will also be disabled if the question
has not been answered let's keep the class name to be margin left Auto and on click I will trigger a function called
handle whoops handle next we'll create this function as well so I'll go over here below let's say handle answer I'm
going to say const handle next let's create a arrow function and now notice inside of it I'm going to say if the
current question is less than the quiz data do length minus one that is it is not the last question right then simply
I'm going to say Set current question question to current question plus one and also I'll make this shed explanation
to false so that we don't see the explanation for the next question right away else we will trigger the
Finish quiz function which obviously does not exist yet so let me just create a dummy function for now finish quiz
something like this and we will basically be calculating our score inside of this finish quiz function and
then we will make the API call for saving the result of our quiz so you know what let's just take the other
server action as well let me just import that right here save quiz result let me just import it from SL action SL
interview so over here we'll take loading function data and set data now this set data as I already explained you
can be manually used for setting the data of our quiz so basically when our quiz is done we can take this set data
and you know set it to null after the new quiz is started you know so that our result data state is empty all right so
let's take this save quiz uh result function and uh let's go inside this finish quiz now first of all before uh
you know making this API call we have to also calculate the score of the user so I'll say const score let's just keep it
Zero by default for now and I'll have a try catch block and insert this I'll say await call this save quiz result
function and we will send the quiz data we will send the answers the users answers and obviously the score then we
will show the success toast so I'll say toast. success and make sure to import toast from sonor and set the catch block
I'll say toast. error if you know anything fails over here now let's calculate this score so for calculating
this score let's just have a function called calculate score and this will be a pretty straightforward function let me
show you so if I put it right here so yeah calculate score we will start with zero right the correct answers are zero
so far and then we will Loop through all of the users answers we'll go inside of it I'll say if the answer is equals to
the actual correct answer right whatever the user has answered I'm going going to go insert the user data dot like off
index and take the correct answer will compare it if it is equals to it then I'll say correct Plus+ and then in the
end I will return the number of correct answers divided by total ansers into 100 that is we are calculating the
percentage over here and that is what we will be sending to our back end to displayed all right so also let's see
let's make use of this saving result over here this loading indicator so I'm going to go to the very bottom where we
had our button and I'm going to say this will be disabled when we are saving our result and also let's just display a bar
loader over here when we are saving our result right cool then let's go on and try it out um what I'll do I'll just uh
for now I'll just console log this result data over here just to see what do we get inside inside of it so result
data okay let's go back to our website I'll click on start quiz and I'll open my inspect over here as well console and
let's see so I'll just randomly answer all of the questions over here and let me just do this real quick okay there we
go I'm in the ninth so now after this it should display a finished quiz and let's just randomly choose something and click
on finish quiz and now it's not displaying the loading indicator we'll check what's wrong over here let's see
what happens okay quiz completed and there we go we get something over here we get all the questions the quiz score
10 did I answer everything correctly and I don't think so that would be the case but let's see what do we get over here
okay this is is correct false this is is correct false over here okay yeah you can see it has created the complete
structure for every single thing like uh what is the correct question was what user answer was right I shouldn't have
displayed the quiz score to be 10 probably I did something wrong over here let's check probably we will check it
later on let's just first uh render all of the results and then we can check it so also uh apart from this bar loader
let's just display this loader to from Lucid react I think this will be better uh in showing the loading indicator
right and also let's just check if this has been entered inside of our database or not so I'll go to the assessment
Table and there we go I think we have something over here but this is is wrong most probably quiz score to be 10 this
shouldn't be that the case so let's do one thing I'll go back to the code and above this return and above this not
quiz data I'm going to say if the result data is there I'm going to return a d with the quiz result component and this
component does not exist we will build it right now we will send it the result data in the result and also we will send
it a prop on start new where we will trigger this start new quiz function and this will be pretty simple we will just
you know null everything inside this function so I'll just say const start new quiz equals set currect question to
zero set answers to empty set show explanation to false H we're going to generate know a new quiz when we trigger
it and set result data to null right we just resetting every single thing over here let's just create this component
first of all so I'm going to go and start the components create a new file called quiz result.
jsx r a fce quiz result let's import this component right over here so I actually tried it out once again and uh
looks like this is working now now the quizes score is not being generated fully not sure what went wrong earlier I
tried generating it with just three interview questions let's just put it back to 10 maybe some bug but it's
working fine now so yeah we're good so let's start working on this quiz result component so this quiz result component
we'll be using in multiple places right over here in this quiz component as well and also on the page of the interview
page like the where we'll be displaying all of the stats and stuff as well right so there we don't want to show this
start new quiz button so I'm going to say I'll have a result I'll have highest hide a start new flag over here as well
we won't be using it right here but we'll be using it somewhere else and an on start new function over here as well
okay so first of all I'm going to say if the result is not present obviously return null but if it is present then
first of all I'm going to say quiz result as the title and I'll display the trophy icon from Lucid react and simply
I'm just going to say display Flex items to be Center some Gap to be two between both of these text to be 3 Exel and
gradient title then after it let's just take a card content component from Shad CN uui and inside of this we can render
the quiz result right so first of all the overview of the score I'm going to have a Dev with the H3 of result do quiz
score and whatever the percentage is right this will be in the percentage so I'll say two fixed one and percentage
and we will also render the progress component just like we've done in the you know insights page as well similar
to that we'll be rendering result. quizes score over here after that we would have also gotten the Improvement
tip generated by AI so if you see yeah in these results yeah you can see the Improvement tip focus on mastering blah
blah blah we cannot see it fully right now yeah you can see this tip was generated using using AI so we will
render this now so after this I'm going to say result do Improvement tip if that is present then inside of a Dev I'm
going to be rendering uh P tag with the Improvement tip title and the result do Improvement tip and obviously we will
say text muted foreground for this and font medium size for this then after this we will display question wise uh
you know explanation like what went wrong if and what went right so I'm going to have a div over here with the
H3 tag which will say say question review then below this I'll take the result and map through it so
result do question questions actually do map so we will map through each and every question and we'll render them
over here let's give this div some space y of four and the H3 of font medium and also this paren Dev I'll just give this
margin horizontal of Auto that this is in the very middle and now over here we will have a d inside this we're going
have another day which will display the question and if that question is correct or not so I'm going to have a P tag
which will display the question so Q do question and if it's correct then we will show the check Circle so it will
look something like this and if it's not correct I'll show The X Circle which will look something like this and both
of them will be imported from Lucid react and for this one I'll put the text green of 500 and this one textured of
500 at some generic styles of height five width five and flex shrink of zero this div is going to be having a class
name of display Flex item start justify between and some gap of two between them and this parent div will have the class
name of some border rounded large and padding to be four space y to be two because after this div right here we
will be displaying more things right like our answers the correct like your answer and the explanation of the answer
so first of all I'm going to say your answer is this and if it was not correct only then we will display the correct
answer over here and also we will display the explanation after it regardless of the fact the answer was
correct or not so I'll have a d and I'm going to say explanation and just render the explanation just like we've done
earlier right and yeah after after this de actually after this card component sorry card content I'm going to say if
hide start new is not true then we will display this start new quiz button over here so I'll say up button on on click
on start new that we are getting from right here and yeah I think uh this should do it this should display all of
the results so let's go back and how about we attempt a new quiz over here so I'll click on start quiz and it's
loading it and there we go so we have 10 questions over here let's just randomly answer all of these one by one there we
go we are on the last question now let's click on finish quiz it is loading it and let's see progress is not defined oh
man okay let's just import the progress over here let's see if there's something else that we have not imported I believe
I have imported this how about card footer let's import card footer button let's import button card content must be
already imported trophy is this imported yeah this is imported let's try it out again anyway let's me just put this to
three questions now instead of 10 10 questions every single time this will be easier for me to test it out so again
let's randomly answer them one by one and also let's just click on show explanation and yeah this is working
fine and okay let's finish the quiz and hopefully nothing goes wrong now Q is not defined wow where is this coming
from so quiz result so we are mapping it and obviously we have not taken the que over here and also the index which we
will be using as a key so key equals index and hopefully that should be it let me just try it out again let's click
on finish quiz and there we go we are getting the quiz results just just like this amazing so you can see we have the
Improvement tip on the top I believe this would need some spacing between these so for this card content I'm going
to put this class name space y26 I'm not going to save this right now because this will you know refresh the page so
apart from that let's see the question review yep we can see we have answered all of them incorrectly and we have the
option to start a new quiz over here as well great so let's just click on start new quiz and let's start to actually
attempt the quiz this time and there we go looks like like I have answered all of the questions correctly now great if
you want you can wrap this quiz results into a card component over here as well instead of this div so if I just say
card and if I go back now yeah I think div was much better so I'll revert it back to the dev and cool then next what
I'll do we can click on back to interview preparation and this is the page where we can render all of the
stats related to the you know assessment that user has attempted and all of the quizzes that user has attempted in the
past so let's build this so I'll go to this interview. JS again and let's create the server action for this so
it's going to be pretty straightforward I'll say export async function get assessment and inside this first of all
let's check for the user authentication uh sorry not authentication authorization I'll just copy this and
I'll paste it right here to check if user is found or not then I'll have a try catch block over here
and here let's fetch all of the assessments so I'm going to say const assessments equals await db. assessment.
find many and I'll say where user ID is this whatever the current user logged in is and sort them in the ascending order
with respect to the created and return the Assessments in the end and in the catch I'll again handle the console
error error fetching assessments cool then let's go to our page. jsx and start building it so let's plan this uh
interview page first so so what are the three things that we will be having over here let's go and check inside of our
deployed website right here so first of all we will have these cards which will show us the statistics then our
performance Trend graph and then after it we will render all of these quizzes and when we click on it we will just
reuse that uh you know quiz results component that we created earlier okay so I'll go back first all over here
let's just display a H1 tag so I'm going to have a de and start of this I'm going to display the H1 tag just like we've
been doing up until till now texx XL gradient title and font bold and also let's just give it some margin bottom of
five over here let's save this and check it out Yep this is what we want now below this I'm going to have a div and
we will display three components over here that we already saw right so let's just create uh a new component for each
and every one of them so I'll say stats card and by the way we just now created this API endpoint like server action
right so let's get all the assessments over here so I'm going to say const assessments equals a weight get
assessments let's import it and also let's make this an asynchronous component since this is a server
component and I'll take this assessments and I'll provide it to these stats card over here like that similarly I'll
create two more components and they will also take the assessments one will be for displaying the performance chart
another will be for displaying the quiz list simple enough let's go on and make these
components so inside of the components folder I'm going to say stats cards. jsx R A fce stats cards second one will be
performance chart. jsx let's paste the same code over here and I'm going to rename it so
performance chart and then the third one will be quiz list oops quiz list. jsx I'll rename it to quiz list okay
cool let's just uh import all these three over here stats cards performance chart and quiz list cool let's just see
if it's fine yep we can see all these three over here let's first work on this stats cards so since we have to display
three cards over here inside of it right so let's just use display grid over here so I'm going to say class name to grid
Gap to be four between them and if the screen size is more than medium I'll say grid columns to be three let's take the
assessments over here from the props and now let's see what are all the types of Assessments that we'll be displaying
we'll be displaying the average score the questions that we have practiced up until this point and the latest score
that we got in the last quiz right in the most recent quiz so for calculating the average score it's going to be very
simple we'll be taking all of the assessments over here right first of all we'll check if we have any assessments
or not if we don't we'll just simply return zero but if we do I'm going to say assessments. reduce I'll take each
and every assessment and the sum like this is an accumulator and this is the each and every value if you know about
reduce I've created an in-depth video on map filter reduce if you want to check it check it out you can you know go and
search my channel so I'm going to take an accumulator and the assessment so by default sum will be zero and we will be
adding assessment do quiz score to it so we will get all of the total and then we can simply say total divide by
assessments. length and we will get the percentage for it now if you want to get the details of the latest assessment
simply I'll just say if assessment. length first of all we'll check if it's there or not else we will just return
assessment of zeroth index and we will get the latest assessment then how do we get the total number of questions I'm
going to say const get total questions and inside of it again we will have the check for it and I'm going to say
assessments. reduce this time instead of this uh quiz score I'm going to say qu questions. length right so we will take
each and every quiz and add the questions length inside of it right so cool then we got all of these three
stats right here now insert this div I'm going to be using three cards so we have already created similar cards right if
we go back to our industry insights see we have created similar cards over here as well right so these are very similar
to what we will be building over here so what I'll do I'll just go back to dashboard right here and let's go over
here dashboard View and let's just take this first card and let's copy it up let's go back and I'll paste it right
here let's just import all of these things card card header card title instead of Outlook icon I'll just say
trophy icon card content and yeah let's work on this I'm going to say instead of Market Outlook I'm going to say average
score and instead of this I'll have simply H4 withd for and text muted foreground and here we can display the
average score right so this thing get average score so I'll just take this and put it right here call this function and
put a percentage after it and on this line I'm going to say across all assessments so let's see if this looks
good I'm going to go to the interview prep page yep that is exactly what we want let's see if the UI is similar to
this yep it's exactly the similar to this one and these other two cards will also be same so let me just duplicate
this card right here two times in the second one we want to display the questions practiced so instead of
average score I'll say questions practiced instead of trophy I'll have brain as the icon Let's uh render the
total questions over here so I'll say get total questions and below it total questions okay for the third one I'll
display the latest score so instead of average let's say latest score here instead of get average score I'm going
to say get latest assessment and I'll take out the quiz score from it fixed to one decimal point and I'll say
percentage instead of across all assessment I'm going to say most recent quiz right let's check it out yep there
we go looks good let's start working on this performance chart now so I'll go to this and this will be using like making
the use of recharts right so let's see what chart will be uh building over here so it must be a line chart right so
let's see I'll go to the rechart documentation and open this simple line chart component so you can see this is
how we will be using it let let's come back to this first let's prepare our data for rendering the chart it will be
very similar to how we did earlier so first of all let's just create a state over here and also we need to input the
assessment right so I'll say assessments and let's create a u state for chart data chart data and set chart data and
now after it I'm going to say use effect and I'll run this use effect as soon as we render this component right so as
soon as the assessments changes we're going to write the logic inside of it so I'll say if assessments has anything
inside of it I'll say const formatted data equals assessments. map and I'll take each and
every assessment and go inside of it and I'll format it so we want two things we want the date and we want the score for
that particular quiz right so that's what we'll write over here so instead of this curly braces actually I'll have a
round bracket or parenthesis and then inside of it I'm going to create an object like this and I'll have a date
and I'll format it so for formatting it we will be importing format from date- FNS just like we did earlier and we will
provide the date of when that assessment was created and we will provide this formatting right month and date like for
example January 2 or something like that right and this score for that particular quiz and that is how we will get this
formatted data and let's just set this data after xile say set chart data to formatted data cool let's just take the
card component from shat CN UI uh to render this what's going on oh sorry this is a client component right so I
have to use use client over here directive so that uh it does not break let's go to shat CN UI and I'll take the
card component this one let's copy it up and paste it right over here we don't need this div over here get rid of it in
the card title I'm going to say performance Trend and let's make this a gradient title right just like we've
been doing up until now so I'm going to say class name is going to be gradient title text 3 XEL and in the larger
screens text is going to be 4 XL let's see how this looks card is not defined of course we have not imported all of
these things card card header card title card description card content and no need for the card footer let's see now
yep that is what we want let's provide the description to it and that will simply be your quiz course over time
okay so now instead of this P tag over here let's just take that chart from recharts so simple line chart and let's
just copy this responsive container from over here till right here let's provide a div over here first of all and I'll
give the class name of height to be 3 100 pixels and then inside of it I'm going to paste that responsive chart
let's make sure to import all of these things line chart from recharts make sure to import it from recharts only
cartasi grid xais y AIS tool tip from recharts as well we won't be needing the legend and we will just have one line
right so I'll get rid of this one I'll just have this line right here okay let's see I think currently it will be
breaking since we have not provided dat yep we have not puted the data so let's see over here in the line chart let's
get rid of this and this instead of this data right here I'm going to say chart data right then uh for this Cagan grid
let's keep it as it is data key will be the date so we have date and the score right you can see date and the score so
on the x-axis I'm going to keep the date and on the y axis it will go from 0 to 100 right so I'm going to say domain it
goes from 0 to 100 and it will map the scores over here now for the this tool tip if you remember uh let me show you
so yeah you can see it is starting to show up see we have this tool tip over here with score % Etc right we did this
earlier when we were working on the uh insights so it takes something called as content oops content inside this we will
have a call back function and this call back function will take active and payload the these are the two things
that we will be needing right now so I'll say if it's active that is we are hovering on it oops Act
and payload has something inside it it's called payload do length let me just put a optional chaining over here so that it
doesn't break and inside of this I'm going to return a very simple de which will contain the score and the date so
I'll have two paragraphs score payload do value percentage right and the date of from inside of that payload and let's
provide it some background as well so I'm going to say BG background border rounded large padding to be two and
Shadow to be medium let's check it out this looks like if I go back to my app okay yeah again we have not rendered the
line over here right so yeah we have to configure this so line will display the score right so uh data key can be score
stroke I'm going to provide the primary color from shat cnii if you want you can provide it some other color as well and
instead of this active dot over here I'm going to say stroke width and let's provide it to be two let's check it out
now there we go it looks awesome with all the tool tool tip and everything right we can see over the time how we
have performed in the quiz we can see the questions practiced latest score and the average score as well awesome let's
render the you know list of the quiz right here and also let's provide some gap between these so I'll go to the
page. jsx and in this div right here I'm going to say class name space y to be 6 and let's see yep we can see the SPAC is
between them all right let's work on uh the quiz list so let's take the assessments over here and this will be
pretty straightforward we will render the card for each and every quiz and then when we click on it we have to
display a dialogue box for the results and also have the option to start new quiz right so for routing to mock
interview page let's just have a use router hook over here imported from next / navigation we will be using it in just
a moment and we will also create a state over here for the selected quiz right the one that we want to open the
dialogue for so let's import use State as well from react let's take the card component right here so let me just have
a fragment and inside of it we'll have the card component so let me just take it from shat CN UI again and paste it
right here let's import the card card header card title card description card content and again we won't be needing
the card footer over here now I've used these react fragments over here because this is where we will be having a
dialogue for our results right so we will come back to this first let's build this card for the card title and
description I'm going to say recent quizzes and let's provide it gradient title text 3 Exel and in the larger
screen text 4 XEL and the description will be review your past quiz performances let's see how this looks uh
what's wrong oh we are using hooks over here so this should be a use client component and now let's see okay yeah
recent quizzes review your past quiz performances and also what we want to display over here is a button to start
new quiz right so I'll have a div and wrap both of these in this div and I'll have a button after it and then button
will simply say start new quiz and on click we will say router. push and push it to/ interiew SL mock let's see button
is not defined obviously let's import it from Shad CNC okay so we want it to be this side right here right so over here
in the card header I'm going to say display Flex items to be Center and justify between so that they are on Far
ends okay I think we need to do Flex row over here as well yep something like that start over here in the card content
we will be rendering all of our assessments so instead of this paragraph tag I'm going to have a div with the
class name of space y to be4 and here I'll take the assessments do map and over here
I'm going to render each and every assessment I'll take the assessment and the index and here I'll say return and
let's just take a card component over here again so I'll just copy the card component and paste it right here let's
get rid of the footer again in the card title I'm going to say quiz whatever the number of the quiz is right I + one in
the description let's just have two things first thing will be the score of that quiz and when that quiz was
conducted right so I'm going to say under with the format from date- FNS and new date whatever the date is and I'll
format it in this format right here right let's see yep we can see all of our quizzes being rendered right here
cool over here in the car description I'm going to say display Flex justify between and width to be full so that
these dates are right over here inside the card content simply let's just display our Improvement tip right so
that this is easily accessible so I'll say as assment do Improvement tip with text small and text muted foreground so
yeah this looks good we can easily see these right here and now let's add the logic for having the dialogue so first
of all let me just add some hover effect on it so on the card on each card I'll say cursor pointer on Hover we'll say
background muted to be 50 opacity and transition will be added on the color so y something like that on click we want
to select that particular quiz on inside of this state right here right so I'm going to say on click set selected quiz
to be that particular assessment and obviously we need to provide the uh key over here as well since we're doing the
map right so Al key equals assessment. ID okay so let's see now how does the dialogues work inui so I'll go over here
in the dialogue and if you click on edit profile you can see it's like a model pops up just like this so let's copy
this dialogue up and I'll go back and right here I'm going to paste this dialogue code so we have this dialogue
header and a trigger which you know opens the dialog I guess we won't be needing a trigger because our triggers
are right here and we will make sure to open the dialogue when we have something inside of this selected quiz right and
if we close this then we will remove everything inside of the selected quiz so I'll say on open change set selected
quiz to null simple as that let's try it out so obviously we need to import uh this dialogue as well so make sure to
import from slash comp components dialog header dialog title we won't be needing the description so let's get rid of it
and let's see how it looks I have not imported alert dialog header okay let's import that as well and now check if I
click on this quiz yep you can see we are rendering it over here let's instead of this alert dialogue header let's just
take the simple dialog header right let's import it from Shad CN UI and remove this alert dialog header so we
actually accidentally imported from another component and we won't be needing any title over here actually and
this is important to keep this tag over here because shat seni might throw us some errors if we don't provide it off
the accessibility right so now we will just simply we would need the quiz result component because that is what
we're supposed to render over here right and here we will give the result which is selected quiz on start new we will
push it to sl/ Mock and we will also provide the hide start new so you might remember we added this flag over here
right so it was for this place hide start new and now we won't be seeing start new quiz button over there so if I
click on any of these Yep this is breaking for some reason I think we need to add some styling over here in the
dialog content I think it's because of this so I'll simply say Max WID to be 3 XL Max height to be 90 VH and overflow y
to be Auto so we can see the complete result on this screen itself so if I click on it now yep looks beautiful and
you see how awesome this feature is the complete entent feature I mean this feature in itself is a whole app right
but this is a part of our complete Sensei app so great then let's move on to the next big feature which is to
build our resume we will start by creating the server actions for it so I'm going to come to this actions folder
over here and I'm going to create a new file called resume. JS and see most of the things in this are going to be
performed in the front end part because we will be building a Resume Builder and all all of those these things is are
going to be on the client right but after we have built the resume we want to save that rume right so we will
create This Server action export ASN function save rume and we will provide it with the markdown content to save the
resume so cool let's start with simply user authorization right if user is logged in or not I'm going to import the
AU from clerk /n/ server and I'm going to import this DB from Prisma file now after this there can be a possibility
that uh rume already exists inide of our database right for that particular user so we'll be using uh a function called
upsert so let me show you so I'm going to say con resume equals a wait db. resume. upsert so basically this means
update or insert right whatever's suitable first of all I want to search the resume for that user so I'm going to
say where user ID is user. ID if rume already exist we are going to update it with this content just update the
content and if it does not exist we will create for that particular user ID and we will insert the content simple enough
and then we will refresh all of the data inside of the/ resume path so I'm going to say revalidate data let me just
import it from next SL cach and then in the cat I'm going to throw the error error saving resume with error do
message now similarly we will create a function to get a rese if a res is already created right
so it will be a very simple function so let me just bring it real quick we will just first check if user is logged in or
not and then I'm going to Simply say await db. res. find unique where user ID is simple enough right now for the third
thing let me show you if I go back to the deployed app and you can see I'm in this Resume Builder feature and I have
my rume right here if I go to form and let's say if I want to add a work experience over here right I'm going to
say frontend developer organization can be let's say Google date and whatever you can set these on your own and then
if I want to add the description let's say if I worked on creating a Chrome extension right or let's say basically a
Chrome browser I worked on Chrome browser in Google right so now we are blanked right what do we write in your
resume so we can add this feature of improving with AI so if I click on this button see it has improved this
description with respect to the uh you know our the little description that we have provided it so this is an awesome
feature let's try to build this right so I'll go back to my app and I'm going to create a new server action over here
called improve with AI now in our current application I have added this feature just for this description right
here right improve with a and I've left this professional summary like this can also be improved with AI right so
professional summary or if you want you can add it in the skills as well so I would highly encourage you guys to
follow the similar patterns to implement it over here as well right so but it's pretty simple let me show you how you
can do that so first of all obviously we need to check if user is logged in after that we want to write the prompt for it
so you know what uh instead of writing it out over here let me just go back into my GitHub repository and let me
copy this whole prompt if you want you can also copy it from right here or of course you can also add your own
variation to it so yeah this is the prompt as an expert resume writer improve the following we're going to
provide the type like if it's for the experience if it's for the project if it's for the education right this
feature is on all of these three places so over here education projects all of these have the Improv with AI so we'll
provide the type for the description for a user who is in this industry which let's say for example software
engineering or front end developer Etc right make it more impactful quantifiable and aligned with the
industry standards and then we will provide the current content that user has provided then the requirements are
following use action verbs include metrics highlight relevant technical just like we should be writing a resume
description right so this will help us a lot in building a resume and format the response as a single paragraph without
any additional text or explanation simple enough and then after this let's make an API call to Gemini right so let
me just uh do one thing let me bring in my import for the Gemini yep these two things and I'm going to put them on the
top right here right let's import this Google generative AI over here and then I'm going to use this model variable to
call it so inste of the try I'm going to actually just go back and simply do what we have already done right so yeah this
thing right here let me just copy it up and I'll paste it right here so const result equals model do generate content
then result do response and then I'll get the text and actually I'll just say dot trim if there's any spacing outside
of it let's call it improved content let say return improved content all right and in the catch block simply I'm going
to throw the error error improving content if there is any error that's going to happen right so yeah these
three are my server actions now let's go to inside of this app folder Main and yeah we have not created for resume so
I'll say resume and I'm going to create a page doj SX right here instead of it I'm going to say R A fce let's call it
resume page and now over here if there's any resume pre-existing I'm going to fetch it so I'll say const resume equals
a wait await get resume so this F function that we just now created server action make sure to make it an
asynchronous component since this is a server component and yeah we will get the info right here obviously does there
is no resume right now so what I do instead of this resume page I'm going to go inside of it and create a component
called resumé Builder again this will be a client component so that we can use the hooks and stuff inside of it let's
get a new folder over here underscore components and I'm going to create a new file resume builder. jsx now this is a
very you know logic heavy component so I need you guys to focus properly we will be sending this the initial content so
I'll say initial content oops contenter this I'll say resume dot content right I'll put a optional chaining over here
just in case if our resume does not exist which currently it obviously does not exist for this div I'm going to
Simply give class name container margin horizontal to Auto and padding vertical to six also since we are you know
loading the resume right here I would recommend you guys to add a layout file just like we have added right here or
like um it's pretty simple right you can just copy it and paste it right here inside of it
right simple enough and now it will show a bar loader whenever this rume is being loaded right here let's import this rume
Builder component am I not exporting oh sorry R fce Resume Builder and I'll take the
initial content right here well let's just import it right over here like this and go back and see yep we can see the
res Builder right here okay let's go inside of our Resume Builder component and start building our Resume Builder
first of all this will be a client component so I'm going to say use client directive over here so first of all
inside of this div I'm going to have another div which will contain our H1 Resume Builder just like we've been
doing up until now I'm going to give this the class name font bold gradient title text to be 5 XEL in smaller
screens in the medium screens it's going to be 6xl below this I'll have a div which will contain our buttons like
saving the resume or you know downloading the PDF Etc so I'll say button import it from shat CN UI this
will be save and I'm going to have an icon before it save icon from Lucid react let's see how it looks yep
something like this let's give it the variant of destructive so that it's red color let me just duplicate this button
right here and this one will before downloading the PDF and let's import this download button from Lucid react
something like this and I don't want this to have a destructive variant this div can have a class name of Space X
tob2 and this parent div for both heading and buttons can have display Flex Flex column but in the larger
screens it's going to be Flex row that is on one single row justify between so at the AR far ends item Center and GAP
to be two so they would look something like this parent div can be class name space y to be four now below this div
right here we will have two tabs so you may have already seen over here we have two tabs one one for form one for
markdown so we have already installed the tabs component from chat CN UI so it looks something like this let me just
copy it up and paste it right here so basically what's going on over here is we have this tabs uh parent tag imported
from components and then we have tabs list one for account one for password for an example over here when we click
on account this value account matches this value of tabs content and it renders this component else it will
render the other component let me show you let me just import all of these from SL components folder tabs content and
yeah I think all of them are imported now let's see y you can see account password looks good instead of these two
I'm going to have form and markdown and default value can be form but you know what we don't want a default value
because that will differ right if we already have a resume we will show the markdown tab else we will show the form
tab let me get rid of this class name over here as well and and let's just create a separate State for the active
tab right so I'll just put this active tab State over here let's import U State and by default I'm going to put it to be
edit and right here I'm going to say the value is going to be active tab on value change we will use this set active tab
so this one can be edit and this one can be preview let's check it out form and markdown okay so now let's first go on
and build this form tab right so so for forms obviously we are using react hook form and zort so I'm going to import the
use form hook over here and this for this we will need to create the schema as well right so I'm going to go to this
lib schema. JS file and inser of this let's see first what are all the different things that our form will
contain so we will have this contact information then professional summary skills and for each and every one of
these this will be an array right we can add a work experience then we can add it then we can add another work experience
right something like that so this has to be an array so I'll create a separate schema for this separate schema for this
and then I'll combine them in one single schema so first of all for contact schema I'm going to say export cons
contact schema Z doob and we will keep four things over here let's just keep email as required only and other things
as optional so z. string email and if it it's not provided I'm going to say invalid email address and for mobile
LinkedIn and Twitter all of these three will be optional now let's understand the entry schema we can call it like
these these ones right let's build these so export con entry schema do object and inside this we'll take an object what
are the different things that we are going to be having inside of it uh title organization start date end date we can
have a checkbox for current experience and we can add the you know check to see if this is selected we won't be
requiring this or if if this is added no need to enter this right so and yeah also description right so we would need
all of these things so it would look something like this title it can be a string minimum one character else title
is required same for organization start date is going to be minimum one characters as the start date is required
end date can be optional description and the current right which will be a Boolean now let's add the check so I'm
going to say refine over here and refine will help us to add some you know checks over here if it's working properly or
not so inside of this call back I'm going to take the data that we have received and simply I'm going to say if
data do current is not present and data. end dat is also not present then we will return false that is we will throw the
error else if either of one is present I'm going to say return true and how do we throw the error after it so I'll say
comma and inste of an object I'm going to say message and date is required unless this is your current position
right and we will throw the err on the end it like below end it if none of these are
selected yeah and uh then in the end let's combine this one and this both of these schema into one single schema so
I'll say resume schema equals z doob first I'll add the contact info contact schema then summary
skills experience all of these will be z. array and we'll provide this entry schema that we have created just over
here right simple enough let's take this rese schema go back to our rese Builder inside of use form form I'm going to say
resolver equals to Zord resolver import it from uh this hook for/ resolver Zod and inste of this I'm going to give this
resume schema make sure to import this as well and then we can provide some default values to our form which I'm
going to say contact info to be empty array sorry empty object summary to be empty skill to be empty and all of these
to be an to be empty arrays yep and just like before we will take out a few things from inside of it like control
register so we did not uh you know took out earlier so I'll explain you what this is all about so register handle
submit to you know submit the form watch to watch a particular field inside of our form or multiple Fields as well and
from the form State we will take out the errors to display the errors now this control basically helps us to
essentially take the control of the whole form and we can manipulate it using this variable right here and I'll
show you how we are going to be using it and now while we are at it let me just take our a API over here as well so I'm
going to say use fetch import use fetch I'll take the save resume as well which will enable us to save the resume when
we submit the form and we will take out loading function data and errors and rename all of them one by one cool now
as we are going to be uh you know writing inside of our form right we'll be entering some data over here right
like something like this we will be updating our markdown in real time right so for that we need to watch all of of
the form Fields so what I'll say I'll say const form values equals watch right now we will make use of it very soon and
also if there has been the initial content provided to us right if a resume already exist then we can say we'll have
a use effect over here make sure to import it from react I'm going to say if initial content is there then the SE
active tab will be previewed right that means we will go to markdown tab directly without going to the form okay
and obviously I'll put it in the dependenc area because because if it changes then this changes as well all
right now let's go on and first start building our form so I'll go down inside of this tab content value edit and I'll
say form over here inside of this first of all we will be taking the contact information so let's create the dev for
that I'll say H3 to be contact information then after this I'll have our div which will contain four
different things like four different inputs so the first one will be label email and the input let's import input
from Shad CN UI we will use register over here obviously to tie it up with the contact info schema so contact
inside the contact infos schema I'm going to go and tie it up with the email right and I'm going to say type email
some placeholder over here and error equals errors. Conta info. email if you remember this errors object comes from
right here right and after this let's uh display our errors as well just like we've done earlier errors. Conta info.
email if it exists then we will show inside of a P tag this this exact error message with the text at 500 and text
small let's provide some Gap in between of those I'll say space Y tob2 and since there are going to be four such divs
over here so actually we should be wrapping them in another div over here so I'll have a div I'll wrap this whole
thing in another div and for this div right here I'm going to say class name to be display grid in the smaller
screens we show one single column in the medium screens two column Gap to be four between them some padding four around
them some border rounded Corners are going to be large like back uh border radius background is going to be muted
with 50 opacity right let's see how this looks currently inside of our app server only cannot be imported okay so I
believe we have not added yeah use server directive over here so I'll say use server and save it now we should not
see the error yep something like this cool let's build the other contact information so I'll actually duplicate
this one three times 1 2 3 okay let me provide some gap between these and for the second one this will be for mobile
number right so I'm going to Simply say mobile number in the label and in the input this will be contact info do
mobile with some with the type of telephone and some placeholder over here in the errors instead of email I'm going
to say mobile then next this one will be for LinkedIn URL again same contact info. LinkedIn and change this error
over here as well then the last one will be for the Twitter account so I'll say Twitter or X profile I'll say contact
info. Twitter and I'll provide some placeholder and the errors as well cool then after this Dev we will have the
professional summary and again it would look exactly the same so I'll just quickly import it it's just a Dev with
the ag3 of professional summary and now over here this is something that you need to understand so when it comes to
react hook forms or react hook form it works fine with the native HTML tags right but when it comes to such third
party components like text area which is provided by you know shaten UI or probably like SEL it component or
something like that we need to wrap it inside of this controller component which comes from react hook form right
so we will name it summary with respect to what it was in our schema then we need to provide the control like this
control if you remember we took it from right here from our form right so this will help it to get the control of the
form then in the render this is where we can render the component in our case this is text area for writing the
professional summary and this gives us this field over here which we need to spread over here so it this takes the
control of this text area then we can simply give some class name placeholder and error to be errors. summary and
simply render the errors in the end let's see how it looks text area is not defined obviously we need to import it
as well yep something like that let's just give the parent if some class so that we have some gap between them so
this one I'm going to say class name to be space y to be four and our form to have space y to be8 and also we will
have an on submit over here right which will give which we will give it handle submit Ander this we will provide the on
submit form which sorry on submit function which does not exist so let me just create a dummy function for now
just like this let's make it an asynchronous function which will get all of the form data okay so now after where
is it professional summary we need to add the skills but let's see how it looks currently yep something like that
this looks much better so that one will also be a text area so what I'll do I'll just copy it and paste it right here
instead of professional summary it will be skills name is going to be skills over here we can say list your key
skills and in the error as well instead of summary I'm going to say errors. skills now after this we will render The
Experience projects and education part right where we we can add multiple experiences or you know skills Etc sorry
not skills I mean projects Etc so simply it will be uh just like what we have done over here as well so I'm just going
to copy it and paste it at here and notice what I'll do so we won't be rendering text area of course we will be
rendering a custom component over here so first of all this will be called as work experience let's say experience and
then in the errors as well I'm going to say experience after this we will be doing the same thing for the education
and the projects as well so let me just duplicate it multiple times so I'll paste it right here and then Gap paste
it right here obviously this will give us error since we don't have anything over here so the second one can be
education education over here as well and over here as well for the third one instead of this I'll say projects and
over here as well okay so what do we put inside this render we will be creating a separate component a new component
called entry form where we'll be writing the logic for this thing right so let's just create a a component right here I'm
going to create a new file entry Das form. jsx R A fce entry form and then inside of this we will take three things
the type all of the entries that we have and on change what happens right so we will be controlling this component
obviously using uh use form as well and also we will be using that improve with AI logic inside of this entry form as
well now over here first of all let's create our use form just like we did earlier so I'll import use form from
react hook form Zord resolver and obviously entry schema that we have created separately right here right then
we will provide some default values to title organization started ended etc etc right and we will take out the register
handle submit form State reset watch set value and all that over here as well and I'll rename this handle submit to handle
validation because simply this will help us in validation only right not submitting the form that's why this
makes more sense and I'll also watch this uh current field so that we can disable the end date field let's import
this right here so first for the work experience I'm going to say entry form type experience entry field. value and
on change field.on change same for the education just type education and for the project as well with the type
project okay let's go back to the entry form and let me just first see if there's any error or not so yeah we can
see all these three right here so first thing first we need to have a button over here which will be responsible for
adding the you know whatever experience and stuff and we need to have a state as well which will tell us that if a new
experience or project or education is being added currently so what I'll do I'm going to say is adding and let's
take use State from here and let's make it a client component so say use client and now I'm going to say if is adding is
not true then only we will show this button and on click we will say set is adding to True right now above it we can
add the form when is adding is true we can display that form right so now above this button I'm going to say if is
adding is true then we will you know let's add a card component over here so let's just take the card from Shad CN UI
yep over here and paste it right here let me import the card card header we not going to be needing the card
description card content and also import card footer as well okay so card title can be add and the type like whatever it
fits Experience Project Etc in the card content we can create our form so this can have a class name of space y to be
four inste of it I'm going to have a div which will contain it and then separate divs for things like title organization
etc etc so inside of it I'm going to have a div first of all for the input of title /os we will register it with our
hook form with the title in the schema right so error will be errors. title and then error St title if it's there an
error then we're going to display the error right here then below it I'm going to have another d similarly for
organization as well and I'm going to register it along with the errors and these both will be inside of one single
div right here so I'm going to say class name display grid grid columns to be two and some gap of four between them so
let's see how it looks button is not defined okay let's import this button from over here plus circle is not
defined okay yeah I have not imported this let's click on ADD experience now and yep we can see title position
organization company ET Etc okay now below this div we will have another similar div but that one will be for you
know our start date and end date so again similar class name so I'll just take this grid class name and I'll put
it right here and I'll put it right here then insert this div first of all I'm going to have a div for type month input
type month and register with the start date and similarly I'll have another div I'll just duplicate it below it and I'm
going to have this for and date but this one will be disabled if the current is enabled so if you
remember this current is watching this current checkbox right if this checkbox is ticked then end date will be disabled
and we will be creating that checkbox right below it so I'm going to have a div and input inside of it of type
checkbox ID is going to be current register current onchange we will set the value like manually setting the
value inside the hook form for the current field to be e. target. checked and if it is checked then I'll say set
value of end it to be empty right then we don't want to have an end it over here and of course we're going to have a
label called current besides the checkbox let's see how this looks so far if I click on over here yep you can see
this is disabled now we cannot select it now below it we need a description as well again exactly the same just like
what we've done until now we're going to have a d with text area placeholder description of your whatever you know
experience or project Etc class name height 32 register with the description error errors. description and we will
render the errors over here as well let's see text area is not defined if I click on ADD experience yep we can see
if I click on ADD education we can see all the things related to education let's add a button for you know
improving with AI but actually before that let's just uh import that API right here that we created improve with AI API
or server action whatever you want to call it so I'll take the use fetch hook and improve with AI so this will have
loading function data and error let's also have a function for handle delete which we will come back to very soon
which will enable us to delete uh you know the experiences or the projects or education we will also have a function
for improving our description with a so I'll say handle improv description and another function for handle add as well
right to add the experience education of projects and while we are at it let's just write this handle improv Des uh
description function right away so it will be very simple uh let's just it will be an asynchronous function and
start of this I'm going to Simply say take the description like I'm I'm going to watch the descriptions value we will
have the descriptions value inside of it and then I'm going to say if description does not exist I'll say toast error
please enter a description first you know before trying to improve it with AI then after that I'm going to say await
improve with AI FN this thing right here I'm going to call it with two things first of all the current description
right in the current field and what the type is right that is experience education or project let's render the
button now so I'll go right over here yep text area and right below the text area Dev I'm going to have a button of
type button sorry we don't submit anything like not submit the form over here in the Resume Builder variant is
going to be ghost size is going to be small on click we will call that handle improve description that we just now
wrote it will be disabled when the description is being improved so is improving is like loading is going on or
we are or we don't have the description over here and we will display the loading indicator when it's loading
using the loader to so make sure to import it from Lucid react and we will also import the Sparkles icon to improve
with AI let's try it out if it's working or not so let's just say same thing Google sde even though these two things
does not matter say I worked on Chrome browser let's click on improve with AI okay improving and this should generate
a description for us which it did not let's see let's open the network Tab and try again improve with AI it did
something yeah you can see we are getting the uh no when oh sorry it should be in the preview developed
Implement oh yeah we are getting the response but we are not able to see it right here I think I have missed
something oh yeah I have to add a use effect over here inside of this we will take the data from the API right
improved content so inside of the use effect I'm going to say if we get this uh improved content right here first of
all over here in the dependency area we need to add a few things like improved content only then this will run or
improve error or is improving or set we don't need actually this one so yeah these three things if any of these three
things changes then we will say if improved content has something and it is not loading anymore then we will set the
value of the description and I'll show the toast. success otherwise if there's any error I'll show toast. error fail to
improve description let's check it out now let's just say I worked on Chrome browser if you want you can also you
know Supply the name of the company as well I think that would be much helpful okay toast is not defined import the
toast one more time let's click on improve with AI and now it should work yep just like like that awesome and
again I would recommend you guys to add like send this company name to the API as well you just have to you know send
it from over here and make changes in this API inside of this right here you have to take this spam over here and
provide it to the prompt very simple I believe you guys can do it on your own all right now how do we add this uh to
our form add this like particular item for the experience and all let's add two buttons inside of this card footer first
one will be for cancelling so when we click on cancel we will reset the form and set is adding to false this will be
of type like variant outline and type button then another one we will had have the add entry button which will trigger
this handle add function that we have created but not added any logic inside of it and we will say add entry let's
import this yeah plus circle is already imported so let's check it out yep something like this let's give this some
class name to be displayed at the very end so I'll say display Flex justify end and Space X to be two so this will yeah
appear right here now when we click on ADD entry we want to add it right so let's go to handle add function over
here and first of all we want to format the data so I'm going to save and by the way since we are submitting this right
so let's wrap this in handle validation or this handle submit function that we took right here right so that we get the
date like access to the data of the form then I'm going to say const formatted entry insert this we're going to have
the object which will take data and then let's format the date right the start date and the end date so for that I'm
going to create a function right here a helper function so I'll say const format display date this will be a
function obviously which will take a date string andert this first of all I'll check if date string does not exist
return empty but if it does I'm going to take this pass from date- FNS and pass this date string in this format right
here and then return I'll like import this format from D- and return it in this like month and whatever 2024 Etc
okay let's go back to this format entry and here simply I'll take the start date and end date and I'll use this format
display date and provide it with the data. start date and obviously if the current is true then we won't be needing
the end date right else we will provide the end date as well after this we would get this on on change function over here
right so if you remember if I go back we get this onchange field. on change which will enable us to add this to our main
form which is inside this Resume Builder so after this I'm going to say on change whatever the entries are already I'll
provide it and then after that formatted entry and then reset the form set is adding to be false after this after
handling the addition we need to render all of these fields over here as well right so above this I'm going to map
through all of the entries so let let's just have a div over here and for this parent div I'm going to say class name
space y24 and this div as well space yb4 and inside of it we will simply just you know map through all of the entries that
we have inside of it so I'll say entries do map and here inside of this call back we will just have a card component so
again let's go back to shaten UI and take this card component and I'll paste it over here make sure to add return
over here I'll say key to be index obviously we need to take the index from here and also each and every entry so or
each and every item so item and index for the card title I'm going to say this title of the user at the organization
whatever companies or whatever the project that you're building for right let's remove this
description and the footer let's import all of these things I think they are already imported since we have used them
in other places below this I will have the option to delete them right so I'll have a button variant outline size icon
type button and on click we will trigger this handle delete function which we will come back to this very soon and
let's import this x icon from Lucid react then inside the card content simply we will just render item do
current if this is true that is if this is a current organization then I will render the date from start date to
present else we render from start date to end date and obviously the description that they've written for
that particular experience education or project for this header let's give this some class name of display Flex Flex to
be row so there are one single line items to be Center justify between so that they are on Far ends Spacey to be
zero and padding bottom to be two between them so that we have some Gap and I think this should render it let's
just quickly go over here and handle it and write the logic so this will simply take the index right so if you see we
are taking the index over here right and it will take the index and it will say con new entries and it will simply
filter out that particular Index right if index is not equals to this index only then return else remove it and on
change we will add these new entries let's check it out I'm going to add let's say XYZ XYZ
XYZ description XYZ org let's just say I'm going to select any random month current experience and click on ADD
entry okay there we go it has been added if I click on X yep it is removed from over here as well awesome so we have
successfully built this form right here now let's render this form and this markdown and add the logic to save our
resume inside of our database as well in the markdown format so for doing that we will be using this package right here
react MD editor and this will allow us to you know render in markdown format and also allow us different different
views to you know edit the markdown directly as well if you you know if you don't want to edit the form so cool all
we have to do is just copy this up npm install and I'm going to go to my terminal and paste it right here npm
install at uw/ react MD editor and press enter we will also be using this another Library called HTML to PDF to save our
markdown resume as a PDF file so copy this up as well and paste it right here and actually I don't think we need to
add uh the version so yeah this should install it now so now let's go inside of this other tab where is it sorry not
here in the Resume Builder component over here in the tab content value value to be preview so inside of it we want to
First display a button over here so that we can add the ability to directly edit the markdown so if you see in our
deployed application we have this button called edit resume when we click on it see we are able to directly edit the
markdown and we also show this warning that if we you know edit the markdown and then go on to edit the form again we
will lose all of the you know progress over here after editing the markdown so okay we only want to show this button
right here if we are on the preview right so so I'm going to be adding this button right here which will say variant
link type button and class name to be margin bottom to be two and we will have this edit icon over here let's import it
from Lucid react and let's see how this looks inside of our application if you go to markdown yep we can see this edit
resume so let's create a state right here on the top which will check if the resume mode is on preview or not if it's
on preview we will show the you know preview else we will show the edit markdown State and then right here if we
are on the resume mode preview we will show edit rume else we will show Show preview and on click whenever we click
on it I'm going to say set res mode if it's on preview set it to edit else we will say preview okay let's see oh
monitor icon is not being imported so let's see if I go over here Yep this is working fine now below it is where we
will be rendering markdown editor but before that like if we are on the edit mode mode we want to show that warning
as well right so I'm going to say here if resme mode is not equals to preview that is we are on the edit mode then
I'll have a d which will show this alert triangle and a message called you will lose edited markdown if you update a
form data and by the way I created this custom over here but you can also take this uh alert from Shad CN UI so alert
yeah you can see it provides you with pre-built component similar to this but this also works fine right so again
let's go on and check it out yeah something like this now below it we can uh render the mdor so how do we do it so
let's go and check in the docs we simply have to take this component MD editor and we need to provide the value of what
we want to render and on change whatever the function is we want to trigger it right so let's create a state for it I'm
going to say preview content right this is where we will have our markdown content we'll provide it the initial
content right here if there's already some content inside of our database now let's just create a function over here
to get the you know to basically convert the form data ins to the markdown format So Below this use effect right here I'm
going to create a new function called get combined content and inide of this is where we will be creating our
markdown content now our markdown content contain multiple different things right so let me just take out the
things from form values so it will be summary skills experience C education etc etc so I'm going to say return and
it's going to be an array and first of all we need to combine uh the contact information right and then we will add
summary skills and then the experience education and project so first of all for creating the contact I'm going to
have a function over here get contact marked down and I will have one more function so let me just uh you know
create a separate helper file for it so helper. JS over here inside this I'll be creating entries to
markdown function which will take the array of you know experiences or projects Etc and it will convert them
into the markdown format right so these two functions are what we will be building and then inside of this return
I'm going to use them something like this so first of all get markdown contact it should create the contact
markdown summary I'll render the summary in this format so this hashes and two hashes are what you know represent the
headings I would recommend you guys to uh learn more more about markdown it's basically a format on how you can create
a particular document or something right just the way you create your readme files on GitHub right so I'll say this
professional summary heading and then I'll say slash n for changing the line and then add this summary similarly for
skills and this entries to markdown will take the experiences education and projects and will structure them
accordingly let's first see this get contact markdown also let me just import it yeah so first of all for getet
contact markdown we will take the contact info from the form values and this has four parts right email mobile
LinkedIn or Twitter right so I'm going to say const parts I'll take an empty array I'm going to say if email is there
then parts. push with this emoji and contact INF for email same with mobile same with ledin and same with Twitter as
well and then in the end I'm going to combine all those four parts by saying Parts dot length if it's more than zero
if we have something inside of it then we will take a div and we want to render it in the very center right so I'm going
to say align Center some inline styling user do full name on the top and then after this the contact information that
is part parts. join with this thing right here right simple enough and then we will render it right here what about
entries to markdown first of all we will check if entries has anything inside of it so if it does not have anything
return empty but if it does then return this so I'm going to say first of all what is the type right so let's say if
it's experience so I'm going to experience then change the line Plus for each and every experience we will do the
following we'll take each and every experience over here and we will render the date from this like if the current
is present then from start date to present else from start date to end date and then after that we will render
things like what is the title the organization how much time we have worked there and the description let me
show you how this will look like so if I go to my deployed app see something like this title at theate organization and
then the date and then the description right after obviously this heading of work experience or education Etc all
right let's go back and now we have this get combined content function and now I want to render it in the markdown right
so let's just let's just before this I'm going to create a use effect hook over here inside of this whenever our form
values changes so inside of this array I'm going to say form values if this changes or the active tab changes then
we will update the markdown content with whatever we have inside the form right so I'm going to say if active tab is
equals to edit then I'm going to take the content from this get combined content over here and then I'm going to
set preview content if we have anything inside this new content then we will set it else we will take whatever the
initial content was being provided to us so if you remember this state that we just now created set preview content
okay now we will take that uh preview content and then render our markdown right over here inside of the other tab
content right in the preview So Below this so just like we saw in the docs let me just have a div over here with the
class name of border and rounded large and instead of it I'm going to import MD editor and provide it with the value
preview content and on change set preview content and I'm going to say hi to be 800 and in inside of the preview
we'll provide this resume mode so if you remember we created this state right if it's preview we will show the preview if
it's edit we will show the edit so let me just check it out inside of our app right here what is the error maximum
update depth increased okay let me just refresh this I think something is wrong over here it is updating this again and
again so it's right here let me check I think I know what's causing that error we have this return over here right
after this we need to say do filter Boolean like if we don't have anything in any of these we need to filter it out
and then join them with the sln so that they are on the separate lines now let's see let's see if I add anything over
here user is not defined okay yeah we are taking user over here right in the contact uh markdown so I need to take
the user from clerk so I'll say use user and I'll take out the user info over here so I'll say user now it should work
let's add something and go to markdown yep something like that let's add some gibberish over here some
skills right and let's see yep we are starting to uh you know form it let's add some chish in the
experience let's say it's a current experience add entry it should have been added now awesome you see how beautiful
this looks we are able to add our resume right here how do we get the PDF generated out of it let's see so what
I'll do right below this one this MD editor I'm going to have another div and and I'm going to be rendering just the
markdown we will give this the class name of hidden so that we cannot see it but since we will have the HTML inside
of our Dom we will just take it and convert it into the PDF right so that's why we given this ID resume PDF over
here because we will be using this thing HTML to PDF library to convert it right so how does it work let's go and see
first of all we need to add the button for downloading PDF which I believe we have already added right so it should be
right here yeah let's create a state for it while the PDF is generating right so I'm going to have U State over here is
generating and set is generating okay then in this button download PDF I'm going to say if is generating is true
then display the loader imported from Lucid react and show generating PDF else show the download button with download
PDF right now over here in the button I'm going to call a function right here called generate PDF and it will be
disabled when the PDF is being generated so let's create this generate PDF function uh let's create it right here
just generate PDF this will be an asynchronous function and first of all I'm going to say is generating to true
then I will have a try catch block over here inside the tri block first of all we will get that particular element from
which we will be generating the PDF so I'll say const element equals document. get element by ID resume D PDF okay
after it how does it uh work html2 PDF PF first of all let me just import it so HTML to PDF import it like this let's
see if it has been imported yep I think this might cause some issues because you know while I was developing this project
this is how it allowed me to use it right so make sure that you also import this HTML to PDF like this I'm not sure
if it has been fixed or not but let's see we will try it out and check if it's been fixed so this will be a wait call
html2pdf Dot and I will set some options over here so let's see what options so I'll say const options equals inside of
an object I'm going to provide it few things like there will be margin 1515 file name is going to be resume.pdf
image type JPEG and we'll provide the quality we will use HTML to Canvas so basically these are some of the things
that I have taken from their documentation and we will provide some PDF configuration over here as well
right like in the format of A4 and orientation be portrayed Etc then I'm going to say these are the options and
from this particular element so I'm say from element and then save it in the end after this for the catch I'm going to
say console. error PDF generation error if there's any error and finally I'm going to say set is generating two fs
and this should give us our PDF let's try it out so yep over here so let's just write anything for let me just have
this contact information and try to download this so if I click on download PDF okay generated is okay let's see oh
yeah amazing it has generated this file for us we can select all this text and all as well we this is clickable you can
see at the bottom you can see mail to this email address right so this is fully interactive resume over here as
well if you want to add some you know links and all to this experience description over here they will continue
to work awesome now the only thing remaining over here is to be able to save this resume inside of our database
and by the way one more thing if we want to edit this directly we can click on edit resume and and we can edit it right
over here if I want to Let's remove agal and click on Show preview yep you can see this is editable in real time
awesome let's go back to the code and we have already created this on submit function let's see what do we get when
we submit it right so I'm just going to console log the data for now and go back open inspect console click on Save uh
doesn't do anything let's see on submit and this form should have have that button for submitting it so I don't
think we are calling that function so let's see yeah we have this save oh yeah we are not calling it right here so I'm
going to say on click all this handle submit on submit and this won't be useful over here so we can remove it
from here yeah so handle submit and we'll call this on submit right here and it will be disabled when this is being
saved and let's just use this loading indicator over here as well so I'm going to say if it's saving show the loader to
Icon and saving else show the save button okay what else do we need to do let's try it out first if I click on
Save still doesn't work what's wrong oh I believe it because we have not filled this professional summary over here so
let me just write anything right here can I save it now oh yeah email address let me just open the inspect click on
Save okay it's asking for the skills again let me just add in gibberish over here click on Save again yes now we are
getting something over over here okay cool then but I don't think we would be making use of this data anyways so it's
not useful for us so you know what uh when I'm clicking on that button over here we can choose to remove this handle
submit from over here right like this so inside of this onsubmit I'm just simply going to have a try catch block and I'll
say await save resme function and provide the preview content that we earlier had save resume function this
one and obviously we won't be making use of this data now now and inside the catch just simply say console error and
whatever the save error is if there's any error right and yeah we need to have a use effect as well which will trigger
our toast right so I'm going to say if save result changes save error changes or is saving changes then trigger this
and I'll go inside of it I'll check if save result has something and it's not saving right now then display this toast
make sure to import it from sonor resume save successfully else if there's an error show the error message right here
right that is all I think this should work now now let's see let me just add a bunch of jish again over here so this is
a random number don't try calling it it's not my number so let's just say XY Z XY Z let's add some work experience
XYZ XYZ from this to this add entry and let's go to markdown yep we can see some
rume over here let's click on Save and it should save it yeah resume save successfully if I refresh it now we
should still see that rume being fetched yep we can see our resume being fetched from the DB let's go and check it out
inside of our neon DB there we go this is the content the markdown content that you can see is being stored and which
user does it belong to and yeah that's pretty much it for the resume right awesome so you have just built a
production grid feature right this is a I would say pretty engineering heavy feature if you have not built something
like this up until now right we are rendering stuff in markdown format we are downloading this as a PDF this
feature alone in itself trust me is such an impressive thing to be added inside of your resume right building a rume
added to your resume so yeah definitely I would recommend you guys to Showcase this in your interviews whenever you're
applying to a company and all right now the next feature is building the cover letter so let me first go to my deployed
website and check how this feature works so you can see we have all of our cover letters over here if you click on create
new we would enter the company name the job title and the description over here and click on generate cover letter and
what this will essentially do and you can see over here we have used Zord validation here as well right and this
will basically provide it to the Gemini API and generate a cover letter for us very very simple very straightforward
feature and I want you guys to build this feature because let's be honest if you have followed this tutorial up until
this point and if you're not able to you know build a feature like this because I would say this is probably the simplest
of features and don't worry I'll tell you as well how you can build this if you're not able to still build a feature
like this then there's something wrong with your learning trust me so I don't want to spoon feed you guys by building
every single aspect so this is an assignment for you guys if you want me to make a separate video on this I will
make a separate video on this let me know in the comments down below but let me explain you how you're going to be
expl like you know building this and I already have the code for the whole thing inside of my GitHub repo so if you
get stuck you can go over here so first of all you will have to build the server actions right and again if you don't
want to see this part you can skip this part and go directly to the deployment right you can check from the chapters
below the video I have mentioned where the deployment starts so if you want to get an idea how you can build this
feature see we will create this function very simple generate cover letter right and we will send it the data of the
title company description and the like the job title right and we will write this prompt over here we'll provide the
user industry years of experience the skills from what user has entered in the top like at the beginning in the
onboarding screen right so that is the information that we will be using to craft this cover letter and we will
enter the requirements on how we want it we would want it in the markdown format as well keep that in mind so if you go
back and see the one that I've already generated if I click on over here in the I button see this is in the markdown
format so this is pretty straightforward to store it and then you can create a server action to get all of the cover
letters if you want to get one single cover letter for one single page right that is what you can do as well and if
you want to delete you can write dis delete all of these things we have already covered in this course and now
you need to take action from your side and build this feature right and the UI which is I would say in this case is
pretty simple is inside of over here in the main folder AI cover letter right I have a separate component for cover
letter generator list preview and obviously the page over here as well the dynamic ID page and obviously for
creating the new cover letter as well right so definitely try it out yourself if you're not able to do it let me know
in the comments down below for now if you want to host this res uh project let's go on and host it on verell right
and then maybe later on you can continue building this cover letter feature awesome so first thing first we need to
push our project to a GitHub repository so let's open GitHub and click on over here to create a new repository let's
name this Sensei let's keep it a public repository create repository all right now let's push all of our code to it so
I'm going to go to the terminal and I'll say first of all get in it press enter and also by the way we need to add
inside of package.json a script over here called post install which will run Prisma generate you know generate all of
our schemas after deployment all right now I'm going to say get add dot to add all the files and then I'll commit the
changes so I'll say get commit dasm oops one one thing I don't don't want to add the do EnV so let me just check if I
have not accidentally pushed it or let's see I don't think we have make sure in the dogit ignore we have EnV over here
yes we do so no issues so now I'm going to say get commit DM and provide the message let's say preparing for
deployment press enter there we go now I'm going to say get push origin master and this should push it uh
what's oh sorry we have not added the origin so make sure to copy this line and paste it over here first get remote
add origin and then get push origin Master there we go it is posted so if I refresh this page now we should see our
code right here awesome so now let's go to verell ver.com and we want to deploy our website right here so click on add
new project over here let's click on import and this will import our get repository and by the way we need to
configure inist as well so I'll go to in.com slocs and inside of this we want to find the deployment so over here in
the deployment overview deploy with versell okay so we are using App router yes installing injest official versell
Integrations click on over here yep right here we need to connect our versel account so click on connect account and
let's select the team connect account okay and then after this oh yeah we after this we need to select that uh
verel project right so right now let's just first log into verel I'm going to sorry not verel I mean inest we will log
into inest right here it's going to show me all of these projects so this is not the project this is actually my previous
deployment so never mind let me just close it for now let's just first go to versel and deploy it so let's add the
environment variables first of all over here so I'll go to my code go to EnV let's take these one by one and add it
right over here the key and the value let me just add them quickly and come back there we go I have added all of
these values over here and now I think we are good to go let's click on deploy and let's see so it has started
deploying right here and first of all it's installing all the dependencies okay creating an optimized production
build hopefully no error will occur okay it is generating static Pages now and this is a good sign I think our
deployment is about to be completed amazing our website is successfully deployed awesome let's click on over
here and see and yeah we need to do one more thing we need to connect inist as well right so click on connect account
now in the same page that we opened earlier and now we need to choose over here that Sensei website y this one
right and click on Save configuration continue to injust worel dashboard let's click on configure and yeah we should be
taken to right over here and we should see yep our Sensei website over here so if I click on configure our project
status enabled versal deployment protection might be block syncing uh might block syncing okay yeah we need to
change this actually so one thing that you need to change uh let's click on continue to dashboard invers Cel go to
settings and we need to disable the deployment protection over here so turn it off and save it and now if I refresh
this up yep now it's working fine so if I go back if I should see over here I don't think we have over let's click on
sync new app and we need to get the uh URL for our app so our URL is Sensei D1 verel app so let me just copy it up
paste it over here and add/ API SL inest after it and click on sync app and there we go our app is synced successfully if
it does not work for the first time try doing it again sometimes it fails right so you can see we have our injust
functions over here as well and we can see how many times they have been replayed obviously right now we have
deployed so they have not been replayed but we can manually trigger it from over here invoke it from over here right so
this is awesome let's go on and test out our app I'm going to click on sign in and let's sign in with Google okay we
are signed in let's click on get started and there we go we are inside of our dashboard if I go to build resume okay
this was the resum that we built earlier right great we have our form and everything over here amazing so you have
successfully created this awesome project to your resume now the next step for you guys is to start applying for
interviews and if you want to prepare for you already know you can check the link in description down below for my
front inter preparation course and enter the coupon career for the maximum discount
Heads up!
This summary and transcript were automatically generated using AI with the Free YouTube Transcript Summary Tool by LunaNotes.
Generate a summary for freeRelated Summaries

Transform Your Teaching with Brisk Teaching: Enhance Lesson Planning and Feedback
Discover how Brisk Teaching can streamline lesson planning and student feedback with AI tools.

The Revolutionary Impact of Claude AI: A Game-Changer for Software Engineering
Explore how Claude AI surpasses GPT-4 and revolutionary features that redefine productivity.

The Future of Business: Leveraging Autonomous AI Agents
Discover how autonomous AI agents can transform the way businesses operate and increase efficiency.

The Future of AI-Assisted Coding: Insights from the Cursor Team
Explore how AI is transforming programming with insights from the Cursor team, including Michael Truell, Arvid Lunark, and Aman Sanger.

Unlock Your Career Potential: Six Companies 30 Days Challenge for Job Seekers
Join the Six Companies 30 Days Challenge to enhance your coding skills and boost your confidence for upcoming interviews.
Most Viewed Summaries

A Comprehensive Guide to Using Stable Diffusion Forge UI
Explore the Stable Diffusion Forge UI, customizable settings, models, and more to enhance your image generation experience.

Pamaraan at Patakarang Kolonyal ng mga Espanyol sa Pilipinas
Tuklasin ang mga pamamaraan at patakarang kolonyal ng mga Espanyol sa Pilipinas at ang mga epekto nito sa mga Pilipino.

Pamamaraan at Patakarang Kolonyal ng mga Espanyol sa Pilipinas
Tuklasin ang mga pamamaraan at patakaran ng mga Espanyol sa Pilipinas, at ang epekto nito sa mga Pilipino.

Kolonyalismo at Imperyalismo: Ang Kasaysayan ng Pagsakop sa Pilipinas
Tuklasin ang kasaysayan ng kolonyalismo at imperyalismo sa Pilipinas sa pamamagitan ni Ferdinand Magellan.

Ultimate Guide to Installing Forge UI and Flowing with Flux Models
Learn how to install Forge UI and explore various Flux models efficiently in this detailed guide.