convert AlertBanner to ViewComponent

This commit is contained in:
Boy132 2025-06-04 23:26:00 +02:00
parent 2961c3e88b
commit 4e469eda41
4 changed files with 52 additions and 32 deletions

View File

@ -4,11 +4,12 @@ namespace App\Livewire;
use Closure; use Closure;
use Filament\Notifications\Concerns; use Filament\Notifications\Concerns;
use Filament\Support\Components\ViewComponent;
use Filament\Support\Concerns\EvaluatesClosures; use Filament\Support\Concerns\EvaluatesClosures;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Livewire\Wireable;
final class AlertBanner implements Wireable final class AlertBanner extends ViewComponent implements Arrayable
{ {
use Concerns\HasBody; use Concerns\HasBody;
use Concerns\HasIcon; use Concerns\HasIcon;
@ -19,18 +20,35 @@ final class AlertBanner implements Wireable
protected bool|Closure $closable = false; protected bool|Closure $closable = false;
public static function make(?string $id = null): AlertBanner protected string $view = 'livewire.alerts.alert-banner';
protected string $viewIdentifier = 'notification';
public function __construct(string $id)
{ {
$static = new self(); $this->id($id);
$static->id($id ?? Str::orderedUuid()); }
public static function make(?string $id = null): static
{
$static = new self($id ?? Str::orderedUuid());
$static->configure();
return $static; return $static;
} }
/**
* @return array<string, mixed>
*/
public function getViewData(): array
{
return $this->viewData;
}
/** /**
* @return array{id: string, title: ?string, body: ?string, status: ?string, icon: ?string, closeable: bool} * @return array{id: string, title: ?string, body: ?string, status: ?string, icon: ?string, closeable: bool}
*/ */
public function toLivewire(): array public function toArray(): array
{ {
return [ return [
'id' => $this->getId(), 'id' => $this->getId(),
@ -42,15 +60,18 @@ final class AlertBanner implements Wireable
]; ];
} }
public static function fromLivewire(mixed $value): AlertBanner /**
* @param array{id: string, title: ?string, body: ?string, status: ?string, icon: ?string, closeable: bool} $data
*/
public static function fromArray(array $data): AlertBanner
{ {
$static = AlertBanner::make($value['id']); $static = AlertBanner::make($data['id']);
$static->title($value['title']); $static->title($data['title']);
$static->body($value['body']); $static->body($data['body']);
$static->status($value['status']); $static->status($data['status']);
$static->icon($value['icon']); $static->icon($data['icon']);
$static->closable($value['closeable']); $static->closable($data['closeable']);
return $static; return $static;
} }
@ -69,7 +90,7 @@ final class AlertBanner implements Wireable
public function send(): AlertBanner public function send(): AlertBanner
{ {
session()->push('alert-banners', $this->toLivewire()); session()->push('alert-banners', $this->toArray());
return $this; return $this;
} }

View File

@ -2,18 +2,18 @@
namespace App\Livewire; namespace App\Livewire;
use Filament\Notifications\Collection;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Livewire\Attributes\On; use Livewire\Attributes\On;
use Livewire\Component; use Livewire\Component;
class AlertBannerContainer extends Component class AlertBannerContainer extends Component
{ {
/** @var array<AlertBanner> */ public Collection $alertBanners;
public array $alertBanners;
public function mount(): void public function mount(): void
{ {
$this->alertBanners = []; $this->alertBanners = new Collection();
$this->pullFromSession(); $this->pullFromSession();
} }
@ -21,15 +21,16 @@ class AlertBannerContainer extends Component
public function pullFromSession(): void public function pullFromSession(): void
{ {
foreach (session()->pull('alert-banners', []) as $alertBanner) { foreach (session()->pull('alert-banners', []) as $alertBanner) {
$alertBanner = AlertBanner::fromLivewire($alertBanner); $alertBanner = AlertBanner::fromArray($alertBanner);
$this->alertBanners[$alertBanner->getId()] = $alertBanner; $this->alertBanners->put($alertBanner->getId(), $alertBanner);
} }
} }
public function remove(string $id): void public function remove(string $id): void
{ {
$alertBanners = &$this->alertBanners; if ($this->alertBanners->has($id)) {
unset($alertBanners[$id]); $this->alertBanners->forget($id);
}
} }
public function render(): View public function render(): View

View File

@ -1,5 +1,5 @@
<div id="alert-banner-container" class="flex flex-col gap-4"> <div id="alert-banner-container" class="flex flex-col gap-4">
@foreach (array_values($alertBanners) as $alertBanner) @foreach ($alertBanners as $alertBanner)
@include('livewire.alerts.alert-banner', ['alertBanner' => $alertBanner]) {{ $alertBanner }}
@endforeach @endforeach
</div> </div>

View File

@ -1,14 +1,12 @@
@props(['alertBanner'])
@php @php
$icon = $alertBanner->getIcon(); $icon = $getIcon();
$title = $alertBanner->getTitle(); $title = $getTitle();
$body = $alertBanner->getBody(); $body = $getBody();
@endphp @endphp
<div class="{{$alertBanner->getColorClasses()}} flex p-4 mt-3 rounded-xl shadow-lg bg-white dark:bg-gray-900 ring-1 ring-gray-950/5 dark:ring-white/10"> <div class="{{$getColorClasses()}} flex p-4 mt-3 rounded-xl shadow-lg bg-white dark:bg-gray-900 ring-1 ring-gray-950/5 dark:ring-white/10">
@if (filled($icon)) @if (filled($icon))
<x-filament::icon :icon="$icon" class="h-8 w-8 mr-2" color="{{$alertBanner->getStatus()}}" /> <x-filament::icon :icon="$icon" class="h-8 w-8 mr-2" color="{{$getStatus()}}" />
@endif @endif
<div class="flex flex-col flex-grow"> <div class="flex flex-col flex-grow">
@ -21,7 +19,7 @@
@endif @endif
</div> </div>
@if ($alertBanner->isCloseable()) @if ($isCloseable())
<x-filament::icon-button color="gray" icon="tabler-x" wire:click="remove('{{$alertBanner->getID()}}')" /> <x-filament::icon-button color="gray" icon="tabler-x" wire:click="remove('{{$getID()}}')" />
@endif @endif
</div> </div>