‫In this lecture we will take care
‫of one of the most important parts of this application,
‫which is to check in guests into the hotel as they arrive.
‫Now, what's important to understand about this part is
‫that a certain booking may not have been paid yet
‫when the guest arrives.
‫So, basically the idea is that a guest can make a booking,
‫for example, on an online site,
‫which can be made without payment.
‫So, basically for the guest to only pay it
‫at the hotel when they arrive.
‫Now, what this means is that in these cases,
‫payment needs to be accepted at the hotel.
‫This payment, however happens outside of the application.
‫So, we will not have any payment processing integrated
‫into our app.
‫However, hotel employees need to confirm
‫that they did in fact receive the payment
‫as they check in a guest,
‫and only then the guest can actually be checked in.
‫Also, during checkout,
‫guests should be able to buy breakfast
‫for the entire stay if they hadn't done that already.
‫So, let's now get back to work
‫and implement these two things
‫over this lecture and the next one.
‫Now, the place in the user interface
‫where we actually want to check in a user is
‫right here in this booking detail page.
‫So, like having a button here,
‫or also we can do so directly here from this context menu.
‫So, we also want to have a link here
‫and later on we will even be able
‫to check in guests that arrive
‫at that day right here in the dashboard.
‫But for now, let's first add a button here
‫and also onto the detail page.
‫So, here we need to add a new button
‫with a text of check in.
‫Then the icon should be hi arrow, down square.
‫And yeah, here again it is menus.
‫And then finally, we want a callback here.
‫So, on click prop, similar to the one
‫where we go to the bookings page.
‫So, here we need to close this one up.
‫And then here we have one too much apparently.
‫All right, so let's see.
‫And so then here we have this check-in icon.
‫But then of course, instead of going to bookings,
‫we want to go to check in
‫and then we still pass in the booking ID.
‫Now, what's important here is
‫that actually not all bookings can be checked in.
‫So, for example, bookings that are already checked in can
‫of course not be checked in again
‫and the ones that are already checked out can
‫also not be checked in again.
‫Let's just quickly go back to 10 results per page here.
‫So, let's reload that here.
‫But in any case, the only bookings
‫that can be checked in are the unconfirmed one.
‫And so, let's add that condition here
‫that we only want to render this
‫if the status is actually unconfirmed.
‫And that doesn't look like unconfirmed.
‫And so let's see.
‫So, actually we want all of them,
‫but that doesn't seem to really work.
‫Actually it does.
‫So, here we have the check-in button, but here we don't.
‫So, that is just perfect.
‫And now we want something similar here
‫also in the booking details page.
‫So, let's come right here,
‫and then right here in this button group,
‫here of course it's not menus.button,
‫but just a regular button.
‫And we also don't need the icon here,
‫but the rest is actually the same.
‫Now here we then need to get the navigate function,
‫and there we go.
‫So, again, this one here is not gonna have that button,
‫but then the other ones will.
‫So, with the unconfirmed status.
‫So, that's taking some time for some reason.
‫But anyway, let's now implement
‫actually the check-in route in app.js.
‫So, I think we haven't done that yet,
‫and indeed we have not.
‫But let's just duplicate this one.
‫And then here the difference is only
‫that this one is called check in.
‫And once again, we also don't have the page yet.
‫So, checkin.JSX.
‫And then here we actually have a similar situation
‫than what we had earlier with the booking page.
‫Because here all we are going to do is
‫to return this check-in booking component.
‫So, let's bring that in.
‫So, check-in booking like this.
‫So, that's this component right here
‫but first we need to import that.
‫Just like this.
‫All right, so notice how here we are
‫in a new features folder.
‫So, this one is called check-in-out.
‫In theory basically have a checkout button
‫and then this check-in button component.
‫And this component here is very similar
‫to the booking detail page.
‫There will just be some differences as we will see soon.
‫But anyway, let's now test this.
‫So, here again, the checked in page doesn't have that button
‫but here this one should have the button.
‫So, indeed there is check in.
‫And so now we can actually go there.
‫So, you moved to check in, so the URL changed,
‫but here everything looks the same.
‫And so that's I think
‫because in the route definition we
‫still haven't changed that here.
‫So, here we actually want the check-in page.
‫So, we need to bring that in manually here.
‫Let's just bring this to the very top where it belongs.
‫And then we have some problem.
‫So, maybe, well here, that actually looks correct.
‫So, let's see, probably there's just some problem
‫with that check-in component.
‫Let's just try that again.
‫And indeed, the problem is again in the booking data box.
‫So, just like before,
‫let's just take this out, and then there we go.
‫So, here on the check-in page it actually says,
‫check-in booking.
‫And then with the number of the booking, so 26 in this case.
‫And so what we need to do here first is
‫to bring in the data about the current booking.
‫And so we will do that exactly in the same way
‫as in the previous lecture.
‫So, booking and is loading and coming from use booking.
‫Then we need to bring that in as well.
‫So, booking and then use booking like this.
‫It's already been declared and that's just
‫because here we need to get rid of that.
‫And then also, in case we are still loading,
‫let's return that spinner component.
‫And now that's not even importing automatically
‫for some reason, but there we go.
‫So, now we get that value of 26.
‫And then right here we can bring back this booking data box.
‫So, here we have again all that data
‫that we already saw earlier about a booking,
‫which difference, that here it says check in.
‫And then here is basically the final button
‫where we can really do the check in itself.
‫So, this page looks very similar to the details page,
‫but that's on purpose.
‫Because later on we will probably do most
‫of the check-ins right from the dashboard.
‫So, then we go immediately to this page.
‫And so not through the details page.
‫But anyway, now it's time to implement that small feature
‫where the hotel employee needs to confirm
‫whether this booking has already been paid.
‫And so for that, we will want to add a checkbox down here
‫and then the user has to click that checkbox
‫and only then they can confirm right here.
‫All right, at least in case the booking hasn't
‫been paid yet.
‫So, if we want the checkbox here
‫and this button here to respond to that checkbox,
‫that means that we need a piece of state, right?
‫So, let's create that here.
‫I'd like to always do it at the very beginning,
‫and let's say confirm paid and set, confirm paid, use state.
‫And then we want to connect the state here
‫with that checkbox that it was just talking about.
‫Now, here again in our UI folder we
‫already have a checkbox component that we can use.
‫So, this is basically
‫just implementing a standard checkbox input plus a label.
‫So, let's use that component here
‫and let's also place all of that
‫into the box component that we have here in the same file.
‫And then comes that checkbox.
‫So, here we can say I confirm that,
‫and then the name of the guest,
‫so that's guest.fullname has paid the total amount.
‫And then later on we will actually place that value there.
‫But here we already now have this checkbox,
‫and if we click here, then that will turn on.
‫But now we need to make this a controlled element,
‫of course.
‫And so there for that we pass in the confirm paid.
‫So, that's the state.
‫And then we also need the on change prop.
‫And so this is again our standard callback function
‫where we then set that.
‫So, set, confirm paid, and then we basically toggle that.
‫Let's just give it an ID here as well.
‫And there we go.
‫All right, and so now we actually need
‫to set this value here at the very beginning.
‫So, in this case, for example,
‫this booking has already been paid.
‫And so then we can immediately set this here to true.
‫Now, we can't actually use the value of booking
‫that is paid to set the initial state here
‫of confirm paid,
‫because by the time this component here mounts,
‫that value hasn't arrived yet.
‫So, we need to start out with faults here.
‫And then later on with an effect we can set that value.
‫So, let's actually do that right here.
‫So, use effect, just a simple callback here,
‫and we will want to run this effect
‫whenever booking.ispaid has been updated.
‫And so here what we want to do is set confirm paid
‫to booking.
‫And now here we need optional training
‫because this might not exist yet, or otherwise to false.
‫And here we can't even use the nullish coalescing operator.
‫And yeah, we also need to move up the booking here.
‫All right, now that for some reason hasn't worked,
‫which it should,
‫but apparently we have some error here.
‫So, cannot read properties of undefined.
‫So, here we have the same problem as before.
‫So, maybe we can just include booking here,
‫it should be good enough, and let's reload that again.
‫But it's still not confirmed there, so let's see.
‫And here actually it's not value, but checked.
‫So, let's see.
‫And now, nice, that is checked.
‫And in this situation the user
‫actually shouldn't even be able to undo this.
‫So, let's set this to disabled
‫whenever confirm paid is true.
‫So, now this can no longer be removed.
‫And so in this situation we are now free
‫to check in the booking.
‫So, here we also need a disabled state,
‫which is whenever confirm paid is actually not true.
‫So, when the opposite is true,
‫then in that situation this button here will be deactivated.
‫So, let's try another one.
‫So, let's see this one here, actually we want to check in.
‫So, all of them have already been paid,
‫at least the ones that we have seen.
‫Let's maybe see this one.
‫And this one did not, but for some reason it changed.
‫Let's reload this.
‫So, that was strange.
‫Let's see this again.
‫Let's click on check in immediately.
‫Well, maybe I saw it wrong.
‫Ah, and for some reason it sometimes takes some time
‫for the data here to arrive.
‫And just looking here at the dev tools,
‫I think I am seeing what the problem is.
‫So, here in this key we actually also want
‫to include the booking ID itself.
‫So, this is actually a bug that we need to fix right now.
‫So, let's come here to our use booking.
‫And then here we need to include the booking ID.
‫And so this is very important, because otherwise,
‫as we switch between these different booking pages,
‫the data that each of them gets will be the same.
‫So, each of them will still be coming then here
‫from this cash with the same name for all of them.
‫But now each page will have its unique name.
‫So, let's go back here, let's change,
‫or let's check this one here.
‫And so now we also get the loading spinner
‫which earlier we were actually not seeing.
‫So, let me try to find another unpaid one.
‫Or let's just go with Emma Watson here.
‫So, this one here is not paid yet.
‫And so this is one of the situations
‫where in the hotel we actually need to accept the payment.
‫And so right now that hasn't happened,
‫and so then we cannot click this button.
‫So, we are not allowed to check this guest in.
‫But then as we click here,
‫then the payment has been received and we can click here.
‫And of course, now as we click, nothing happens.
‫And so let's take care of that next.
‫So, here we go back,
‫this one we no longer need the booking row.
‫We also no longer need the booking detail, the same thing,
‫and also the same thing with the constants.
‫Now here, let's just quickly finish this part here.
‫So, here we also want the total amount of,
‫and let's bring in the format currency function,
‫and then just with the total price, all right?
‫And then let's actually take care of checking the user in.
‫Now, what is actually checking the user in?
‫Well, all that we're going
‫to do is basically update the booking.
‫So, let's check out what the booking looks like,
‫just so we see what we actually have to do.
‫So, here in the bookings table, we have a remember
‫that status field, which should appear here at some point.
‫So, we have the status.
‫And so basically checking in means to change the status
‫from unconfirmed to checked in, right?
‫So, basically being checked in means
‫that the booking status is indeed set to checked in
‫and also is paid will need to be set to true,
‫because that's what we have just been working on.
‫So, making sure that the employee has
‫actually received the payment.
‫And so then for sure, this is true.
‫And so basically, what we will now do is a mutation
‫where we update a booking by setting these two fields.
‫So, the status to check in entity is paid to true.
‫And so let's create a new custom hook here.
‫called usecheckin.js.
‫So, export function, use check in.
‫At this time let's actually do it again by hand,
‫'cause we haven't done that in a long time.
‫And we don't just want to always copy paste everything,
‫because then we also don't learn.
‫So, here we will want to use
‫as I mentioned earlier, the use mutation hook.
‫And so this will then return the mutate function,
‫which we want to save here as, or rename as check in.
‫And we also get the is loading state
‫which we can rename to is checking in.
‫And then here as always, we need the mutation function.
‫And so this is where we will then call this function
‫that we already have in our services,
‫which is update booking.
‫So, very similar to update cabins that we did before,
‫which is the reason why we are not writing this one here
‫from scratch.
‫So, just like before it receives the ID
‫of the row that needs to be updated,
‫and the object with all the new field values.
‫So, all the values
‫for the columns that are going to be updated.
‫So, update booking.
‫And so here we need the booking ID,
‫and we are going to receive that
‫by passing it in to this mutate function.
‫And then the second argument needs to be
‫that data that will be updated.
‫And so as we said earlier, here the status will be changed
‫to checked in and is paid will be set to true.
‫All right, so that is the mutation function.
‫Then let's also define some on success handlers.
‫So, first of all, let's bring back our friend,
‫details notifications.
‫And so here we will have a success.
‫Let's do a template literal,
‫because here I actually want to show you something
‫which I don't remember if we did it already before or not.
‫I think I mentioned this.
‫But in any case, this on success function here does
‫actually receive some data.
‫And that data is exactly the data.
‫So, it's the value that is returned from the function.
‫So, this one right here is returned
‫from this mutation function.
‫And so that will then become the data
‫in the on success handler.
‫And so therefore we can then do booking number,
‫data.id successfully checked in.
‫All right, then we also want
‫to invalidate the queries as always.
‫So, let's get the Query client
‫from use Query client like this.
‫So, invalidate queries.
‫And previously what we did here was
‫to pass in the Query key,
‫but we can also do it in another way,
‫which is simply to say, active true.
‫And so this will then invalidate all the queries
‫that are currently active on the page.
‫So, this is a bit easier,
‫because then we don't have to remember any Query keys.
‫And then finally, we also want to navigate back
‫to the dashboard.
‫So, navigate from use, navigate,
‫and then here we will go back to the homepage,
‫which is basically that dashboard.
‫And then just to finish, let's also do an on error.
‫And here we will just toast.error.
‫There was an error while checking in.
‫And then all we have to do is to return an object
‫with the check-in function and is checking in.
‫Okay, so this video is running a bit long already,
‫but let's just drive it home here.
‫So, here we will just grab those two.
‫So, check in it is.
‫Checking in from use check in.
‫And so then, let's use finally the function here.
‫So, first let's also make sure again
‫that payment has been received.
‫So, if is not confirmed paid, then return.
‫But otherwise, check in the current booking ID.
‫And then let's also use the is check in state.
‫So, here, let's also disable if is checking in,
‫and the same thing on the button.
‫All right, so let's give it a try.
‫So, right now, again, we cannot click here,
‫and now we should be able.
‫All right, so let's try that.
‫And indeed, booking number nine was successfully checked in.
‫And if now we go back here to the bookings,
‫then indeed Emma Watson,
‫which is the one that we have been working on,
‫is checked in.
‫And if we see the details,
‫then we see that everything has been paid.
‫Great, so, this part is now actually working.
‫And so now let's move on to the next lecture,
‫where we will also add the ability
‫for the guest to buy breakfast as they check in.