complete story 5.3 with qa tests

This commit is contained in:
Naser Mansour
2025-12-27 01:52:42 +02:00
parent d29959d54d
commit 77d32d0dae
7 changed files with 485 additions and 49 deletions
@@ -16,6 +16,7 @@ new class extends Component
public string $status = 'draft';
public bool $showPreview = false;
public bool $showDeleteModal = false;
public function mount(Post $post): void
{
@@ -120,6 +121,35 @@ new class extends Component
{
$this->showPreview = false;
}
public function delete(): void
{
$this->showDeleteModal = true;
}
public function confirmDelete(): void
{
AdminLog::create([
'admin_id' => auth()->id(),
'action' => 'delete',
'target_type' => 'post',
'target_id' => $this->post->id,
'old_values' => $this->post->toArray(),
'ip_address' => request()->ip(),
'created_at' => now(),
]);
$this->post->delete();
session()->flash('success', __('posts.post_deleted'));
$this->redirect(route('admin.posts.index'), navigate: true);
}
public function cancelDelete(): void
{
$this->showDeleteModal = false;
}
}; ?>
<div wire:poll.60s="autoSave">
@@ -205,28 +235,35 @@ new class extends Component
</div>
</div>
<div class="flex items-center justify-end gap-4 border-t border-zinc-200 pt-6 dark:border-zinc-700">
<flux:button variant="ghost" :href="route('admin.posts.index')" wire:navigate>
{{ __('common.cancel') }}
</flux:button>
<flux:button type="button" wire:click="preview">
{{ __('posts.preview') }}
</flux:button>
@if($status === 'published')
<flux:button type="button" wire:click="saveDraft">
{{ __('posts.unpublish') }}
<div class="flex items-center justify-between gap-4 border-t border-zinc-200 pt-6 dark:border-zinc-700">
<div>
<flux:button variant="danger" type="button" wire:click="delete">
{{ __('posts.delete_post') }}
</flux:button>
<flux:button variant="primary" type="button" wire:click="publish">
{{ __('posts.save_changes') }}
</div>
<div class="flex items-center gap-4">
<flux:button variant="ghost" :href="route('admin.posts.index')" wire:navigate>
{{ __('common.cancel') }}
</flux:button>
@else
<flux:button type="button" wire:click="saveDraft">
{{ __('posts.save_draft') }}
<flux:button type="button" wire:click="preview">
{{ __('posts.preview') }}
</flux:button>
<flux:button variant="primary" type="button" wire:click="publish">
{{ __('posts.publish') }}
</flux:button>
@endif
@if($status === 'published')
<flux:button type="button" wire:click="saveDraft">
{{ __('posts.unpublish') }}
</flux:button>
<flux:button variant="primary" type="button" wire:click="publish">
{{ __('posts.save_changes') }}
</flux:button>
@else
<flux:button type="button" wire:click="saveDraft">
{{ __('posts.save_draft') }}
</flux:button>
<flux:button variant="primary" type="button" wire:click="publish">
{{ __('posts.publish') }}
</flux:button>
@endif
</div>
</div>
</form>
</div>
@@ -255,6 +292,30 @@ new class extends Component
</div>
</div>
</flux:modal>
{{-- Delete Confirmation Modal --}}
<flux:modal wire:model="showDeleteModal">
<div class="space-y-4">
<flux:heading size="lg">{{ __('posts.delete_post') }}</flux:heading>
<flux:callout variant="danger">
{{ __('posts.delete_post_warning') }}
</flux:callout>
<p class="text-zinc-700 dark:text-zinc-300">
{{ __('posts.deleting_post', ['title' => $post->getTitle()]) }}
</p>
<div class="flex gap-3 justify-end pt-4">
<flux:button wire:click="cancelDelete">
{{ __('common.cancel') }}
</flux:button>
<flux:button variant="danger" wire:click="confirmDelete">
{{ __('posts.delete_permanently') }}
</flux:button>
</div>
</div>
</flux:modal>
</div>
@push('styles')
@@ -17,6 +17,9 @@ new class extends Component
public string $sortDir = 'desc';
public int $perPage = 10;
public ?Post $postToDelete = null;
public bool $showDeleteModal = false;
public function updatedSearch(): void
{
$this->resetPage();
@@ -85,8 +88,25 @@ new class extends Component
public function delete(int $id): void
{
DB::transaction(function () use ($id) {
$post = Post::lockForUpdate()->find($id);
$this->postToDelete = Post::find($id);
if (! $this->postToDelete) {
session()->flash('error', __('posts.post_not_found'));
return;
}
$this->showDeleteModal = true;
}
public function confirmDelete(): void
{
if (! $this->postToDelete) {
return;
}
DB::transaction(function () {
$post = Post::lockForUpdate()->find($this->postToDelete->id);
if (! $post) {
session()->flash('error', __('posts.post_not_found'));
@@ -108,6 +128,15 @@ new class extends Component
session()->flash('success', __('posts.post_deleted'));
});
$this->showDeleteModal = false;
$this->postToDelete = null;
}
public function cancelDelete(): void
{
$this->showDeleteModal = false;
$this->postToDelete = null;
}
public function with(): array
@@ -268,7 +297,6 @@ new class extends Component
</flux:button>
<flux:button
wire:click="delete({{ $post->id }})"
wire:confirm="{{ __('posts.confirm_delete') }}"
variant="danger"
size="sm"
>
@@ -293,4 +321,30 @@ new class extends Component
<div class="mt-6">
{{ $posts->links() }}
</div>
{{-- Delete Confirmation Modal --}}
<flux:modal wire:model="showDeleteModal">
<div class="space-y-4">
<flux:heading size="lg">{{ __('posts.delete_post') }}</flux:heading>
<flux:callout variant="danger">
{{ __('posts.delete_post_warning') }}
</flux:callout>
@if($postToDelete)
<p class="text-zinc-700 dark:text-zinc-300">
{{ __('posts.deleting_post', ['title' => $postToDelete->getTitle()]) }}
</p>
@endif
<div class="flex gap-3 justify-end pt-4">
<flux:button wire:click="cancelDelete">
{{ __('common.cancel') }}
</flux:button>
<flux:button variant="danger" wire:click="confirmDelete">
{{ __('posts.delete_permanently') }}
</flux:button>
</div>
</div>
</flux:modal>
</div>