Posts
Para prosseguirmos com as notificações, precisamos de eventos que as acionem. Como mencionado anteriormente, notificaremos um usuário sempre que ele for marcado em um post. Portanto, avançaremos para a criação dos posts.
Novos posts
Vamos adicionar a nossa navbar uma opção para o cadastro dos posts:
Em resources/views/livewire/layout/navigation.blade.php:
<x-nav-link :href="route('posts.index')" :active="request()->routeIs('posts.index')" wire:navigate>
{{ __('Posts') }}
</x-nav-link>
<x-responsive-nav-link :href="route('posts.index')" :active="request()->routeIs('posts.index')" wire:navigate>
{{ __('Posts') }}
</x-responsive-nav-link>
Através dos comandos do Laravel podemos criar vários recursos ao mesmo tempo, para mais detalhes https://laravel.com/docs/10.x/eloquent#generating-model-classes, no nosso caso vamos criar a Model, migration and controller with resources:
php artisan make:model -mrc Post
Em database/migrations/{date}_create_posts_table.php:
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('tagged_user_id')->nullable()->constrained('users')->cascadeOnDelete();
$table->string('message', 280);
$table->timestamps();
});
}
tagged_user_id pode ser nula, visto que, um post pode ser criado sem ter que marcar alguém.
Vamos rodar as migrations:
php artisan migrate
Route::view('posts','posts.index')->middleware('auth')->name('posts.index');
protected $fillable = [
'user_id',
'tagged_user_id',
'message',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function taggedUser(): BelongsTo
{
return $this->belongsTo(User::class, 'tagged_user_id');
}
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
public function taggedPosts(): HasMany
{
return $this->hasMany(Post::class, 'tagged_user_id');
}
Vamos criar os componentes de cadastro e listagem dos posts:
php artisan make:livewire posts.post-create
php artisan make:livewire posts.post-list
Vamos criar em resources/views/posts o arquivo index.blade.php, e importaremos o layout default com nossos componentes:
<x-app-layout>
@livewire('posts.post-create')
@livewire('posts.post-list')
</x-app-layout>
Um ponto de atenção: Para tornar o projeto mais simples não trabalharemos com camadas de validação e repositório.
Em resources/views/livewire/posts/post-create.blade.php:
<div>
<form class="grid grid-cols-2 max-w-xl mx-auto m-6" wire:submit.prevent="save">
<textarea
wire:model="state.message"
placeholder="{{ __('Post Message') }}"
class="col-span-2 w-full shadow rounded-lg border-gray-200"
></textarea>
@error('state.message') <span class="error">{{ $message }}</span> @enderror
<select wire:model="state.tagged_user_id" class="mt-4 border-gray-200 rounded-lg">
<option value=""></option>
@foreach($users as $user)
<option value="{{$user->id}}">{{$user->name}}</option>
@endforeach
</select>
@error('state.tagged_user_id') <span class="error">{{ $message }}</span> @enderror
<div class="flex justify-end">
<button class="w-16 rounded-lg mt-4 bg-blue-500 shadow text-white">{{ __('Save') }}</button>
</div>
</form>
</div>
Vamos adicionar em app/Livewire/Posts/PostCreate.php:
public $state = [
'tagged_user_id' => null,
'message' => ''
];
public $users = null;
public function mount()
{
$this->users = User::query()->get();
}
public function save(Request $request)
{
$this->validate([
'state.message' => 'required|max:280',
'state.tagged_user_id' => 'sometimes'
]);
$request->user()->posts()->create($this->state);
$this->reset('state');
}
Listagem dos posts
Agora, procederemos com a listagem dos posts, onde incluiremos tanto os posts que criamos quanto aqueles nos quais fomos marcados.
Em resources/views/livewire/post/post-list.blade.php:
<div>
<div class="max-w-xl mx-auto mt-16">
@foreach($posts as $post)
<div class="bg-white p-6 rounded-md shadow-md text-center break-words mt-4">
<p class="text-gray-700">
"{{$post->message}}"
</p>
<p class="text-blue-500 text-sm">{{ optional($post->taggedUser)->name ? '@'.$post->taggedUser->name : '' }}</p>
<p class="text-end text-sm text-gray-500 mt-2">{{$post->user->name}}</p>
</div>
@endforeach
</div>
</div>
Em app/Livewire/Posts/PostList.php:
<?php
namespace App\Livewire\Posts;
use Livewire\Component;
class PostList extends Component
{
public $posts;
public function render()
{
$this->posts = auth()->user()->posts()
->orWhere('tagged_user_id', auth()->user()->id)
->orderBy('id', 'desc')
->get();
return view('livewire.posts.post-list');
}
}
Reatividade
Quando um post é criado, é necessário recarregar a tela para visualizá-lo. No entanto, com Livewire, conseguimos tornar a listagem reativa. Isso significa que ao criarmos um post, a lista será atualizada automaticamente.
Mas como?
Vamos realizar um dispatch do componente de criação para o componente de listagem, indicando que é necessário atualizar a lista.
Em app/Livewire/Posts/PostCreate.php vamos adicionar o dispatch:
$this->dispatch('refreshPostList');
Em app/Livewire/Posts/PostList.php vamos adicionar nosso listener com o evento de refresh:
protected $listeners = [
'refreshPostList' => '$refresh'
];
Pronto! Nossas funcionalidades já estão reativas.
Top comments (0)