Appearance
User: profile
PODCAST
- The user profile page contains the following features:
- Profile Information: user can update his name and email address
- Update Password: user can change his password
- Two Factor Authentication: for additional 2FA security
Read the documentation before you enable this feature! - Browser Sessions: user can see his active sessions and logout sessions on other devices
- Delete Account: user can delete his account
DO THIS FIRST
- Check if the mail settings are correct in the .env file.
- The start the mail server with the command
mailpit
. - Open the browser and go to http://localhost:8025/ to see the emails.
Enable the profile photo
- All the Jetstream features can be managed in the config/jetstream.php file
- Open the config/jetstream.php file and change the following settings:
- Enable the
profilePhotos()
feature - Disable the
accountDeletion()
feature
- Enable the
php
...
'features' => [
// Features::termsAndPrivacyPolicy(),
Features::profilePhotos(),
// Features::api(),
// Features::teams(['invitations' => true]),
// Features::accountDeletion(),
],
...
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- The new feature is now available in the profile page
- Upload a new profile photo and click the SAVE button
TIP: download some free profile photos from https://randomuser.me/photos - The profile photo is immediate visible on the page, but not in the navigation bar
Where is the profile photo stored?
- The profile photo is stored under a random name:
- stored in the storage/app/public/profile-photos folder
- with the symlink accessible via public/storage/profile-photos
- the path to the file is stored in the profile_photo_path column in the users table
- use
auth()->user()->profile_photo_path
to get the path to the profile photo in the views
Profile Information
- Login as john.doe@example.com (password: admin1234) or with your own user credentials
- Change the name from John Doe to e.g. Dave Adams and click on the SAVE button
- The name and the avatar are updated but the changes are not visible in the navigation bar!
- Refresh the page and now the name is updated in the navigation bar (but not the avatar)
Add Livewire components
- The navigation bar is a Blade component and not a Livewire component
- To immediately see the changes in the navigation bar we need some JavaScript
- The profile component emits a custom event when the user clicks the SAVE button
- The Livewire components can listen to the custom event and updates the component as soon as the changes are made
- Livewire makes it very easy to emit an event in one component and listen to the event in another component
See the documentation - We are lucky because the profile component already emits an event each time you change the name
Find the event that is emitted by the profile component
- The name of the event is not so hard to find
- Open the resources/views/profile/show.blade.php file
Ctrl + click
on'profile.update-profile-information-form'
to open the component
php
@if (Laravel\Fortify\Features::canUpdateProfileInformation())
@livewire('profile.update-profile-information-form')
<x-section-border />
@endif
1
2
3
4
5
2
3
4
5
TIP
Until now, we only uses Livewire components with a full page layout (remember the Shop page with the #[Layout(...)]
attribute).
But Livewire components can also contain only a part of the page (like Laravel Blade components) that can be used in other components.
This is what we are going to do now
Replace the name with a Livewire component
- Create a new Livewire component for the name with the command
php artisan livewire:make Partials/Name
- Open the navbar and the livewire component
- To listen for an event in a Livewire component, just add the
#[On]
attribute above the method you want to be called when a given event is dispatched:- Line 10: the render method is called when the
refresh-navigation-menu
event is emitted - Line 2: don't forget to import the
On
attribute
- Line 10: the render method is called when the
php
<?php
namespace App\Livewire\Partials;
use Livewire\Attributes\On;
use Livewire\Component;
class Name extends Component
{
#[On('refresh-navigation-menu')] // refresh the NavBar component when the 'refresh-navigation-menu' event is emitted
public function render()
{
return view('livewire.partials.name');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Replace the avatar with a Livewire component
- Create a new Livewire component for the avatar with the command
php artisan livewire:make Partials/Avatar
- Open the navbar and the livewire component
- Line 11: create a public property
$avatar
- Line 13: add the
#[On]
attribute above the render method to listen for therefresh-navigation-menu
event
- Line 13: add the
- Line 16: only if the user is logged in:
- Line 17: set the default value for the
$avatar
property to the avatar with the initials of the users name - Line 18: check if
auth()->user()->profile_photo_path
is not empty- Line 19: if it's not empty, check if the file exists
- Line 20: if the file exists, set the
$avatar
property to the profile photo
- Line 17: set the default value for the
php
<?php
namespace App\Livewire\Partials;
use Livewire\Attributes\On;
use Livewire\Component;
use Storage;
class Avatar extends Component
{
public $avatar;
#[On('refresh-navigation-menu')] // refresh the NavBar component when the 'refresh-navigation-menu' event is emitted
public function render()
{
if (auth()->user()) {
$this->avatar = 'https://ui-avatars.com/api/?name=' . urlencode(auth()->user()->name);
if (auth()->user()->profile_photo_path) {
if (Storage::disk('public')->exists(auth()->user()->profile_photo_path))
$this->avatar = asset('storage/' . auth()->user()->profile_photo_path);
}
}
return view('livewire.partials.avatar');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25