- 00:00:01 in the last video we worked on
- 00:00:03 authentication we'll finish this up in
- 00:00:05 this video when we add logout and
- 00:00:08 thereafter we'll start working on events
- 00:00:11 and make sure that we can create events
- 00:00:13 by in this video adding a modal which
- 00:00:16 we'll use to hold the form for adding
- 00:00:18 events so let's dive in
- 00:00:23 so in the last videos we implemented
- 00:00:26 authentication and if you followed along
- 00:00:28 you will notice that the styling is a
- 00:00:30 little different
- 00:00:31 I really wasn't happy with the colors I
- 00:00:33 picked before I did this was recording
- 00:00:36 now I took some time chose a little bit
- 00:00:38 some nicer colors here in my opinion and
- 00:00:40 in the video description below the video
- 00:00:42 you of course find a link to get up
- 00:00:44 repository armed with this which is the
- 00:00:47 entire code just with these colors here
- 00:00:50 so that is one thing here this now looks
- 00:00:54 nicer and besides that it's the same as
- 00:00:57 before and hence we can also still log
- 00:01:00 in here for example with our credentials
- 00:01:02 and we are forwarded to this page now in
- 00:01:05 this video I want to work on the events
- 00:01:08 I want to start working on that but I
- 00:01:09 also want to make sure that we can log
- 00:01:11 out because that's a functionality which
- 00:01:13 is missing thus far and for dad and the
- 00:01:15 main navigation I want to add a log out
- 00:01:18 button of course only if we're locked in
- 00:01:20 so essentially in this block where I
- 00:01:22 also render my bookings link there I'll
- 00:01:25 add a new list item where I want to have
- 00:01:27 my log out button so I'll add my button
- 00:01:32 element here and say log out on it and
- 00:01:35 react doesn't like this if we have two
- 00:01:38 adjacent elements in one block where we
- 00:01:43 must return only one element so you
- 00:01:45 could wrap this in a diff but that would
- 00:01:47 be a semantically incorrect and
- 00:01:49 unordered list
- 00:01:50 so I will actually use react fragment
- 00:01:53 which is basically an empty react
- 00:01:55 component that we can use as a container
- 00:01:57 so now we have that button in place I
- 00:02:00 want to make sure that this button also
- 00:02:02 looks nice and for that we could
- 00:02:06 actually give it the style we have on
- 00:02:08 all the links here and for that here in
- 00:02:11 this CSS file I'll add another rule for
- 00:02:14 main navigation items any buttons that
- 00:02:17 have I have in there should have the
- 00:02:18 same styles as my links I will remove
- 00:02:22 any border I might have there though set
- 00:02:25 the font to inherit to use my default
- 00:02:27 font set the background to transparent
- 00:02:30 and one other thing which is important
- 00:02:32 set the cursor to pointer so that our
- 00:02:34 mouse mouse cursor updates
- 00:02:37 correctly well and then down there I
- 00:02:39 also want to add my rules for buttons
- 00:02:43 where I hover over or my buttons where I
- 00:02:46 which are active and of course you could
- 00:02:48 use different styles but I'll just use
- 00:02:50 the same styles as I use on my links so
- 00:02:55 with that let's quickly sign in again
- 00:02:59 now the alignment is an issue here we
- 00:03:02 can fix that and also the padding here
- 00:03:04 now that I see that or distance we have
- 00:03:08 between the button here and bookings
- 00:03:10 let's fix that I'll add a margin of 0 Q
- 00:03:15 my anchor tags and to my button and on
- 00:03:17 the or unordered list which surrounds
- 00:03:20 that all I'll add aligned items since I
- 00:03:23 use flexbox off-center to align that all
- 00:03:27 on the same level and now this looks
- 00:03:29 better to me ok perfect so we have that
- 00:03:33 now let's make sure that the logout
- 00:03:34 button also works and for this on this
- 00:03:37 button I'll add on click equals and then
- 00:03:42 here I want to execute a method which
- 00:03:44 well does log us out and we do have our
- 00:03:47 off context here right and we do added
- 00:03:51 such that I can access by context there
- 00:03:53 now all my context I already prepared
- 00:03:56 this logout method and in Apps is where
- 00:04:00 we set up this context I also set up a
- 00:04:03 log art method already which should do
- 00:04:05 everything I need to do so the remaining
- 00:04:07 thing is that in the main navigation I
- 00:04:09 use this context and call log out there
- 00:04:13 and I don't call it like this with
- 00:04:15 parentheses instead I just pass a
- 00:04:17 reference to this logout method to the
- 00:04:19 onclicklistener so that when the click
- 00:04:21 occurs it's executed for me so to say so
- 00:04:24 back on this page let's log in real
- 00:04:28 quick here we are and click log out and
- 00:04:31 I'm locked out and I can log in again
- 00:04:34 and if I should be on bookings while
- 00:04:38 logging out I'm redirected or I should
- 00:04:41 be redirected I'm not I stay on bookings
- 00:04:43 so that's also something which I want to
- 00:04:44 change let's quickly change that an app
- 00:04:48 chess where we set up all these routes
- 00:04:50 there I am making sure that I redirect
- 00:04:53 from slash to off and that I redirect
- 00:04:57 from off to events and so on but if I
- 00:04:59 don't have a token which means I'm not
- 00:05:00 authenticated then I'll duplicate this I
- 00:05:03 want to redirect from bookings to off as
- 00:05:07 well and of course we could also write
- 00:05:09 this in a more generic way instead of
- 00:05:12 covering all the cases individually here
- 00:05:14 so I could say if I'm not authenticated
- 00:05:17 then I'll not add a from here instead
- 00:05:20 I'll always go to off here that's the
- 00:05:24 idea so I always redirect you off and
- 00:05:28 I'll just move this to the end or at
- 00:05:31 least after events so that this route in
- 00:05:35 case I'm on events has a chance of being
- 00:05:36 handled first because I want to allow
- 00:05:38 access to events but for all other cases
- 00:05:41 I want to redirect so let's try if that
- 00:05:45 works the way it should if I go to
- 00:05:46 events I can go there if I now do login
- 00:05:50 and I'm on events and I log out I stay
- 00:05:55 on events but if I log in again here and
- 00:06:02 I'm on bookings and log out I'm
- 00:06:04 redirected to off so this is working but
- 00:06:07 this is actually not even what I want to
- 00:06:09 focus on in this video instead let's
- 00:06:12 work on the events now now on the events
- 00:06:15 here my goal is that we're able to
- 00:06:17 create new events and that we then can
- 00:06:19 see the events we created for that let's
- 00:06:22 briefly have a look at our schema again
- 00:06:24 to understand how we create events we do
- 00:06:27 that by sending a mutation to create
- 00:06:29 event of course and we do pass our event
- 00:06:31 input and event input happens to be an
- 00:06:35 object with a title a description a
- 00:06:37 price and a date and the date has to be
- 00:06:39 a string here when we submit that so on
- 00:06:43 our events page we're currently only
- 00:06:46 schody of the events page I want to give
- 00:06:49 the user a button that allows the user
- 00:06:52 to create a new event for this I'll
- 00:06:56 render a div here and in that death
- 00:06:59 let's render a button create event
- 00:07:05 which if I save that looks like this now
- 00:07:11 that's nice let's give it some basic
- 00:07:14 styling at least and for that I want to
- 00:07:16 reuse the styling of the buttons I had
- 00:07:18 in my off file so therefore let's
- 00:07:21 actually grab these styles here in form
- 00:07:24 actions button and so on and let's grab
- 00:07:26 all these form controls here and let's
- 00:07:30 outsource these in a global styling file
- 00:07:32 which which would be the index CSS file
- 00:07:34 so that application wide I can have
- 00:07:36 these styles and of course I wrap my
- 00:07:40 button here in form actions well I'll
- 00:07:44 simply add an additional selector and
- 00:07:45 make sure that not just buttons and form
- 00:07:47 actions look that way but all the
- 00:07:49 buttons that have the BTN class and
- 00:07:51 therefore down there I'll look for BTN
- 00:07:54 hover and BTN active and this allows me
- 00:07:58 to add that BTN class to this button
- 00:08:00 here so class name BTN and by just
- 00:08:04 adding this well we have this button
- 00:08:06 which looks a lot nicer obviously now I
- 00:08:08 want to Center it as well so in my
- 00:08:11 events page here I'll give this div here
- 00:08:16 a class of event or events control and
- 00:08:23 I'll add an event start CSS file where I
- 00:08:27 want to style that so events control is
- 00:08:29 my death there I'll add
- 00:08:32 text-align:center to align that button
- 00:08:34 in the center but I'll also give this a
- 00:08:37 border of one pixel solid and now I'll
- 00:08:41 reuse that color I used for my button
- 00:08:44 this one this purple color here and
- 00:08:47 assign that for the border and a padding
- 00:08:51 of let's say free REM and a margin of QM
- 00:08:55 top and bottom and auto left right and
- 00:08:58 the width of 30 REM with a max width of
- 00:09:02 80% here these are my styles for the
- 00:09:06 events control for these to apply here I
- 00:09:10 of course need to import that events dot
- 00:09:12 CSS file and now as this reloads or
- 00:09:16 refreshes this is
- 00:09:18 looks like this is my control area um a
- 00:09:21 little bit less padding would probably
- 00:09:24 look good so lets me reduce the reading
- 00:09:26 heading to one room and now here I'll be
- 00:09:29 able to create a new event with that
- 00:09:32 button now I'll also add a paragraph
- 00:09:35 above that share your own events
- 00:09:40 something like that okay so now we can
- 00:09:43 click that button but this button you
- 00:09:45 guessed it will not do much for creating
- 00:09:48 an event we could of course open a new
- 00:09:51 page on our screen here or what I'll do
- 00:09:55 we can use a modal and for this let's
- 00:09:58 create a new component in a new folder
- 00:10:00 which I'll name modal and in there I'll
- 00:10:02 have my modal J's file now I'll create a
- 00:10:06 new constant modal which receives props
- 00:10:09 and which should in the end return the
- 00:10:13 modal content we need to import react
- 00:10:16 from react for this and at the bottom
- 00:10:19 I'll export this as my default modal or
- 00:10:24 that's the default for this file now in
- 00:10:27 here let's just render some J's Xcode
- 00:10:30 that could well basically reflect our
- 00:10:32 modal I'll have a div and now in that
- 00:10:35 modal I would have an area for for the
- 00:10:37 title I want to have my content and I
- 00:10:39 want to have some action items at the
- 00:10:41 bottom so in the div here I'll have a
- 00:10:44 couple of sections or actually a header
- 00:10:48 for my modal title which of course
- 00:10:52 should be settle from outside so instead
- 00:10:54 of hard-coding it let's set props title
- 00:10:57 here I want to have a Content now here I
- 00:11:01 can add a section with a class name of
- 00:11:06 modal content like this and I also want
- 00:11:12 to have another section with a class
- 00:11:13 name of modal actions and that will hold
- 00:11:18 my the buttons where I can control this
- 00:11:20 modal now you can build a model in 1,000
- 00:11:24 different ways in all kinds of
- 00:11:27 variations you can build a very flexible
- 00:11:29 a modal where you can pass
- 00:11:31 configure everything here I'll try to
- 00:11:34 find them some middle ground I'd say for
- 00:11:38 the content here in the modal I want you
- 00:11:42 allow you to pass it in from outside so
- 00:11:45 here I will render props children which
- 00:11:47 is basically the slot solution react
- 00:11:51 offers so we can pass anything between
- 00:11:54 our modal JSX tags later and that will
- 00:11:57 be rendered into the modal for reactions
- 00:12:00 I'll have exactly two buttons I'll have
- 00:12:04 a button which allows me to cancel and a
- 00:12:08 button which allows me to confirm and
- 00:12:10 obviously you could make this more con
- 00:12:12 configurable to the only thing that I
- 00:12:17 will allow the user to configure is I
- 00:12:19 will accept props here props can cancel
- 00:12:24 if data set the cancel button will be
- 00:12:27 rendered and props can confirm if that
- 00:12:32 is rendered or if that is set the
- 00:12:34 confirm button will be rendered that is
- 00:12:37 my take on that now the buttons will
- 00:12:40 receive my button styles so I'll give
- 00:12:42 this class name equal BTN and the modal
- 00:12:47 as a whole here will receive a class
- 00:12:48 name of modal with that let's add a
- 00:12:51 modal CSS file next to the modal J's
- 00:12:53 here and import modal CSS into the modal
- 00:12:58 J's file and in modal CSS I of course
- 00:13:01 want to set the styling for my modal now
- 00:13:04 this styling is something you can of
- 00:13:06 course adjust to your requirements and
- 00:13:08 wishes I'll give my model a width of
- 00:13:10 let's say 40 M or 50 R m though it will
- 00:13:14 have a max width of 90% of the available
- 00:13:18 page size it will have a background of
- 00:13:22 white so about a white background color
- 00:13:25 and it'll have a box shadow of 0 2
- 00:13:28 pixels 8 pixels and then this light
- 00:13:33 slightly transparent black color here
- 00:13:38 so that's the modal container or so to
- 00:13:40 say I also want to position that and it
- 00:13:44 will have a fixed positioning on the
- 00:13:46 page and from the top let's say it'll
- 00:13:49 have a distance of let's say 20 VH that
- 00:13:53 is a relatively modern unit in CSS and
- 00:13:57 it stands for a viewport height so 20%
- 00:13:59 of the viewport browser support is
- 00:14:01 pretty good right now for this unit so
- 00:14:03 we can use it here and from the left I
- 00:14:07 now have a problem because I don't know
- 00:14:10 the exact width whether it's 90% or this
- 00:14:13 so I will actually define a two rules
- 00:14:17 here I will have a width of 90% as a
- 00:14:21 default and then I'll add a media query
- 00:14:24 for bigger screens because that is meant
- 00:14:27 for smaller screens so a media query
- 00:14:30 where I will check that we have a min
- 00:14:35 width of let's say 768 pixels and if
- 00:14:39 that is the case
- 00:14:40 I'll override my modal rule and they're
- 00:14:43 set to with – yeah maybe 50 M and then
- 00:14:49 up here I can set left to 5% because I
- 00:14:53 have 90% with I divided the remaining
- 00:14:56 part between the left and right side and
- 00:14:58 down there I know I have a width of 50 R
- 00:15:01 M so I can calculate the left distance
- 00:15:05 by using 100% of the screen size of the
- 00:15:08 of the page width so to say – 50 R M and
- 00:15:16 that should now be divided by 2
- 00:15:23 now let's add that modal on our events
- 00:15:26 jazz page just so that we can see it for
- 00:15:30 this I'll wrap this all in a react
- 00:15:31 fragment and then I'll add the modal by
- 00:15:34 just adding it's a JSX
- 00:15:37 selector here so import modal from
- 00:15:42 components modal modal and we could use
- 00:15:45 react portal for that I'll just
- 00:15:47 implement it like this and add my molar
- 00:15:50 here with my modal content which again
- 00:15:53 is passed between the opening and
- 00:15:55 closing tags so this is my modal looks
- 00:15:58 centered to me now on smaller screens
- 00:16:01 this also looks good so we can take this
- 00:16:05 I guess now of course I'm not done with
- 00:16:08 the modal well first of all I think it's
- 00:16:10 too big but that's a minor thing I think
- 00:16:12 30 Ram will do so let's use 30 Ram down
- 00:16:16 there as well but the most important
- 00:16:18 thing is I'm not done with the styling I
- 00:16:21 have my modal header I have my modal
- 00:16:23 content I'll give my modal header here a
- 00:16:25 class of modal header because I want to
- 00:16:28 select that by a class two and I'll then
- 00:16:31 add modal header here now in the modal
- 00:16:35 header I'll have a padding of a 1 R M
- 00:16:38 and I'll add a background of my purple
- 00:16:43 color which I used before so let me grab
- 00:16:45 that purple color and yes of course we
- 00:16:48 could use SAS or anything like that but
- 00:16:50 I'll just do it with vanilla CSS and set
- 00:16:54 the text color to white in there and
- 00:16:56 then in my header here the props title
- 00:17:00 will actually be inside of a h1 tag
- 00:17:04 let's say and therefore in the CSS code
- 00:17:08 I want to make sure that this h1 tag in
- 00:17:10 the modal header has no extra margin
- 00:17:13 because I already set a padding and I'll
- 00:17:15 set the font size to let's say 1.25 rep
- 00:17:19 so that's the malt modal header the
- 00:17:22 modal content will have the padding of 1
- 00:17:26 R M and that's it basically the rest is
- 00:17:29 passed in from outside and for my modal
- 00:17:32 actions where well they're all set this
- 00:17:34 to display flex
- 00:17:36 and then justify content to flex and to
- 00:17:38 move them to the end of my mode now in
- 00:17:42 events where I use the modal let's also
- 00:17:45 set some props to configure it correctly
- 00:17:48 set the title for example to add event
- 00:17:52 set D let me quickly have a look at the
- 00:17:56 modal the can cancel and can confirm
- 00:17:59 props so can cancel and can confirm like
- 00:18:03 this will be treated as true and if we
- 00:18:05 go back we therefore see our buttons
- 00:18:07 some spacing at the bottom would be nice
- 00:18:09 so in the modal here on my actions I'll
- 00:18:15 also add a padding of one room around
- 00:18:17 that safe this yeah looks good now
- 00:18:21 obviously our modal also needs a
- 00:18:23 backdrop behind it on the page and I
- 00:18:26 will create that separately in a new
- 00:18:28 folder the backdrop backdrop j/s and
- 00:18:31 there will be a very simple component
- 00:18:34 this backdrop here in the end this is
- 00:18:38 just a div here which I'll give a class
- 00:18:43 name of backdrop and which will now
- 00:18:45 receive some styling obviously we need
- 00:18:48 to import react from react here too and
- 00:18:51 we then need to export the backdrop as a
- 00:18:56 default so that is the backdrop let's
- 00:19:01 now add the backdrop CSS file to add the
- 00:19:04 styles for the backdrop and here for the
- 00:19:07 stalls I want to have a position of
- 00:19:11 fixed top should be zero left should be
- 00:19:15 zero height should be 100 VH to take the
- 00:19:19 full height of the viewport width will
- 00:19:21 be 100% and the background color will be
- 00:19:28 slightly transparent black color a less
- 00:19:33 transparent than the shadow of the modal
- 00:19:35 though now let's use that backdrop on
- 00:19:37 the events page as well so for this
- 00:19:40 I'll not just import the modal but also
- 00:19:43 the backdrop from components backdrop
- 00:19:48 backdrop
- 00:19:49 and for now I'll just drop it in there
- 00:19:51 my backdrop like this and if we go back
- 00:19:55 nothing happens because in my backdrop
- 00:20:00 J's file I of course need to import the
- 00:20:02 backdrop CSS file otherwise we see no
- 00:20:05 styling but now we got a backdrop so
- 00:20:07 this is now the modal this is how it
- 00:20:09 will look like I want to open that modal
- 00:20:14 when I click create event of course and
- 00:20:16 I will manage this flow here in events J
- 00:20:22 s by adding an onclicklistener to this
- 00:20:31 create event button and I extend my
- 00:20:36 component so I use the class based
- 00:20:38 approach and hence I can manage state
- 00:20:40 here and in that state we could have a
- 00:20:45 creating property which initially is
- 00:20:47 false and we can then add a method
- 00:20:51 create event handler or a start create
- 00:20:57 event handler to be very descriptive of
- 00:20:59 what's happening and in there all I call
- 00:21:03 this set state and set creating to true
- 00:21:06 and that will be my trigger for showing
- 00:21:08 or hiding dead bactrim intermodal so I
- 00:21:12 will now wrap this year with conditional
- 00:21:16 statements and check if this state
- 00:21:18 creating is true if it is then I will
- 00:21:20 render this backdrop so and backdrop and
- 00:21:24 the same for the modal here I can check
- 00:21:27 if this state creating is true and if it
- 00:21:30 is with the shortcut in there and
- 00:21:31 percent signs of the boolean and
- 00:21:33 connector arm I can render both the
- 00:21:37 backdrop at the modal I got an error
- 00:21:40 down there
- 00:21:43 yeah obviously I should assign my click
- 00:21:46 listener so this should point at start
- 00:21:48 create event handler so is there we can
- 00:21:51 save this and if I now click create
- 00:21:53 event we open this which is awesome
- 00:21:56 now I want to close it when I click
- 00:21:58 cancel or confirm and for this in the
- 00:22:01 modal I need to add some event listeners
- 00:22:03 to my buttons so when I click the cancel
- 00:22:06 button I want to trigger a method or a
- 00:22:10 function which is received on a prop and
- 00:22:13 the prop will be named on cancel but you
- 00:22:15 could name it whatever you want and use
- 00:22:17 this uses the classic way of executing
- 00:22:21 functions across components and react
- 00:22:23 where we receive a handle to the
- 00:22:26 function of reference to a function in a
- 00:22:28 component through props and then we can
- 00:22:30 call a function that lives in another
- 00:22:32 component in yet another component
- 00:22:35 because of that connection through props
- 00:22:37 and that's what I establish here I'll
- 00:22:39 add my own to props on cancel and on
- 00:22:43 confirm and I can't pass in function
- 00:22:46 references on these properties so now in
- 00:22:49 the events JS file here on my modal I
- 00:22:52 can simply add on cancel here and on
- 00:22:58 confirm and execute some methods in this
- 00:23:01 events page and there I'll have my modal
- 00:23:06 confirm Handler and my modal cancel
- 00:23:15 handler method in that class now in the
- 00:23:19 modal cancel handler I'll call set state
- 00:23:21 and set creating to false and for now
- 00:23:26 that's also the only thing I'll do here
- 00:23:28 though later in the modal confirm
- 00:23:30 handler I want to basically gather all
- 00:23:32 the values I entered for a new event and
- 00:23:34 output these so now let's bind this year
- 00:23:40 to the modal cancel handler and then
- 00:23:44 this on confirm prop will receive the
- 00:23:46 modal confirm handler and now with that
- 00:23:49 setup we can go back and we can now open
- 00:23:52 that modal and close it through cancel
- 00:23:55 and confirm now that
- 00:23:57 all amazing but obviously we still can't
- 00:24:01 enter anything so in the next video
- 00:24:03 we'll now finally get started with that
- 00:24:06 and make sure that we can create a new
- 00:24:08 event