Zum Hauptinhalt springen

Notification Resources

Drei Resources für das Benachrichtigungssystem:

  1. NotificationResource: Gesendete Benachrichtigungen anzeigen
  2. NotificationTemplateResource: Templates verwalten
  3. EmailTemplateResource: E-Mail-Templates verwalten

NotificationResource

File: NotificationResource.php

Zeigt alle gesendeten Datenbank-Benachrichtigungen (Read-Only mit Statusänderung).

Konfiguration

EigenschaftWert
ModelIlluminate\Notifications\DatabaseNotification
Navigation GroupKommunikation
Navigation LabelBenachrichtigungen
Navigation Iconheroicon-o-bell
Navigation Sort10
Polling Interval30 Sekunden
public static function getNavigationBadge(): ?string
{
return static::getModel()::query()
->whereNull('read_at')
->count();
}

Berechtigungen

public static function canCreate(): bool
{
return false; // Benachrichtigungen werden programmatisch erstellt
}

Table-Spalten

SpalteTypBeschreibung
notifiable_nameTextColumnEmpfänger-Name
typeBadgeColumnBenachrichtigungstyp mit Farben
dataTextColumnTitel/Betreff aus JSON
read_atBadgeColumn"Gelesen" oder "Ungelesen"
created_atTextColumnErstellungsdatum

Notification-Typen

TypLabelFarbe
OrderAcceptedOrRejectedAuftrag angenommen/abgelehntsuccess
NewOrderAvailableNeuer Auftraginfo
OrderCompletedAuftrag abgeschlossensuccess
InvoiceGeneratedRechnung erstelltprimary
UpcomingAppointmentTerminerinnerungwarning
PaymentReminderZahlungserinnerungwarning
InvoiceRejectedRechnung abgelehntdanger
OrderCancelledAuftrag storniertdanger
BillingStatusChangedAbrechnungsstatus geändertinfo

Actions

Action::make('mark_as_read')
->label('Als gelesen markieren')
->icon('heroicon-o-check')
->action(fn ($record) => $record->update(['read_at' => now()]))
->visible(fn ($record) => $record->read_at === null)

Action::make('mark_as_unread')
->label('Als ungelesen markieren')
->icon('heroicon-o-eye-slash')
->action(fn ($record) => $record->update(['read_at' => null]))
->visible(fn ($record) => $record->read_at !== null)

Bulk Actions

  • mark_as_read: Mehrere als gelesen markieren
  • mark_as_unread: Mehrere als ungelesen markieren
  • delete: Löschen

NotificationTemplateResource

File: NotificationTemplateResource.php

Verwaltet Benachrichtigungs-Templates für alle Kanäle.

Konfiguration

EigenschaftWert
ModelApp\Models\NotificationTemplate
Navigation GroupKommunikation
Navigation LabelBenachrichtigungs-Templates
Navigation Iconheroicon-o-envelope
Navigation Sort11
public static function getNavigationBadge(): ?string
{
return static::getModel()::query()
->where('is_active', false)
->count();
}

public static function getNavigationBadgeColor(): ?string
{
return 'warning';
}

Form-Struktur

Basis-Daten

FeldTypBeschreibung
notification_typeSelectAus verfügbaren Typen
target_role_idSelectZiel-Rolle (admin/requester/interpreter)
channelSelectmail/database/push
localeSelectde/en
nameTextInputTemplate-Name
descriptionTextareaBeschreibung
is_activeToggleAktiv/Inaktiv

Kanal-spezifische Felder

KanalFelder
mailsubject, content_template (MarkdownEditor)
databasetitle, content_template (Textarea)
pushtitle, content_template (Textarea, max 200 chars)

Dynamische Variablen

Das Formular zeigt verfügbare Variablen basierend auf dem gewählten Notification-Typ:

Forms\Components\Placeholder::make('available_variables')
->label('Verfügbare Variablen')
->content(function (Get $get) {
$type = $get('notification_type');
if (!$type) return 'Wählen Sie zuerst einen Benachrichtigungstyp';

$notification = $this->createDummyNotificationInstance($type);
if (!$notification) return 'Keine Variablen verfügbar';

$variables = $notification->getAvailableVariables();
return implode(', ', array_map(fn ($v) => "{{ $v }}", $variables));
})

Verfügbare Notification-Typen

NotificationTemplate::getAvailableNotificationTypes()

// Beispiel-Output:
[
'App\Notifications\OrderAcceptedOrRejected' => 'Auftrag angenommen/abgelehnt',
'App\Notifications\NewOrderAvailable' => 'Neuer Auftrag verfügbar',
'App\Notifications\UrgentOrderAvailable' => 'Dringender Auftrag verfügbar',
'App\Notifications\OrderCompleted' => 'Auftrag abgeschlossen',
'App\Notifications\InvoiceGenerated' => 'Rechnung erstellt',
// ...
]

Test-Actions

test_template

Rendert das Template mit Testdaten und sendet (bei Mail) oder zeigt Vorschau:

Action::make('test_template')
->label('Template testen')
->icon('heroicon-o-play')
->form([
Forms\Components\Select::make('test_user_id')
->label('Test-Empfänger')
->options(User::pluck('email', 'id'))
->required(),
])
->action(function (NotificationTemplate $record, array $data) {
$testVariables = $this->getTestVariables($record->notification_type);
$renderedContent = $this->renderTemplate($record->content_template, $testVariables);

if ($record->channel === 'mail') {
// Echte E-Mail senden
Mail::to(User::find($data['test_user_id']))
->send(new TemplateTestMail($record, $renderedContent));

Notification::make()
->success()
->title('Test-E-Mail gesendet')
->send();
} else {
// Vorschau anzeigen
Notification::make()
->title('Template-Vorschau')
->body($renderedContent)
->persistent()
->send();
}
})

