Disney+ Clone (NextJS, TypeScript, NextAuth & Styled Components)
Aug 15, 2023
Disney+ Clone (NextJS, TypeScript, NextAuth & Styled Components)
In this video, we will be creating the Disney+ Clone on NextJS using TypeScript, NextAuth \u0026 Styled Components. You will also learn how to create a slider banner in react with React-Slick and also how to autoplay a video on hover in React with react-hover-video-player. Check Out My Linkshttps://imrancodes.com/links/ Repo: https://github.com/imran-codes/disney … 00:00:00 Introduction 00:02:38 Project setup 00:07:58 Created a dynamic Header for logged in/out state 00:15:36 Setup Next Auth With Google Sign In 00:30:44 Creating the Login Page with Redirect functionality 00:40:50 Create a Slider Component 00:46:53 Create the Category Component and use react-hover-video-player 01:00:47 Create the API 01:07:41 Fetch data server side with GetServerSideProps 01:12:13 Create the FilmsRow Component and filter and map the movies 01:22:53 Create the Individual Movies page and fetch the relevant with GetStaticPaths and GetStaticProps 01:30:39 Create the Film Layout on the Individual Movies page Media Fileshttps://drive.google.com/drive/folder …
Content
0.16 -> if you want a job or career in web development
this video will be covering the latest modern
5.6 -> framework of next js and typescript which
is used in most professional environments
11.44 -> this can also be used with react.js because nextgs
is just built on top of it the topics covered in
17.52 -> this video are we are going to have client-side
authentication using next auth and we're going
24.16 -> to be using the google sign-in as a provider we're
going to be using components as most professional
30.88 -> companies use that to handle their styling
we're going to create sliders with react slick
36.88 -> we are going to have server-side rendering and
also be using something called incremental static
42.4 -> regeneration we will be using typescript for type
checking and catching bugs okay so we are going
49.36 -> to be building the disney clone as you can see
here we have the login page we are currently on
54.48 -> slash login if we click on the login button we
now have a authorization page which we can sign
62.64 -> in with google so if i click sign in with google
it will then authenticate us onto the home page
70 -> we have the google icon here so the same one i
have in the corner that is passed in with the
76.72 -> session provider from next auth we have the header
component a slideshow component we have viewers
84.64 -> that the video plays on when we hover over we have
the relevant sections on the disney website where
92.4 -> we have recommended trending new for you and
originals and this is all with data we are
98.48 -> fetching from the server side these are also
scrollable so if i click it will scroll onto
104.08 -> the next and then when we reach the end the icon
gets disabled and we can also go back also these
110.4 -> are all coming from an api that we will build in
our application also if i scroll down and click
117.04 -> through to a movie for example the incredibles
i now get the url changing to slash movie
123.52 -> 13 and then i get the relevant information
for the specific movie that i clicked on
128.88 -> so if i go back onto my home page and for example
click the queen to soldier and again the image is
136.4 -> displayed as the background image we are having a
title image and we are also having the description
142.24 -> rendered correctly this is all done with
incremental static regeneration as well and what
147.68 -> we can do is if we hover over our icon we can sign
out like so and then we also get redirected back
154 -> to the login page as well so let's get started
with the build okay so first of all i'm going to
159.76 -> create a new repository on github for this so i'm
just going to call it disneyland yt for youtube
166.72 -> and then it's going to be a public profile
and i'm going to just create the repository
172 -> so now i have a few commands here that i could
do so all i'm going to do is copy this here
178.16 -> i'm in my youtube folder now on my terminal so
all i'm going to do is hit clone i'm pasting the
185.44 -> link that i have here so now press enter and
now if i press ls i now have my disney clone
193.12 -> yt folder so now i just need to move into that
so cd disney clone yt press enter and ls again
203.92 -> so now i'm going to install the app so i'm going
to install next js and typescript with styled
210.16 -> component so if i paste in with yawn create next
up with typescript and i'm also going to bring in
217.68 -> style components and there is an example
for this so if we just add dash dot
222.4 -> example with styles components it does the initial
setup of style components for us it adds all the
230.08 -> configurations into the nexus file structure
for us so if i press enter it now prompts to
237.76 -> give a project name so i'm just going to name
this disney blonde yt and press enter again
246.08 -> okay so if i go into the folder we have a
component folder and we have global styles in here
254.8 -> we also have shared styles so when we imported the
with style component it has given us an example so
262.32 -> all i want to do now is cd into my disney clone
and then yawn f this will start on localhost for
272.64 -> us if i just refresh this and press enter so now
you can see it says welcome to nexjs and we have a
280.48 -> initial render of the next yes page so what we
want to do is delete that if we go into pages
287.68 -> and index.tsx we have a template here which is
what is seen on the page so if we just delete
295.76 -> all of this within the container and i am also
going to delete the container so all the styles
303.04 -> from shared styles we don't need so if we delete
them and also delete the shared styles file so
309.68 -> delete and then we will get an error so i'm
just going to render a h1 on here saying
316 -> disney plus clone on the home page and if i save
all so now we have a disney plus chrome page on
323.28 -> the home page so the index.tsx file within the
pages folder is always going to be the home page
331.52 -> uh the about will be the slash about and so
on we don't need an about.tsx in this build
338.24 -> so i'm going to delete that as well and we also
don't need a card.tsx so i'm going to delete that
345.28 -> and i'm going to keep the global styles i'm going
to move this out of the components folder onto the
352.32 -> main root directory and update the imports as well
so i can clean up everything here we have a home
360.16 -> page underscore document.tsx this is where the
style components gets initialized and rendered so
367.44 -> i'll just keep that as is and we have an app.tsx
page here where we have a default theme being
374.48 -> rendered a global style within the theme provider
and then all our components fall within this
381.68 -> what i also want to do is i just want to remove
the colors property from the theme so we have
387.84 -> direct access to the theme when we get props and
now if i go into the type of theme so if i press
395.68 -> command and click through i can see the interface
declared here so i just need to update that as
401.2 -> well so delete the colors object so we now have
direct access to the primary and secondary colors
408.48 -> and if i save all and refresh we just need
to update the styles within the component
416.64 -> we also need to update the styles in the
global styles.tsx so where i deleted colors
423.52 -> it is now just theme.primary so now that is
all of the style components section complete
429.52 -> we just need to create the folder structure so we
have a components folder we have a pages folder
436.24 -> a public folder where we will import our images
and our video so i'm just going to copy them
442.56 -> across now and import them into public because we
will be using these later on in the project i am
450.48 -> also going to be creating a new folder for the
types so we're typescript types so if you click
456.56 -> on that and type in types and there's one final
thing to do on the setup is in our ts config json
464.56 -> we want to set strict to true so we want to
actually catch the book to make the most of
470.24 -> typescript so now if i save and restart my up
so yawn dev we can now get started on the build
478.56 -> okay so the first component that we want to create
is the header so if i go into my components and
485.2 -> create a new folder named header and in here
i'm going to create a new file named index.psx
492.56 -> and if you have the react functional snippets es6
7 snippets extension then you can just type in ts
500.72 -> rfce like so and tab and it creates a functional
component for you with types so this one is going
509.6 -> to be named header we don't need any types as we
don't have any prop so i'm just going to delete
515.2 -> the types and i'm going to delete the props and
the header i'm going to import in my app dot tsx
523.28 -> just above where the components get rendered
as this is being used globally so if i control
529.44 -> space and imports in that way so if i now
save all i now have the header at the top
536.16 -> of the page and that is regardless of the page
that i go on to so if i go back into my header
543.04 -> i want to change this to nav because it is
a navigation that we're going to be creating
548.4 -> so if i create a new file called styled.tsx
and import styled from style component
557.04 -> like so i'm just going to copy across the
nav that i already have made as i don't want
562.24 -> to focus too much on the css element of this
so we have a height of 70 pixels for the nav
570.24 -> a background color display of flex align item
center which means it would align everything
577.12 -> centrally on the horizontal axis it will justify
the content a space between we have a padding on
584 -> the top and bottom of zero and left and right
of 36 px we don't have any overflow on this
591.2 -> and this will have a zen index which means it
pops out of the page and we also have a color of
598.24 -> white for the text i am also going to go into the
app dot tsx and update the colors to the ones i
608.24 -> have already made so paste these in so we have
a primary secondary a white a bright blue silver
615.12 -> and a dark grey so these are the colors being
used in this build what also we can do is we can
621.12 -> export this theme into its own file but we will
keep it in here for now so going back into the
627.68 -> header i'm going to now import the nav from the
styles.tsx like so and now if i save everything
636.32 -> we now have a header being rendered on here
with a child of just the text header we do have
642.96 -> two errors on the project so if i go into app.tsx
it's got a few errors that we need to sort out so
650.08 -> essentially we need to add these to the default
theme type or interface so if i command base
657.12 -> and paste into here and we just need to add these
new colors in and essentially what they all are
664.24 -> are strings so if i just play string in
here and again we should have now have this
671.92 -> issue resolved so now if i save essentially what
we are doing is on our app.tsx these colors here
680.88 -> will be strings so as you can see here it is
highlighting that this is a string the same
687.92 -> with the bright blue this is just enforcing the
types in typescript so if i was to delete the the
695.52 -> speech mark from here it would trigger an error
which it does so i just need to add that back in
702.16 -> now going back into my header i have the out and
now rendering and it's working correctly on the
707.68 -> page i'm going to have have the disney logo so i'm
going to create an image so image of image source
716.08 -> is equal to i have the url here which i've just
copied from the disney website and paste that in
723.6 -> and then we'll just leave keep the alt as disney
logo so and if i save we now have the disney logo
732.08 -> we just need to style that as well so i'm going to
give this as a style component so if i name this
737.76 -> logo and then i'm going to import that from my
styles or go into styles and then i'm just going
745.04 -> to copy across my logo style so export const logo
which is equal to style.image it's going to have
752.56 -> a width of 80 80 pixels sorry and then a cursor
pointer as well so if i now save we now have the
760.48 -> width of the image as 80 pixels and it's on the
left so that's the first child being rendered so
767.44 -> what i'm going to do now to keep the code clean
is just under logo i'm going to create a function
774.4 -> and i'm going to name this render header the
reason i'm doing this is because there are two
779.76 -> states of the header there's one where we have
the login button and there is one where we have
785.76 -> the menu items on there so essentially what we are
going to do is create a function so const render
793.44 -> header and first of all going to check if the
person is logged in or if the user is logged in so
799.84 -> if logged in sure be logged in header but if not
then we want to show the logged out header where
808.8 -> we have a button saying logged in so first off
i'm going to create the login button so i'm going
816.56 -> to return a login container like so so this is a
div which has a log in button that just says login
826.08 -> so now i just need to create the relevant style
component for this so if i go into styles we have
832.56 -> got a login container and a login button so if
i copy the styles that i currently have across
840.32 -> and paste them in so the login container has
a display of flex justify content of flex
847.84 -> end and a flex of one which means take up all the
space that we have here so put it at the end here
853.84 -> the button element is it has a border of one pixel
solid a padding of top and bottom of eight pixels
861.68 -> and left and right of sixteen a four p export
rate border radius let us spacing of 1.5 pixels
868.8 -> a background color of a black with a 0.6 opacity a
transition when we hover over a cursor pointer so
878.4 -> when we hover over it we noise the clickable
element and then the hovering styles here as
883.68 -> well so i am exporting them all i need to do now
is import them from styles so this function here
891.76 -> we are calling after the logo so now if i save we
now have the login button so if i hover over it
899.12 -> it changes color as well so now within
this header render header function before
905.84 -> i render the login container we are going to check
if the user is signed in if they are signed in
913.92 -> then we render whatever we return from there
otherwise if they are not signed in then we render
920.72 -> the login button here like so this way it keeps
the return on the header component quite neat
927.84 -> and tidy we have a logo image here on the left and
then whatever is on the right is getting handled
934.16 -> in this render header function so now what we need
to do is install authentication with next auth so
941.04 -> if you go on to the website nextoauth.js and click
get started it does say here how to install so we
948.88 -> are using yawn so yarn add next off so if i just
copy this and create a new terminal i'm going
955.92 -> to just install next off into the project so we
also are using typescript so we have typescript
962.64 -> documentation here but what i am essentially going
to do is add a new file so it says here add an api
970.96 -> route so to add next auth to your project create
a file in pjs api also if we go into pages we want
979.84 -> to create a new folder in here called api and we
will also be creating our movies api within the
987.28 -> api folder and then a new folder within api
named auth and then within auth a new file
995.04 -> and we're going to give it brackets dot dot next
auth and close the brackets ts because we're using
1003.36 -> typescript so now i'm just going to copy this
across paste this in and we will get some errors
1010.24 -> so if i just say open this up and instead of
github we're going to be using google so if i just
1017.28 -> go instead of github i'm just going to change
all of the github so this will be google because
1024 -> we will need an api key from google themselves and
then we are going to import that from slash google
1032.24 -> like so we also need to create a dot emv file so
i am going to go into the package.json level and
1040.56 -> then a new file in here named env which is where
we will have our env files and i'm just going to
1050.08 -> call this one google id so google underscore id
is equal to an empty string for now because we
1058.96 -> need to go and get that and we're going to get a
google underscore secret key as well so we will do
1066.8 -> that later on okay so going back into the next
auth tss file we are getting an error so if we
1073.92 -> hover over it it's essentially saying that we need
to provide a string in here so because this is not
1080.64 -> a string we are importing it from the emb file we
just want to put in here straight after as string
1089.6 -> that should fix the error and the same with the
secret key and we also need to update the name so
1097.6 -> i'm just going to name this google underscore
client id sorry for id and then google client
1105.2 -> underscore secret just copy this and grow it back
into our next auth ts and this is going to be the
1115.12 -> secret and this is going to be the google id
so now we have that initial setup complete
1122.96 -> we now need to go ahead and get a google api and
secret keys so if we go into our so if we go into
1129.76 -> the google api console for developers and i want
to agree and continue so this is my first time on
1136.24 -> this account setting it up so i want to dismiss
this and go into credentials and then create a
1142.24 -> new project i'm going to name this disney clone
youtube and create so the project will be getting
1150.08 -> created so now we want to select the project okay
i've got this and then configure consent screen
1158.88 -> and just click external for now and create i
can ignore the learn section so give this an
1164.96 -> app name of disney plus i'm just going to put
my email in there my gmail we don't need a logo
1171.52 -> we don't need any of this and then again just give
in my email address so if we go on to credentials
1178.64 -> and then create credentials and we want to go
on all auth client id the application type is a
1185.04 -> web application i'm just going to give it a name
of disney client and we are using localhost 3000
1193.68 -> so i'm going to add the uri in here and for
authorized redirect uris if we just go on to
1200.8 -> next auth and type in uri the redirect uri
so we've got that here so it'll be localhost
1208.8 -> slash api slash all slash call block callback
and then you put the provider name in here so
1214 -> that in our case is google so if i now create
i now have the id and the secret so i'm just
1220.56 -> going to add these into my env file like so and
these will be deleted at the end of the video
1227.36 -> and i'll get new ones for here so they won't
be used so if i press ok and now if i save oh
1234.4 -> and go back into my next all file i want to delete
this because we're only going to be using google
1240.8 -> as the providers so now with the next auth we
should have access to something called use session
1247.44 -> so if i type in new session which is already
there we can get access to the status or whether
1253.84 -> the person is logged in or not so if i copy
this across and go into my header component so
1261.76 -> where it says here if logged in sure the header
will be at the top of the functional component
1268.4 -> we're just going to paste in the session that we
are using and import in the use session from next
1276.64 -> and then we want to have a check to say
if session if session we want to return
1284.8 -> a new component which we will create called signed
in header like so and we also want to pass down
1292.24 -> the session as a prop into there because we want
to log in and log out and we have access to that
1299.28 -> within the session object so if i save we need
to create a new folder within here named signed
1307.28 -> in header so a new folder called signed in
header and this will have an index dot tsx file
1315.68 -> and ts c a named signed in header which will take
in the session as props and instead of type i'm
1325.6 -> going to give this an interface so interface
of props and this will take in a session
1333.52 -> and i'm going to declare this session as a
session and this is coming from next auth like so
1340.72 -> so now that's the sign in header rendering so
if i save we have an error within here so we
1347.28 -> just need to import the signed in header component
and now we can remove this comment so essentially
1354.16 -> this render header function now is saying
if there is a session we want to return the
1359.36 -> signed in header otherwise we want to return the
login container and this is being rendered in here
1366.64 -> after the logo image so if i now render header
and what we need to do in the login container
1376.08 -> is we have access to you session which is in
here so in use session if i scroll down further
1384.24 -> we should have a sign in and sign out which is on
here so if i import sign in from next auth react
1392.56 -> and also if i import sign out which is a bit
further down and then all you need to do is add
1399.2 -> an on click on there to say sign in so hours is
the login so if we paste that in close that off
1406.48 -> and now if i save i go into my local host and
refresh so now we also need to wrap a session
1415.04 -> provider around the app so if i go into my app.tsx
and just above global styles i'm going to import
1423.84 -> session provider from next author react close
that off and then add the children within there
1430.96 -> and then the session provider has access
to the session which is equal to his props
1438.72 -> session so now i'm going to restart the server so
beyond dev and if i refresh the page and press log
1446.8 -> in we now get directed to slash api slash auth
slash sign in and if i click sign in with google
1454.72 -> it directs me to the sign in with google page
and if i just log in with my gmail account
1461.2 -> so now as you can see we are signed in and we are
seeing the signed in header so if i go into header
1468.08 -> and if there is a session return the signed
in header i'm passing in the session so if
1472.8 -> we go in here and now we are seeing the header
so it's just the case of now rendering out the
1478.96 -> menu items on there so so i'm going to import
a nav menu so if i paste that in so this is
1484.88 -> rendering out the navigation menu of the links
that we want to have on the page so home search
1490.8 -> watchlist originals movies and series so i'm
going to import the now menu styles into our
1497.12 -> styles file so in here import the nav menu
styles so it is a display of flex and we
1504.64 -> are going to give it a flex of one to give
it as much space as possible we're going to
1509.44 -> have a margin left of 25 pixels on there
so it gives a bit of space after the logo
1515.52 -> the span text i'm going to have a font size of 13
pixels some letter spacing position of relative
1523.12 -> and a text decoration of non so because it is
an a tag we don't want to have the underlines on
1529.52 -> there we're going to give it a slight transition
when we hover over so we're going to give that a
1535.36 -> line and background of white or in this case we'll
give it the props of white so props and then crocs
1542.16 -> or theme all right this after section will have a
position of absolute because it will be underneath
1549.52 -> the text a left and right of zero and the bottom
of minus six as we are positioning it underneath
1556.32 -> and then a slightly transition which you can copy
but it kind of goes from left to right the image
1562.72 -> so the image icon on the left of it will have
a height of 20 pixels and again styling the
1569.84 -> a tag here and if it reaches the width of 768
pixels or less then we won't display it at all
1576.08 -> so if i go back into here and ctrl space and
import the styles and now if i save we now have
1584.16 -> the menu items rendering and as you can see the
after effect is showing when we hover over as well
1591.68 -> so now that the menu is rendering we just need
to create a sign out button here and also show
1598.16 -> the icon of our gmail login so a circle in the
corner or whatever we have as an image so if i
1606.08 -> create a section named sign out as a div and
now there are two children within here and
1612.4 -> we can only have one so i'm going to create a
react fragment which is the shorthand version
1617.76 -> so if you just put empty brackets in like that and
then if i copy this and push it up one and in the
1626.08 -> sign out div we are going to render an image so
in this case it will be a user img this will be
1635.28 -> the image and the source will be equal to and
first off what i want to do is comment this out
1642.32 -> now and at the top where we are getting our props
we want to console log the session so session
1650.4 -> and now if i save and inspect the page so if
i go into my console i get two objects in here
1657.68 -> i'm just going to open one of them up and in here
we get a session and in here we get a user so
1666.4 -> the user has an image as you can see here an
image with the url so what i'm going to do is
1673.6 -> render that as my user image source so if
i uncomment this and then it is going to be
1681.04 -> session and we're going to add optional change to
see if we have a session not a user image like so
1690.4 -> and then the alt tag for this is going to equal
same but in this case we're going to just take
1697.04 -> the name so session user dot name so i now need to
add the styles for the sign out and the user image
1704.24 -> so if i go back into my styles and paste this
in or i've got a sign out a drop down and a
1710.72 -> user image so if i go back and import them in
and close this off save all so we now have the
1719.76 -> circle with the user image on there that is
working correctly now when we hover over the icon
1728.08 -> i want to show a sign out button so all i want
to do now is have a drop down span underneath so
1737.36 -> we have imported the styles for the drop down and
in here we're going to have a span which says sign
1743.68 -> out and all we are going to do is have an on
click span on click sign out being called and
1751.76 -> this will be called from next auth react and
that's imported in from next wars react there
1758.88 -> so now we're getting an error in here saying
no overload match is this called because it
1763.36 -> could be undefined so what we essentially
want to do is check if there is a session
1768.32 -> first before we render so if session is
true we want to return the user image
1776.72 -> like so otherwise we want to return no and now if
i save so now i have this area so what i am going
1784.64 -> to do is i'm going to put this into a constant so
if i cut this out and i'm just going to call this
1791.6 -> image or at the top here i'm going to give it
a constant image is equal to session.user.image
1800.24 -> as a string and i want to do the same for the
name so image is going to be changed to name
1808.96 -> as a string so on the alt i'm just going to give
this name as the constant and save so now if i
1816.8 -> log in and sign in with google i get redirected to
the new signed in header and now if i hover over
1825.76 -> we have sign out here so if i just click on that
we are now signed out also what's like tweak is
1832.64 -> sign out should be one word and now i should
save so that is the header complete and the
1838.16 -> next auth implementation complete as well now
what we will do is build out the login page
1844.32 -> okay so now we're going to create the login
page so if i go into pages and a new file called
1850.72 -> login.tsx and then essentially i'm just going
to copy what's on home and paste that in here
1857.92 -> and home it will return to login we are going to
create a component called sign up so sign up which
1866.56 -> will get rendered on the login page so if we go
into our component folder and create a new folder
1873.44 -> named sign up and in here create a new file named
index dot tsx and we're just going to say rfce as
1884.08 -> we won't need any props being passed on for this
so this will be named sign up and now if i go back
1890.96 -> in login and import this in and now save and if we
go into localhost 3000 slash login we now have the
1900 -> sign up component rendering on there so if i go
into my sign up component essentially what we want
1906.16 -> to do is render out the cta and the background
image for the disney login page so we will have
1915.44 -> the disney logo the headline the description
and the import field which will be the email
1923.36 -> input and the button to sign up this will all be
visual so there won't be any functionality other
1930.56 -> than when we click the button we will be signing
in and then getting redirected to the home page
1936.72 -> if i copy what i already have and paste this
in so in my return block i want to render out
1942.64 -> the following so we have a container that has a
cta and within the cta we have our logo we are
1949.92 -> loading lazy so this is a shorthand method to do
lazy loading for your image we have a headline
1956.16 -> a description an input component which we will
comment out for now because we need to make that
1962.16 -> and a description thing you get 12 months for the
price of 10. so all we need to do now is create
1968.72 -> a new file called styles.tsx and then import the
styles in auto so just to highlight the styles the
1977.2 -> background is going to be covered with an image
so we're going to give it a position of relative
1982.64 -> and the min height of 100 viewport height the
url is copied from the login page on the disney
1990 -> plus website and then everything else is
self-contained so the cta will be hovering
1996 -> on the left so it will have a padding of 80 and
40 pixels with a max width of 650 pixels and then
2003.04 -> we have some media queries handling the width
and the align items so the logo will take on 50
2010.16 -> of its container the headline has a font
size of 1.5 rim and align the text to
2016 -> the left and then the description has a
font size of 11 pixels also so now if i
2021.84 -> import these from the styles file and now if i
save all we have everything rendering but the text
2028.96 -> is in black so we can't see it so what
i need to do is go into my global styles
2035.52 -> and give the headings and the p type of color so
i paste them in and save we now can see the text
2042.88 -> and if i expand out the image is also on the right
we just now need to insert the import component so
2050.56 -> if i create that now so if i close my header and
within sign up i want to create a new folder this
2057.36 -> will be called input and in here we're going to
have an index of tsx file or fce as this will not
2064.96 -> receive any props and this will be named input so
in here we're going to have a container once again
2071.92 -> and within this container we're going to first
off have an email input field which will have
2078.16 -> no functionality with the placeholder equal to
email and then we will also have a sign up link
2086.4 -> so this will have functionality so sign up link
and the text inside will say continue so now
2092.88 -> on the sign up link we need an on click and on
the on click we are going to get the sign in
2099.2 -> function from next authoriac so sign in from next
all three act like so that's the functionality
2106.4 -> they're complete we just need to add the styling
for the input so again styles dot tsx and i'm
2112.96 -> just going to copy over my styles for this so
paste this in we have the container which has
2118.96 -> a width of a hundred percent a display of flex
align item center and justify content center
2125.12 -> a margin and a flex wrap of wrap the email input
is a styled dot input and we have given this a
2133.92 -> background color of the dark gray with a border
of the dark gray also and that's one p x solid the
2141.2 -> color within is a props.theme.white and then we
are going to give this a flex with 0.7 which means
2149.2 -> that it would take up 70 of its 100 width which is
declared up here the signup link would be a link
2157.84 -> that takes up thirty percent as its width and also
a background color of bright blue and some padding
2164.8 -> on there as well so if i go into the index and
import these files from the styles and now if i
2172.16 -> save and what i need to do also is render the
input so inserting that and i'm importing it from
2179.04 -> slash input and now save we now have the input
rendering on the page as you can see so there are
2185.92 -> two entry points to log in so you can log in here
or you can log in there also so now if i go back
2193.52 -> into my login page what i want to do is add some
functionality in here to say when we log in we
2200.88 -> want to then redirect to the home page so what we
want to do is get access to you session from next
2207.44 -> author react and within there we are destructuring
the data and the status so within the data we can
2214.08 -> access this session and essentially what we want
to do is if there is a session then we want to
2221.76 -> redirect to the home page so what we need is
a router so that is from next router so if i
2230.48 -> import router is equal to use router from next
router like so so now if we have a session we want
2239.68 -> to push so router dot push to an object containing
the path name we want to push the path name to
2249.2 -> the forward slash and now if i save we want to do
this on the page load so we can use use effect and
2258.72 -> in here we are passing in a callback which
is this code snippet here that we have just
2266.32 -> created so if there is a session and we only want
to do this on page load so we pass in an empty
2272.24 -> dependency so when the component mounts we pass in
if there is a session router.push to the path name
2279.68 -> of forward slash which is the home page directory
and then we also want to return anonymous function
2286.88 -> so now if i save i also i want to add another
guard clause in there so if status which is
2294.4 -> what we are accessing from the session is equal to
or triple equal to the string of loading then we
2302 -> just want to return a p type in loading and just
finally to add extra check we want to say if there
2310.88 -> is no session then we want to return the sign up
page and now if i save and go on to the home page
2319.36 -> the functionality is still not there so what
we want to do is we want to go into our api and
2326.64 -> next auth cs we need to add a callback in here so
what i will do is just copy what i already have so
2335.12 -> the callbacks will be added in here so if the url
includes slash login we want to return the home
2342.4 -> page if the url doesn't include the forward
slash meaning it we're on the home page then
2347.76 -> return to slash login so now if i save all and go
into my terminal restart my server so take it out
2355.76 -> and you're on dev again and refresh my page and
go into slash login and then if i log in now i
2363.76 -> now get directed to the home page so now that is
the login and functionality for the login page
2370.08 -> complete next we will do the home page okay so now
that the login page is complete we just need to do
2376.88 -> the same for the home page so if i just copy
what i have here i'll paste it in my home page so
2384.24 -> on here i'm just going to paste in the use session
from next or three act use router from next router
2391.76 -> use effect again from react and then the session
if there is no session then we want to redirect
2398.48 -> to the login page this time and again if status is
loading return loading and if there is a session
2405.2 -> then we want to return the disney clone so now if
i save there isn't a session so i need to log in
2412 -> sign in with google and now i'm on the home page
like so and what i want to do is i want to create
2419.68 -> a new component in here called home layout and
if i close this off as well now in my components
2427.44 -> folder i'm going to create a new folder called
home layout and in here a file called index.psx
2435.84 -> save and the home layout will take props in this
time because we are going to get movie data from
2442.64 -> the api so if we do ts rfce and for now i'm just
going to name this home layout and in this div
2452.08 -> we're going to have a few elements so we're going
to have for this slider banner and we're going to
2458.64 -> have categories so these are the categories that
we hover over so pixar disney store and that sort
2467.84 -> of categories and if we hover over them then a
video will be shown then we are going to have
2473.68 -> rows the relevant movies so we will have a title
and then underneath we will render out the movies
2481.04 -> that fit that title so we will be using the
filter method and then mapping across on each row
2487.68 -> so first off i'm going to start with the banner
so within home layout i'm going to create a new
2494.56 -> folder named glider banner and in here we're
going to create a new file named index dot tsx
2502.88 -> and in the banner we are going to do rfce
slider banner and what we need to do now
2510.4 -> is import react select if you want to react slick
and here go on to the docs and we need to add
2519.04 -> react slick into our project so open a new
terminal and paste yarn add react slick in there
2526.16 -> i also need to install slick carousel so if i copy
that across go into my terminal and yawn add slick
2534.64 -> carousel save so now that is in there we need
to include the css files also so if i copy them
2542.96 -> and import them at the top and i'm going to rename
the div to a carousel which will take in settings
2550.64 -> that we pass across so we spread settings and up
top here i have already got the settings so i'll
2557.92 -> just copy and paste them in essentially we want
the dots underneath for the slides to be true
2563.52 -> we want it to be infinite so it goes to the end
and then goes back to the first we have a speed
2568.72 -> on there we will show one slide at a time and it
will auto play as well so now we have the carousel
2575.52 -> and within the carousel i'm just going to paste
in my slides so we have a container for each one
2583.36 -> and within the container we have an image being
rendered so container for the images is named wrap
2589.76 -> so what we could also do is each wrap could be a
separate component and then within the component
2596.4 -> we pass the image down as props and then we render
the image that way but for now we're just going to
2602.96 -> render it like this it's not how you would do it
in a production environment it's just a way to
2608.32 -> render out everything in one slide for our slider
so we can visually see what is being shown so now
2614.64 -> what i need to do is create the styles.tsx file
and in our styles file we want to paste in what
2623.28 -> i already have so i am essentially importing
slider from react slick so this is the
2630.08 -> carousel and i am editing the slider from react
slick in here i've got a margin top of 20 pixels
2637.52 -> we are accessing the class name of slick list to
show that there is an overflow and it is visible
2643.84 -> increasing the font sizes of the buttons
to 10 pixels and give it a white color
2649.04 -> the slick dots which is the bottom which
shows the slider position so these dots here
2656.24 -> we want to have them at the bottom right of
the image so now if i save everything and
2661.6 -> import we will visually see what is happening
and the wrap also from the styles so if i save
2669.52 -> and in styles we have an error which says react
slick is not there so what we need to do is close
2677.52 -> our terminal and restart again and we need to
import the home layout and save so now that we've
2684.56 -> created the slider we just need to import it into
the home layout so where the slider banner is i'm
2690.96 -> just going to import that in and if i save so to
debug this problem if i go into my package.json
2699.2 -> i do have slick carousel installed here so what i
need to do is go into my file and just remove this
2707.76 -> from here and now if i save i now have the slider
rendering on the page so now if i go into the
2714.4 -> home layout component close this one off in here
this div is going to get styled so i'm going to
2720.32 -> name this container so we can bring the margin
on the left and right in a little bit and i'm
2726.08 -> going to create a new file in the home layer named
styles.tsx and if i just copy my styles over paste
2735.04 -> them in so export the container which is equal to
style.main so we are using semantic html tags so
2742.24 -> this is the main element on the page we're going
to give you a min height of 100 v h minus the 70
2748.08 -> from the header some padding as well on the left
and the right a position of relative and overflow
2754.08 -> on the x-axis of hidden before anything renders
on the page we're going to give it a background
2760.48 -> of the home background which is located in the
public slash images slash home background.png
2768.16 -> it will be behind any other elements on that
page and then we are also going to style all
2773.44 -> the corresponding h4s with a font size of 1.3
rem and some letter spacing and some line height
2780.24 -> so if i go back into my home layout and
import the container from dot styles so
2786.48 -> now we are rendering the slider button now if i
save so because the background image is in the
2794.4 -> images folder i just need to add slash images
slash home background like so and now if i save
2801.36 -> we now have the background rendering on the
home page so if i go back into the index
2807.92 -> tsx file on the home layout i now need to
create the categories component okay so now
2814.88 -> that the slider is done i'm going to create a
category component so if i go into my component
2821.04 -> and create a new folder called categories and in
here i'm just going to create a new file which
2826.56 -> is named index.tsx rfce for functional snippet and
it's going to be called categories and then i also
2834.08 -> want to render that in my home layout categories
and i'm going to also move the categories in
2840.24 -> within the home layout as well just so it's all
contained within the home layout folder so in
2846.24 -> categories index.js that is exporting and now i
need to import it so that is working correctly
2853.44 -> now if i save i should now see the categories
component which is here the text is in black
2860.56 -> so essentially we want to create six category
components that are the same so we want to map
2865.84 -> over them showing three on the top and three
on the bottom and then when we get to a bigger
2871.68 -> screen then we can show six in a row so first
thing i'm going to do is create a container
2877.12 -> and the container is going to be imported from
style so if i create a styles.psx file and if
2884.32 -> i import my container i also want to import style
components and in my container i'm going to have a
2890.88 -> margin top because it is touching at the minute of
30 pixels a display of grid the following padding
2898.32 -> and we want to have six columns in total so that
should be six and then create a gap between the
2903.92 -> columns of 25 pixels and the border radius of
10 and then when we drop to 768 pixels and below
2912.48 -> then we change the columns to three so if i go
into my index file now and import this from the
2920.32 -> dot slash styles and now if i save we have that
in there so we need to render some children within
2926.24 -> the container so we want to first of all create
some data and map a reusable component so the best
2934.32 -> way to do this is to create an array of objects
so what i'm going to do is in my categories here
2941.12 -> i'm going to create a new file called data dot tsx
and i already have the data created so i'm going
2950 -> to say export const video data which is equal to
an array and i'm going to paste in six objects
2958.56 -> in here and we have an id which is a number and
name which is a string of disney the video is
2965.36 -> coming from slash videos slash disney mp4 and we
also have an image url which we are getting from
2971.84 -> the disney website if we hover over video data we
can see here that typescript is already inferring
2979.84 -> the types but what i want to do is create the type
for the video data so i can easily just copy this
2986.88 -> and in types i want to create a new file called
videos.ts like so and in here i'm going to export
2995.92 -> the interface of the video data which is an object
like so and i'm going to take this out and delete
3004.48 -> this as well so now we have access to the video
data type so if i go back into my data dot tsx
3012.32 -> i can now declare the type on here so if i give
it a colon and video data and import this with
3019.36 -> control spacebar from types there is still an
error because it is an object that i have stated
3025.84 -> here so an object that contains id of a number
name of string video of string and image url
3032.48 -> offstring so all i need to do now here on video
data type is just add array brackets like so
3039.04 -> and i still i'm still getting the error so what i
will do is rename this type video data type again
3045.6 -> video data type and then if i go into types here
again video data type and now if i save i now have
3052.96 -> the video data in my data tsx file and i have
given it a type of video data type which is an
3060.4 -> object that contains the relevant information and
that is within an array so if i was to change this
3067.44 -> to a string for example it now throws an error of
id saying that type string is not assignable to
3074.32 -> number so all i need to do is take that back and
keep it as a number for the id so now if i save
3082 -> we have our first type which is the videos.ts and
we have our data file here so in index.tsx i have
3091.28 -> now got the data so now i'm going to get access to
the video data so video data from slash data and
3100.48 -> i want to map over this so optional chaining so
if video data is there then i want to map over it
3108.4 -> and for each video that i have or movie whatever
you want to call it i want to implicitly return
3116 -> within the jsx so implicitly return is when you do
the parentheses like so and in here i'm going to
3124.08 -> render a component render component with relevant
data being passed down relevant data being passed
3133.04 -> down as prompt so in this case we would the data
we will be getting is the individual video itself
3140.72 -> and that will be of video data type only and
not the array so what i want to do is create a
3148.32 -> component named category content but before i do
that i want to create a wrapper so this will wrap
3156.32 -> across the category content so category content
is going to be a component and the wrapper will
3164 -> be the style so i already have the style for the
wrapper which i will paste in it has a border
3171.44 -> a background color the image image has a
background color as well that is a linear
3176.32 -> gradient a border radius for each of the wrappers
of 10 pixels a cursor pointer because it is going
3183.28 -> to be a hoverable element a box shadow on
each wrapper with the transition so when we
3189.6 -> hover over we want to transition into the video
and then we also add the scale on this way the
3197.12 -> wrapper itself increases in size so if i go
back into my index js and the wrapper is wrapper
3204.56 -> like so and if i import this from dot slash
styles i now need to create a category content
3211.52 -> folder within my category so new folder category
content and this will have an index.tsx file
3220.88 -> and again rfca pasting in the category content
and this will receive some props which will be
3228.56 -> the video a default image and a name and we will
define the same props or props like so and then in
3237.36 -> here it's best practice to add the interface props
and the props that are received are these ones
3243.6 -> over here and all of these props will be strings
so they will all be receiving strings on here like
3252.32 -> so and if i just copy this paste that in and paste
that in so now if i save we should get an error
3261.28 -> because we aren't passing anything down into
category content and we are also not rendering the
3267.52 -> components so if i import that i have an error on
here saying it is missing the following properties
3274.88 -> from type props so we need to pass them up in
so if i just copy this and paste that in so the
3281.2 -> video is going to be equal to and if i go into my
data.tsx i have a video here so video is equal to
3291.28 -> video dot video which does not make sense so what
i'm going to do is i'm going to change this to
3296.96 -> item and then rename this item so it does make
sense the default image is going to be equal to
3304.64 -> item box and the thing is with typescript because
we've already declared the type it does provide
3311.52 -> us documentation and we can see here we have four
properties that we can access so for our default
3318.8 -> image i want to get the item dot image url like
so so it saves me going back and forth or looking
3326.4 -> and console logging the data and then finally
item dot and then i have access to the name
3333.44 -> and with our wrapper always as if we map through
something we want to give it a key this will be
3339.2 -> the item id so now i'm passing the right props in
i can now remove these comments and then now if i
3347.52 -> save i also need to go to the home page and now
we have six category contents rendering and when
3354.8 -> we hover over them we are showing the right data
here so if i go to a smaller screen size it does
3361.52 -> go to the three and three in two rows so now the
categories section is complete we now need to go
3369.44 -> into the category content section so we need to
render out an image and also when we hover over
3378.16 -> we want a video to be playing and that will
be accessed from data.tsx once again the
3384.56 -> video mp4 file but we have passed down the
props now and we just need to render it out
3390.96 -> so for this i'm going to import a package called
react hover video player so if we open a new tab
3397.84 -> and paste this in and there is a package on npm
called react hover video player which is where
3404.08 -> if we hover over we see the video player there so
if i copy this and close my terminal and instead
3411.28 -> of mpm i'm going to do yarn add and paste it in we
want to take out the mpmi and now press enter so
3419.6 -> this should install it does provide documentation
here of what we want so i'm just going to run my
3428.08 -> dev again and i'm going to first off import
the video player from react hover video player
3435.52 -> and then i've got this component here that
is getting rendered so if i just copy this
3441.36 -> and paste it in my return block within the jsx so
for the video source i'm now going to use my video
3450.4 -> that i'm getting passed down from the props the
paused overlay is an image so what i'm going to do
3456.32 -> is use the next image tag for this which provides
many benefits and you can read this up on the next
3462.96 -> js website but essentially it converts your image
to a base64 string and it loads more efficiently
3470.24 -> and it optimizes the image also so for this
i'm going to have a source which is equal to
3476.08 -> default image which is being passed down from the
props so we're using that the alt will be the name
3483.28 -> which i am passing down from the props and i am
going to ignore the style here because nextgs
3489.84 -> has built in styles on the image component so i'm
just going to give it a layout of fill which will
3497.12 -> mean that it will cover the it's entire parent div
element and we don't need a loading overlay so i
3503.2 -> will delete that as well so now if i save and go
back into my local host we now have an error which
3510.48 -> means that we need to add a url onto our host name
which is the project delivery plus net so this
3519.68 -> happens when we use the next image component so it
essentially means that we can only use predefined
3525.92 -> urls so if i go into my next config.js and after
compiler i'm going to add an images object in here
3535.2 -> which takes in domains and this will be an array
of domains so i'm going to paste in my domain
3541.76 -> like so and if i save what i now need to do is
restart the server because i've made changes to
3547.52 -> the connect config file so if i do yandev and
i want to go to the home page i'm still getting
3553.44 -> this error so if i just scroll along they all have
the same url and i can see the issue which is the
3560.48 -> domains i need to put an s on the end and if i
save again and again restart the server beyond
3567.2 -> dev and now if i go into the home page we now
have the images rendering and if we go to bigger
3574.72 -> and then smaller so now if i hover over at
the pixel we now have the pixar video playing
3582.4 -> and the same with the disney and the
marvel and the national geographic as well
3587.12 -> so now that is the category section complete the
final thing we need to do is create a reusable
3593.92 -> film component which renders the rows that we
looked at at the beginning of the video so if we
3599.6 -> go into our home layout and close these folders
so we have the categories and the slider banner
3606.88 -> contained within the home layout component so if
i go into index.tsx for the home layout and delete
3614.64 -> this comment for the categories the final thing
left to do is the rows with the relevant movies
3621.76 -> i'm now going to copy the titles
across that we need so the first title
3626.16 -> is recommended for you second one is
trending the third one is new for you
3633.6 -> and the final one is originals now if i save we
have them rendering here so what we need to do now
3640.4 -> is create the role for them but before we do that
we need to create both the apis so to create an
3647.36 -> api with nextgs is quite simple all we do is go
into our pages folder and within api we have a
3654.16 -> folder called auth we just want to create a new
folder in here and i'm going to call this movies
3659.04 -> and within movies i just want to create a new
file called index.ts like so so if i want to slash
3665.92 -> movies then i will have a file on there so if i
go into localhost 3000 forward slash api forward
3673.84 -> slash movies we will have access to an api here
at the minute we don't have one so we will create
3680.08 -> one so if we go into our next documentation on
api routes we can first of all see we have pages
3686.72 -> slash api slash user.js so in our case it will be
pages slash api slash movies so i'm just going to
3693.6 -> copy this handler function here and paste this in
over here and instead of the name being john doe
3699.6 -> i'm going to have an array of objects which i have
already defined so if i just copy this across we
3705.92 -> have a long list of 19 objects in here so we want
to return this and each one is separated by a type
3713.6 -> which is original or it could be new or whatever
it may be and that is what is going to be filtered
3720.16 -> into each of these rows if i save in my file and
then refresh the slash api movies we now have the
3728.08 -> api data here so it's as simple as creating that
i now have two areas here which are typescript
3734.56 -> errors so if i control space nothing happens
so on a handler function we get a request
3741.44 -> and a response so for the request we can import it
from next api request and next api response so i'm
3749.44 -> just going to paste this in and as you can imagine
the request is going to have a type of next api
3755.92 -> request and the response is going to have a type
of next api response like so and now if i save now
3762.88 -> have the get all movies route defined so now what
we want to do is create a individual movies route
3770.32 -> so if i go into here and go into dynamic api route
as you can see we have a slash pages slash api
3778.48 -> post and then we have a wildcard id dot js so
we want to create our own wild card on there
3785.28 -> so in movies going to create a new file and gonna
have array brackets of id close the brackets dot
3792 -> ts like so essentially what we want to do now
is when we go to forward slash the id of 4 we
3800.8 -> want to return the id of this one here which is
tangled so if i press enter at the minute again
3808.24 -> we have the same error which is resolver is not a
function so in our id dot ts i want to define our
3815.84 -> list so i've already got this here as a constant
so essentially if we get the array of the objects
3823.04 -> that we have so constant movie list scroll to the
top is here and i also want to give this a type so
3829.68 -> if i go into and close this component and into my
type and create a new file and i'm going to name
3836.4 -> this movie list dot ps like so and this movie list
is going to contain the same as this object over
3843.52 -> here so in my movie list rename this to ts dot ts
and we want to export the interface face of movie
3854.16 -> list type a movie list type which is an object
and this object will contain the following data
3862.64 -> so first off we want to remove the extra closing
and opening brackets and this type will be string
3870.16 -> and essentially most of them will be a string
so if we paste this in place in another string
3876.32 -> here this one is a string also so is this one as
you can see they all are strings apart from this
3882.88 -> one which is a number and now if i save we have a
movie list type that we are exporting now if i go
3889.52 -> back into my api and paste in import this from the
types again this is an array of objects so if we
3898.88 -> add the array brackets here so we have defined
the movie list now if we go into our file here
3906.88 -> essentially we want to create a handler so if
i copy movie list scroll to the bottom paste in
3913.76 -> the movie list here and if i just copy this syntax
across into my id file so essentially what we want
3922 -> to get is the slug or in our case it's going
to be the id so instead of that it'll be id so
3928.96 -> request.query.id and if i go into my index again
we want to copy the request and response so i'll
3936.64 -> copy this across from there and then we can just
control space more to import from next like so now
3943.12 -> we have access to the id which is in the params
which is slash 4. we essentially want to filter
3950 -> out the relevant id from the movie filter that we
have this declared above so const filtered movie
3957.52 -> is equal to movie missed astaire dot filter each
movie we have we want to return the movie dot
3967.12 -> id that is equal to the id that we get from
the request structure query dot id like so
3974.72 -> and if i just delete this res dot end here
what we also want to do is get the first index
3981.44 -> of this so if we add the array brackets at the end
and zero and then as you do with node.js because
3988.32 -> this is essentially node.js we want to send
the data the 200 response so res dot send the
3995.28 -> 200 response of json so we want to convert
to json the filtered movie like so so now if
4003.36 -> i save and refresh the page we get 200 we should
change this to status instead save and refresh we
4012 -> aren't getting anything back so that is because id
would be a string within the url whereas movie.id
4020.56 -> is a number so essentially what we need to do is
this condition will always return false since the
4027.36 -> types number and string have no overlap so we need
to convert the movie id to a string so easiest way
4034.96 -> to do that is to wrap it around a string like so
and now if i save and refresh the page we now have
4042.48 -> access to the individual movie and the individual
movie data like so so if i change this to
4049.12 -> 7 we should get a different response which we do
and we get the title of my music story like so
4055.92 -> so that is the apis complete what we now need
to do is render out the films onto the home page
4062 -> so now that we have created the api for our
project if i go onto the home page so if i close
4068.72 -> down the api and go into index.tsx we now want to
fetch the data but on the server side so before
4076.48 -> the page is loaded so if i go into next js
documentation here and search for get service
4083.44 -> i props essentially we want to get the props
from the server side and pass them down into
4088.08 -> our home component here so we want to access the
movie results that we fetch from the server side
4095.36 -> and then i'm also going to create an interface for
this and that is props of movie results and then
4102.96 -> what we essentially are going to do is pass this
down as a prop into home layout and then render
4108.24 -> down the film roles that way so this will be equal
to movie list type like so but for now we will
4117.68 -> just leave that and i will explain get server side
prop as it says on the next yes documentation so
4124.16 -> essentially it will pre-render this page on each
request using the data returned by get server side
4130 -> props so you got examples of when it runs here
so it's only going to be exported from a page
4137.04 -> so when you should use graph server side props
is only if you need to render a page whose data
4142.48 -> must be fetched at request time this could be
due to the nature of the data or properties of
4147.76 -> the request pages using get server side
props will be server-side rendered at
4152.96 -> request time and only be cached if cache control
headers are configured so essentially what will
4158.8 -> happen is we will fetch the data once at build
time and then it will get cached so the data
4163.52 -> will always be there unless we change the data but
in this case we won't be changing the movie data
4169.76 -> so at the bottom of my index.tsx i'm going to
get a function called get server side props
4177.84 -> and there are examples of this on the nexus
documentation but i'm just going to type it out
4182.88 -> it will be slightly different because
we are using typescript so there will be
4187.68 -> some types we need to import from net js so export
const server side prop and this is going to get a
4195.2 -> type of get server side drops from next which
is equal to an async function and then we have
4202.32 -> a callback so get server side props and i'm going
to get my movie results so const movie result is
4209.36 -> equal to a weight fetch and we're going to get it
from here so if i copy this and paste this in so
4216.72 -> essentially we are going to get access to
all of the movies here and then we're going
4221.28 -> to convert them to json and then once we have
done that after this block we're going to return
4228.96 -> props and the props we are going to return is
the movie result so return movie results like so
4236.64 -> and also pull on this off like that and
typestrip's quite good at inferring the
4242.32 -> types anyway so if there isn't an error you
would just leave it and allow typescript to
4248.08 -> do its thing so now we are getting movie results
so in our console we should be getting access to
4254.16 -> this in the index route so movie list type i'm
now going to console log this out so console log
4262.64 -> movie result equal to movie results and now
if i save and go back into my home page and
4269.84 -> inspect the home page in my console i am now
getting the object back of this however i'm not
4278.4 -> getting the movie results back it's showing up as
undefined so i what i need to do is add an array
4285.6 -> it is an array that is getting returned so if i
now save and now get access to the movie results
4291.44 -> and there is an array of 20 objects in there so
now i am getting access to the movie results we
4298.48 -> now just need to pass this down as propped into
home layout as movie results and i'm just going to
4305.28 -> copy this interface across into the home layout
index.ts and paste that in and import this as
4314.8 -> props and get our relevant type from movie list
type so now if i save we now have access to the
4323.28 -> movie results so what i now need to do is create
film component that will render the movies
4330.72 -> for the relevant category okay so now that we have
our movie results being passed down as props and
4337.68 -> we are seeing this in the console we now want
to create a reusable films raw component so film
4344.72 -> row component and i'm going to go into components
and create a new folder named filmed raw and in
4352.32 -> here create a new file index dot tsx and this
is going to be a type group file so ts rfce
4364.72 -> and if i go back into my home layout i can now
import this from films raw and we are also going
4370.88 -> to pass down the movie results into there and i'm
also going to copy again the props into the film
4378.56 -> draw component what you can also do is because we
are reusing the same props over and over we can
4385.76 -> export this into a type and then import that into
here but for consistency we're just going to keep
4391.84 -> this interface as props i'm passing the relevant
data and types so import movie list type again
4398.72 -> and this is going to be the movie results like so
this is also going to be a react slit container so
4405.84 -> i'm going to have a container in here and create
a styles file so a new file styles dot tsx and
4413.2 -> i'm going to copy once again my styles across so
i'm going to import slider from react slick also
4420.32 -> and then the container is going to be a div
it's going to take in a prop called add margin
4425.6 -> and we will add the margin onto the last
film's row of 15 pixels at the bottom when
4431.04 -> we reach the original section so that it
doesn't touch the bottom of the page and
4435.52 -> we are going to have a width of 100 view
width so now if i import the container from
4440.88 -> the styles file like so within the container
we are going to have the content which is also
4447.28 -> going to be the slider from react slick so i am
going to pass in the settings so spread them in
4454.24 -> and these settings are going to be responsive
also so i will just copy them across like so so
4460.96 -> we have the settings here we have no dots and
it's not infinite so when we reach the end then
4466.48 -> we can only press the back arrow to go back we're
going to show four slides and scroll two each time
4473.2 -> and we have got three break points on there i
just need to move this up slightly so after props
4479.92 -> like so so now the settings are being passed
into the content we now need to get the content
4486.88 -> from the styles file so we have already imported
the slider so the content will be styled.slider
4494.8 -> as we did with the slider banner component and
we are going to have a gap again of 25 pixels
4500.88 -> a width of 89 a margin top of 30 pixels a display
of flex so it's in a row and we want to align the
4508.8 -> items centrally so now if i import this as well so
within each slider we are going to get access to
4516.08 -> the props or movie results and if that is true
then we want to map again optional chaining so
4525.6 -> i want to implicitly return a div element so div
and within the div we're going to have a wrapper
4533.84 -> and the key for each rapper will be the movie dot
and again we can have access to the properties
4540.64 -> within the movie so i'm going to choose the id as
the key we also need to add this into the styles
4546.8 -> file so if i paste this in here this will be the
styles for each movie so the wrapper will have a
4553.76 -> margin of top and bottom of zero 15 pixels on
the left and right we will have a border of 4
4560.56 -> pixels solid a radius of 8 pixels so it's round
and overflow x the horizontal axis here as hidden
4569.44 -> a min width for each wrapper of 200 pixels each
wrapper will have a box shadow similar to this
4576 -> one here it will also have a transition so when
we hover it will scale in size the border when we
4582.08 -> hover will be white and the same border radius of
8 pixels and with the image we will have a width
4588.8 -> of 100 and a height of 100 and an object fit
of cover which means fit the image as much as
4595.2 -> possible within its container so now if i import
the wrapper also from styles and in the wrapper
4602 -> i want to have an image so the source will be the
movie dot and then it will be the card image and
4612.48 -> then the alt will be the movie dot title and i'm
also going to add loading of lazy on there as well
4622.96 -> so we are optimizing correctly so now if i save we
now have the images loading and the cards loading
4630.96 -> so if i open this up and we scroll as you can
see the images are loading lazily so i'm just
4638.48 -> going to take that out so that we can see them and
if i save again all of the images are now loading
4644.88 -> but what we are doing is we are loading the entire
api so we have a list of 20 objects on the api
4653.04 -> and we want to filter out the ones on the
relevant sections so we only want to filter
4658.08 -> out the ones that have a certain type so in this
case it should be recommend if we look at the api
4665.04 -> we want to filter out the type of recommend
so if we go back into our home layout into our
4673.04 -> index file we want to pass down a category also
so the category is going to be equal to a string
4682.16 -> and if i go into the api i want to filter the
category as recommend for this one and now if i go
4689.28 -> into filmed row i will get access to the category
and then i'll also need to add this into my
4697.68 -> interface the category will be a string but
now that i have access to the category i want
4704.16 -> to also filter so movie results first off we want
to first off dot filter so for each movie or item
4714.48 -> i will call this one i want to filter out
the item that is equal to the category so
4721.04 -> item dot type so in the api is type is equal to
the category that we are passing in so for this
4731.36 -> example it will be the recommend type that we
will pass through so we should have miss marvel
4737.44 -> in there and we should have only four or five
wrappers in there so if i go into my local host
4744 -> and now press save all as you can see now the
data has changed and the slides have changed
4750.32 -> so we now have only four on here so now that we
have created the film's row all we need to do now
4757.52 -> is render that out a few more times on the home
page layout so if i delete the comment and then
4765.68 -> i'm just going to copy this and paste it
under each title like so so each title has
4771.04 -> a relevant filmed row and then the category
is the only thing that needs changing so
4776.48 -> for the second row the category name or type would
be trending so this one will be trending for new
4786.56 -> it will be new and then if we find an original
if i now save and go back into my local host i
4795.04 -> now have all the categories rendering on the page
so at the bottom now we need to add the margin so
4801.28 -> the last item so the last film draw i'm going to
put add margin as the boolean value and the crop
4809.12 -> so if i copy this and go into my film draw and
paste that in we also need to paste it in here
4816.32 -> as a boolean value and this will cause an
error if i save all so on the container if i
4824.08 -> for add margin is equal to add margin like so and
i go back into here i now have an error saying add
4831.6 -> margin is missing in type movie results so
what i need to do now is go into the films row
4838.32 -> and because this is an optional prop i'm going
to put in the question mark like so and that will
4844.72 -> mean that is an optional prop so we don't have to
pass it in always so now if i save that should add
4852.48 -> the margin at the bottom which it has done there's
a little margin now and if we test the film draw
4859.2 -> out it is working correctly what we now need to do
is render out the links for each film raw item so
4868 -> within here within each wrapper i'm going to have
the link tag wrapped around it and close the link
4875.6 -> off as well like so so if we import this from
next link and it's going to have a href or
4882.56 -> forward slash movies slash movie id so the id
of each movie that we have if we click through
4890.32 -> we should get the relevant page so if i now save i
should now be able to go through to each of these
4897.2 -> and go through to the page so slash movie slash 3
would be the simpsons but because the page is not
4903.68 -> yet built we would get nothing on this so what i
need to do now is to create the page so if i press
4910.16 -> back we have the home page and the individual
films rendering and linking to the correct pages
4917.12 -> all we need to do now is to create these pages
so if i go into pages i have my api folder here
4923.92 -> i'm just going to create a new folder in here
so we have a directory of forward slash movies
4930.72 -> slash movie id so similar to how we did the api
i'm going to create a movies folder and in here
4938.48 -> i'm going to create a file a wild card file so
array bracket id close the brackets dot tsx like
4947.28 -> so so now if we do ts or fce and i'm going to name
this movie information and now in here we're going
4956.4 -> to have an interface and pass down some data that
we will fetch from the api individual endpoint
4964.48 -> source slash api slash movies slash 7 and we
will do this with incremental static regeneration
4973.04 -> so now when we click through to an individual film
for example the credibles we want to essentially
4979.52 -> get the relevant data for this so this is slash 13
so if i go into here and type slash 13 we should
4987.36 -> get this information here we have an error so i'm
just going to export the default function on here
4995.04 -> so it's going to be export default functional
movie information now save but we now have the
5001.52 -> relevant information on this page what we need to
do is fetch the data for all of the id paths that
5009.04 -> we have on here so essentially we want to find out
how many ids there are within the api we only want
5016.16 -> to stop until we reach the last id so we will do
this with get static paths and get static props
5023.2 -> so if we go into here we have access to get static
paths which gets the amount of paths on here that
5029.6 -> we need so essentially we want to get the amount
of ids we have within the apis and this generates
5037.52 -> post 1 2 and so on and then we want to also get
static paths which requires get static props so
5045.28 -> essentially what gets static path is is when you
export a function called get static paths static
5051.28 -> site generation from a page that uses dynamic
route so in this case we are using a wildcard id
5058 -> so slash movies slash the id number next js will
statically pre-render all the paths specified by
5065.68 -> get static paths so essentially we will specify
the id's length and then if we're going to get
5072.56 -> static props next yes we'll pre-render page at
build time using the props returned by get static
5079.76 -> props you can read more about this on the docs
here so these are the two sections to read up upon
5086.56 -> so we will get started on the movie information
page so first off i want to get all of the paths
5094.08 -> from the slash movies api so this api over here
where it has the entire list of all the movies
5101.6 -> so export const static parts and we'll also want
to get the static paths type from next here as
5111.04 -> you can see which is equal to an async function
which has a callback in here and we want to get
5119.04 -> a response so contras is equal to so awake fetch
the data from localhost slash api slash movies
5129.28 -> and then the movie data so const movie data is
equal to await response dot json like so so now
5140.32 -> we want to define the paths or the length of ids
that we have on here so const paths is equal to
5150 -> the movie data that we have just received dot
map so for each movie we want to return an object
5156.96 -> and this object will be params and in the params
we want to have a key value pair so we will
5163.68 -> destructure an id property which is equal to movie
dot id but because this movie dot id is a number
5174.24 -> we want to convert it into a string so if we wrap
it around in a string like so we now have the
5181.12 -> params.id here stated and just finally we want to
return the paths that we have just declared above
5189.52 -> and we want to give it a full back of fault and to
see what a fallback of faults is if we just search
5196.56 -> for a fallback or fault and if a fallback is false
then any path not returned by get static paths
5203.52 -> will result in a 404 page so for example anything
after the id of 19s so anything after slash 20
5211.6 -> would result in a four or four page we also have
a type error here so movie implicitly has any type
5218.64 -> so all i'm going to do here is import the movie
type from the types file previous type like so
5225.44 -> and this is going to be an object so now we
have the path set we now need to fetch the props
5232.16 -> so if i just copy this and this is going to
be get static props this time instead of paths
5239.68 -> and we are going to get the props and
not the paths from next and within here
5246.48 -> we will now have access to the context object so
if i pass in the context like so and then in here
5253.84 -> i want to restructure the id from context.params
so id is equal to context.params now if i save
5264.96 -> property id does not exist on type cost url query
so i'm going to declare an interface for this so
5272.72 -> interface of i params extends the past url query
from query string as you can see here and in
5282.88 -> here we're going to define the id as a string
so all we now need to do is context operands
5290.16 -> as the iparon so now we have d structured the id
from the context.params that we have set up in
5298.24 -> the get static path section up here and now i want
to pass the movie results down as a props or const
5306 -> movie results as equal to await fetch and this
time we're going to give template literals so what
5314.88 -> we want to fetch is this here so localhost 3000
slash api slash movies and this is going to be
5322.8 -> a dynamic value so we are now going to pass in
the id here and then we're going to chain the
5329.92 -> dot friend which gives a response and we're going
to convert the response to json and then the final
5337.12 -> thing is to return the props so props and in here
we just want to pass down the movie result and as
5345.68 -> a second argument we are also going to revalidate
as 100 which means that the pages will be
5353.68 -> statically generated at build time only and then
after that we can choose to revalidate the pages
5360.48 -> so recheck the pages every 100 seconds if you
wanted to do it more then we can do so may i just
5367.12 -> do a thousand on here now all that is left to do
is pass the movie results down into the props so
5375.2 -> movie results and we also need to add this into
the interface and again this will be the movie
5382.08 -> list type that we have already imported in here
and before i return the movie information text
5389.12 -> i want to console log movie results from the
id page now if i save all and inspect my page
5398.72 -> in my console i have undefined or id page
if i just refresh again it is building now
5405.28 -> so it's building the cache of the data
and now as you can see here we have the
5410.88 -> slash 13 and we have the relevant data for this
page so if i go on to forward slash 6 for example
5419.28 -> we now have the relevant id for the slash six
id as well so now all that is left to do is
5426.32 -> create the page so the movie information page but
what i'm going to do is create a component called
5433.76 -> film layout similar to what we did with the
home layout as well okay so now we have the
5440.08 -> movie results data being passed down what we
need to do is create a film layout so if i go
5446.16 -> into my component and create a new folder called
film layout or movie layout whatever you prefer
5452.48 -> and in here i'm going to create a index.tsx file
and tsrfce and this will be named film layout like
5461.76 -> so we are going to get the movie results so i'm
going to pass in the movie results and have this
5468.88 -> as an interface which is what i prefer into the
types and then in my id tsx render out the film
5477.36 -> layout from the relevant import so in components
slash film layout the movie result is going to
5484.96 -> be passed down as a prop movie result is equal to
movie result so now if i go into the films layout
5494.4 -> i should also be getting the movie result which
is equal to the movie list type because it is
5501.92 -> just the one object here and now if i save all
the film layout is now being rendered as you can
5508.72 -> see on here now there are a lot of elements
that are going to be rendered within this so
5514 -> first off i'm going to have a container as we
always do and we are going to create a styled
5519.2 -> file for the film layout so styles dot tsx and
i'm going to import all of the styles that i need
5528.32 -> first off i want the container to be a hundred
view height an overflow horizontal of hidden a
5534.56 -> display of block a top of zero pixels so it covers
the top padding for our children and the color of
5541.68 -> white so now if i import this from styles and
now save everything is going to be contained in
5548.88 -> here i also want to have inline styling in here
just to show you how that would work so if i copy
5555.76 -> what i have and paste it in and save we now
have the background of the relevant movie here
5563.04 -> so what is essentially happening is we are setting
the background image as a url and within the url
5570.4 -> we are passing in the movie results dot background
image so this image here in the props that are
5577.04 -> being received we're going to increase the opacity
to 0.8 background position of center a background
5583.84 -> repeat of no repeat and the background size of
cover which means essentially cover the whole page
5590.64 -> so if we did a id of 15 for example as you can see
the relevant movie background is being rendered
5598.72 -> and if you do one same again so now if i save we
just need the children section to be implemented
5607.12 -> now also it's not recommended to do in-line
styling and then adding style components in a
5613.28 -> professional environment it's just to show you how
you would do either or i would recommend to stay
5619.6 -> and keep consistent with your folder structure and
how you put your styles into the relevant folders
5625.68 -> like we are doing now but this inline styling can
be done on certain occasions so in my children
5632.72 -> i want to add an image title which i have already
defined and i will copy this across so in here and
5640.72 -> paste and i also want to import these styles now
we have the image titles which is the source of
5647.44 -> movie results dot title image so if i go into my
styles the image title is here we want to display
5655.68 -> flex align item towards the ends of flex end
justify content as flick start a margin of zero
5662.88 -> auto a height of 30 v h a min i o for 170 pixels
a padding bottom of 24 pixels to separate what's
5672.16 -> underneath and then also a width of 100 i'm going
to also pull in the controls into our index which
5680.16 -> will be the buttons underneath the image and we
just need to import these as well from the styles
5685.68 -> file so we have a play button trailer button an
add button and a group watch button so now if i
5693.28 -> save we have them rendering underneath underneath
the controls we want to render the subtitle and
5699.52 -> the description so if we pull the subtitle from
the styles and the description from the styles so
5706.64 -> the subtitle is movie results dot subtitle and
movie results dot description and delete this
5712.32 -> container here as it's a duplicate and now save we
have the relevant text rendering on the page also
5719.12 -> just to go over the styles we have the controls so
display of flex in a row and align items centrally
5726.08 -> on the horizontal axis the play button is
this button here where we hover over it's
5731.28 -> got a border radius of 4 pixels a font size of 15
pixels display of flex and align items of center
5739.12 -> it's got a height of 56 and a background of a
slightly kind of white-ish color padding on the
5745.52 -> left and right are 24 pixels and then we have some
margin to separate on this right here to the next
5752 -> container and we also have this letter spacing of
1.8 pixels we also have a cursor pointer on there
5759.2 -> and then when we hover over the background
changes as well with the trailer button we are
5763.68 -> essentially copying the play button in terms of
the styling but it's just a change in background
5769.04 -> border and color the add button and watch button
are similar they have a border radius of 50
5775.84 -> and the only difference would be the background
color that is the rgb of black the subtitle has
5781.76 -> a certain font size of 15 pixels and then the
description font size is 20 pixels so now if
5788.72 -> i save everything we should have the project
complete now so if i go into the home page so
5795.2 -> forward slash home we now have the home page that
has the banner above we have the categories that
5803.04 -> are rendering the relevant images and videos on
here we have filtered categories for the film's
5809.68 -> rows and then if we was to click on one we get
taken to the relevant page with the relevant id
5816.4 -> so we are getting this we get static paths and get
static props both server side we are fetching the
5822.08 -> data so if i now log out of the site and click
sign out i should now get redirected to the
5830 -> home page so i need to implement that feature so
as we have done with the home page i just want
5835.12 -> to add this functionality into the forward slash
movie slash id page so id dot tsx and in my props
5844.56 -> paste in the new session hook we use router hook
and the use effect we want to check if there is
5852.56 -> no session then we want to redirect to the
login page like so and if there is a session
5860.16 -> then we want to return the film results so if i
now save we are now redirected to the login page
5866.72 -> so if i was to click login and sign in
with google we are now authenticated on
5873.12 -> here and if i was to click onto incredibles for
example we have the page rendering the relevant
5879.68 -> information if i was to sign out i now
get redirected to the login page as well
Source: https://www.youtube.com/watch?v=eVU1-AWKnlk