This episode is for members only

Sign up to access "Build a Starter Kit With Inertia and Fortify" right now.

Get started
Already a member? Sign in to continue
Playing
21. Profile photo output and swapping

Episodes

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

Transcript

00:00
So in the next couple of episodes, we're going to tackle uploading a profile photo.
00:04
The first thing that we need to do is actually output a proper profile photo, because at the moment we have this static link within here. So let's go ahead and do that now, and we'll swap over our user model and our user resource to actually output a generated default profile photo.
00:23
So if we head over to our navigation, just so we can remind ourselves, let's go over to where the username is. So let's find that username, and this is what we're using at the moment. So let's say by default, we want to use this UI avatars API to output the user's default avatar.
00:42
So let's go over to the user model, and we'll go ahead and create out a method in here called avatar URL, and we'll just go ahead and return what we had before, but we'll go ahead and swap out the name for the URL encoded name. So let's go ahead and say URL encode, and let's pass in the user's name.
01:05
Okay, so we can take the avatar URL now and add that to our user resource. So let's go and say avatar URL, and let's return what we get from that by default, and then we can just output this on the page within our source. So we can bind this in with page props auth user and avatar URL.
01:27
So we shouldn't see any difference here when we refresh this, it just looks the same. So now that we've got this, what we can do is start to build out a component here, which shows this default avatar, but allows us to click, select a new image, and then actually see that preview and allow us to clear it.
01:44
Then in the next episode, we'll look at how we can send this through to actually upload the photo and go ahead and reset it. So let's go over to our account section, and let's just start to build out the basic part of this. So just above here, this is where our avatar is going to sit.
02:03
Okay, so the first thing that we'll include is a label. So let's just grab one of these down here and pop this in. That's going to be for photo, that's the name that we're going to use here. And let's just say profile photo.
02:16
And then down here, let's go ahead and create our div. Now we need to think about this because we're going to have a avatar on one side, and then we're going to have a button on the other side. So let's go and make this flex.
02:28
We'll set a margin on the top to keep it away from the label. And we'll set item center, and we'll set a space X of three. So we're going to have the image here. And then we're going to have the selector here to actually choose a new file.
02:42
So this is where the default image is going to go. So into the image section, let's just output the default image first of all. We're going to need to change this when we select a new profile photo. So let's go ahead and bind in the current user's avatar in here first of all.
02:57
So let's say page props and auth user and avatar URL. And let's have a look. There we go. And we can just very quickly start that up with a width of 12, height of 12, and rounded full.
03:12
OK, so the selector here is going to be a file selector. So for this, we're going to need a label, which will be something like choose new photo, something like that, or upload a file. And then we're going to have an input down here with a type of file.
03:29
We'll hook that up to photo just here. And we'll set a class of screen reader only. So that means when we click on this label, it's going to go ahead and trigger this input. But we won't actually see the input on the page.
03:46
So when we click on that, we get a bunch of these avatars I have pre-saved. And we can just choose any of them and upload them. Great. So let's just style this up really quickly in terms of this label,
03:56
just so it looks like something we can click. And let's just set the text to small, font to semi-bold. And we'll set the text to a blue 500. Great.
04:09
OK. There we go. So we can choose a new photo, click on a photo. But we need to get that replaced out here.
04:15
So we don't want to upload at the point we click. That wouldn't make sense. But we want to show that preview in there. And then when that preview is in there, we want to change this text to be able to clear that photo out.
04:27
So how are we going to do this? Well, we somehow need to hook this input up to something that we can use to actually detect whether we have a photo in there. So let's go to the top of the page and let's just do this all down here underneath here.
04:41
So I'm going to go ahead and create out a photo ref. By default, we'll set that to null. And let's just make sure we import ref in here from view. And we want to set this when that gets clicked.
04:57
So we can really easily add a V on change here and then set the photo value to that new value. So for this, we get through an event. And then we access the target, which is this input. And then we access the files that have been uploaded and the first file.
05:15
We're not going to have multiple files in here. So we just grab the first one. So that photo will now contain that file. So let's just dump it out on the page and see what we get.
05:25
So I'm going to go ahead and choose one of these. And there we go. We get an object, which is a file. So with that, what we can now do is extract out the preview for this photo.
05:36
So how are we going to do this? Well, let's go to the top here. And just underneath here, let's create out a photo preview value. And this will use a computed property.
05:47
So let's just make sure we pull computed in. And let's go ahead and create out that computed property. And we basically want to return something that we can put inside of an image tag inside of this computed property.
06:01
So let's go ahead and first of all, check if we don't have a photo. So if there's no photo value, we just want to do an early return. Otherwise, we're going to go ahead and return using URL create object URL from that photo value. So all that will do is give us something that we can use to output that within an image tag.
06:22
So let's go ahead and dump this photo preview down here and just see what this gives us. So let's just do this up here. It doesn't really matter where. And let's have a look.
06:32
So let's go ahead and choose someone. And there we go. We get a blob with this information in here. Now, how are we going to get this into an image tag?
06:41
And we also need to do a couple of if statements to swap out the image here if that's been selected. So let's do this next to it first. And then we'll add in the if statements to swap this out. So we're going to go ahead and create another image tag in here.
06:55
And the source will literally just be the photo preview. That's pretty much all we need to get this working. And of course, we can use the same styles for this as well. So let's go over.
07:06
And yeah, we already saw it. So let's choose someone else. And there we go. So that's as easy as it is to get a photo preview inside of an image tag using that functionality
07:16
and using a computed property. So now all we need to do is just kind of add some if statements here. So we can say if photo preview. And then we can do a V else on this as well.
07:27
So now that will pretty much just swap this out and look like we have this, which is great. So we can do the same thing now with this photo preview with our choose new photo label, because we're not going to need this if we already have a photo. We want to be able to clear this out first of all.
07:45
Remember, the whole functionality here is going to be clicking to choose a new photo, choosing someone, hitting update, or clearing it to choose a new one. It's up to you what you do in terms of the user experience. But this is how we're going to implement it.
07:58
So let's add a button up here, which we can click to clear that photo if that is actually available. So if photo preview, or in our case, probably more appropriate, if photo, we're going to clear that. And then V else, we're going to have choose new photo.
08:16
So let's just click that. And that is, of course, going to go ahead and click that. Now, at the moment, we have an issue because this is a button. We need to specifically set this to a type of button so that doesn't submit the form.
08:27
And when we click that, we want to clear the photo out. Now, that's going to be pretty straightforward to do. So let's just say V on click, and we are going to set the photo back to null. Let's go over, click clear, and there we go.
08:42
We're back to the original state. So we can choose someone, hit clear, and it just works as we'd expect. So with this, we'll just style this up so it looks exactly the same. And then I think we are pretty much done here.
08:53
And let's go through the whole flow. So let's click, choose someone, clear it out, and it works as you'd expect. Really nice. Now, when we hit update, we want that profile photo to go through and submit and actually
09:05
store in the back end. Now we've got this functionality working, we can move over to the next episode and actually send this through without form, upload it, and then, of course, display it up here and as our default profile photo as well.
40 episodes5 hrs 21 mins

Overview

Let’s build our own Laravel starter kit with Inertia and include all the features you’d expect. We’ll implement authentication, email verification, profile photo uploads, two factor authentication, and more.

Fortify is a frontend agnostic authentication package for Laravel, meaning most of the work is done for us — we just need to build the frontend and make requests to the endpoints that Fortify registers.

Once you’re done, you’ll have a clean slate for building your next project, with the ability to control everything in your own starter kit.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!