This episode is for members only

Sign up to access "Build An Uptime Monitor with Inertia" right now.

Get started
Already a member? Sign in to continue
Playing
35. Adding email addresses via the UI

Episodes

0%
Your progress
  • Total: 4h 59m
  • Played: 0m
  • Remaining: 4h 59m
Join or sign in to track your progress

Transcript

00:00
By the end of this episode, we will have created out the UI that allows us to add email addresses and validate them, and then store them in that JSON column.
00:08
So we're going to, first of all, add the UI element down here. And then we'll go ahead and send these requests via inertia. So we're going to head over to our dashboard here. And just at the bottom, we're just going to create out a new container here.
00:21
Now, this is going to have the potential for other notification types as well. So I'm going to go ahead and, first of all, set a margin top on this. And I'm going to set a flex with a flex column type. Inside of here, we're going to go ahead and create out an H2 just to show us
00:37
that these are the notification channels. And we can go ahead and add some styling here. Let's make this semi-bold, text-large, pretty much everything that we've already done for headers already.
00:48
And we'll set the leading to typed here. Or you could just copy and paste that from somewhere else. There is our notification channel section that matches everything else. And then just underneath this, we're going to create out a div.
01:00
And this is actually going to be a CSS grid, but obviously put in here with Tailwind. So we're going to set the grid class on here. We're going to set the grid columns to three because we're going to have
01:10
a potential of three different notification channels. We're going to set a gap in between each of them of 12. And we're going to set a margin top here of four. So now every container within here is going to be set in a three-column grid.
01:25
So let's just do 1, 2, 3 with divs here. And you can see that these are nicely evenly spaced out. And they actually have that gap of 12 in there as well. You can see that by going ahead and adding a background on here.
01:37
So let's just say a background of black. And let's check this out. So you can see they're nicely evenly spaced with that gap in between. Okay, so we're going to get rid of these two here because we're just going to go
01:47
ahead and focus on email notifications for now. And this is where our email notifications component is going to live. We're splitting this up into a component purely just to move it out of this entire dashboard.
02:02
And you might even want to do that with some of the other things as well. So let's go ahead and create this component out. So I'm going to call this email notifications. Again, there's not much organization here, but you can move this out later.
02:14
And I'm just going to write email notifications in here. So we're going to go ahead and pull this into this page. Let's define the component out first of all. And we're done.
02:25
And let's go down and just pull that in from here. So email notifications. So we should now see that text in there. Great.
02:33
Okay, so if we head over to the email notifications component, let's go ahead and start to start this up. Let's start by just giving this outer wrapper here a background of white. We will set the overflow to hidden, just in case we have anything flowing out.
02:49
We'll set a shadow here of small. It's pretty much everything we've already got in here already. And we will set this to rounded large, and we'll set a padding of four. So that just gives us that little component in here that pretty much
03:02
matches everything we've already done. We'll go ahead and copy one of the headers here. So let's go to the notifications channels. Notification channels header.
03:14
Copy this over just to save a little bit of time. But we're going to set the text here to base. And there we go. So this is now just going to say email, like so.
03:24
And then just underneath here, we'll have the ability to add an email address in. And that is, of course, going to be inside of a form. So with this, let's just add in some of the inputs that we would expect to see here.
03:38
And I'm actually going to copy these over from somewhere else. So let's go ahead and say input label. This looks like the new endpoint section. And I think this is actually going to look very, very similar.
03:50
So why don't we just copy all of this over, just so we don't have to type it out again. Grab all of that. And we're just going to put it in there.
03:59
Let's go ahead and indent this, and then just get rid of what we don't need. We need an input label. We want a text input for the email address that's going to be added. We want an error for the validation.
04:12
We don't need this select here, because we're just adding an email address. And we do want a primary button in here as well. So let's swap these over quickly. So location is now going to be email.
04:23
This is going to say email. It's still going to be screen reader only. This is going to be email. And let's just get rid of the placeholder in here.
04:33
And we'll get rid of the V model as well, because we're not sure where that's being hooked up to yet. The input error is going to stay the same. And we're not sure of the message yet.
04:41
So let's just go ahead and get rid of that. And just put message in there. And then just undo the binding. OK, so we need all of these components to be imported.
04:51
So let's just go ahead and grab them. And we want our input error, input label, and primary button. So let's pull all of these over to this script section here. And make sure we do script setup.
05:05
And let's pop them in. And we should see the following. Now, we want these to sit next to each other. So let's add some styles to this form.
05:14
We're going to say flex items start, margin top of 4. And we'll do a space x of, say, 2. And that's pulled this up next to this. And we've got the error underneath here as well,
05:28
which is great. So everything is looking as it should. So we're not even going to output the email addresses yet. We're just going to go ahead and look at storing these
05:37
so we can see that they're going into the database properly. So we're going to come away from our component just for a second. And we're going to head over to our web routes and create out an endpoint to handle this.
05:49
So let's define the endpoint out first of all, just to figure out what we want this to actually be called and how we want this to work. So it's going to post through, because we're
05:57
going to be posting through to store this. And let's store this under Sites. So for a particular site, and let's say Notifications and Emails, or email.
06:09
We'll just say emails to keep it plural. So that's where we want to post through to. The reason that we're splitting it up like this is later on we might have an SMS version of this to store to.
06:19
So we're going to keep it like this so we have a nice structure. OK, so we're not sure of the controller yet. But we can pretty much figure out the name based on the route
06:27
that we have created. So let's make our controller. And I always like to keep these really specific. So site, notifications, or notification, email, store,
06:38
controller. Of course, feel free to choose a shorter name if you want to. I just like to make these really explicit. So let's go over and hook this up to that.
06:47
So site, notification, email, store, controller. And there we go. So we're going to go ahead and open this up. We know that the constructor needs
06:56
to include the auth middleware because we need to be signed in to do this. And then in our invoke magic method, we are going to get a request in here.
07:08
Now, we need to think about validation for this. So we need to validate the email addresses that are coming in. So I'll just put a note in here. And of course, we're going to get a site in here
07:16
with route model binding as well because, of course, our notification emails are stored on our site itself. So now that we've done this, let's just die dump here and say add email, get this hooked up,
07:29
and then we'll actually implement the functionality to go ahead and get this stored. So over in email notifications, we want to post through, of course, to actually store this.
07:38
We need a form for this. And we need to hook the text input up here to a form. So let's go ahead and start to import use form from and inertia view three.
07:50
And let's go down here and create this form out really quickly, so use form. Very simple because we just have an email address that needs to be sent.
07:58
And we can post this data through to that endpoint that we've just created. So if we head up here to the input text here, let's go ahead and say v model and form and email.
08:10
Great. So when we submit this, we can post through. So let's go ahead and say v on submit. And we can say form.post.
08:19
And we can post it through to that endpoint. Now, the only problem at the moment is we don't know what the site ID is. So this is going to look like sites, x, notifications,
08:29
and emails. Let's figure out how we're going to get this site in here. So we can do that directly from the dashboard. So let's find the component that we already have here.
08:38
And we can either pass the entire site in here, or we can just pass in the site ID. Let's pass the entire site object in just to make it a little bit more convenient.
08:47
And if we don't need any of that data, we can always refactor it out later. OK, so we're passing a prop into this component now. So of course, what we want to do is define out the props
08:56
we're actually getting into here. So let's define out the site coming in here as an object. Great. And then all we need to do here is hook this up to, say, site.
09:10
And it will probably be data. Let's just see what we've done elsewhere. Yeah, so site data ID. And we should now be able to post through to this.
09:22
So let's go over and try this out. So I'm going to go ahead and type in my email address. I'm going to go ahead and hit Add. And yeah, sure enough, it did post through.
09:31
But we didn't use Prevent here to prevent the default behavior of the form. In fact, just to test this out even further, let's go ahead and die dump on the request email
09:41
that we're actually getting through. So let's go over. Let's type in my email address, hit Add. And yeah, there we go.
09:48
We're getting through the correct email address that we can store in that array. Now, just before we actually store this email, what we're going to do is just demonstrate
09:56
by getting rid of this die dump and returning back the preserved scroll. Because we've not actually seen this in action with Inertia properly.
10:03
We've been adding the preserved scroll when we've been sending a request. But we've not actually seen what it's actually preventing. So when I hit Add on this, you can
10:11
see that we jump right back to the top of the page. That's not really what we want. So over in our email notifications component, we can still pass data down into here.
10:22
So we're going to say preserve scroll and say that's true. And of course, we could extract this out to a method to actually store this. But we'll leave it as it is.
10:32
And we can say on success in here. And we're going to go ahead and say form reset, like so. So we've done that all in line, which is a really nice way to do things
10:48
if it's nice and short like this so we can see immediately what's happening. But of course, you can extract this out to a function within this component if you want to.
10:56
So let's just look at this new functionality. So I'm going to add my email address in. And there we go. So we stay in the same place.
11:02
And of course, the form gets reset after that email has been added. OK, so now for the good part, we're actually going to go ahead and store the email
11:11
address over in the site. Now, of course, we're going to want to do site update to actually update the notification emails, so notification emails.
11:21
But what are we going to do with taking the data and adding it? It's not like we can just create a new record on a relationship anywhere because we've got an array of emails.
11:30
What we're going to do instead is we're going to go ahead and prepend the email that we have just posted through to the current notification emails and then store it back into the model.
11:41
So what we can do here is use Laravel's array helper. So let's just make sure we pull in the namespace for that. And we're going to prepend on, and we're going to choose the array that we're prepending onto,
11:51
which is going to be the notification emails from the site. And this is really important because site notification emails is now going to be an array because over in site,
12:02
we cast that to an array. So really important. That's why we added that cast. So we're prepending to this array.
12:07
The second argument is going to be what we are prepending. And that is going to be the email that we have sent through. And that is pretty much it.
12:16
So if we return back, that's now going to go ahead and, of course, send this back. And once we start to list through the emails, we'll actually see them.
12:23
Let's keep an eye on the database just for now because we've not got to the point where we're showing the emails. And let's add in a couple of email addresses in here.
12:30
So let's say alex.cocourse.com. And yeah, it actually looks like the thing that we're trying to prepend to isn't an array. So what I've probably done is not actually cast this properly
12:43
to an array. I've added it in there, but I didn't choose the type. So there we go. That is actually how casts needs to look.
12:51
Brilliant. So we've caught that. Let's go over and try that again and type in my email address. Hit Add, and there we go.
12:58
So what we'll see now in the database is an array with alex.cocourse.com in. Now, when we add a new email address, the reason that we used array prepend and not
13:08
something like array merge is because we want this to be at the top of the list. Because we're not using relationships, we can't order these by the latest created date.
13:17
So we have to use array prepend to put this at the top. So if we add another email address, say mabel.cocourse.com, add, what we'll see is this now first in the list.
13:31
So it always pushes this to the very top. OK, so we have now got our notification emails being stored. But of course, we are missing something really,
13:42
really important, and that is validation. And of course, authorization as well. So let's get these done, and then we can move over to listing out the email addresses.
13:52
So I'm going to use a form request again for this. So let's go ahead and create our form request. I'm actually going to go ahead and exit out of this because we don't need that just for now.
14:01
So phpArtisan make request. And again, this is going to be quite long winded, but I'm just going with convention here. So site, notification, email, store, request.
14:14
And let's go ahead and swap that out. Site, email, notification, store request. Let's open this up. We'll look at authorizing in a second, but for our rules,
14:24
let's think about what we need to do. So we've only got one column here, which is great. So the email address is required, and it needs to be an email.
14:33
Now, we also need to figure out how to do unique rules. If we were storing this in a database, we could easily say unique to the sites table under the notification email column.
14:46
That's not going to work here because we've got a JSON column with an array of email addresses. So we'll figure out unique in a second. Let's just go back over to our component
14:55
and update our input error here. So the message here is going to be form errors and email. Let's just check this out. Hit Add, and it's unauthorized at the moment
15:08
because by default, we have false in here. Swap that to true for now. Hit Add, and there we go. The email field is required.
15:16
If we type in something that clearly isn't an email address, let's get rid of part of that. Ah, it does actually work. So Laravel's email rule does allow that in.
15:26
Let's just put Alex in there. You can see it must be a valid email address. OK, so let's just get rid of these. Save that out, and let's go down and figure out
15:35
this unique rule. So we shouldn't be able to add the same email address twice, but we know that we can't use the unique rule because we're not working with a database relationship,
15:45
and it's not quite going to work with this in terms of it being an array. So what we can do here is we can create our own rule. So if we pull in the illuminate validation rule object,
15:55
we can say not in, and we can just say, well, we don't want this to be in a particular array. That's pretty much all this rule does. So what we can do here is save this site,
16:06
because we have root model binding set up, and notification emails. So basically, it can't exist within the notification emails that are already within the array
16:16
that we're storing in that column. That's all we need to do. So let's go over and just try this out. So alex.cocourse.com, that works.
16:24
alex.cocourse.com, and you can see the selected email is invalid. And of course, we could customize the actual validation message to make that a little bit clearer,
16:34
but we will leave that for now. Okay, so in terms of authorization, pretty much what we've already seen before, we're going to go over to our site policy for this,
16:44
because we want a general rule to say, can we store notification channels? So let's create a new rule here called store notification channels.
16:53
And I'm just doing that as a general, can this user add things to notifications? Of course, we could always change this up later. So here, we just want to switch this out for this user,
17:03
can store notification channels on this site? Can they store notification channels on here? That's pretty much what we need to do. So now if we just come over and add in
17:15
maybe a cocourse.com, for example, hit add, that works. We've got them two email addresses in there, ready to receive notifications when any end points go down.
44 episodes4 hrs 59 mins

Overview

Ready to dive into Inertia? Let's build a real-world app with Laravel, Inertia and Vue! If you're already working with Inertia, you'll pick up some tips and techniques for future projects.

This uptime monitor allows you to create and switch between sites, then add endpoints to monitor with frequency intervals. Using the power of scheduling and queues, it'll automatically alert the email addresses you've added via the UI when an endpoint goes down.

In this course, you'll learn to:

  • Build a real app from scratch with Inertia
  • Work with Laravel queues
  • Perform actions on models at user-defined intervals
  • Work with sub-minute schedules in Laravel
  • Send out channel notifications with Laravel
  • Use API resources to simplify Inertia data
  • Organise apps with events and observers
  • Create modals in Vue
  • Perform inline editing with Inertia forms
Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Comments

No comments, yet. Be the first to leave a comment.