Feat: add confirmation modal component and Livewire support
- Introduced `Confirmation` trait for reusable confirmation modal logic in Livewire components. - Added `ConfirmationModal` Livewire component for handling confirmation prompts with customizable title, subtitle, description, and styling. - Updated `captainhook.json` to increase `subjectLength` limit. - Integrated confirmation modal in the sidebar layout with `<livewire:confirmation-modal/>`.
This commit is contained in:
parent
2956d03001
commit
5eca6d3602
65
app/Concerns/Confirmation.php
Normal file
65
app/Concerns/Confirmation.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Concerns;
|
||||
|
||||
use Livewire\Attributes\On;
|
||||
|
||||
trait Confirmation
|
||||
{
|
||||
/**
|
||||
* Shows a confirmation modal before executing the given method.
|
||||
*
|
||||
* @param string $method Method name that should be executed if the user confirms.
|
||||
* @param mixed|null $params Any parameters that should be passed to the method.
|
||||
* @param string $title Title of the confirmation modal.
|
||||
* @param string $subtitle Subtitle of the confirmation modal.
|
||||
* @param string|null $description Description of the confirmation modal.
|
||||
* @param string $descriptionClass Classes to apply to the description element. (!, !important to overide)
|
||||
* @param string $acceptBtnClass Classes to apply to the accept button. (!, !important to overide)
|
||||
* @param string $icon Icon to display in the confirmation modal.
|
||||
*/
|
||||
public function requireConfirmation(
|
||||
string $method,
|
||||
mixed $params = null,
|
||||
string $title = 'Are you sure?',
|
||||
string $subtitle = 'This action cannot be undone.',
|
||||
?string $description = null,
|
||||
string $descriptionClass = '',
|
||||
string $acceptBtnClass = '',
|
||||
string $icon = 'lucide.triangle-alert'
|
||||
): void {
|
||||
$this->dispatch(
|
||||
'open-confirmation',
|
||||
componentId: $this->getId(),
|
||||
action: $method,
|
||||
params: $params,
|
||||
title: $title,
|
||||
subtitle: $subtitle,
|
||||
description: $description,
|
||||
descriptionClass: $descriptionClass,
|
||||
acceptBtnClass: $acceptBtnClass,
|
||||
icon: $icon
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen globally for the acceptance, but only process if the ID matches.
|
||||
*/
|
||||
#[On('confirmation-accepted')]
|
||||
public function onConfirmationAccepted(string $action, mixed $params, string $componentId): void
|
||||
{
|
||||
// Ignore the event if it wasn't requested by this specific component instance
|
||||
if ($this->getId() !== $componentId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify the method actually exists on the component
|
||||
if (method_exists($this, $action)) {
|
||||
|
||||
// Execute the requested method, passing any provided parameters
|
||||
$this->{$action}($params);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
{
|
||||
"action": "\\CaptainHook\\App\\Hook\\Message\\Action\\Beams",
|
||||
"options": {
|
||||
"subjectLength": 50,
|
||||
"subjectLength": 100,
|
||||
"bodyLineLength": 300
|
||||
}
|
||||
}
|
||||
|
||||
97
resources/views/components/⚡confirmation-modal.blade.php
Normal file
97
resources/views/components/⚡confirmation-modal.blade.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\On;
|
||||
use TailwindMerge\TailwindMerge;
|
||||
|
||||
new class extends Component {
|
||||
public bool $open = false;
|
||||
|
||||
public string $title = 'Are you sure?';
|
||||
public string $subtitle = 'This action cannot be undone.';
|
||||
public ?string $description = null;
|
||||
|
||||
public string $icon = 'lucide.triangle-alert';
|
||||
public string $descriptionClass = '';
|
||||
public string $acceptBtnClass = '';
|
||||
|
||||
public string $action = '';
|
||||
public mixed $params = null;
|
||||
public string $componentId = '';
|
||||
|
||||
#[On('open-confirmation')]
|
||||
public function openModal(
|
||||
string $componentId,
|
||||
string $action,
|
||||
mixed $params = null,
|
||||
string $title = 'Are you sure?',
|
||||
string $subtitle = 'This action cannot be undone.',
|
||||
?string $description = null,
|
||||
string $descriptionClass = '',
|
||||
string $acceptBtnClass = '',
|
||||
string $icon = 'lucide.triangle-alert'
|
||||
): void {
|
||||
$this->action = $action;
|
||||
$this->componentId = $componentId;
|
||||
$this->title = $title;
|
||||
$this->subtitle = $subtitle;
|
||||
$this->description = $description;
|
||||
$this->params = $params;
|
||||
|
||||
$this->descriptionClass = $descriptionClass;
|
||||
$this->acceptBtnClass = $acceptBtnClass;
|
||||
$this->icon = $icon;
|
||||
|
||||
$this->open = true;
|
||||
}
|
||||
|
||||
public function confirm(): void
|
||||
{
|
||||
$this->open = false;
|
||||
|
||||
$this->dispatch('confirmation-accepted',
|
||||
action: $this->action,
|
||||
params: $this->params,
|
||||
componentId: $this->componentId
|
||||
);
|
||||
}
|
||||
|
||||
public function getMergedAlertClass(): string
|
||||
{
|
||||
return TailwindMerge::factory()->make()->merge(
|
||||
'alert-warning alert-soft text-red-600',
|
||||
$this->descriptionClass
|
||||
);
|
||||
}
|
||||
|
||||
public function getMergedButtonClass(): string
|
||||
{
|
||||
return TailwindMerge::factory()->make()->merge(
|
||||
'btn-warning',
|
||||
$this->acceptBtnClass
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div>
|
||||
<x-mary-modal wire:model="open" :title="$title" :subtitle="$subtitle" class="backdrop-blur" persistent>
|
||||
@isset($description)
|
||||
<x-mary-alert
|
||||
class="{{ $this->getMergedAlertClass() }}"
|
||||
:icon="$icon">
|
||||
{{ $description }}
|
||||
</x-mary-alert>
|
||||
@endisset
|
||||
<x-slot:actions>
|
||||
<x-mary-button label="Cancel" @click="$wire.open = false"/>
|
||||
|
||||
<x-mary-button
|
||||
label="Confirm"
|
||||
class="{{ $this->getMergedButtonClass() }}"
|
||||
wire:click="confirm"
|
||||
spinner="confirm"/>
|
||||
</x-slot:actions>
|
||||
</x-mary-modal>
|
||||
</div>
|
||||
@ -15,6 +15,7 @@
|
||||
</main>
|
||||
</div>
|
||||
<x-mary-toast/>
|
||||
<livewire:confirmation-modal/>
|
||||
</div>
|
||||
@livewireScripts
|
||||
</body>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user