00:02
All right, so what about the use case where we accidentally enter in the wrong email here? So let's say that we do cancel1@invite.com
00:12
and then we go and send an invitation to them, but instead we actually meant to invite a different email from the one that we've entered. That's where our cancellation flow is gonna come into play. So let's first jump back into our terminal here
00:22
and create our action for this. So we'll do node.ace make action. We can put this inside of our organizations folder and we'll call this cancelOrganizationInvite.
00:31
All right, we can clear our terminal out there and let's next jump into our text editor. And we can start directly inside of that action. So cancelOrganizationInvite, jump into there.
00:39
For our params, we're gonna want our organization of type organization. We have that canceled by user ID column on the invitation itself so that we can track
00:49
who actually canceled the invitation. So here we'll take their user ID in as a number and then we'll also take the invite ID in as a number and then we can extract those three
00:59
out of our handle method, canceled by and invite. As you might've guessed, the very first thing that we're gonna wanna do is get access to our invitation. So we can reach through our organization
01:09
via its related invites to query where the ID equals our invite ID and then grab the first or fail for that. And once we have that record,
01:19
we can use the models canceled at property to cancel this actual invitation. Remember, we're working with this in two different ways. If it has a value, then it has been canceled
01:28
and if it has not a value, then it has not been canceled. And we're also using this as a lux and date time so that we also know exactly when it was canceled
01:37
if it indeed was. And then of course, we also have our invites installed by user ID property that we can populate with the canceled by user ID variable. Once we've set these two properties,
01:47
we can go ahead and await, invite, save that to the database and then return our invite back. And that should do it for our action.
01:55
Next, let's jump into our organization controller. Now for this one, we wanna jump into the settings controller here because this is where our invite
02:03
and the actual cancel actions reside. And we wanna grab our response, organization,
02:09
params, session and off out of the HTTP context for this. Go ahead and await, cancel organization invite dot handle
02:19
and we'll want to pass our organization through there as well as our canceled by user ID which will come from our off and use the web guard user. And then we want to reach for the ID.
02:29
This will be off protected so we can assert that the ID will be there. And then we also have our invite ID which will come through our route parameters as the ID route parameter there. Once we have that set,
02:39
we can go ahead and session flash a success message. The invitation has been canceled
02:46
and then return response redirect on back. Okay, let's next jump into our web routes, scroll back down into our organization settings
02:56
route section and we can do a router dot delete slash settings, organization, invites and then take in that ID route parameter.
03:05
This will use our settings organization controller and it's cancel invite method as settings, organization, invite, cancel.
03:15
Lastly, we can jump down into our organization user invite card, jump into our table section here within our card content. We have this empty table cell
03:25
which is where our actions for the invitations are meant to reside. And the invitation cancellation is the one and only action that we need. So we can use inertia's link component here.
03:34
Just go ahead and close that out just like so. And we can put the text cancel invite within it. Then for the link itself, what we're gonna want this to do is reach
03:43
through the href to our slash settings, organization, invite, and then drop the invite ID for the invitation that we are currently looping over here in view.
03:53
Now this is a delete route. So we also want to tell our link component that the method it should use for this request is the delete method. And that will now send this href out
04:03
with the HTTP method delete rather than get. And then since this is a destructive action in a way we can go ahead and add the class text red 500.
04:13
We're not actually deleting the invitation out of our database we are deleting its usability inside of our application. So we'll treat this as a destructive action as it were.
04:22
And then we also want to preserve the scroll position so that the users return right back to the same scroll spot after we redirect them back. Natively this link component is going to render out
04:32
as an anchor element inside of our HTML. What would be better since we're performing this as a delete action is to treat this like a button instead.
04:40
So we can switch how this element renders out by adding the as prop and switching that to a button rather than an anchor. Okay, we should be able to jump back up
04:49
into our browser now, let that do its refresh. Scroll back down to our pending organization invites table and we should see this cancel invite button. And we can see down in the bottom left-hand corner
04:59
we're showing the href for this action that the invite ID that we're pointing to here is eight. So keep that in reference here for a moment. Let's go ahead and click our cancel invite.
05:08
And there we go, the invitation has been canceled and is now out of our pending invitations. Furthermore, if we jump back into our terminal here, let's jump into our REPL session.
05:18
So node, base, REPL. We can await, load models, and then let's grab our invite. So equals await models, organization,
05:26
invite.find or fail. And this had an ID of eight. So hit enter there and we should have our invitation here. So we should be able to see the invite ID is eight.
05:36
Invite.email is our cancel one at invite.com. And I'm going to go ahead and call invite. Serialize to just plop the rest of the properties here on our page. And you should be able to note immediately
05:45
that our canceled at here is now populated for this invitation and validating it with the flow that we set up in the last three lessons. Since it has a value, that means that this invitation has been canceled.
05:55
And we also know via this date time exactly when it was canceled. Awesome, so we can go ahead and .exit out of there, clear that out, and we're ready to move onward.