test_push_notification

Sendet eine echte Push-Notification an einen Sprachmittler:

Action::make('test_push_notification')
->label('Push-Notification testen')
->icon('heroicon-o-device-phone-mobile')
->visible(fn ($record) => $record->channel === 'push')
->form([
Forms\Components\Select::make('interpreter_id')
->label('Sprachmittler')
->options(
User::interpreters()
->whereHas('devices')
->pluck('full_name', 'id')
)
->required(),
])
->action(function (NotificationTemplate $record, array $data) {
$interpreter = User::find($data['interpreter_id']);
$testVariables = $this->getTestVariables($record->notification_type);

OneSignal::sendNotificationToUser(
$interpreter->player_id,
$this->renderTemplate($record->title, $testVariables),
$this->renderTemplate($record->content_template, $testVariables)
);

Notification::make()
->success()
->title('Push-Notification gesendet')
->body("An: {$interpreter->full_name}")
->send();
})

Bulk Actions

  • activate: Templates aktivieren
  • deactivate: Templates deaktivieren
  • delete: Templates löschen

EmailTemplateResource

File: EmailTemplateResource.php

Verwaltet allgemeine E-Mail-Templates (nicht Notification-spezifisch).

Konfiguration

EigenschaftWert
ModelApp\Models\EmailTemplate
Navigation GroupKommunikation
Navigation LabelE-Mail-Templates
Navigation Iconheroicon-o-envelope
Navigation Sort12

Form-Struktur

Basis-Informationen

FeldTypBeschreibung
nameTextInputTemplate-Name
typeSelectTyp (siehe unten)
languageSelectde/en/fr/es
subjectTextInputE-Mail-Betreff
toTextInputOptional: Feste Empfängeradresse
versionTextInputVersionsnummer

Template-Typen

TypBeschreibung
password_resetPasswort-Zurücksetzung
profile_deletionProfil-Löschung
welcomeWillkommens-E-Mail
notificationAllgemeine Benachrichtigung
invoiceRechnungs-E-Mail
reminderErinnerung
otherSonstiges

Template-Inhalte

FeldTypBeschreibung
body_textTextareaPlain-Text Version
body_htmlRichEditorHTML Version (WYSIWYG)
body_html_rawTextareaRaw HTML (monospace)
show_html_editorToggleEditor-Auswahl
Forms\Components\Toggle::make('show_html_editor')
->label('WYSIWYG-Editor verwenden')
->default(true)
->live()

Forms\Components\RichEditor::make('body_html')
->visible(fn (Get $get) => $get('show_html_editor'))

Forms\Components\Textarea::make('body_html_raw')
->visible(fn (Get $get) => !$get('show_html_editor'))
->extraAttributes(['class' => 'font-mono'])

Variablen & Einstellungen

FeldTypBeschreibung
variablesKeyValueTemplate-Variablen
metadataKeyValueMetadaten (description, category, tags)
is_activeToggleAktiv
is_defaultToggleStandard-Template für diesen Typ

Table-Spalten

SpalteTypFormatierung
nameTextColumn-
typeBadgeColumnFarbcodiert
languageBadgeColumnde=info, en=success, etc.
subjectTextColumn-
toTextColumnOder "Standard"
is_activeIconColumn✓/✗
is_defaultIconColumn
versionBadgeColumn-

Type-Farben

Tables\Columns\TextColumn::make('type')
->badge()
->color(fn (string $state) => match ($state) {
'password_reset' => 'danger',
'welcome' => 'success',
'invoice' => 'primary',
'reminder' => 'warning',
'notification' => 'info',
default => 'gray',
})

Test-Action

Action::make('test_template')
->label('Test-E-Mail senden')
->icon('heroicon-o-paper-airplane')
->form([
Forms\Components\TextInput::make('test_email')
->label('Empfänger')
->email()
->required()
->default(fn () => auth()->user()->email),
])
->action(function (EmailTemplate $record, array $data) {
$testVariables = $this->getTestVariables();

Mail::to($data['test_email'])->send(
new TemplateMail($record, $testVariables)
);

Notification::make()
->success()
->title('Test-E-Mail gesendet')
->body("An: {$data['test_email']}")
->send();
})

NotificationPreferenceResource

File: NotificationPreferenceResource.php

Hidden Resource

Diese Resource ist in der Navigation versteckt (shouldRegisterNavigation = false) und wird primär über den UserResource RelationManager verwendet.

Konfiguration

EigenschaftWert
ModelApp\Models\NotificationPreference
NavigationHidden

Table mit Toggle-Columns

Tables\Columns\ToggleColumn::make('email_enabled')
->label('E-Mail')
->onColor('success')
->offColor('danger')

Tables\Columns\ToggleColumn::make('push_enabled')
->label('Push')
->onColor('success')
->offColor('danger')

Tables\Columns\TextColumn::make('database_enabled')
->label('In-App')
->badge()
->state('Immer aktiv')
->color('gray')

Reset-Action

Action::make('reset_to_defaults')
->label('Auf Standard zurücksetzen')
->icon('heroicon-o-arrow-path')
->requiresConfirmation()
->action(function (NotificationPreference $record) {
$defaults = NotificationPreference::getDefaultPreferences($record->user->role);
$record->update($defaults[$record->notification_type] ?? []);
})