🚀 Integrate Flux modals and toasts into Blade templates, refactor delete confirmation logic, and replace deprecated WireUI notifications for improved UX.

This commit is contained in:
HolgerHatGarKeineNode
2026-01-18 20:47:12 +01:00
parent b090336c4f
commit 18f8dd99e3
6 changed files with 127 additions and 128 deletions

View File

@@ -89,14 +89,15 @@
($currentPleb && $currentPleb->id === $project->einundzwanzig_pleb_id) ($currentPleb && $currentPleb->id === $project->einundzwanzig_pleb_id)
|| ($currentPleb && in_array($currentPleb->npub, config('einundzwanzig.config.current_board'), true)) || ($currentPleb && in_array($currentPleb->npub, config('einundzwanzig.config.current_board'), true))
) )
<flux:modal.trigger name="delete-project">
<flux:button <flux:button
icon="trash" icon="trash"
xs xs
negative negative
wire:click="confirmDelete({{ $project->id }})"
wire:loading.attr="disabled"> wire:loading.attr="disabled">
Löschen Löschen
</flux:button> </flux:button>
</flux:modal.trigger>
<flux:button <flux:button
icon="pencil" icon="pencil"
xs xs

View File

@@ -120,6 +120,10 @@
{{ $slot }} {{ $slot }}
</flux:main> </flux:main>
@persist('toast')
<flux:toast />
@endpersist
@fluxScripts @fluxScripts
@livewireScriptConfig @livewireScriptConfig
<script> <script>

View File

