Coding

#17 Adding Event Features | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 welcome back to the serious I know this
  • 00:00:04 serious is going on for quite some time
  • 00:00:06 now
  • 00:00:07 I haven't finished recording it so I
  • 00:00:08 can't tell how many other parts there
  • 00:00:10 will be but I really like the progress
  • 00:00:13 we're making now by the end of this
  • 00:00:15 video we'll have even more progress to
  • 00:00:17 show we'll be able to see a bit more
  • 00:00:21 about the events we created we'll be
  • 00:00:23 able to view the details and have a nice
  • 00:00:25 book button here and we'll also be able
  • 00:00:28 to tell whether we are the creator of an
  • 00:00:30 event or if we well can actually book it
  • 00:00:33 because we are not the creator so a lot
  • 00:00:37 of tiny improvements will also add a
  • 00:00:38 spinner and much more let's dive in
  • 00:00:44 so back in the project this is how we
  • 00:00:46 display our events and if I do
  • 00:00:49 authenticate here then we also have this
  • 00:00:53 extra box here which allows us to create
  • 00:00:56 a new event through that modal now
  • 00:00:59 that's all pretty nice but it would also
  • 00:01:01 be nice if in the boxes down there where
  • 00:01:03 I display my events which I did create
  • 00:01:05 if I had information like the price if I
  • 00:01:10 had a button that allows me to view
  • 00:01:12 details of this event and maybe also
  • 00:01:15 some indicator that allows me to
  • 00:01:17 identify whether I am the creator of
  • 00:01:19 that event or if I can book that event
  • 00:01:23 so if I'm a user who did not create that
  • 00:01:25 event so that is what I want to work on
  • 00:01:27 now and for this here in the fronted
  • 00:01:30 part of the app let's have a look at our
  • 00:01:32 events page because there at the bottom
  • 00:01:35 we have two part this one where we
  • 00:01:37 render our event list event list here in
  • 00:01:40 turn is generated here and now I want to
  • 00:01:43 work on that list and change what we
  • 00:01:45 display there now react is all about
  • 00:01:48 components obviously as you know and
  • 00:01:50 therefore let's create a separate
  • 00:01:52 component for this event so here in the
  • 00:01:54 components folder I will also create a
  • 00:01:57 new folder which I'll name events you
  • 00:02:00 can name it however you want and in
  • 00:02:03 there I will start with an event list
  • 00:02:06 first of all and then in there I'll have
  • 00:02:09 an event item now it's up to you whether
  • 00:02:13 you like this one component per folder
  • 00:02:16 style I like it hence I organize my
  • 00:02:18 components like this if you want to
  • 00:02:20 group more files together into one
  • 00:02:22 folder feel free to do so so I will
  • 00:02:25 create an event item J's file here and I
  • 00:02:28 will create my event list J's file here
  • 00:02:31 in the event list folder and I will also
  • 00:02:35 add my event item dot CSS file next to
  • 00:02:38 the event item and my event list dot CSS
  • 00:02:42 file next to my event list here so this
  • 00:02:46 is the folder structure I want to work
  • 00:02:47 with now let me grab this event item
  • 00:02:51 here from the event J's file in the
  • 00:02:54 pages folder where we previously had it
  • 00:02:56 and let's add this
  • 00:02:57 the event item here by creating a new
  • 00:02:59 react component so let's import react
  • 00:03:02 from react there and create a new
  • 00:03:05 constant event item where I get some
  • 00:03:07 props and where I in the end want to
  • 00:03:09 return my event item JSX code and where
  • 00:03:14 I will of course export the event item
  • 00:03:17 as a default now here I'm referring to
  • 00:03:21 event ID and event title now these are
  • 00:03:24 things I don't have in my event item J's
  • 00:03:27 file of course instead I expect to get
  • 00:03:30 that wire my props so here I want you
  • 00:03:33 out put my let's say props event ID and
  • 00:03:36 down there I want to have my title now
  • 00:03:40 we will add more here no worries but for
  • 00:03:42 now that is it in the event list here I
  • 00:03:47 will also import react from react I will
  • 00:03:52 have my constant event list which holds
  • 00:03:54 my function that renders tjs X code for
  • 00:03:58 this component and it will export as a
  • 00:04:01 default this event list so this is the
  • 00:04:04 event list component now in there the
  • 00:04:07 idea is to have this event list here so
  • 00:04:12 let me copy that JSX code and move it in
  • 00:04:16 there and now we can also migrate these
  • 00:04:19 styles so in the events CSS file I got
  • 00:04:22 that event list style and I will grab
  • 00:04:25 that or cut that from the events CSS
  • 00:04:28 file here and move it into my event list
  • 00:04:31 CSS file and it will also rename it to
  • 00:04:34 just event list and use that event list
  • 00:04:38 class here in my event list J's file now
  • 00:04:42 that's one part I also of course have
  • 00:04:44 two stars for the individual list items
  • 00:04:46 and you can probably guess where this
  • 00:04:49 will go of course in the event item CSS
  • 00:04:51 file so now I have my Styles and here
  • 00:04:54 obviously to use these Styles I need to
  • 00:04:56 import them so in the event item file I
  • 00:04:59 will import it event items CSS file here
  • 00:05:02 and in the event the list J's file I
  • 00:05:04 will of course add and import that
  • 00:05:06 points at my event list dot CSS file
  • 00:05:10 with that
  • 00:05:11 these components are added now the event
  • 00:05:14 list refers to an event list here and
  • 00:05:17 with that and my I don't mean that
  • 00:05:19 constant it's just a coincidence that
  • 00:05:21 this is the same name now to not clash
  • 00:05:24 with this constant name I'll rename this
  • 00:05:26 to events and now I actually need a full
  • 00:05:30 function body here not that shorthand
  • 00:05:33 expression where I just have my return
  • 00:05:36 statement instead now I need a full
  • 00:05:39 function body because I want to generate
  • 00:05:41 this events constant here which should
  • 00:05:43 be my list of events and for that I
  • 00:05:46 expect to get my events here on my props
  • 00:05:50 here so a prop named events and then
  • 00:05:54 again I want to map through that and do
  • 00:05:56 basically the same I did here in events
  • 00:05:59 chess so what I do up here and therefore
  • 00:06:02 if you want you can of course copy this
  • 00:06:06 part here let me grab that and move it
  • 00:06:09 over to the event list J's file replace
  • 00:06:12 map with that map obviously now the goal
  • 00:06:15 is not you have my li item being
  • 00:06:18 rendered here but I want to use my own
  • 00:06:21 event item component so we'll import
  • 00:06:25 event item from my event item file and
  • 00:06:27 there folder and there the event item
  • 00:06:30 file and then here I will return event
  • 00:06:33 item where I now needs to pass two
  • 00:06:37 properties at least the event ID and the
  • 00:06:40 title because that is what I use in
  • 00:06:42 there so I pass in the event ID which
  • 00:06:44 will be my event underscore ID and the
  • 00:06:49 title will be my event titles of what I
  • 00:06:53 previously used here in the list item
  • 00:06:55 now I'm using my event item component
  • 00:06:57 the event list component obviously
  • 00:06:59 should be used to and there I will need
  • 00:07:01 to pass in my list of events so if the
  • 00:07:04 raw data not of the JSX elements and
  • 00:07:07 therefore let's now move back to the
  • 00:07:10 events page here and I can remove that
  • 00:07:13 event lists constant and down at the
  • 00:07:18 bottom where I had this list of events
  • 00:07:21 before there I now want to use my new
  • 00:07:25 event
  • 00:07:25 component which you therefore need to
  • 00:07:27 import so let's quickly do that let's
  • 00:07:30 import event list from and then we go to
  • 00:07:35 components events you at least event
  • 00:07:38 list this file here so now we can use
  • 00:07:41 the event list component in this file
  • 00:07:44 and I want to use it in my JSX code down
  • 00:07:46 there so here let's render event list
  • 00:07:50 like this and as I mentioned in there
  • 00:07:53 we'll need to add events prop and there
  • 00:07:56 I want to pass in this state events so
  • 00:07:58 the events I've fetched so if you're now
  • 00:08:00 saved is it should behave in the same
  • 00:08:02 way as before if I reload and it does
  • 00:08:05 now I'm missing that key prop which I
  • 00:08:08 forgot in event list where a do loop
  • 00:08:11 through my items I need to assign a
  • 00:08:13 unique key here to every element and I
  • 00:08:16 can't just use my event ID so that is it
  • 00:08:21 and that was a lot of work for the same
  • 00:08:23 result I guess but now we have that
  • 00:08:25 dedicated event item component which
  • 00:08:28 groups and this event item functionality
  • 00:08:31 in that list of event items and here is
  • 00:08:34 now where I want to continue my work
  • 00:08:35 so in this event item there
  • 00:08:39 I want to output the title let's say the
  • 00:08:42 price below it and on the right side of
  • 00:08:44 this box so here I want to have the
  • 00:08:46 buttons that allow me to interact with
  • 00:08:48 this event for that I'll simply add a
  • 00:08:51 div in here and put my title in there
  • 00:08:54 and I'll wrap the title in our h1 tag
  • 00:08:57 which I guess makes sense semantically
  • 00:08:59 somehow so let me close that h1 tag
  • 00:09:03 after the title here and below that I
  • 00:09:07 will have let's say a h2 tag where I
  • 00:09:10 ought to put the price so for now I'll
  • 00:09:13 just hardly kill at this $19.99
  • 00:09:15 something like this on the other side
  • 00:09:19 I'll have another death where I want to
  • 00:09:21 have the actions I can perform on this
  • 00:09:24 event something like view details so
  • 00:09:27 there I want to have a button where I
  • 00:09:29 see view details for example or you
  • 00:09:34 could have something like edit or delete
  • 00:09:36 here if you're the owner of the event if
  • 00:09:38 our API would support
  • 00:09:39 though just a quick look at our schema
  • 00:09:41 we have the added such functionality
  • 00:09:43 here we only got the creative and
  • 00:09:46 functionality and we would have to
  • 00:09:47 delete or edit the event through the
  • 00:09:50 database through some graphical user
  • 00:09:52 interface connected to the database feel
  • 00:09:54 free to add it I don't have it here and
  • 00:09:56 I don't plan on adding it right now so I
  • 00:09:59 will have that view details button here
  • 00:10:01 or if I'm the creator of the event then
  • 00:10:04 I actually want to have let's say some
  • 00:10:07 text here where I say you're the owner
  • 00:10:10 of this event something like this now if
  • 00:10:14 I save it like that we'll first of all
  • 00:10:16 see all these things here it is and of
  • 00:10:20 course the formatting is also not super
  • 00:10:22 pretty now to work on the formatting
  • 00:10:25 here an event item I will use display
  • 00:10:28 flex I wanna use flexbox and in case you
  • 00:10:30 don't know flexbox um in the video
  • 00:10:32 description you'll find some helpful
  • 00:10:34 resources we got for you so I want to
  • 00:10:37 use flexbox
  • 00:10:38 I want a was to default which is flex
  • 00:10:39 direction row which means I'll have
  • 00:10:41 these items in my list item which
  • 00:10:44 actually will be these two divs as sit
  • 00:10:47 next to each other that is what I want
  • 00:10:48 to have I want to have space between
  • 00:10:50 them so that the first step is all the
  • 00:10:52 way on the left and the average F is all
  • 00:10:53 the way on the right and that can be
  • 00:10:55 achieved with justified content space
  • 00:10:57 between like this yeah so that should be
  • 00:11:01 a first step we can see the general
  • 00:11:05 direction of course I want to style like
  • 00:11:07 the h1 tag and it's on and we can
  • 00:11:10 achieve that of course with proper CSS
  • 00:11:13 so here I can stall the h1 tag in my
  • 00:11:17 event list item I'll remove the margin
  • 00:11:19 there for example set the font size to
  • 00:11:22 1.5 Ram something like that
  • 00:11:25 yeah looks better let me also grab that
  • 00:11:29 color and maybe a sign that here that we
  • 00:11:32 color this in our main color now this
  • 00:11:37 price here should be much smaller maybe
  • 00:11:39 a slight grayish color no and no margin
  • 00:11:44 so this will be my age to tack which I
  • 00:11:46 want to target so let me select the h2
  • 00:11:49 tag in my events list item element here
  • 00:11:52 and there I will as I said remove the
  • 00:11:55 margin gives us a fun size of one room
  • 00:11:58 only and then a color of maybe not that
  • 00:12:03 great but something in that area
  • 00:12:04 something like this maybe let's see how
  • 00:12:07 that looks like yeah so that looks
  • 00:12:10 better now let's work on the on the
  • 00:12:12 other side here I want to have that
  • 00:12:14 button and I wanna of course style on my
  • 00:12:18 one stylist paragraph as well now for
  • 00:12:21 the button obviously here in events jazz
  • 00:12:25 in the page we already got a button with
  • 00:12:27 the class name button and I will reuse
  • 00:12:30 that class name here simply because that
  • 00:12:32 basically is the global but the style I
  • 00:12:34 want here so I will just give that a
  • 00:12:37 class name of button and let's see what
  • 00:12:44 that gives us if it reloads view details
  • 00:12:47 that looks are great now regarding that
  • 00:12:50 you're the owner of this event here I
  • 00:12:52 will target the paragraph in my events
  • 00:12:55 list item and I will remove the margin
  • 00:12:59 from that to see what that gives us
  • 00:13:03 batter now some spacing theoretically
  • 00:13:06 would be nice here but keep in mind that
  • 00:13:08 this here will only be displayed if we
  • 00:13:11 don't see the view details button so
  • 00:13:13 we'll see either of the two we just
  • 00:13:15 haven't added that logic yet so with
  • 00:13:18 that that is actually fine there is one
  • 00:13:20 thing I want to change on the events
  • 00:13:23 list item this flex box I'll set the
  • 00:13:25 line items to center to center all these
  • 00:13:28 items on the cross axis which is here
  • 00:13:30 from top to bottom you don't see an
  • 00:13:33 effect yet but later when we display
  • 00:13:36 ever just button or this text you should
  • 00:13:38 see it effect and speaking of that let's
  • 00:13:41 implement that logic to display either
  • 00:13:42 of the two so here we basically want to
  • 00:13:46 display the button if we're not the
  • 00:13:47 creator of this event we want to display
  • 00:13:50 this text if we are now how can we find
  • 00:13:53 out if we have a look at our schema at
  • 00:13:56 the event object we get back we see we
  • 00:13:59 can get the creator and the creator is a
  • 00:14:01 user and in the user we get an ID and an
  • 00:14:05 email
  • 00:14:06 now that of course information we can
  • 00:14:08 have in the front end to in the app
  • 00:14:10 jeaious where we manage our token there
  • 00:14:13 I also manage my user ID when I log in I
  • 00:14:16 set that user ID so we have to use her
  • 00:14:18 ID on the front-end and we can fetch it
  • 00:14:20 for every event that we use so on the
  • 00:14:23 events page in fetch events here I do
  • 00:14:28 actually get the ID of every creator so
  • 00:14:31 that is exactly what I want here so with
  • 00:14:34 that information we got the idea of the
  • 00:14:36 creator and the idea of the currently
  • 00:14:38 logged in user and with that combined we
  • 00:14:41 should be able to display either the
  • 00:14:44 button or the text now to get the ID of
  • 00:14:47 the logged in user
  • 00:14:48 we'll need to use our context API and
  • 00:14:53 here in the events page I already did
  • 00:14:55 connect to that with that static type
  • 00:14:58 being set here so I can't just add a
  • 00:15:01 access this context and then in my
  • 00:15:04 context I should have access to my user
  • 00:15:07 ID therefore here to this event list I
  • 00:15:13 will pass in let's say the off user ID
  • 00:15:18 prop which is this context user ID that
  • 00:15:25 should work so I'm passing off user ID
  • 00:15:28 as a prop to the event list each event
  • 00:15:31 has information about its creator
  • 00:15:34 anyways and therefore here in the event
  • 00:15:36 list j/s where i get that data i just
  • 00:15:40 passed it on to an event item so here
  • 00:15:43 I'll pass on my user ID which will be
  • 00:15:45 props off a user ID because that's the
  • 00:15:48 name of the prop we just to find on the
  • 00:15:50 event list component and of course you
  • 00:15:53 could also directly connect the event
  • 00:15:55 item to the context if you wanted to
  • 00:15:57 this approach by using props makes it a
  • 00:15:59 little bit more reusable you could add
  • 00:16:01 it anywhere in your component tree
  • 00:16:03 independent of whether it's inside of a
  • 00:16:06 branch that has access to the off
  • 00:16:07 context kind of theoretic here because
  • 00:16:10 our whole app has access to the off
  • 00:16:12 context but still let's do it like this
  • 00:16:14 and now I know whether the user is
  • 00:16:17 authenticated or not or I got
  • 00:16:19 the idea of the authenticated user and I
  • 00:16:21 can now determine if that is the user
  • 00:16:23 who created the event so down there
  • 00:16:26 where I only want to render the button
  • 00:16:28 if this is not the Creator I can access
  • 00:16:32 this props user ID so props user ID and
  • 00:16:35 check if that is equal to my creator of
  • 00:16:40 that event so props and now I will need
  • 00:16:44 to pass on that creator information of
  • 00:16:47 course
  • 00:16:47 so creator ID is equal to event creator
  • 00:16:53 and then there we have the ID right that
  • 00:16:56 is what we fetched from our back-end so
  • 00:16:59 in the event item I now have that
  • 00:17:01 creator ID and I can compare that to my
  • 00:17:05 user ID of the locked-in user if that is
  • 00:17:09 equal then I want to render this text so
  • 00:17:12 let's render this text in this case our
  • 00:17:15 wise and this is a ternary expression in
  • 00:17:19 case you're wondering so otherwise I'm
  • 00:17:20 rendering this button let's save that
  • 00:17:24 and let's have a look here when I reload
  • 00:17:26 and fetch my events again I see view
  • 00:17:29 details here when that makes sense
  • 00:17:32 because I am not locked in by the way
  • 00:17:33 now let me log in here with the user who
  • 00:17:36 should have created these events and you
  • 00:17:39 see you're the owner of this event now
  • 00:17:42 let me log out and I see view details
  • 00:17:44 again
  • 00:17:44 and login with a different user here
  • 00:17:48 let's see if I did create that one in
  • 00:17:51 the past and I see view details again if
  • 00:17:54 I create an event now let's say a snow
  • 00:17:57 walk for a 999 and we'll have that event
  • 00:18:01 on January 30th at around 18 o clocks
  • 00:18:08 out at 6:00 p.m. a lovely walk through
  • 00:18:12 the cold snow if I confirm that here it
  • 00:18:18 isn't there I now am the owner of this
  • 00:18:21 event which of course is correct because
  • 00:18:23 well I am so I'm the owner of this event
  • 00:18:27 I got these other events where I can
  • 00:18:29 view the details and that's exactly the
  • 00:18:30 behavior I want here now
  • 00:18:33 as a totally unreal of totally front an
  • 00:18:35 unrelated side note you might notice
  • 00:18:37 that the more and more events we add the
  • 00:18:39 slower our API becomes because right now
  • 00:18:42 our API is built in a way where we have
  • 00:18:44 many round trips when we fetch the
  • 00:18:46 creator of an event because we basically
  • 00:18:48 make an extra request to the database to
  • 00:18:51 get the creator of an event for every
  • 00:18:53 event that we fetched and we'll fix this
  • 00:18:56 later in this series for now I think
  • 00:19:00 it's still a speed with which we can
  • 00:19:02 work but just in case you're wondering
  • 00:19:04 why this is getting slow this is an
  • 00:19:06 issue which will take care about so here
  • 00:19:09 I now got my events rendered I can now
  • 00:19:12 see all the events we created and I can
  • 00:19:15 differentiate between the events I
  • 00:19:16 created and events created by other
  • 00:19:18 users before I conclude this I want to
  • 00:19:23 make sure that we can actually go to a
  • 00:19:25 details page and that we view a spinner
  • 00:19:27 when we're loading the events and I also
  • 00:19:30 want to make sure that when we add an
  • 00:19:31 event we instantly add a 2d list of
  • 00:19:34 existing events and don't fetch all
  • 00:19:36 events again unnecessarily so a couple
  • 00:19:40 of things let's start with the addition
  • 00:19:43 of a new event so in the events page
  • 00:19:45 here where I have that methods to create
  • 00:19:50 a new amend here the modal confirm
  • 00:19:52 Handler and there I do create an event
  • 00:19:55 and please note that I get back
  • 00:19:59 information about the event and of
  • 00:20:02 course off the creator I don't even need
  • 00:20:05 to fetch the creator information here
  • 00:20:07 because since this event was created by
  • 00:20:10 the currently locked in user we can't
  • 00:20:12 just take the idea of the currently
  • 00:20:14 logged in user and now with that I get
  • 00:20:17 this information back and very important
  • 00:20:20 I get back the ID as well the real ID
  • 00:20:22 that was created on the server and
  • 00:20:24 therefore when we successfully added
  • 00:20:27 this here instead of calling dispatch
  • 00:20:29 events I can simply add my event to my
  • 00:20:34 current events so I can call this set
  • 00:20:36 state and set my events equal to the old
  • 00:20:40 events plus the new event and to do that
  • 00:20:43 I will use the function form of said
  • 00:20:46 state
  • 00:20:47 where we have safe access to the old
  • 00:20:50 state and can rely on the latest update
  • 00:20:52 being applied to our state and then I'll
  • 00:20:56 get my updated events here stored in a
  • 00:20:59 new constant access previous state
  • 00:21:01 events and basically just copy that list
  • 00:21:07 to not mutate my original events array
  • 00:21:11 and to updated events I will push a new
  • 00:21:14 event a new JavaScript object which
  • 00:21:17 should now be a valid event of course
  • 00:21:19 for that if we have a look at fetch
  • 00:21:22 events there we see I just push my
  • 00:21:24 events as I get them back from the
  • 00:21:26 server so I have basically events in
  • 00:21:29 there with ID title description so with
  • 00:21:32 these fields here you could say so we
  • 00:21:34 can also just copy these fields and then
  • 00:21:36 this object which I push we can add them
  • 00:21:38 now the idea as I mentioned will be the
  • 00:21:41 idea of the currently locked in user
  • 00:21:43 so context user ID the title will be a
  • 00:21:47 returned by our create event call so
  • 00:21:53 here in rest data we should have a data
  • 00:21:55 field just as we have it down there
  • 00:21:59 where I also access rest data data
  • 00:22:01 events now here I should be getting back
  • 00:22:04 rest data data and then create event
  • 00:22:10 field which holds thailand's on so here
  • 00:22:13 I should be getting that create event
  • 00:22:17 field which then holds my title create
  • 00:22:19 event because that was the name our of
  • 00:22:21 our mutation of our query therefore and
  • 00:22:24 I can just copy that and do the same for
  • 00:22:26 the description here and also for the
  • 00:22:32 date and here also for the price and
  • 00:22:37 then for the creator
  • 00:22:39 well that indeed will be a nested
  • 00:22:41 JavaScript object where the ID will be
  • 00:22:44 this context user ID of course it's
  • 00:22:46 totally wrong to use that up here there
  • 00:22:49 I want to use res data data create event
  • 00:22:52 underscore ID so I want to use that I
  • 00:22:54 did it was created on the server so up
  • 00:22:56 here we of course don't use the user ID
  • 00:22:58 I won't think about
  • 00:23:00 asleep there but here we do and I don't
  • 00:23:04 really need to store the email I'm not
  • 00:23:06 using it right now anyways so this
  • 00:23:08 should see erratically push a new event
  • 00:23:10 to that list of events instantly let's
  • 00:23:13 give that a try let me login I create a
  • 00:23:20 new event testing 2029 let's pick some
  • 00:23:27 date and time this is a test not
  • 00:23:31 canceled confirm doesn't look like it
  • 00:23:35 worked yeah that makes sense because
  • 00:23:37 it's nice that I do update my events
  • 00:23:40 list here but of course I should also
  • 00:23:42 return my new state object or the data I
  • 00:23:46 want to merge with my existing state
  • 00:23:47 where I do overwrite the existing events
  • 00:23:50 with the updated events so this is an
  • 00:23:53 important addition here obviously to set
  • 00:23:55 state and now with the add let's try
  • 00:23:58 logging in again submit and create
  • 00:24:04 another test here real quick and I will
  • 00:24:08 assume clean up some events behind the
  • 00:24:10 scenes in the database so that this
  • 00:24:12 doesn't get too slow and we have a
  • 00:24:14 manageable amount of events here
  • 00:24:19 confirmed and I think this looks good
  • 00:24:23 because we can see our test event here
  • 00:24:25 now and we can also see that where the
  • 00:24:27 owner of this event so adding our user
  • 00:24:30 ID and so on seems to have worked and we
  • 00:24:32 would we would not see that here appear
  • 00:24:34 there if we wouldn't have pushed it
  • 00:24:37 successfully if we wouldn't have changed
  • 00:24:39 our events a list or array here
  • 00:24:41 successfully because I am NOT fetching
  • 00:24:43 events anymore when we added one so it
  • 00:24:46 can't it's definitely not from our
  • 00:24:48 database so this is great
  • 00:24:51 we now have all these events available
  • 00:24:53 there now we also display whether we are
  • 00:24:56 at a creator and I instantly add them
  • 00:24:58 here let's now also make sure that we
  • 00:25:01 have some loading indicator some-some
  • 00:25:02 spinner or anything like that when we
  • 00:25:04 are loading and for this in the events
  • 00:25:07 page in the end I want to manage and you
  • 00:25:09 state here so in my global state object
  • 00:25:12 I'll add is loading which initially is
  • 00:25:14 false
  • 00:25:14 and I want to set that true for example
  • 00:25:18 when I fetch my events we could also set
  • 00:25:23 it to true when I added a new event and
  • 00:25:25 then show a spinner below that list of
  • 00:25:27 events but for dad we would have to
  • 00:25:28 manage an extra state here were kind of
  • 00:25:32 add some extra control for when to
  • 00:25:34 display which spinner where so I will
  • 00:25:37 only display a spinner here when I'm
  • 00:25:38 fetching my events not there here in the
  • 00:25:42 fetch events method and they're
  • 00:25:44 essentially right at the start I will
  • 00:25:46 just call this set state and set is
  • 00:25:50 loading to true
  • 00:25:52 now with that set to true here I want to
  • 00:25:55 reset it once I am done so here once I
  • 00:25:58 got my events I will set is loading to
  • 00:26:01 false and important I also want to do
  • 00:26:04 that when I get an error because even if
  • 00:26:06 we get an error we're still done with
  • 00:26:07 fetching so we'll set is loading to
  • 00:26:09 false here so now we have the is loading
  • 00:26:15 state and I will now use that to show a
  • 00:26:17 loading indicator for that down here
  • 00:26:22 where I have two deven slist I even want
  • 00:26:24 to show that list or well that indicator
  • 00:26:26 a very simple indicator of course is
  • 00:26:29 some text so here we'll check if this
  • 00:26:31 state is loading if that is true if it
  • 00:26:34 is we can display a let's say a
  • 00:26:36 paragraph where I say loading and
  • 00:26:38 otherwise if we're just not loading I
  • 00:26:41 want to display my events list here so
  • 00:26:44 something like this that is a relatively
  • 00:26:47 simple approach that should actually
  • 00:26:49 work here is loading and once we got the
  • 00:26:55 event said that is gone obviously that
  • 00:26:57 was not super beautiful though so let's
  • 00:26:59 work on that a little bit instead of
  • 00:27:03 just this blowing loading here I want to
  • 00:27:04 display a spinner and for dad you can
  • 00:27:06 visite loading dot io / CSS and that
  • 00:27:10 should give you some beautiful CSS
  • 00:27:12 spinners here they are and I will just
  • 00:27:15 go with this one here and now you just
  • 00:27:17 need to copy this HTML code here and use
  • 00:27:22 that here basically and then you need to
  • 00:27:25 copy that CSS code here of course as
  • 00:27:27 well and
  • 00:27:28 adjust the colors and so on now I will
  • 00:27:32 actually create a new component for that
  • 00:27:34 so it will create my spinner component a
  • 00:27:37 spinner JS file and a spinner dot CSS
  • 00:27:40 file into which I'll copy that CSS code
  • 00:27:43 here now into the jss file into the
  • 00:27:47 chase file not jss I will copy in my my
  • 00:27:52 my JavaScript code
  • 00:27:53 so here spinner obviously we need to
  • 00:27:55 import react from reacting here then I
  • 00:27:58 have my spinner constant and that will
  • 00:28:02 just render this div here and I export
  • 00:28:05 this as a default here and obviously I
  • 00:28:09 also want to import my spinners CSS file
  • 00:28:12 to apply the styling now that is all it
  • 00:28:14 takes to have a spinner component we'll
  • 00:28:16 have to adjust the color but for now
  • 00:28:19 I'll just render my spinner here and for
  • 00:28:22 that I'll need to import it at the top
  • 00:28:24 so import spinner from components
  • 00:28:28 spinner spinner so with that import
  • 00:28:31 added in the events page here I can use
  • 00:28:34 my spinner down there at the bottom and
  • 00:28:37 render it here and now regarding the the
  • 00:28:40 coloring which I mentioned I will use my
  • 00:28:43 default purple color here and replace
  • 00:28:45 white ear with that color and now it
  • 00:28:50 should look better now when this page
  • 00:28:52 reloads we do see that spinner because I
  • 00:28:58 copied that HTML code I have a little
  • 00:29:00 error that should be class name here not
  • 00:29:02 class and I of course still want to
  • 00:29:06 Center it so I'll will actually wrap
  • 00:29:09 this into another DEATH oops
  • 00:29:14 like that which I'll give a class name
  • 00:29:18 of spinner and then in my spinner CSS
  • 00:29:22 fall I'll target that class name use
  • 00:29:25 flexbox again and then justify my
  • 00:29:28 content in the center and align items in
  • 00:29:31 the center to have the perfectly
  • 00:29:32 centered spinner just like that and
  • 00:29:36 therefore now when we reload we see our
  • 00:29:38 spinner here and after some time we
  • 00:29:41 should
  • 00:29:42 our events great so that is the spinner
  • 00:29:45 edit that is the events added and so on
  • 00:29:47 now why don't we also display the real
  • 00:29:51 price here then and to date and then
  • 00:29:54 make sure that we can go to the details
  • 00:29:55 page so back on the event item JS file
  • 00:29:58 here this price is now is still a dummy
  • 00:30:01 price but obviously we can simply expect
  • 00:30:04 the price as a prop on event item and
  • 00:30:07 then ensure that we pass it on here in
  • 00:30:09 the event list so a forward price by
  • 00:30:12 simply accessing event price and it will
  • 00:30:15 also already forward to date by
  • 00:30:18 accessing event not price but date here
  • 00:30:21 because if you have a look at our schema
  • 00:30:24 you see that for an event we got our
  • 00:30:26 date and that is a string actually
  • 00:30:28 because it's stored as such in the
  • 00:30:31 database were fetched as such by graph
  • 00:30:33 QL
  • 00:30:33 so now date and price is passed on to
  • 00:30:35 the event item price is already getting
  • 00:30:37 used and I'm going to output the date
  • 00:30:39 let's say right after that there I want
  • 00:30:44 to add a hyphen and output props date
  • 00:30:48 like that yep I got my dates here now of
  • 00:30:51 course the day that's not reformat it in
  • 00:30:53 a way that I want to use here and to
  • 00:30:56 change that a little bit we can actually
  • 00:31:00 wrap this into our date constructor and
  • 00:31:04 then call to local date string which
  • 00:31:08 allows us to format the date and we
  • 00:31:10 could even pass in a local so something
  • 00:31:13 like de de to adjust the way its output
  • 00:31:17 to the region our users in if we fetch
  • 00:31:20 that first if we just call it like this
  • 00:31:22 without any extra configuration we still
  • 00:31:26 get output like this which doesn't look
  • 00:31:27 too shabby to me now for the price a
  • 00:31:30 tiny changes that I will add a dollar
  • 00:31:32 sign in front of that now I want to be
  • 00:31:34 able to view details and and see the
  • 00:31:36 details and actually I'll not do that in
  • 00:31:38 a new page but in a modal because we
  • 00:31:41 have all the data loaded in this page
  • 00:31:42 already so I just want to open a modal
  • 00:31:44 show the details and give me the button
  • 00:31:47 to to book there now obviously we
  • 00:31:52 already have our modal component um with
  • 00:31:56 are canceling confirm buttons and I will
  • 00:32:00 reuse that model here basically so in my
  • 00:32:03 event item here when I click view
  • 00:32:06 details I want to open it modal but I'll
  • 00:32:08 not add that modal in here instead on a
  • 00:32:12 click here I want to execute drops on
  • 00:32:16 detail and event list where I add event
  • 00:32:20 item I now know that an item was clicked
  • 00:32:25 and here I will actually bind props
  • 00:32:31 event ID so I will pass the idea of the
  • 00:32:35 clicked event as an argument to on
  • 00:32:38 detail here and I use pine here because
  • 00:32:41 if it was directly executed like this
  • 00:32:43 then I would execute this when our J's X
  • 00:32:46 code here gets rendered but I want to
  • 00:32:47 execute it when it is a click occurs and
  • 00:32:50 with that I just prepare the function to
  • 00:32:53 be called I don't call it yet so an
  • 00:32:55 event list
  • 00:32:56 I now can add on detail which is
  • 00:32:58 executed when we click this this is how
  • 00:33:00 we now pass it up and regarding that
  • 00:33:04 modal in events J s here we already add
  • 00:33:09 the modal with our add event logic now
  • 00:33:15 in the end I want to render that other
  • 00:33:16 modal regarding the booking and the
  • 00:33:18 event details in the same place so an
  • 00:33:22 event list I will pass this event up one
  • 00:33:26 more level so I will target props on
  • 00:33:31 view detail and I'm using different
  • 00:33:34 names here to make it clear which
  • 00:33:35 component triggers what and that's it
  • 00:33:39 that will just pass on the data passed
  • 00:33:42 to this component to the next component
  • 00:33:44 in line and that next component will now
  • 00:33:46 be the events page where I do render my
  • 00:33:49 event list and there I now have on view
  • 00:33:52 detail and here I now need to hook up a
  • 00:33:55 method that is actually then passed down
  • 00:33:57 through all these components and that
  • 00:34:00 will be a method here show detail
  • 00:34:04 handler for example where I get my
  • 00:34:09 event ID that is what I did pass up in
  • 00:34:13 the end and here I now want you again
  • 00:34:17 use state to show my details so here I
  • 00:34:20 will add selected event and set this to
  • 00:34:25 null initially in my state and then in
  • 00:34:28 my show detail handler there I will call
  • 00:34:32 this set state and set the selected
  • 00:34:36 event equals you the event with that
  • 00:34:40 event ID for dad let me actually turn
  • 00:34:43 this into the function form so that I
  • 00:34:45 can access all fetched events so here I
  • 00:34:48 will have my selected event stored in a
  • 00:34:51 constant I get that from my previous
  • 00:34:53 state there I have that events array and
  • 00:34:56 there I want to find that event where
  • 00:35:00 the ID is equal to the event ID I'm
  • 00:35:04 getting here so this gives me that event
  • 00:35:06 which we actually selected and then I
  • 00:35:08 can return and set selected event in my
  • 00:35:12 state equal to that selected event I
  • 00:35:14 have here so now we set the selected
  • 00:35:17 event and this is all the trigger for us
  • 00:35:20 to open a modal if we have a selected
  • 00:35:21 event now of course not this modal here
  • 00:35:24 this is our create modal but a different
  • 00:35:27 modal so we might alter something into a
  • 00:35:30 different component but for now I'll
  • 00:35:32 just add a new dynamic part in my output
  • 00:35:35 J's Xcode here if selected event is true
  • 00:35:40 ish so if this is not null or false or
  • 00:35:42 anything like that
  • 00:35:43 then I want to open my modal so just as
  • 00:35:45 a check for creating up here I can now
  • 00:35:48 copy this code here for my modal down
  • 00:35:52 there and show it when selected event is
  • 00:35:56 true oops like that now the title here
  • 00:36:02 will be and let's say the tide lofty
  • 00:36:05 selected event so this whoops and it's
  • 00:36:07 not this selected event it's this state
  • 00:36:09 selected event so this state selected
  • 00:36:12 event title I want to be able to cancel
  • 00:36:17 and confirm confirming we'll be booking
  • 00:36:20 and owl add logic to change the text as
  • 00:36:23 soon on cancel I executed this modal
  • 00:36:28 cancel helper and this is really getting
  • 00:36:30 a big component here as a see but we can
  • 00:36:33 split it up later
  • 00:36:34 here I was heading creating two faults I
  • 00:36:37 also want to set selected event to null
  • 00:36:39 here because we execute this for both
  • 00:36:41 modal's and it's always correct to reset
  • 00:36:44 the creation and the select event mode
  • 00:36:46 basically already selected event in on
  • 00:36:49 cancel here in my second modal of course
  • 00:36:53 want to exit a different method I want
  • 00:36:55 to have my book event handler be
  • 00:36:58 executed or anything like that so we'll
  • 00:37:00 add my book event handler here and then
  • 00:37:06 we'll have to do something in this
  • 00:37:07 method but we'll ignore that for now
  • 00:37:10 inside of the modal I of course don't
  • 00:37:13 want to render I forum and we should
  • 00:37:16 also close our normal parenthesis there
  • 00:37:17 by the way but inside of the modal I
  • 00:37:20 really just want you output information
  • 00:37:23 about that event so like the h1 tag
  • 00:37:27 where I output my this stayed selected
  • 00:37:32 event title and hope then again maybe
  • 00:37:36 the the price and the date so what I
  • 00:37:41 already do in my preview there we can
  • 00:37:46 copy that from there there's a h2 tag
  • 00:37:50 like this and the big difference of
  • 00:37:52 course will be that besides this same
  • 00:37:57 information which we already have in our
  • 00:37:59 list I can add a paragraph and also
  • 00:38:03 output this state selected event
  • 00:38:06 description and of course up here props
  • 00:38:10 should be this state selected event so
  • 00:38:14 now we have that in place let's see if
  • 00:38:17 that logic works on view detail is a
  • 00:38:21 problem here an event list now in at the
  • 00:38:26 bottom of my events chest file yeah
  • 00:38:27 there I of course wanna execute my show
  • 00:38:31 detail handler that's the idea
  • 00:38:33 now this compiles and well let's now see
  • 00:38:36 what happened
  • 00:38:37 when I do click view details here now
  • 00:38:42 this is also my network being slow um
  • 00:38:46 nothing unfortunately let's check what's
  • 00:38:49 wrong and my problem is an error I made
  • 00:38:52 here in the event item when I bind the
  • 00:38:56 first argument to bind of course is what
  • 00:38:58 this should refer to and that doesn't
  • 00:39:00 really matter here but I can't just set
  • 00:39:02 it to this it's the second argument that
  • 00:39:04 will be passed on asta first argument
  • 00:39:06 that is then called so the event idea
  • 00:39:10 wasn't passed up correctly now this
  • 00:39:14 looks much better now we can also close
  • 00:39:17 it and we can view the details which
  • 00:39:19 doesn't look too bad we can also tell
  • 00:39:21 that it really does load different event
  • 00:39:23 data here now a little backdrop wouldn't
  • 00:39:28 be too shabby we did add it before so we
  • 00:39:31 should definitely add it again
  • 00:39:33 so in our events page here and when I
  • 00:39:36 render the backdrop I want to render
  • 00:39:38 that when this state is creating or this
  • 00:39:45 state selected event is true so let me
  • 00:39:47 wrap that heater in parentheses as a
  • 00:39:50 first aura condition and now as this
  • 00:39:54 reloads yeah that looks better now of
  • 00:39:57 course I don't want to display confirm
  • 00:39:59 here but book and to change this I will
  • 00:40:02 have to adjust the modal a little bit
  • 00:40:04 here in the modal we need to make this
  • 00:40:07 confirm text settable from outside so
  • 00:40:10 here I want to set let's say props
  • 00:40:13 confirm text and that just means that in
  • 00:40:15 the places where I do use the modal I
  • 00:40:17 need to pass a new prop confirm text and
  • 00:40:21 for the first modal that is just not
  • 00:40:24 cancelled but I confirm but for the
  • 00:40:27 second modal which is my booking modal
  • 00:40:28 there my confirm text will actually be
  • 00:40:32 booked and that is now important so that
  • 00:40:40 we can see book here but if I do login
  • 00:40:42 again
  • 00:40:44 and I see that creative and box here
  • 00:40:48 there indeed it's still confirm tiny
  • 00:40:53 side note I just saw that the spinner is
  • 00:40:55 actually on top of my modal so in the
  • 00:41:00 modal CSS file I'll add a set index of
  • 00:41:02 100 so that this should indeed be above
  • 00:41:06 all the other elements in my in my view
  • 00:41:09 so that is it though that doesn't look
  • 00:41:13 too bad we worked a lot on the events
  • 00:41:15 let's now continue with the bookings