Documentation

Notification Patterns

AI Powered
Back to Docs

Advertisement

Notification Patterns

Documentation & Guides

Notification Patterns Documentation

Overview

This document describes the notification patterns used in the RiftSurge application, specifically the multi-state confirmation notification system.

Multi-State Confirmation Notifications

The application uses a sophisticated notification system that provides visual feedback during user actions, particularly for destructive operations like deletions.

Components

1. notification-confirmation-multi-state.blade.php

The main component for confirmation dialogs with multi-state animations.

Features:

  • Initial state: Shows warning icon and action buttons
  • Processing state: Shows spinner and "Processing..." message
  • Completed state: Shows checkmark and "Done!" message
  • Error state: Shows X icon and error message
  • Shake effect: Gets increasingly violent when clicking outside
  • Auto-cleanup: Removes notification after animations complete

2. notification-multi-state.blade.php

General multi-state notification component for non-confirmation scenarios.

3. notification-bar.blade.php

Simple notification bar component.

Usage Pattern

1. Livewire Component Setup

use App\Traits\DispatchesNotifications;

use Livewire\Attributes\On;

class YourComponent extends Component

{

use DispatchesNotifications;

public $itemToDelete = null;

public function showDeleteConfirmation($itemId)

{

$this->itemToDelete = $itemId;

$this->notifyConfirmationMultiState(

'Delete Item',

'Are you sure you want to delete this item? This action cannot be undone.',

[

['action' => 'namespace.cancelDelete', 'label' => 'Cancel', 'variant' => 'secondary'],

['action' => 'namespace.confirmDelete', 'label' => 'Delete Item', 'variant' => 'danger'],

],

10000,

'item_actions'

);

}

#[On('namespace.confirmDelete')]

public function confirmDelete()

{

// Just acknowledge the confirmation - actual deletion happens when animation completes

\Log::info('confirmDelete called - starting processing animation', ['itemToDelete' => $this->itemToDelete]);

}

#[On('namespace.executeDelete')]

public function executeDelete()

{

// Perform the actual deletion

\Log::info('executeDelete called - performing actual deletion', ['itemToDelete' => $this->itemToDelete]);

if (!$this->itemToDelete) {

$this->notifyError('No item selected for deletion.');

return;

}

try {

$item = YourModel::findOrFail($this->itemToDelete);

$item->delete();

$this->itemToDelete = null;

$this->dispatch('$refresh');

} catch (\Exception $e) {

\Log::error('Failed to delete item', ['error' => $e->getMessage()]);

throw $e;

}

}

#[On('namespace.cancelDelete')]

public function cancelDelete()

{

$this->itemToDelete = null;

}

}

2. Event Flow

1. User clicks deleteshowDeleteConfirmation() called

2. Confirmation shown → Notification appears with action buttons

3. User confirmsnamespace.confirmDelete event dispatched

4. Processing animation → Shows spinner for 1 second

5. Completed animation → Shows checkmark for 1.2 seconds

6. Exit animation → Notification starts closing

7. Animation completesnamespace.executeDelete event dispatched

8. Item deleted → Database operation happens

9. UI refreshes → Item disappears from list

3. Namespacing

Use namespaced event names to prevent conflicts:

  • folder.cancelDelete, folder.confirmDelete, folder.executeDelete
  • play.cancelDelete, play.confirmDelete, play.executeDelete
  • scrim.cancelDelete, scrim.confirmDelete, scrim.executeDelete

Animation Timing

  • Processing duration: 1000ms (1 second)
  • Completed duration: 1200ms (1.2 seconds)
  • Exit animation: 400ms
  • Total time: ~2.6 seconds from confirmation to completion

Error Handling

  • Errors during execution are logged and re-thrown
  • The notification component handles error states automatically
  • Failed operations show error animation and auto-close

Best Practices

1. Always use namespaced events to prevent conflicts

2. Split confirmation and execution into separate methods

3. Log important steps for debugging

4. Use descriptive action names that match the namespace

5. Handle errors gracefully with try-catch blocks

6. Reset state variables after operations complete

7. Dispatch refresh events to update the UI

Testing

When testing these components:

// Test the confirmation flow

Livewire::actingAs($user)

->test(YourComponent::class)

->call('showDeleteConfirmation', $itemId)

->assertSet('itemToDelete', $itemId);

// Verify the item still exists (deletion happens after confirmation)

expect(YourModel::find($itemId))->not->toBeNull();

Migration from Old Pattern

Before (Old Pattern)

public function deleteItem($itemId)

{

$item = YourModel::findOrFail($itemId);

$item->delete();

$this->notifySuccess("Item deleted successfully!");

}

After (New Pattern)

public function showDeleteConfirmation($itemId)

{

$this->itemToDelete = $itemId;

$this->notifyConfirmationMultiState(/ ... /);

}

#[On('namespace.confirmDelete')]

public function confirmDelete() { / acknowledge / }

#[On('namespace.executeDelete')]

public function executeDelete() { / actual deletion / }

This pattern provides better user experience with visual feedback and prevents accidental deletions.

Need help? Check our FAQ

Advertisement