DEV Community

Cover image for Notificações e Conclusão 🎉
Northon Iserhardt
Northon Iserhardt

Posted on • Edited on

Notificações e Conclusão 🎉

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

<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" />
Enter fullscreen mode Exit fullscreen mode

Vamos criar o componente de notificações:
php artisan make:livewire components.notification

Em resources/views/livewire/layout/navigation.blade.php adicione:
Image description

@livewire('components.notification')
Enter fullscreen mode Exit fullscreen mode

Mobile:
Image description

@livewire('components.notification')
Enter fullscreen mode Exit fullscreen mode

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

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

Em resources/views/livewire/components/notification.blade.php:
Image description

<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>
Enter fullscreen mode Exit fullscreen mode

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

Em app/Notifications/PostCreated.php vamos adicionar as configurações de broadcast:
O construtor:
Image description

    public $userId;
    public $dataNotify;

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

Canal e tipo:
Image description

    /**
     * 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';
    }
Enter fullscreen mode Exit fullscreen mode

Nome do canal e conexão:
Image description

    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}");
    }
Enter fullscreen mode Exit fullscreen mode

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.

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

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

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.

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

Image description

    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');
    }
Enter fullscreen mode Exit fullscreen mode

E vamos modificar a blade para exibir o contador de notificações:

Image description

<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>
Enter fullscreen mode Exit fullscreen mode

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:

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

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

Top comments (2)

Collapse
 
andreleaoj profile image
andreleaoj

👏👏👏

Collapse
 
northoniserhardt profile image
Northon Iserhardt

😁