Notificações e Conclusão 🎉
Tags: tutorial, programming, laravel, beginners
Published: 2023-12-26 22:36:00

##Agora, voltando as notificações
Vamos agora adicionar um espaço na barra de navegação para exibir nossas notificações.

Em resources/views/layouts/app.blade.php adicione o código abaixo para podermos usar o material icons:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxpzkqhdxqsbo9ljeh1v.png)
``` php
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
```
Vamos criar o componente de notificações:
`php artisan make:livewire components.notification`

Em resources/views/livewire/layout/navigation.blade.php adicione:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6pduwj5qo1q2g6958j0.png)
``` php
@livewire('components.notification')
```

Mobile:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw24byciovr1kpnonpdo.png)
``` php
@livewire('components.notification')
```

Vamos incorporar o Laravel Echo para monitorar eventos de notificações. Dessa forma, assim que uma notificação for recebida, poderemos recarregar dinamicamente os componente de notificações e listagem de posts.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56xrv5io4zlhghhbib4l.png)

``` php
<script>
    document.addEventListener('DOMContentLoaded', () => {
        Echo.private('App.Models.User.{{auth()->user()->id}}')
            .notification(() => {
                Livewire.dispatch('refreshNotification');
                Livewire.dispatch('refreshPostList');
            });
    });
</script>
```

Em resources/views/livewire/components/notification.blade.php:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62rfbdqg29487vmkmwvx.png)

``` php
<div>
    <x-dropdown align="right" width="48">
        <x-slot name="trigger">
            <button
                class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
                <span class="rounded-full p-1 bg-red-500 text-white">17</span>
                <span class="material-symbols-outlined">
                    notifications
                </span>
            </button>
        </x-slot>
        <x-slot name="content">
            <div class="p-3 text-center">
                <p>some notifications</p>
            </div>
        </x-slot>
    </x-dropdown>
</div>
```

## Classe de notificação

Como vamos mandar nossas notificações via canal database, precisamos criar a tabela de notificações:
`php artisan notifications:table`
`php artisan migrate`


Para criar um classe de notificação:
`php artisan make:notification PostCreated`

Um novo diretório contendo nossa classe será criado:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylbcksbp1e99iy5vlqlw.png)

Em app/Notifications/PostCreated.php vamos adicionar as configurações de broadcast:
**O construtor:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpw7spyzqy3jt9bwh040.png)

``` php
    public $userId;
    public $dataNotify;

    /**
     * Create a new notification instance.
     */
    public function __construct($userId, $dataNotify)
    {
        $this->userId = $userId;
        $this->dataNotify = $dataNotify;
    }
```

**Canal e tipo:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlvx2j6p2fbk77tcy71l.png)

``` php
    /**
     * Get the notification's delivery channels.
     *
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['broadcast', 'database'];
    }

    public function broadcastType()
    {
        return 'broadcast.message';
    }
```

**Nome do canal e conexão:**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6sk6nucjj402149dn3d.png)

``` php
    public function toBroadcast(object $notifiable): BroadcastMessage
    {
        return (new BroadcastMessage($this->dataNotify))->onConnection('database');
    }

    public function broadcastOn(): Channel
    {
        return new PrivateChannel("App.Models.User.{$this->userId}");
    }
```

Para enviar notificações, optaremos por utilizar a trait Notifiable, que já está incorporada no nosso modelo User por padrão. Isso nos proporciona uma abordagem eficiente e pronta para uso. Para obter mais informações sobre a utilização desta trait [https://laravel.com/docs/10.x/notifications#using-the-notifiable-trait](https://laravel.com/docs/10.x/notifications#using-the-notifiable-trait).

Em app/Livewire/Posts/PostCreate.php vamos adicionar a ação de notificar um novo Post para o usuário que for marcado:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqu898onu12s2cm2egh2.png)

``` php
if ($this->state['tagged_user_id']) {
    $taggedUser = User::query()->find($this->state['tagged_user_id']);
    $taggedUser?->notify(new PostCreated($taggedUser['id'], $this->state));
}
```

A documentação explica a maneira correta de recuperar as notificações dos usuários [https://laravel.com/docs/10.x/notifications#accessing-the-notifications](https://laravel.com/docs/10.x/notifications#accessing-the-notifications).

Vamos adicionar a lógica de recuperação das notificações em app/Livewire/Components/Notification.php:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9h7zy3oin8pdeqc0zku.png)

``` php
    protected $listeners = [
        'refreshNotification' => '$refresh'
    ];

    public $notifications;
    public $notificationsCounter;

    public function getNotifications()
    {
        $this->notifications = auth()->user()->unreadNotifications;
        $this->notificationsCounter = $this->notifications->count();

    }

    public function render()
    {
        $this->getNotifications();

        return view('livewire.components.notification');
    }
```
 E vamos modificar a blade para exibir o contador de notificações:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/475f5s7f80jiwj3smr2w.png)

``` php
<div>
    <x-dropdown align="right" width="48">
        <x-slot name="trigger">
            <button
                class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
                @if($notificationsCounter)
                    <span class="rounded-full p-1 bg-red-500 text-white">{{$notificationsCounter}}</span>
                @endif
                <span class="material-symbols-outlined">
                    notifications
                </span>
            </button>
        </x-slot>
        <x-slot name="content">
            @foreach($notifications as $notification)
                <div class="p-3 text-center">
                    <p>You have been tagged in a new post!</p>
                </div>
            @endforeach
        </x-slot>
    </x-dropdown>
</div>
```

Vamos iniciar o nosso worker:
`php artisan queue:work`

Nesse momento nossas notificações já estão sendo processadas em filas e sendo direcionadas em tempo real para os usuários marcados, como a seguir:

{% embed https://youtu.be/HCALH6pAzLk %}

##Conclusão
Conseguimos construir, passo a passo, a funcionalidade de notificações em tempo real utilizando Laravel e Livewire, seguindo apenas as documentações oficiais. Apesar do sucesso, ainda há diversas melhorias possíveis para aprimorar o projeto, tais como:

- Criação da camada de validação.
- Criação da camada de repositório.
- Passar dados para a notificação, como o nome de quem marcou o usuário.
- Marcar as notificações como lidas.

**Estou deixando o link do repositório para quem tiver interesse: [https://github.com/northoniserhardt/still-loving-docs](https://github.com/northoniserhardt/still-loving-docs)**

Além disso, você é quem decide! Muito obrigado por ter acompanhado o tutorial.