‫Now let's finish this feature
‫and integrate the geolocation data
‫that we just loaded using Redux
‫into our create order form.
‫Now, first of all, we need to fix a small bug here,
‫which is that here, it should be called state.status.
‫So make sure to fix that here.
‫And then we can go back to our create order form.
‫So we want a button like this one, but not right here.
‫So we want it actually to be really close
‫to the address field.
‫Now our cart is empty again,
‫so let's add something,
‫and there we go.
‫So the idea is to put this button right here,
‫so on top of this input field.
‫So let's grab it from here,
‫and then down in the form,
‫let's place it right here.
‫All right, so of course, this now looks a bit wrong.
‫And so let's, first of all, use our button component,
‫which apparently we need to include manually,
‫or actually it's already there,
‫but we need to, of course, give it the type.
‫And so let's make this one a small button,
‫and that's a bit better.
‫And so now let's basically position it absolutely
‫here on top of this field.
‫Now here we cannot really pass in any new class names,
‫so let's just wrap it into a span.
‫So that's no problem at all.
‫And so here we need to position this absolutely.
‫For this, we just use Tailwind's absolute class.
‫But for that,
‫we then need to make the closest parent
‫relatively positioned,
‫so with position 'relative.'
‫So we are getting somewhere,
‫now we just need to position it
‫all the way to the right there,
‫so let's say right-0,
‫or actually let's move it a little bit more to the left.
‫So let's do right-1,
‫and that's a bit too much,
‫so maybe we have 0.5,
‫and that's a little bit too little. (chuckling)
‫So let's use our own values here
‫to escape Tailwind's rigidly formatted values,
‫that's a bit too much,
‫maybe 3 pixels just like this.
‫And just to make sure that it stays on top here,
‫we can also set the z index
‫just by typing z and then just some value here,
‫it's not really important.
‫All right, so that's working now,
‫but if we clicked this button,
‫then we would have a problem,
‫because this is right now a button inside a form,
‫and so clicking this would then automatically submit a form.
‫So we need to prevent that default behavior.
‫So let's do that right here,
‫so then we need the event object.
‫Then let's wrap all this into curly braces
‫so that then we can first do e.preventDefault.
‫And now if we click here,
‫that will then, again, get our position.
‫So here, probably, we now have a new item,
‫which you can't really see,
‫but that's also not really important
‫because we actually want to get this data
‫right here into this component.
‫So let's select it.
‫And this code here is getting a little bit messy,
‫but nevermind.
‫So we are actually already selecting some stuff here
‫from the user state,
‫but let's now change this.
‫So let's remove this username here
‫and simply get the entire user.
‫So then we can hear the structure that
‫into the username, the status.
‫Let's rename that to addressStatus
‫just to make things a bit more clear,
‫then the position and the address.
‫All right, so we will check then
‫for this address status a few times.
‫And so let's create a variable for that,
‫so isLoadingPosition or Address.
‫And so this is going to be true
‫whenever the address status is gonna be equal to loading.
‫All right, and so,
‫let's use that right here.
‫So here, whenever we are loading the position,
‫we want to make this here disabled.
‫So disabled, whenever, isLoadingAddress.
‫And the same for this button,
‫so disabled isLoadingAddress like this.
‫And so let's test this.
‫And indeed, for a short period of time,
‫it was disabled there.
‫And now let's again use the default value prop here
‫to then display that address here.
‫And so by doing this,
‫the user is then able to edit it before submitting the form.
‫So this, for example, might not be super helpful.
‫And so then the user can come in and change it here.
‫Now, if we do already have a position,
‫it doesn't make sense
‫to then keep displaying the button here, I guess,
‫and so let's make some conditional rendering here
‫and say that we want to display this
‫only if there is no latitude.
‫So that's position.latitude
‫and no position.longitude.
‫And so only then, we want to display the button.
‫And so now since we already fetched the position,
‫the button is gone.
‫But if we reloaded this, then it would be back,
‫which I'm not going to do now,
‫because then we have to add another item to the cart again.
‫Let me just also use that state right here
‫in the submitting one
‫so that here we can also not submit
‫if we are loading the address.
‫Next up, let's also display a possible error there.
‫So let's copy that style from here.
‫So taking all of this,
‫which we already styled earlier,
‫and then let's place that here.
‫And of course, here we will want to display it
‫whenever the address status is equal to error,
‫so that we set here in this situation, right?
‫So whenever this happens here,
‫we then want to display some message.
‫So let's actually use this error message right there.
‫So I think we haven't grabbed that yet.
‫So let's call that error address.
‫So let's take this here from the state, so error,
‫and renaming it to errorAddress like this.
‫So now we need to reload this.
‫So let's add some new item to the cart,
‫there we go.
‫And now as we get the position,
‫ah, but we forgot to actually disallow it again,
‫because that is what will create that error.
‫So we need to basically block this here.
‫So you can click here and block it,
‫but then we need to again reload first,
‫or maybe we can try to reset the state here,
‫or we could also just try to revert to this state here,
‫yeah, and so this is now the nice thing
‫about these Redux DevTools,
‫which is that we can basically travel in time.
‫And so now if we click this,
‫then there should be some error.
‫Well, somehow there isn't,
‫at least that what it seems like.
‫Or actually, we do see here that we got an error,
‫and here, the user denied geolocation,
‫but for some reason, it's not showing up here in the UI.
‫So let's see if we did something wrong,
‫but I don't think we did.
‫Let's try to write something else here.
‫No, that's not working.
‫But yeah, this is actually the same thing.
‫And we are now at error,
‫so I'm not sure what's happening here.
‫Let's maybe just actually reload,
‫add another item to the menu,
‫and then here, let's again disallow geolocation.
‫So for that, we can also do it here.
‫Yeah, and it is already disallowed,
‫so let's try to get that.
‫Ah, and now it is actually working, nice!
‫So I don't really like that error message there,
‫but let's fix that in a minute.
‫For now, let's just fix here the positioning of the error.
‫So here we probably also need to add this to the top,
‫so top and 3 pixels as well.
‫Now, this worked actually on the smaller screen,
‫but right now, we need a bit more.
‫So basically, let's just add some media queries here.
‫So I think it's the small one.
‫So this, of course, just a minor detail,
‫but if we're doing it, let's do it right.
‫All right, so now we have it positioned correctly again.
‫Let's make it here, the media query,
‫and that looks just right.
‫Now here, let's change the error message
‫to something a bit more actionable.
‫So let's say, "There was a problem getting your address.
‫"Make sure to fill this field."
‫'Cause this one is, of course, really important.
‫All right, let's just try this one more time.
‫Yeah, beautiful.
‫Okay, but now let's actually allow it again,
‫so that also works.
‫And then as the last step,
‫we, of course, also need to get this data then
‫here into our form action.
‫So right here in the form action,
‫when we submit the new order,
‫we will also want to submit it
‫with the actual position data,
‫so with the user's GPS location,
‫because that's going to be really important
‫or really helpful for the company
‫to deliver the pizza.
‫And so let's use the same trick that we used here
‫for the cart.
‫So let's do another hidden input field,
‫so of the type of 'hidden,'
‫let's name this one here simply 'position.'
‫And then as a value here,
‫let's actually simply create a string,
‫so let's say position.latitude,
‫position.longitude,
‫just like this,
‫and apparently, we forgot to close the element, and nice.
‫However, when the user denies the geolocation
‫or if there is some other problem with geolocation,
‫then we do not get this position right here.
‫But still, we want to allow the user to submit the form
‫in that situation,
‫so they can still manually input their address here,
‫and that should be good enough.
‫And so let's first check here
‫if this position actually exists.
‫So if position.longitude,
‫then let's basically submit this string
‫that we just created,
‫and otherwise, just an empty string.
‫Here we should probably also ask for position.latitude,
‫so both of these.
‫So if they exist,
‫then we pass this formatted GPS position
‫into the form action,
‫and if not, well, then it just receives that empty string.
‫So let's just check out what we get here with the order,
‫but once again, without actually doing any of this here,
‫let's just do a big comment like this,
‫and then we also need to return null again.
‫So let's check our console.
‫We just input some name here and some valid phone number.
‫And then let's try to order,
‫let's see what we get.
‫And indeed, there is our GPS position, beautiful!
‫And so now as we submit this order,
‫it will be submitted not only with this address,
‫but also with this position, great!
‫So we can put this back,
‫just like this.
‫And actually, with this, our work is finished.
‫Let's just submit this here just to make sure,
‫but we shouldn't get any problems after implementing this.
‫And indeed, it seems like it worked, nice!
‫So this was a lot of work over these two lectures
‫only to implement this small feature,
‫but if it makes the application better,
‫it's totally worth it.
‫And in this case, of course,
‫this was more of a learning exercise
‫so that we could learn and practice
‫how to use these Redux Thunks
‫with this new function here inside Redux Toolkit.