Appearance
User: profile
- 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
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 is updated but the changes are not visible in the navigation bar!
- Refresh the page and now the name is updated in the navigation bar
Convert the nav bar to a Livewire component
- 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 navigation component listens to the custom event and updates the name and the avatar in the navigation bar 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
@if (Laravel\Fortify\Features::canUpdateProfileInformation())
@livewire('profile.update-profile-information-form')
<x-section-border />
@endif
1
2
3
4
5
2
3
4
5
Convert the nav bar to a Livewire component
- Create a new Livewire NavBar component with
php artisan livewire:make Layout/NavBar
- Open the old Blade component resources/views/components/layout/nav.blade.php
- Open the new Livewire component resources/views/livewire/layout/nav-bar.blade.php
- Move the code from the old nav.blade.php file to the new nav-bar.blade.php file
- Open the resources/views/layouts/vinylshop.blade.php file
- Replace the reference to the old Blade component
<x-layout.nav />
with the new Livewire component@livewire('layout.nav-bar') />
- Replace the reference to the old Blade component
php
<div class="flex flex-col space-y-4 min-h-screen text-gray-800 bg-gray-100">
<header class="shadow bg-white/70 sticky inset-0 backdrop-blur-sm z-10">
{{-- Navigation --}}
{{-- <x-layout.nav /> --}}
@livewire('layout.nav-bar')
</header>
<main class="container mx-auto p-4 flex-1 px-4">
{{-- Title --}}
<h1 class="text-3xl mb-4">
{{ $subtitle ?? $title ?? "This page has no (sub)title" }}
</h1>
{{-- Main content --}}
{{ $slot }}
</main>
<x-layout.footer />
</div>
<div class="flex flex-col space-y-4 min-h-screen text-gray-800 bg-gray-100">
<header class="shadow bg-white/70 sticky inset-0 backdrop-blur-sm z-10">
{{-- Navigation --}}
{{-- <x-layout.nav /> --}}
@livewire('layout.nav-bar')
</header>
<main class="container mx-auto p-4 flex-1 px-4">
{{-- Title --}}
<h1 class="text-3xl mb-4">
{{ $subtitle ?? $title ?? "This page has no (sub)title" }}
</h1>
{{-- Main content --}}
{{ $slot }}
</main>
<x-layout.footer />
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Listen to the 'refresh-navigation-menu' event in the nav component
- Now we can add an event listener to the nav-bar component
- Open the app/Livewire/Layout/NavBar.php file
- 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
php
<?php
namespace App\Livewire\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
class NavBar extends Component
{
#[On('refresh-navigation-menu')] // refresh the NavBar component when the 'refresh-navigation-menu' event is emitted
public function render()
{
return view('livewire.layout.nav-bar');
}
}
<?php
namespace App\Livewire\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
class NavBar extends Component
{
#[On('refresh-navigation-menu')] // refresh the NavBar component when the 'refresh-navigation-menu' event is emitted
public function render()
{
return view('livewire.layout.nav-bar');
}
}
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
- Try it out and change the name back from Dave Adams to John Doe and click the SAVE button
- The changes are now immediately visible in the navigation bar
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(),
],
...
...
'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
Update the NavBar component
- Open the app/Livewire/Layout/NavBar.php file
- Open the resources/views/livewire/layout/nav-bar.php file
- Update the code for the avatar in the component and view
- Make a public property
- If
auth()->user()->profile_photo_path
is not empty AND the file exists, use the profile photo - Otherwise, use the avatar with the initials of the users name
- If
- Line 11: create a public property
$avatar
- Line 16 - 22: 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 uploaded photo exists
- Line 20: if the photo exists, set the
$avatar
property to the profile photo
- Line 17: set the default value for the
php
<?php
namespace App\Livewire\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
use Storage;
class NavBar 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.layout.nav-bar');
}
}
<?php
namespace App\Livewire\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
use Storage;
class NavBar 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.layout.nav-bar');
}
}
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
- The profile photo is now automatically synchronized within the nav bar
- Try some different scenarios to see how the nav bar is updated:
- Upload a new profile photo
- Delete the profile photo
- Change the name of the user