Coding

#12 Adding a Navbar | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi everyone welcome back to this series
  • 00:00:04 in the last part of this series we
  • 00:00:06 started setting up our react project we
  • 00:00:09 added some basic pages and added basic
  • 00:00:11 routing but besides that not much is
  • 00:00:13 happening time to change that and time
  • 00:00:16 to start working on our user interface
  • 00:00:18 so right now what we have is this boring
  • 00:00:22 h1 tag for every page we visit now how
  • 00:00:26 about the navigation bar at the top that
  • 00:00:28 sounds like a good idea to start right
  • 00:00:30 so that's exactly what we'll do in this
  • 00:00:32 video and a little bit more as well
  • 00:00:37 so let's start building some react
  • 00:00:39 components as mentioned in the last part
  • 00:00:42 of this series basic react knowledge is
  • 00:00:44 required dive into the official box or
  • 00:00:46 take my complete guide to get that basic
  • 00:00:49 knowledge in the source folder of my
  • 00:00:51 front-end I will now add a new folder
  • 00:00:54 which I named components and that is
  • 00:00:56 where it will store all my regular
  • 00:00:57 components now regarding that file
  • 00:01:00 structure you could use a different file
  • 00:01:02 structure for example you could also use
  • 00:01:04 a by feature structure where you don't
  • 00:01:06 have pages and components but you have
  • 00:01:08 off bookings events and then you have
  • 00:01:10 sub components the pages and the other
  • 00:01:12 components that belong to a feature in
  • 00:01:15 that sub folder I will go for that
  • 00:01:17 structure right now now in components I
  • 00:01:20 want to have a navigation bar so we'll
  • 00:01:23 add a new subfolder in there and I will
  • 00:01:25 name it navigation and in there I will
  • 00:01:28 add my main navigation jeaious file now
  • 00:01:33 here again I will create a normal react
  • 00:01:36 component this time however not a
  • 00:01:38 class-based one not a stateful one by
  • 00:01:41 the way of course these components don't
  • 00:01:42 need to be stateful right now but we
  • 00:01:44 will add logic that requires State in
  • 00:01:47 the future here however I'm very
  • 00:01:49 unlikely to need state so what I will do
  • 00:01:52 in my navigation here actually is I will
  • 00:01:56 import react from react and then create
  • 00:01:59 a functional component so I will create
  • 00:02:01 a new con steer name that main
  • 00:02:03 navigation you could start with a
  • 00:02:05 capital M I as a convention name it in a
  • 00:02:09 camel case here inside of that file we
  • 00:02:12 only need to have Pascal case in the
  • 00:02:14 files where we then start using this as
  • 00:02:16 a component and there
  • 00:02:19 this is a function as a functional
  • 00:02:21 component we get props here that is how
  • 00:02:24 functional components work in react and
  • 00:02:26 then we have the function body where we
  • 00:02:30 need to return some JSX and if all
  • 00:02:33 you're doing is return some JSX
  • 00:02:36 you can use the shorthand notation for
  • 00:02:38 the arrow function and instantly returns
  • 00:02:42 i'm JSX
  • 00:02:42 like h1 tag the nav bar and then you can
  • 00:02:48 export this function as
  • 00:02:50 default for this file now this is one
  • 00:02:53 single expression and so is it the case
  • 00:02:56 if I wrapped it in a div for example but
  • 00:03:00 of course this gets harder to read the
  • 00:03:02 more and more elements we add even if
  • 00:03:04 it's all wrapped by one element and
  • 00:03:05 therefore one notation you often see is
  • 00:03:08 that you wrap this in normal brackets
  • 00:03:10 and then you can write multi-line code
  • 00:03:13 here even though it's still technically
  • 00:03:14 only one expression but it's easier to
  • 00:03:16 read now I don't want to wrap this in a
  • 00:03:19 div though I will wrap it in a header
  • 00:03:21 and in that header I wanna have a couple
  • 00:03:24 of different areas and here I will add a
  • 00:03:28 div and that will get a CSS class and in
  • 00:03:32 a react you have to use class name here
  • 00:03:34 which will be my main navigation logo
  • 00:03:39 using some PM style naming here or class
  • 00:03:43 naming and I will not name this the nav
  • 00:03:46 bar but let's come up with some fancy
  • 00:03:49 name for our app could be easy event or
  • 00:03:52 whatever you like then I also want to
  • 00:03:55 have my navigation items and I want to
  • 00:03:57 have them on the right and for that I
  • 00:04:00 will reserve a different div with a
  • 00:04:03 class name of main navigation items for
  • 00:04:07 example and in there I wanna have a
  • 00:04:11 unordered list and since that will be
  • 00:04:14 navigation items I'll actually convert
  • 00:04:16 this from a div to an F whoops a nav
  • 00:04:19 element and there I'll have an unordered
  • 00:04:22 list with a couple of list items and
  • 00:04:25 each list item should be a link to the
  • 00:04:28 different pages we have here and I could
  • 00:04:32 use Angoor tag but to catch any clicks
  • 00:04:35 on that and prevent a real request from
  • 00:04:37 being sent and therefore the page
  • 00:04:39 reloading I will instead import
  • 00:04:41 something from react router dumb and
  • 00:04:45 then something here is the link or there
  • 00:04:49 is a special form the nav link component
  • 00:04:52 and that will render a normal anchor tag
  • 00:04:54 in the end but when we click on it it
  • 00:04:56 will catch the click and prevent the
  • 00:04:59 default which would be that the browser
  • 00:05:00 sends a request and hence reloads the
  • 00:05:02 page
  • 00:05:03 will not reload the page and instead
  • 00:05:05 analyze that the click basically
  • 00:05:08 analyzed which path you wanted to go
  • 00:05:10 manually update the URL to reflect that
  • 00:05:14 and manually rendered the right page for
  • 00:05:17 you so that you don't leave that single
  • 00:05:20 page application illusions so that you
  • 00:05:21 don't reload the page but you stay in
  • 00:05:24 your currently rendered application
  • 00:05:26 therefore in this list item I'll use
  • 00:05:29 Natalie and the difference between nav
  • 00:05:31 link and link basically is that nav
  • 00:05:34 links get a extra CSS class rendered
  • 00:05:37 when they are active so when the path
  • 00:05:38 you are on matches the path the link
  • 00:05:41 points to so that you can style them
  • 00:05:42 differently and here that nav link needs
  • 00:05:45 a two property and let's say here we
  • 00:05:48 have one that leads to slash events and
  • 00:05:51 the text will be events and we have
  • 00:05:54 another list item and there we have
  • 00:05:56 bookings and we can go to our bookings
  • 00:06:00 we could also add one to authentication
  • 00:06:05 so let's maybe duplicate this and up
  • 00:06:06 there have off and there right
  • 00:06:10 authenticate something like that now but
  • 00:06:13 restructured thanks to Auto formatting
  • 00:06:15 this is how our navigation could look
  • 00:06:18 like it will have no styling right now
  • 00:06:20 but this is how it can look like from a
  • 00:06:23 structural perspective now since we
  • 00:06:26 already export it we can start using it
  • 00:06:28 and I want to use it on every page here
  • 00:06:30 on the off page the bookings paged
  • 00:06:32 events page because the main navigation
  • 00:06:34 bar should always be the same to do that
  • 00:06:38 we can of course simply go back to app
  • 00:06:41 jeaious which is a wrapper around all
  • 00:06:43 these components and here I can import
  • 00:06:46 my main navigation from and then go to
  • 00:06:51 components navigation main navigation
  • 00:06:55 and please also note that this
  • 00:06:57 navigation will have no styling at all
  • 00:06:59 and therefore right now it will also not
  • 00:07:01 be responsive it will not even look good
  • 00:07:03 on desktop devices it's just unstyled
  • 00:07:06 now I have this main navigation
  • 00:07:08 component and here you have to use
  • 00:07:10 Pascal case by the way you can names
  • 00:07:12 however you want doesn't have to be the
  • 00:07:14 name you chose here because you export
  • 00:07:16 as a default but it has to be Pascal
  • 00:07:19 case so that you can use it as a
  • 00:07:21 component in JSX and now I want to use
  • 00:07:25 it here around my switch statement main
  • 00:07:28 navigation I will use or not around it
  • 00:07:31 but on top of it so did I have the
  • 00:07:33 navigation at the top with the links so
  • 00:07:36 inside of the browser router because the
  • 00:07:37 nav links are provided by that react
  • 00:07:40 router package but above the place where
  • 00:07:43 the content will then be rendered we
  • 00:07:45 could also put that content into a main
  • 00:07:47 component a main element that is a
  • 00:07:50 normal HTML element and it's totally
  • 00:07:52 optional as well you don't need that but
  • 00:07:55 I like this from a semantic perspective
  • 00:07:57 if I do that and I save everything and I
  • 00:08:00 go back I get an error here yeah the
  • 00:08:05 problem is that I may only have one
  • 00:08:07 child element here browser router is not
  • 00:08:09 okay with having two sibling elements as
  • 00:08:12 child as children and to work around
  • 00:08:15 that we can use a component built-in to
  • 00:08:17 react react dot fragment which is
  • 00:08:21 basically an empty shell you could say
  • 00:08:24 it does not render a real HTML element
  • 00:08:27 but it fulfills that requirement of
  • 00:08:30 being a rapper even though it's
  • 00:08:31 invisible so to say so I wrap react
  • 00:08:34 fragment around my navigation and the
  • 00:08:36 main element and now it is reloads and
  • 00:08:39 this is my unstyled navigation bar
  • 00:08:41 doesn't look much like a bar I know but
  • 00:08:44 it will be and these are my links and
  • 00:08:47 actually if you click on them
  • 00:08:48 you see they work and the interesting
  • 00:08:51 thing which can be hard to spot at first
  • 00:08:53 is that this page never reloads watch
  • 00:08:56 Ted reload icon when I click around here
  • 00:08:59 this never spins now you can see the
  • 00:09:02 difference if you replace one of these
  • 00:09:04 links let's say the events linked
  • 00:09:06 temporarily with a normal anchor tag
  • 00:09:09 which leads to slash events like this if
  • 00:09:13 I do that using a normal anchor tag then
  • 00:09:17 you see no difference here it looks the
  • 00:09:18 same and authenticated bookings works as
  • 00:09:21 before but watch to reload I can hear
  • 00:09:24 when I click on events you see that's
  • 00:09:27 benzene you can clearly see that the
  • 00:09:29 page
  • 00:09:30 when I click on it not for authenticated
  • 00:09:32 bookings but clearly for events and
  • 00:09:34 that's the idea of or behind not using
  • 00:09:38 that anchor tag but using that nav link
  • 00:09:40 because that prevents this and keeps us
  • 00:09:43 in the already running application which
  • 00:09:45 is a much nicer user experience of
  • 00:09:47 course okay so this is the unstyled
  • 00:09:50 navigation now it's time to add some
  • 00:09:52 styling and for that I'll add a new file
  • 00:09:54 here main navigation dot CSS and I will
  • 00:09:58 import that styling file here in main
  • 00:10:01 aviation j/s you can do that the create
  • 00:10:04 react app tool gives you a project that
  • 00:10:08 is capable of importing CSS into
  • 00:10:10 JavaScript so to say it does not really
  • 00:10:13 import it but it uses web pack behind
  • 00:10:16 the scenes which is a tool which sees
  • 00:10:18 that import and which then takes your
  • 00:10:20 CSS code and injects it into the final
  • 00:10:23 page for you so it's just a convenient
  • 00:10:26 way of adding CSS you could say the CSS
  • 00:10:29 code here is not scoped to this
  • 00:10:31 component by the way it's still imported
  • 00:10:33 as global CSS if you do it like that and
  • 00:10:36 now we can still write CSS code that
  • 00:10:39 with style every or any element on the
  • 00:10:42 page but of course thanks to me using
  • 00:10:45 the e/m class names I can use these
  • 00:10:47 class names to make sure I only style
  • 00:10:49 the parts and want a style so I will
  • 00:10:52 also give my header a class name of main
  • 00:10:55 navigation here so that I can target the
  • 00:10:58 header itself then have a way of
  • 00:11:00 targeting the logo wrapper and I have a
  • 00:11:03 way of targeting my navigation items so
  • 00:11:07 in here we can now target main
  • 00:11:10 navigation which is the entire header
  • 00:11:11 and I want to have that fixed to the top
  • 00:11:14 and now this is some CSS code again as
  • 00:11:17 always I have a course for that if you
  • 00:11:20 want to learn more about that take my
  • 00:11:22 CSS the complete guide it's a great
  • 00:11:24 course which takes you from CSS novice
  • 00:11:27 to advanced CSS user or as always take
  • 00:11:30 free resources
  • 00:11:31 the idea behind my courses obviously is
  • 00:11:33 that I give you all the knowledge in a
  • 00:11:35 in my opinion well presented and optimal
  • 00:11:40 way but no need to buy them if you don't
  • 00:11:42 want to you can take free read
  • 00:11:43 versus as well I just assumed some basic
  • 00:11:46 CSS knowledge here I will not walk
  • 00:11:48 through every tiny behavior and every
  • 00:11:51 property we add so here I will set the
  • 00:11:54 entire header to a fixed position in the
  • 00:11:57 top left corner with these two
  • 00:12:00 properties I want to take the entire
  • 00:12:02 width and I will give this a height in
  • 00:12:04 rem of let's say 3.5 REM that should be
  • 00:12:09 fine and I will give it a background
  • 00:12:11 color off let's start with orange and
  • 00:12:16 then pick a nice color here I will
  • 00:12:19 probably refine that don't know what
  • 00:12:21 looks good maybe this orangish color
  • 00:12:25 here we'll see um let's go with that for
  • 00:12:29 now where that's actually maybe go more
  • 00:12:33 into the bluish area here something like
  • 00:12:36 that so this is my background color here
  • 00:12:39 and we'll give it some padding zero to
  • 00:12:42 top and bottom but let's say one rm2
  • 00:12:44 left and right and if we now save that
  • 00:12:47 we should already see the first change
  • 00:12:49 this is my header styling it does not
  • 00:12:52 give the background color to the entire
  • 00:12:53 header content because I restrict the
  • 00:12:56 the height here and now my goal of
  • 00:12:58 course is to position all the header
  • 00:13:00 children inside of the header for that I
  • 00:13:03 will use flexbox here so display flex
  • 00:13:06 and that already makes a difference the
  • 00:13:09 moment I add it now you see these items
  • 00:13:11 jump to the right of my logo and now I
  • 00:13:15 also want to target main navigation
  • 00:13:17 logos so that's the div around my h1 tag
  • 00:13:20 and I want to target that h1 tag in
  • 00:13:23 there to be very precise and I will
  • 00:13:26 remove the margin from there and I will
  • 00:13:31 also set the font size to 105 Ram only
  • 00:13:36 and now this looks like that but I want
  • 00:13:39 to position it in a vertical center and
  • 00:13:41 with Flex box that's really easy on the
  • 00:13:44 wrapping element so the main navigation
  • 00:13:46 header here I just have to set align
  • 00:13:49 items to center here and what this does
  • 00:13:53 is that it aligns items on the center on
  • 00:13:56 the so-called cross
  • 00:13:57 axis the main axis here is from left to
  • 00:13:59 right by default the cross axis is from
  • 00:14:02 top to bottom therefore and it aligns
  • 00:14:04 all the items at the center of the cross
  • 00:14:06 axis now obviously my items here the
  • 00:14:10 navigation items should also be
  • 00:14:12 positioned next to each other without
  • 00:14:14 bullet points and therefore I will now
  • 00:14:16 target my main navigation items that
  • 00:14:20 should be items here which is the
  • 00:14:24 unordered list and there I will remove
  • 00:14:27 any margin we have and remove any
  • 00:14:31 padding we have and also set the list
  • 00:14:34 style to non here and on the margin I
  • 00:14:37 will remove it almost I want to remove
  • 00:14:40 it on the top I want to remove it on the
  • 00:14:43 right and on the bottom but to the left
  • 00:14:47 I actually want to have let's say 1.5
  • 00:14:49 rim to have some spacing to the logo and
  • 00:14:51 now with dad to observer semicolon if we
  • 00:14:55 save that it looks like that now I want
  • 00:14:59 to position the items next to each other
  • 00:15:00 as I said we have to keep in mind that
  • 00:15:02 main navigation items is only a wrapper
  • 00:15:04 around the unordered list so now I need
  • 00:15:07 to select that unordered list in there
  • 00:15:09 and I will turn this into a flex box to
  • 00:15:12 into a Flex container to with display
  • 00:15:14 flex and therefore by the way I need
  • 00:15:18 list-style:none on this year and the
  • 00:15:22 padding should also be reset there and
  • 00:15:26 the margin can actually be 0 in all
  • 00:15:31 directions here and up there which was
  • 00:15:35 just an F so tiny mistake on my side I
  • 00:15:37 just want to have some margin left so
  • 00:15:39 dad will do entirely for a moment I
  • 00:15:42 thought that this was added to the
  • 00:15:44 ordered a to the unordered list but it
  • 00:15:46 was not it was there never item which
  • 00:15:48 has no default stylings so no need to
  • 00:15:51 reset the padding for the unordered list
  • 00:15:53 I do need to do that however and I do
  • 00:15:55 set the display to flex and with that if
  • 00:15:57 we save that the items are already
  • 00:16:00 aligned next to each other
  • 00:16:01 thanks to flex box obviously would be
  • 00:16:04 nice to have a little bit different
  • 00:16:06 stylings here and a little bit more
  • 00:16:07 spacing so
  • 00:16:10 on my main navigation items I will
  • 00:16:12 select the individual list item ament's
  • 00:16:14 and I will give these a margin of zero
  • 00:16:17 top to bottom or a top and bottom but
  • 00:16:20 left and right I will give these let's
  • 00:16:24 say one REM and then I'll also select
  • 00:16:29 main navigation items any anchor tags in
  • 00:16:33 there and keep in mind that nav link
  • 00:16:36 will render a anchor tag in the end so I
  • 00:16:38 do select my nav links with that you can
  • 00:16:40 select JSX elements in CSS anyways by
  • 00:16:43 the way you have to select the HTML
  • 00:16:45 elements there the JSX renders in the
  • 00:16:48 end so here I select the anchor tags and
  • 00:16:51 I will remove the text decoration there
  • 00:16:54 and let's give them some text color
  • 00:16:59 let's also start from orange again now I
  • 00:17:03 chose this bluish color here maybe
  • 00:17:06 something like this can be used as a
  • 00:17:09 contrast for the links then maybe a
  • 00:17:14 little bit more to the white color
  • 00:17:19 that's not super good to see let's make
  • 00:17:23 this totally white actually and give it
  • 00:17:25 a hover color of yellow when we hover
  • 00:17:28 over it we could also go with black here
  • 00:17:30 by the way might be even easier to see
  • 00:17:33 and now let's add Mae navigations I
  • 00:17:37 anchor tags we are hovering over or any
  • 00:17:42 anchor tags which are active with just a
  • 00:17:45 case when we just touch them or when we
  • 00:17:47 have them clicked and we haven't
  • 00:17:49 released the mouse button yet and there
  • 00:17:52 I want to give them a color well let's
  • 00:17:55 go with yellow there maybe a yellow like
  • 00:17:59 this something like that
  • 00:18:03 yeah that should do we can clearly read
  • 00:18:06 everything and we hover over it we can
  • 00:18:08 just see it gets activated obviously you
  • 00:18:11 can pick our styles there I'm just
  • 00:18:13 making them up as I write this code but
  • 00:18:15 that should be okay for now
  • 00:18:17 now that is my navigation what we can
  • 00:18:20 see is that the content that is actually
  • 00:18:23 rendered is below that navigation the
  • 00:18:26 reason for that is that I have position
  • 00:18:28 fixed here on the main navigation and
  • 00:18:30 therefore it's just positioned in the
  • 00:18:32 top left corner of this page and it
  • 00:18:34 doesn't it's not added to the normal
  • 00:18:37 document flow and therefore the average
  • 00:18:39 which are rendered on the page don't
  • 00:18:41 take care about that main navigation now
  • 00:18:44 I want to keep it fixed and therefore I
  • 00:18:47 will solve this by giving this main
  • 00:18:50 element here some margin to the top
  • 00:18:53 essentially so here I will give this a
  • 00:18:57 class of let's say main content you can
  • 00:19:00 name this class however you want
  • 00:19:02 we already import app CSS here so in app
  • 00:19:05 CSS I can now style main content and
  • 00:19:09 there I will give this a margin to the
  • 00:19:13 top of at least the height of my header
  • 00:19:15 which is 3.5 Ram but I will actually go
  • 00:19:20 with for Ram to have some additional
  • 00:19:21 spacing and I also want to have some
  • 00:19:26 margin – left and right so let's
  • 00:19:28 actually change this to margin top is 4
  • 00:19:31 m and then we have left and right off
  • 00:19:35 let's say 2.5 Ram and bottom is all the
  • 00:19:38 for Ram because I don't set a separate
  • 00:19:40 value and now we can clearly see the
  • 00:19:43 events page here and if I switch around
  • 00:19:45 you see that as positioned correctly for
  • 00:19:47 every page now what we don't see is the
  • 00:19:50 the page were on is is not marked as
  • 00:19:53 active here in the navigation now if we
  • 00:19:58 inspect that however here in the
  • 00:20:00 developer tools you see I'm on /off and
  • 00:20:03 actually this anchor tag has a class a
  • 00:20:06 CSS class of active and that is a CSS
  • 00:20:09 class which is added automatically by
  • 00:20:12 that nath link component we are using
  • 00:20:15 here so what we know is which
  • 00:20:17 ever pages active will have the act of
  • 00:20:20 CSS clasp now obviously we can use that
  • 00:20:22 for styling then so I want to apply my
  • 00:20:25 highlighted style here not only when we
  • 00:20:28 hover over it or when it is active in a
  • 00:20:30 sense of we're clicking on it but also
  • 00:20:32 when it has this active class with a dot
  • 00:20:37 act if we say whenever anchor tag has
  • 00:20:39 the active class it should get that
  • 00:20:42 color and now you see that it's yellow
  • 00:20:44 now obviously you can change the
  • 00:20:47 stylings to your likings if you prefer
  • 00:20:49 different stylings now it's still not
  • 00:20:51 responsive of course you see if we
  • 00:20:53 preview this on a mobile device let me
  • 00:20:57 increase it a little bit um you can
  • 00:20:59 clearly see the navigation just gets cut
  • 00:21:01 off and this is obviously not the the
  • 00:21:04 layout gonna have on a mobile view there
  • 00:21:06 we would like to have some some
  • 00:21:08 hamburger button and a sliding side menu
  • 00:21:11 now there is something um I'll not take
  • 00:21:15 care about for now right now I do have a
  • 00:21:18 video by the way where I do build just
  • 00:21:21 something like that
  • 00:21:23 responsive navigation with react so
  • 00:21:25 definitely check that out if you want to
  • 00:21:27 implement it on your own immediately
  • 00:21:29 link is in the video description for now
  • 00:21:31 we'll go with that so we can move on
  • 00:21:33 with the other features and with the
  • 00:21:35 other parts of the app like for example
  • 00:21:37 here some meat some content for our
  • 00:21:41 pages or to start with at least for our
  • 00:21:44 authentication page