@@ -516,8 +516,6 @@ new class extends Component {
<h1 class="text-xl leading-snug text-gray-800 dark:text-gray-100 font-bold mb-1 sm:mb-0 ml-2"> <h1 class="text-xl leading-snug text-gray-800 dark:text-gray-100 font-bold mb-1 sm:mb-0 ml-2">
Wahl des Präsidiums Wahl des Präsidiums
</h1> </h1>
<div class="grid sm:grid-cols-2 gap-6">
<div
<div class="grid sm:grid-cols-2 gap-6"> <div class="grid sm:grid-cols-2 gap-6">
<flux:card> <flux:card>
<header> <header>
@@ -569,8 +567,6 @@ new class extends Component {
Wahl der übrigen Vorstandsmitglieder Wahl der übrigen Vorstandsmitglieder
</h1> </h1>
<div class="grid gap-6"> <div class="grid gap-6">
<div
<flux:card> <flux:card>
<div class="flex flex-col h-full p-5"> <div class="flex flex-col h-full p-5">
<div class="grow mt-2"> <div class="grow mt-2">
@@ -744,6 +740,7 @@ new class extends Component {
</div> </div>
</div> </div>
</div>
@endif @endif
</div> </div>

View File

@@ -160,9 +160,7 @@ class extends Component {
<div class="space-y-2"> <div class="space-y-2">
@forelse($news as $post) @forelse($news as $post)
<article wire:key="post_{{ $post->id }}" <flux:card wire:key="post_{{ $post->id }}">
<article wire:key="post_{{ $post->id }}"
<flux:card>
<!-- Avatar --> <!-- Avatar -->
<div class="shrink-0 mt-1.5"> <div class="shrink-0 mt-1.5">
<img class="w-8 h-8 rounded-full" <img class="w-8 h-8 rounded-full"

View File

@@ -4,6 +4,7 @@ use App\Enums\AssociationStatus;
use App\Livewire\Forms\ApplicationForm; use App\Livewire\Forms\ApplicationForm;
use App\Models\EinundzwanzigPleb; use App\Models\EinundzwanzigPleb;
use App\Support\NostrAuth; use App\Support\NostrAuth;
use Flux\Flux;
use Livewire\Component; use Livewire\Component;
use swentel\nostr\Event\Event as NostrEvent; use swentel\nostr\Event\Event as NostrEvent;
use swentel\nostr\Filter\Filter; use swentel\nostr\Filter\Filter;
@@ -14,7 +15,6 @@ use swentel\nostr\Relay\RelaySet;
use swentel\nostr\Request\Request; use swentel\nostr\Request\Request;
use swentel\nostr\Sign\Sign; use swentel\nostr\Sign\Sign;
use swentel\nostr\Subscription\Subscription; use swentel\nostr\Subscription\Subscription;
use WireUi\Actions\Notification;
new class extends Component { new class extends Component {
public ApplicationForm $form; public ApplicationForm $form;
@@ -132,8 +132,7 @@ new class extends Component {
$this->currentPleb->update([ $this->currentPleb->update([
'email' => $this->email, 'email' => $this->email,
]); ]);
$notification = new Notification($this); Flux::toast('E-Mail Adresse gespeichert.');
$notification->success('E-Mail Adresse gespeichert.');
} }
public function pay($comment): \Illuminate\Http\RedirectResponse public function pay($comment): \Illuminate\Http\RedirectResponse
@@ -175,9 +174,9 @@ new class extends Component {
return redirect($response->json()['checkoutLink']); return redirect($response->json()['checkoutLink']);
} catch (\Exception $e) { } catch (\Exception $e) {
$notification = new Notification($this); Flux::toast(
$notification->error(
'Fehler beim Erstellen der Rechnung. Bitte versuche es später erneut: '.$e->getMessage(), 'Fehler beim Erstellen der Rechnung. Bitte versuche es später erneut: '.$e->getMessage(),
variant: 'danger',
); );
return redirect()->route('association.profile'); return redirect()->route('association.profile');
@@ -319,7 +318,7 @@ new class extends Component {
</div> </div>
<flux:card mb-8> <flux:card>
<div class="flex flex-col md:flex-row md:-mr-px"> <div class="flex flex-col md:flex-row md:-mr-px">
<!-- Sidebar --> <!-- Sidebar -->
@@ -340,7 +339,7 @@ new class extends Component {
</a> </a>
</li> </li>
</ul> </ul>
</flux:card> </div>
<!-- Panel --> <!-- Panel -->
<div class="grow"> <div class="grow">
@@ -432,8 +431,6 @@ new class extends Component {
</div> </div>
</flux:card> </flux:card>
<flux:card> <flux:card>
<div
class="md:flex justify-between items-center space-y-4 md:space-y-0 space-x-2">
<!-- Left side --> <!-- Left side -->
<div class="flex items-start space-x-3 md:space-x-4"> <div class="flex items-start space-x-3 md:space-x-4">
<div> <div>
@@ -454,8 +451,6 @@ new class extends Component {
</div> </div>
</div> </div>
</flux:card> </flux:card>
</div>
</div>
@endif @endif
<div class="flex flex-wrap space-y-2 sm:space-y-0 items-center justify-between"> <div class="flex flex-wrap space-y-2 sm:space-y-0 items-center justify-between">
@@ -474,9 +469,7 @@ new class extends Component {
</div> </div>
</template> </template>
@if($currentPubkey && $currentPleb->association_status->value < 2) @if($currentPubkey && $currentPleb->association_status->value < 2)
<div
<flux:card> <flux:card>
<div class="flex w-full justify-between items-start">
<div class="flex"> <div class="flex">
<svg class="shrink-0 fill-current text-green-500 mt-[3px] mr-3" <svg class="shrink-0 fill-current text-green-500 mt-[3px] mr-3"
width="16" height="16" viewBox="0 0 16 16"> width="16" height="16" viewBox="0 0 16 16">
@@ -492,7 +485,6 @@ new class extends Component {
</section> </section>
<section> <section>
@if($currentPubkey && !$currentPleb->application_for && $currentPleb->association_status->value < 2)
<h3 class="text-xl leading-snug text-[#1B1B1B] dark:text-gray-100 font-bold mb-1"> <h3 class="text-xl leading-snug text-[#1B1B1B] dark:text-gray-100 font-bold mb-1">
Einundzwanzig Mitglied werden Einundzwanzig Mitglied werden
</h3> </h3>
@@ -520,9 +512,7 @@ new class extends Component {
</flux:button> </flux:button>
</div> </div>
</div> </div>
@endif
@if($currentPubkey) @if($currentPubkey)
<div
<flux:card class="mt-6"> <flux:card class="mt-6">
<div class="flex w-full justify-between items-start"> <div class="flex w-full justify-between items-start">
<div class="flex w-full"> <div class="flex w-full">
@@ -577,7 +567,11 @@ new class extends Component {
</div> </div>
@endif @endif
</div> </div>
</flux:card> </div>
</div>
</div>
@endif
@endif
</div> </div>
</div> </div>
@endif @endif
@@ -610,7 +604,6 @@ new class extends Component {
<section> <section>
@if($currentPleb && $currentPleb->association_status->value > 1) @if($currentPleb && $currentPleb->association_status->value > 1)
<div
<flux:card> <flux:card>
<div class="flex w-full justify-between items-start"> <div class="flex w-full justify-between items-start">
<div class="flex"> <div class="flex">
@@ -627,46 +620,35 @@ new class extends Component {
class="break-all">{{ $currentPleb->paymentEvents->last()->event_id }}</span> class="break-all">{{ $currentPleb->paymentEvents->last()->event_id }}</span>
</p> </p>
<div> <div>
@php
// latest event by created_at field of $events
$latestEvent = collect($events)->sortByDesc('created_at')->first();
@endphp
@if(isset($latestEvent)) @if(isset($latestEvent))
<p>{{ $latestEvent['content'] }}</p> <p>{{ $latestEvent['content'] }}</p>
<div class="mt-8"> <div class="mt-8">
@if(!$currentYearIsPaid) @if(!$currentYearIsPaid)
<div class="flex justify-center"> <div class="flex justify-center">
<button <flux:button wire:click="pay('{{ date('Y') }}:{{ $currentPubkey }}')" class="text-2xl">
wire:click="pay('{{ date('Y') }}:{{ $currentPubkey }}')"
class="btn text-2xl dark:bg-gray-800 border-gray-200 dark:border-gray-700/60 hover:border-gray-300 dark:hover:border-gray-600 text-green-500"
>
<i class="fa-sharp-duotone fa-solid fa-bolt-lightning mr-2"></i> <i class="fa-sharp-duotone fa-solid fa-bolt-lightning mr-2"></i>
Pay {{ $amountToPay }} Sats Pay {{ $amountToPay }} Sats
</button> </flux:button>
</div> </div>
@else @else
@if($currentYearIsPaid) @if($currentYearIsPaid)
<div class="flex sm:justify-center"> <div class="flex sm:justify-center">
<div <flux:button disabled class="sm:text-2xl">
class="btn sm:text-2xl dark:bg-gray-800 border-gray-200 dark:border-gray-700/60 text-green-500"
>
<i class="fa-sharp-duotone fa-solid fa-check-circle mr-2"></i> <i class="fa-sharp-duotone fa-solid fa-check-circle mr-2"></i>
aktuelles Jahr bezahlt aktuelles Jahr bezahlt
</div> </flux:button>
</div> </div>
@endif @endif
@endif @endif
</div> </div>
@else @else
<div class="flex sm:justify-center"> <div class="flex sm:justify-center">
<button <flux:button disabled>
class="btn dark:bg-gray-800 border-gray-200 dark:border-gray-700/60 hover:border-gray-300 dark:hover:border-gray-600 text-amber-500"
>
<i class="fa-sharp-duotone fa-solid fa-user-helmet-safety mr-2"></i> <i class="fa-sharp-duotone fa-solid fa-user-helmet-safety mr-2"></i>
Unser Nostr-Relay konnte derzeit nicht erreicht Unser Nostr-Relay konnte derzeit nicht erreicht
werden, um eine Zahlung zu initialisieren. Bitte werden, um eine Zahlung zu initialisieren. Bitte
versuche es später noch einmal. versuche es später noch einmal.
</button> </flux:button>
</div> </div>
@endif @endif
</div> </div>
@@ -743,6 +725,7 @@ new class extends Component {
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>

View File

@@ -2,12 +2,14 @@
use App\Models\ProjectProposal; use App\Models\ProjectProposal;
use App\Support\NostrAuth; use App\Support\NostrAuth;
use Flux\Flux;
use Livewire\Component; use Livewire\Component;
use WireUi\Actions\Notification;
new class extends Component { new class extends Component {
public string $activeFilter = 'all'; public string $activeFilter = 'all';
public ?string $confirmDeleteId = null;
public string $search = ''; public string $search = '';
public \Illuminate\Database\Eloquent\Collection $projects; public \Illuminate\Database\Eloquent\Collection $projects;
@@ -74,16 +76,8 @@ new class extends Component {
public function confirmDelete($id): void public function confirmDelete($id): void
{ {
$notification = new Notification($this); $this->confirmDeleteId = $id;
$notification->confirm([ Flux::modal('delete-project')->show();
'title' => 'Projektunterstützung löschen',
'message' => 'Bist du sicher, dass du diese Projektunterstützung löschen möchtest?',
'accept' => [
'label' => 'Ja, löschen',
'method' => 'delete',
'params' => $id,
],
]);
} }
public function setFilter($filter): void public function setFilter($filter): void
@@ -91,10 +85,12 @@ new class extends Component {
$this->activeFilter = $filter; $this->activeFilter = $filter;
} }
public function delete($id): void public function delete(): void
{ {
ProjectProposal::query()->findOrFail($id)->delete(); ProjectProposal::query()->findOrFail($this->confirmDeleteId)->delete();
Flux::toast('Projektunterstützung gelöscht.');
$this->loadProjects(); $this->loadProjects();
Flux::modals()->close();
} }
}; };
@@ -170,5 +166,25 @@ new class extends Component {
@endforeach @endforeach
</div> </div>
<!-- Confirmation modal -->
<flux:modal name="delete-project" class="min-w-[22rem]">
<div class="space-y-6">
<div>
<flux:heading size="lg">Projektunterstützung löschen</flux:heading>
<flux:text class="mt-2">
<p>Bist du sicher, dass du diese Projektunterstützung löschen möchtest?</p>
<p>Diese Aktion kann nicht rückgängig gemacht werden.</p>
</flux:text>
</div>
<div class="flex gap-2">
<flux:spacer />
<flux:modal.close>
<flux:button variant="ghost">Abbrechen</flux:button>
</flux:modal.close>
<flux:button type="submit" wire:click="delete" variant="danger">Ja, löschen</flux:button>
</div>
</div>
</flux:modal>
</div> </div>
</div> </div>