diff --git a/app/Http/Controllers/Api/Tenant/EventMemberController.php b/app/Http/Controllers/Api/Tenant/EventMemberController.php
index 1848074..da05f3c 100644
--- a/app/Http/Controllers/Api/Tenant/EventMemberController.php
+++ b/app/Http/Controllers/Api/Tenant/EventMemberController.php
@@ -82,6 +82,10 @@ class EventMemberController extends Controller
$member->refresh();
+ if (! $user->hasVerifiedEmail()) {
+ $user->sendEmailVerificationNotification();
+ }
+
return (new EventMemberResource($member))->response()->setStatusCode(201);
}
diff --git a/app/Models/User.php b/app/Models/User.php
index 30e58b4..0ff026f 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -3,6 +3,7 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
+use App\Notifications\VerifyEmailNotification;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasName;
use Filament\Models\Contracts\HasTenants as FilamentHasTenants;
@@ -92,6 +93,11 @@ class User extends Authenticatable implements FilamentHasTenants, FilamentUser,
return null;
}
+ public function sendEmailVerificationNotification(): void
+ {
+ $this->notify(new VerifyEmailNotification);
+ }
+
protected function fullName(): Attribute
{
return Attribute::make(
diff --git a/app/Notifications/Addons/AddonPurchaseReceipt.php b/app/Notifications/Addons/AddonPurchaseReceipt.php
index 4ef32fe..e24dfe2 100644
--- a/app/Notifications/Addons/AddonPurchaseReceipt.php
+++ b/app/Notifications/Addons/AddonPurchaseReceipt.php
@@ -30,18 +30,8 @@ class AddonPurchaseReceipt extends Notification implements ShouldQueue
return (new MailMessage)
->subject(__('emails.addons.receipt.subject', ['addon' => $label]))
- ->greeting(__('emails.addons.receipt.greeting', ['name' => $tenant?->name ?? __('emails.package_limits.team_fallback')]))
- ->line(__('emails.addons.receipt.body', [
- 'addon' => $label,
- 'event' => $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback'),
- 'amount' => $amount ? $amount.' '.$currency : __('emails.addons.receipt.unknown_amount'),
- ]))
- ->line(__('emails.addons.receipt.summary', [
- 'photos' => $this->addon->extra_photos,
- 'guests' => $this->addon->extra_guests,
- 'days' => $this->addon->extra_gallery_days,
- ]))
- ->action(__('emails.addons.receipt.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->view('emails.addons.receipt', [
+ 'addon' => $this->addon,
+ ]);
}
}
diff --git a/app/Notifications/Customer/RefundReceipt.php b/app/Notifications/Customer/RefundReceipt.php
index d7d62df..e35f97e 100644
--- a/app/Notifications/Customer/RefundReceipt.php
+++ b/app/Notifications/Customer/RefundReceipt.php
@@ -27,20 +27,29 @@ class RefundReceipt extends Notification implements ShouldQueue
$tenant = $this->purchase->tenant;
$package = $this->purchase->package;
$amount = number_format((float) $this->purchase->price, 2);
-
- $mail = (new MailMessage)
- ->subject(__('emails.refund.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]))
- ->greeting(__('emails.refund.greeting', ['name' => $tenant?->name ?? __('emails.package_limits.team_fallback')]))
- ->line(__('emails.refund.body', [
+ $subject = __('emails.refund.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]);
+ $greeting = __('emails.refund.greeting', ['name' => $tenant?->name ?? __('emails.package_limits.team_fallback')]);
+ $lines = [
+ __('emails.refund.body', [
'amount' => $amount,
'currency' => '€',
'provider_id' => $this->purchase->provider_id ?? '—',
- ]));
+ ]),
+ ];
if ($this->reason) {
- $mail->line(__('emails.refund.reason', ['reason' => $this->reason]));
+ $lines[] = __('emails.refund.reason', ['reason' => $this->reason]);
}
- return $mail->line(__('emails.refund.footer'));
+ return (new MailMessage)
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => $lines,
+ 'footer' => __('emails.refund.footer'),
+ ]);
}
}
diff --git a/app/Notifications/InactiveTenantDeletionWarning.php b/app/Notifications/InactiveTenantDeletionWarning.php
index a8c4c06..e874c82 100644
--- a/app/Notifications/InactiveTenantDeletionWarning.php
+++ b/app/Notifications/InactiveTenantDeletionWarning.php
@@ -27,13 +27,25 @@ class InactiveTenantDeletionWarning extends Notification implements ShouldQueue
{
$locale = $this->tenant->user?->preferred_locale ?? app()->getLocale();
$formattedDate = $this->plannedDeletion->copy()->locale($locale)->translatedFormat('d. F Y');
+ $subject = __('profile.retention.warning_subject', [], $locale);
return (new MailMessage)
- ->locale($locale)
- ->subject(__('profile.retention.warning_subject', [], $locale))
- ->line(__('profile.retention.line1', ['name' => $this->tenant->name], $locale))
- ->line(__('profile.retention.line2', ['date' => $formattedDate], $locale))
- ->line(__('profile.retention.line3', [], $locale))
- ->action(__('profile.retention.action', [], $locale), url('/login'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => __('profile.retention.line1', ['name' => $this->tenant->name], $locale),
+ 'heroTitle' => $subject,
+ 'lines' => [
+ __('profile.retention.line1', ['name' => $this->tenant->name], $locale),
+ __('profile.retention.line2', ['date' => $formattedDate], $locale),
+ __('profile.retention.line3', [], $locale),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('profile.retention.action', [], $locale),
+ 'url' => url('/login'),
+ ],
+ ],
+ ]);
}
}
diff --git a/app/Notifications/Ops/AddonPurchased.php b/app/Notifications/Ops/AddonPurchased.php
index 6cd2e25..a50a9cd 100644
--- a/app/Notifications/Ops/AddonPurchased.php
+++ b/app/Notifications/Ops/AddonPurchased.php
@@ -26,18 +26,32 @@ class AddonPurchased extends Notification implements ShouldQueue
$label = $this->addon->metadata['label'] ?? $this->addon->addon_key;
$amount = $this->addon->amount ? number_format((float) $this->addon->amount, 2) : null;
$currency = $this->addon->currency ?? 'EUR';
+ $subject = __('emails.ops.addon.subject', ['addon' => $label]);
+ $greeting = __('emails.ops.addon.greeting');
+ $lines = [
+ __('emails.ops.addon.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]),
+ __('emails.ops.addon.event', ['event' => $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback')]),
+ __('emails.ops.addon.addon', ['addon' => $label, 'quantity' => $this->addon->quantity]),
+ ];
+
+ if ($amount) {
+ $lines[] = __('emails.ops.addon.amount', ['amount' => $amount, 'currency' => $currency]);
+ }
+
+ $lines[] = __('emails.ops.addon.provider', [
+ 'checkout' => $this->addon->checkout_id ?? '—',
+ 'transaction' => $this->addon->transaction_id ?? '—',
+ ]);
return (new MailMessage)
- ->subject(__('emails.ops.addon.subject', ['addon' => $label]))
- ->greeting(__('emails.ops.addon.greeting'))
- ->line(__('emails.ops.addon.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]))
- ->line(__('emails.ops.addon.event', ['event' => $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback')]))
- ->line(__('emails.ops.addon.addon', ['addon' => $label, 'quantity' => $this->addon->quantity]))
- ->when($amount, fn ($mail) => $mail->line(__('emails.ops.addon.amount', ['amount' => $amount, 'currency' => $currency])))
- ->line(__('emails.ops.addon.provider', [
- 'checkout' => $this->addon->checkout_id ?? '—',
- 'transaction' => $this->addon->transaction_id ?? '—',
- ]))
- ->line(__('emails.ops.addon.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => $lines,
+ 'footer' => __('emails.ops.addon.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Ops/PurchaseCreated.php b/app/Notifications/Ops/PurchaseCreated.php
index e296aeb..d463b6e 100644
--- a/app/Notifications/Ops/PurchaseCreated.php
+++ b/app/Notifications/Ops/PurchaseCreated.php
@@ -25,19 +25,28 @@ class PurchaseCreated extends Notification implements ShouldQueue
$package = $this->purchase->package;
$amount = number_format((float) $this->purchase->price, 2);
$consents = $this->purchase->metadata['consents'] ?? [];
+ $subject = __('emails.ops.purchase.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]);
+ $greeting = __('emails.ops.purchase.greeting');
return (new MailMessage)
- ->subject(__('emails.ops.purchase.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]))
- ->greeting(__('emails.ops.purchase.greeting'))
- ->line(__('emails.ops.purchase.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]))
- ->line(__('emails.ops.purchase.package', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]))
- ->line(__('emails.ops.purchase.amount', ['amount' => $amount, 'currency' => '€']))
- ->line(__('emails.ops.purchase.provider', ['provider' => $this->purchase->provider, 'id' => $this->purchase->provider_id ?? '—']))
- ->line(__('emails.ops.purchase.consents', [
- 'legal' => $consents['legal_version'] ?? 'n/a',
- 'terms' => $consents['accepted_terms_at'] ?? 'n/a',
- 'waiver' => $consents['digital_content_waiver_at'] ?? 'n/a',
- ]))
- ->line(__('emails.ops.purchase.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.ops.purchase.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]),
+ __('emails.ops.purchase.package', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]),
+ __('emails.ops.purchase.amount', ['amount' => $amount, 'currency' => '€']),
+ __('emails.ops.purchase.provider', ['provider' => $this->purchase->provider, 'id' => $this->purchase->provider_id ?? '—']),
+ __('emails.ops.purchase.consents', [
+ 'legal' => $consents['legal_version'] ?? 'n/a',
+ 'terms' => $consents['accepted_terms_at'] ?? 'n/a',
+ 'waiver' => $consents['digital_content_waiver_at'] ?? 'n/a',
+ ]),
+ ],
+ 'footer' => __('emails.ops.purchase.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Ops/RefundProcessed.php b/app/Notifications/Ops/RefundProcessed.php
index 1d5061b..85c7ed1 100644
--- a/app/Notifications/Ops/RefundProcessed.php
+++ b/app/Notifications/Ops/RefundProcessed.php
@@ -29,24 +29,33 @@ class RefundProcessed extends Notification implements ShouldQueue
$tenant = $this->purchase->tenant;
$package = $this->purchase->package;
$amount = number_format((float) $this->purchase->price, 2);
-
- $mail = (new MailMessage)
- ->subject(__('emails.ops.refund.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]))
- ->greeting(__('emails.ops.refund.greeting'))
- ->line(__('emails.ops.refund.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]))
- ->line(__('emails.ops.refund.package', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]))
- ->line(__('emails.ops.refund.amount', ['amount' => $amount, 'currency' => '€']))
- ->line(__('emails.ops.refund.provider', ['provider' => $this->purchase->provider, 'id' => $this->purchase->provider_id ?? '—']))
- ->line($this->success ? __('emails.ops.refund.status_success') : __('emails.ops.refund.status_failed'));
+ $subject = __('emails.ops.refund.subject', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]);
+ $greeting = __('emails.ops.refund.greeting');
+ $lines = [
+ __('emails.ops.refund.tenant', ['tenant' => $tenant?->name ?? __('emails.tenant_feedback.unknown_tenant')]),
+ __('emails.ops.refund.package', ['package' => $package?->name ?? __('emails.package_limits.package_fallback')]),
+ __('emails.ops.refund.amount', ['amount' => $amount, 'currency' => '€']),
+ __('emails.ops.refund.provider', ['provider' => $this->purchase->provider, 'id' => $this->purchase->provider_id ?? '—']),
+ $this->success ? __('emails.ops.refund.status_success') : __('emails.ops.refund.status_failed'),
+ ];
if ($this->reason) {
- $mail->line(__('emails.ops.refund.reason', ['reason' => $this->reason]));
+ $lines[] = __('emails.ops.refund.reason', ['reason' => $this->reason]);
}
if ($this->error) {
- $mail->line(__('emails.ops.refund.error', ['error' => $this->error]));
+ $lines[] = __('emails.ops.refund.error', ['error' => $this->error]);
}
- return $mail->line(__('emails.ops.refund.footer'));
+ return (new MailMessage)
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => $lines,
+ 'footer' => __('emails.ops.refund.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackageGalleryExpiredNotification.php b/app/Notifications/Packages/EventPackageGalleryExpiredNotification.php
index 58f6655..b17f130 100644
--- a/app/Notifications/Packages/EventPackageGalleryExpiredNotification.php
+++ b/app/Notifications/Packages/EventPackageGalleryExpiredNotification.php
@@ -27,20 +27,34 @@ class EventPackageGalleryExpiredNotification extends Notification implements Sho
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = __('emails.package_limits.gallery_expired.subject', [
+ 'event' => $eventName,
+ ]);
+ $greeting = __('emails.package_limits.gallery_expired.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.gallery_expired.subject', [
- 'event' => $eventName,
- ]))
- ->greeting(__('emails.package_limits.gallery_expired.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.gallery_expired.body', [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'date' => optional($this->eventPackage->gallery_expires_at)->toFormattedDateString(),
- ]))
- ->action(__('emails.package_limits.gallery_expired.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.gallery_expired.body', [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'date' => optional($this->eventPackage->gallery_expires_at)->toFormattedDateString(),
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.gallery_expired.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackageGalleryExpiringNotification.php b/app/Notifications/Packages/EventPackageGalleryExpiringNotification.php
index 43f1fef..2053bd5 100644
--- a/app/Notifications/Packages/EventPackageGalleryExpiringNotification.php
+++ b/app/Notifications/Packages/EventPackageGalleryExpiringNotification.php
@@ -30,22 +30,36 @@ class EventPackageGalleryExpiringNotification extends Notification implements Sh
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = trans_choice('emails.package_limits.gallery_warning.subject', $this->daysRemaining, [
+ 'event' => $eventName,
+ 'days' => $this->daysRemaining,
+ ]);
+ $greeting = __('emails.package_limits.gallery_warning.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(trans_choice('emails.package_limits.gallery_warning.subject', $this->daysRemaining, [
- 'event' => $eventName,
- 'days' => $this->daysRemaining,
- ]))
- ->greeting(__('emails.package_limits.gallery_warning.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(trans_choice('emails.package_limits.gallery_warning.body', $this->daysRemaining, [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'days' => $this->daysRemaining,
- 'date' => optional($this->eventPackage->gallery_expires_at)->toFormattedDateString(),
- ]))
- ->action(__('emails.package_limits.gallery_warning.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ trans_choice('emails.package_limits.gallery_warning.body', $this->daysRemaining, [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'days' => $this->daysRemaining,
+ 'date' => optional($this->eventPackage->gallery_expires_at)->toFormattedDateString(),
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.gallery_warning.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackageGuestLimitNotification.php b/app/Notifications/Packages/EventPackageGuestLimitNotification.php
index 0d6bafb..99c59e0 100644
--- a/app/Notifications/Packages/EventPackageGuestLimitNotification.php
+++ b/app/Notifications/Packages/EventPackageGuestLimitNotification.php
@@ -30,22 +30,39 @@ class EventPackageGuestLimitNotification extends Notification implements ShouldQ
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = __('emails.package_limits.guest_limit.subject', [
+ 'event' => $eventName,
+ ]);
+ $greeting = __('emails.package_limits.guest_limit.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.guest_limit.subject', [
- 'event' => $eventName,
- ]))
- ->greeting(__('emails.package_limits.guest_limit.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.guest_limit.body', [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'limit' => $this->limit,
- ]))
- ->line(__('emails.package_limits.guest_limit.cta_addon'))
- ->action(__('emails.package_limits.guest_limit.addon_action'), $url)
- ->action(__('emails.package_limits.guest_limit.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.guest_limit.body', [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'limit' => $this->limit,
+ ]),
+ __('emails.package_limits.guest_limit.cta_addon'),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.guest_limit.addon_action'),
+ 'url' => $url,
+ ],
+ [
+ 'label' => __('emails.package_limits.guest_limit.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackageGuestThresholdNotification.php b/app/Notifications/Packages/EventPackageGuestThresholdNotification.php
index f787260..c0daf3d 100644
--- a/app/Notifications/Packages/EventPackageGuestThresholdNotification.php
+++ b/app/Notifications/Packages/EventPackageGuestThresholdNotification.php
@@ -34,24 +34,38 @@ class EventPackageGuestThresholdNotification extends Notification implements Sho
$remaining = max(0, $this->limit - $this->used);
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = __('emails.package_limits.guest_threshold.subject', [
+ 'event' => $eventName,
+ 'percentage' => $percentage,
+ ]);
+ $greeting = __('emails.package_limits.guest_threshold.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.guest_threshold.subject', [
- 'event' => $eventName,
- 'percentage' => $percentage,
- ]))
- ->greeting(__('emails.package_limits.guest_threshold.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.guest_threshold.body', [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'percentage' => $percentage,
- 'used' => $this->used,
- 'limit' => $this->limit,
- 'remaining' => $remaining,
- ]))
- ->action(__('emails.package_limits.guest_threshold.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.guest_threshold.body', [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'percentage' => $percentage,
+ 'used' => $this->used,
+ 'limit' => $this->limit,
+ 'remaining' => $remaining,
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.guest_threshold.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackagePhotoLimitNotification.php b/app/Notifications/Packages/EventPackagePhotoLimitNotification.php
index e76a492..e34756a 100644
--- a/app/Notifications/Packages/EventPackagePhotoLimitNotification.php
+++ b/app/Notifications/Packages/EventPackagePhotoLimitNotification.php
@@ -30,22 +30,39 @@ class EventPackagePhotoLimitNotification extends Notification implements ShouldQ
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = __('emails.package_limits.photo_limit.subject', [
+ 'event' => $eventName,
+ ]);
+ $greeting = __('emails.package_limits.photo_limit.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.photo_limit.subject', [
- 'event' => $eventName,
- ]))
- ->greeting(__('emails.package_limits.photo_limit.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.photo_limit.body', [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'limit' => $this->limit,
- ]))
- ->line(__('emails.package_limits.photo_limit.cta_addon'))
- ->action(__('emails.package_limits.photo_limit.addon_action'), $url)
- ->action(__('emails.package_limits.photo_limit.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.photo_limit.body', [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'limit' => $this->limit,
+ ]),
+ __('emails.package_limits.photo_limit.cta_addon'),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.photo_limit.addon_action'),
+ 'url' => $url,
+ ],
+ [
+ 'label' => __('emails.package_limits.photo_limit.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/EventPackagePhotoThresholdNotification.php b/app/Notifications/Packages/EventPackagePhotoThresholdNotification.php
index f15facd..83d9654 100644
--- a/app/Notifications/Packages/EventPackagePhotoThresholdNotification.php
+++ b/app/Notifications/Packages/EventPackagePhotoThresholdNotification.php
@@ -35,24 +35,38 @@ class EventPackagePhotoThresholdNotification extends Notification implements Sho
$eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback');
$url = url('/tenant/events/'.($event?->slug ?? ''));
+ $subject = __('emails.package_limits.photo_threshold.subject', [
+ 'event' => $eventName,
+ 'percentage' => $percentage,
+ ]);
+ $greeting = __('emails.package_limits.photo_threshold.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.photo_threshold.subject', [
- 'event' => $eventName,
- 'percentage' => $percentage,
- ]))
- ->greeting(__('emails.package_limits.photo_threshold.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.photo_threshold.body', [
- 'event' => $eventName,
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'percentage' => $percentage,
- 'used' => $this->used,
- 'limit' => $this->limit,
- 'remaining' => $remaining,
- ]))
- ->action(__('emails.package_limits.photo_threshold.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.photo_threshold.body', [
+ 'event' => $eventName,
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'percentage' => $percentage,
+ 'used' => $this->used,
+ 'limit' => $this->limit,
+ 'remaining' => $remaining,
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.photo_threshold.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/TenantPackageEventLimitNotification.php b/app/Notifications/Packages/TenantPackageEventLimitNotification.php
index ec23740..787c2c0 100644
--- a/app/Notifications/Packages/TenantPackageEventLimitNotification.php
+++ b/app/Notifications/Packages/TenantPackageEventLimitNotification.php
@@ -28,19 +28,33 @@ class TenantPackageEventLimitNotification extends Notification implements Should
$package = $this->tenantPackage->package;
$url = url('/tenant/billing');
+ $subject = __('emails.package_limits.event_limit.subject', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ ]);
+ $greeting = __('emails.package_limits.event_limit.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.event_limit.subject', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- ]))
- ->greeting(__('emails.package_limits.event_limit.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.event_limit.body', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'limit' => $this->limit,
- ]))
- ->action(__('emails.package_limits.event_limit.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.event_limit.body', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'limit' => $this->limit,
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.event_limit.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/TenantPackageEventThresholdNotification.php b/app/Notifications/Packages/TenantPackageEventThresholdNotification.php
index de71ae0..1c07f4e 100644
--- a/app/Notifications/Packages/TenantPackageEventThresholdNotification.php
+++ b/app/Notifications/Packages/TenantPackageEventThresholdNotification.php
@@ -33,23 +33,37 @@ class TenantPackageEventThresholdNotification extends Notification implements Sh
$remaining = max(0, $this->limit - $this->used);
$url = url('/tenant/billing');
+ $subject = __('emails.package_limits.event_threshold.subject', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'percentage' => $percentage,
+ ]);
+ $greeting = __('emails.package_limits.event_threshold.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.event_threshold.subject', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'percentage' => $percentage,
- ]))
- ->greeting(__('emails.package_limits.event_threshold.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.event_threshold.body', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'percentage' => $percentage,
- 'used' => $this->used,
- 'limit' => $this->limit,
- 'remaining' => $remaining,
- ]))
- ->action(__('emails.package_limits.event_threshold.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.event_threshold.body', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'percentage' => $percentage,
+ 'used' => $this->used,
+ 'limit' => $this->limit,
+ 'remaining' => $remaining,
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.event_threshold.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/TenantPackageExpiredNotification.php b/app/Notifications/Packages/TenantPackageExpiredNotification.php
index 2e53d9c..e0e47b3 100644
--- a/app/Notifications/Packages/TenantPackageExpiredNotification.php
+++ b/app/Notifications/Packages/TenantPackageExpiredNotification.php
@@ -25,19 +25,33 @@ class TenantPackageExpiredNotification extends Notification implements ShouldQue
$package = $this->tenantPackage->package;
$url = url('/tenant/billing');
+ $subject = __('emails.package_limits.package_expired.subject', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ ]);
+ $greeting = __('emails.package_limits.package_expired.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(__('emails.package_limits.package_expired.subject', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- ]))
- ->greeting(__('emails.package_limits.package_expired.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(__('emails.package_limits.package_expired.body', [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'date' => optional($this->tenantPackage->expires_at)->toFormattedDateString(),
- ]))
- ->action(__('emails.package_limits.package_expired.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ __('emails.package_limits.package_expired.body', [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'date' => optional($this->tenantPackage->expires_at)->toFormattedDateString(),
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.package_expired.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/Packages/TenantPackageExpiringNotification.php b/app/Notifications/Packages/TenantPackageExpiringNotification.php
index ae9f14b..4de6bfb 100644
--- a/app/Notifications/Packages/TenantPackageExpiringNotification.php
+++ b/app/Notifications/Packages/TenantPackageExpiringNotification.php
@@ -28,21 +28,35 @@ class TenantPackageExpiringNotification extends Notification implements ShouldQu
$package = $this->tenantPackage->package;
$url = url('/tenant/billing');
+ $subject = trans_choice('emails.package_limits.package_expiring.subject', $this->daysRemaining, [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'days' => $this->daysRemaining,
+ ]);
+ $greeting = __('emails.package_limits.package_expiring.greeting', [
+ 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
+ ]);
return (new MailMessage)
- ->subject(trans_choice('emails.package_limits.package_expiring.subject', $this->daysRemaining, [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'days' => $this->daysRemaining,
- ]))
- ->greeting(__('emails.package_limits.package_expiring.greeting', [
- 'name' => $tenant?->name ?? __('emails.package_limits.team_fallback'),
- ]))
- ->line(trans_choice('emails.package_limits.package_expiring.body', $this->daysRemaining, [
- 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
- 'days' => $this->daysRemaining,
- 'date' => optional($this->tenantPackage->expires_at)->toFormattedDateString(),
- ]))
- ->action(__('emails.package_limits.package_expiring.action'), $url)
- ->line(__('emails.package_limits.footer'));
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $greeting,
+ 'heroTitle' => $greeting,
+ 'heroSubtitle' => $subject,
+ 'lines' => [
+ trans_choice('emails.package_limits.package_expiring.body', $this->daysRemaining, [
+ 'package' => $package?->getNameForLocale() ?? $package?->name ?? __('emails.package_limits.package_fallback'),
+ 'days' => $this->daysRemaining,
+ 'date' => optional($this->tenantPackage->expires_at)->toFormattedDateString(),
+ ]),
+ ],
+ 'cta' => [
+ [
+ 'label' => __('emails.package_limits.package_expiring.action'),
+ 'url' => $url,
+ ],
+ ],
+ 'footer' => __('emails.package_limits.footer'),
+ ]);
}
}
diff --git a/app/Notifications/TenantFeedbackSubmitted.php b/app/Notifications/TenantFeedbackSubmitted.php
index 8d3a67c..f575b69 100644
--- a/app/Notifications/TenantFeedbackSubmitted.php
+++ b/app/Notifications/TenantFeedbackSubmitted.php
@@ -35,38 +35,45 @@ class TenantFeedbackSubmitted extends Notification implements ShouldQueue
'tenant' => $tenantName,
'sentiment' => $sentiment,
]);
-
- $mail = (new MailMessage())
- ->subject($subject)
- ->line(__('emails.tenant_feedback.tenant', ['tenant' => $tenantName]))
- ->line(__('emails.tenant_feedback.category', ['category' => $this->feedback->category ? Str::headline($this->feedback->category) : '—']))
- ->line(__('emails.tenant_feedback.sentiment', ['sentiment' => $sentiment]));
+ $lines = [
+ __('emails.tenant_feedback.tenant', ['tenant' => $tenantName]),
+ __('emails.tenant_feedback.category', ['category' => $this->feedback->category ? Str::headline($this->feedback->category) : '—']),
+ __('emails.tenant_feedback.sentiment', ['sentiment' => $sentiment]),
+ ];
if ($eventName) {
- $mail->line(__('emails.tenant_feedback.event', ['event' => $eventName]));
+ $lines[] = __('emails.tenant_feedback.event', ['event' => $eventName]);
}
if ($rating) {
- $mail->line(__('emails.tenant_feedback.rating', ['rating' => $rating]));
+ $lines[] = __('emails.tenant_feedback.rating', ['rating' => $rating]);
}
if ($this->feedback->title) {
- $mail->line(__('emails.tenant_feedback.title', ['subject' => $this->feedback->title]));
+ $lines[] = __('emails.tenant_feedback.title', ['subject' => $this->feedback->title]);
}
if ($this->feedback->message) {
- $mail->line(__('emails.tenant_feedback.message'))->line($this->feedback->message);
+ $lines[] = __('emails.tenant_feedback.message');
+ $lines[] = $this->feedback->message;
}
$url = TenantFeedbackResource::getUrl('view', ['record' => $this->feedback], panel: 'superadmin');
- if ($url) {
- $mail->action(__('emails.tenant_feedback.open'), $url);
- }
+ $lines[] = __('emails.tenant_feedback.received_at', ['date' => $this->feedback->created_at?->toDayDateTimeString()]);
- $mail->line(__('emails.tenant_feedback.received_at', ['date' => $this->feedback->created_at?->toDayDateTimeString()]));
-
- return $mail;
+ return (new MailMessage)
+ ->subject($subject)
+ ->view('emails.notifications.basic', [
+ 'title' => $subject,
+ 'preheader' => $subject,
+ 'heroTitle' => $subject,
+ 'lines' => $lines,
+ 'cta' => $url ? [[
+ 'label' => __('emails.tenant_feedback.open'),
+ 'url' => $url,
+ ]] : [],
+ ]);
}
protected function resolveName(mixed $name): ?string
diff --git a/app/Notifications/UploadPipelineFailed.php b/app/Notifications/UploadPipelineFailed.php
index 5edb712..04182a4 100644
--- a/app/Notifications/UploadPipelineFailed.php
+++ b/app/Notifications/UploadPipelineFailed.php
@@ -11,9 +11,7 @@ class UploadPipelineFailed extends Notification implements ShouldQueue
{
use Queueable;
- public function __construct(private readonly array $context)
- {
- }
+ public function __construct(private readonly array $context) {}
public function via(object $notifiable): array
{
@@ -29,15 +27,29 @@ class UploadPipelineFailed extends Notification implements ShouldQueue
public function toMail(object $notifiable): MailMessage
{
$context = $this->context;
+ $job = $context['job'] ?? 'n/a';
+ $queue = $context['queue'] ?? 'n/a';
+ $eventId = $context['event_id'] ?? 'n/a';
+ $photoId = $context['photo_id'] ?? 'n/a';
+ $exception = $context['exception'] ?? 'n/a';
+ $timestamp = now()->toDateTimeString();
return (new MailMessage)
- ->subject('Upload-Pipeline Fehler: '.($context['job'] ?? 'Unbekannter Job'))
- ->line('In der Upload-Pipeline ist ein Fehler aufgetreten.')
- ->line('Job: '.($context['job'] ?? 'n/a'))
- ->line('Queue: '.($context['queue'] ?? 'n/a'))
- ->line('Event ID: '.($context['event_id'] ?? 'n/a'))
- ->line('Foto ID: '.($context['photo_id'] ?? 'n/a'))
- ->line('Exception: '.($context['exception'] ?? 'n/a'))
- ->line('Zeitpunkt: '.now()->toDateTimeString());
+ ->subject(__('emails.upload_pipeline_failed.subject', ['job' => $job]))
+ ->view('emails.notifications.basic', [
+ 'title' => __('emails.upload_pipeline_failed.subject', ['job' => $job]),
+ 'preheader' => __('emails.upload_pipeline_failed.preheader'),
+ 'heroTitle' => __('emails.upload_pipeline_failed.hero_title'),
+ 'heroSubtitle' => __('emails.upload_pipeline_failed.hero_subtitle'),
+ 'lines' => [
+ __('emails.upload_pipeline_failed.line_job', ['job' => $job]),
+ __('emails.upload_pipeline_failed.line_queue', ['queue' => $queue]),
+ __('emails.upload_pipeline_failed.line_event', ['event' => $eventId]),
+ __('emails.upload_pipeline_failed.line_photo', ['photo' => $photoId]),
+ __('emails.upload_pipeline_failed.line_exception', ['exception' => $exception]),
+ __('emails.upload_pipeline_failed.line_time', ['time' => $timestamp]),
+ ],
+ 'footer' => __('emails.upload_pipeline_failed.footer'),
+ ]);
}
}
diff --git a/app/Notifications/VerifyEmailNotification.php b/app/Notifications/VerifyEmailNotification.php
new file mode 100644
index 0000000..afc0203
--- /dev/null
+++ b/app/Notifications/VerifyEmailNotification.php
@@ -0,0 +1,22 @@
+verificationUrl($notifiable);
+
+ return (new MailMessage)
+ ->subject(__('emails.verification.subject'))
+ ->view('emails.verify-email', [
+ 'user' => $notifiable,
+ 'verificationUrl' => $verificationUrl,
+ 'expiresIn' => (int) config('auth.verification.expire', 60),
+ ]);
+ }
+}
diff --git a/resources/lang/de/emails.php b/resources/lang/de/emails.php
index 9f0c085..ecdfbe2 100644
--- a/resources/lang/de/emails.php
+++ b/resources/lang/de/emails.php
@@ -1,14 +1,51 @@
[
+ 'label' => 'Die Fotospiel.App',
+ 'footer' => 'Mit freundlichen Grüßen,
Das Team von Die Fotospiel.App',
+ 'tagline' => 'Die Fotospiel.App · Event-Pakete mit Wow-Effekt',
+ ],
+
'welcome' => [
- 'subject' => 'Willkommen bei Fotospiel, :name!',
- 'greeting' => 'Willkommen bei Fotospiel, :name!',
- 'body' => 'Vielen Dank für Ihre Registrierung. Ihr Account ist nun aktiv.',
+ 'subject' => 'Willkommen bei Die Fotospiel.App, :name!',
+ 'greeting' => 'Willkommen bei Die Fotospiel.App, :name!',
+ 'subtitle' => 'Schön, dass Sie da sind. Ihr Event-Erlebnis kann sofort starten.',
+ 'body' => 'Vielen Dank für Ihre Registrierung. Wir haben Ihren Account vorbereitet – jetzt fehlt nur noch Ihr erstes Event.',
+ 'account_label' => 'Ihre Zugangsdaten',
'username' => 'Benutzername: :username',
'email' => 'E-Mail: :email',
- 'verification' => 'Bitte verifizieren Sie Ihre E-Mail-Adresse, um auf das Admin-Panel zuzugreifen.',
- 'footer' => 'Mit freundlichen Grüßen,
Das Fotospiel-Team',
+ 'verification' => 'Bitte bestätigen Sie Ihre E-Mail-Adresse, um vollen Zugriff zu erhalten.',
+ 'next_steps_title' => 'So geht es weiter',
+ 'step_one' => 'Event anlegen und das passende Paket auswählen',
+ 'step_two' => 'Gäste einladen und den Upload-Link teilen',
+ 'step_three' => 'Fotos sammeln, kuratieren und genießen',
+ 'cta' => 'Event-Admin öffnen',
+ 'footer' => 'Sie brauchen Unterstützung? Wir sind jederzeit für Sie da.',
+ ],
+ 'verification' => [
+ 'subject' => 'Bitte bestätigen Sie Ihre E-Mail-Adresse',
+ 'preheader' => 'Bestätigen Sie Ihre E-Mail, um den vollen Zugriff zu erhalten.',
+ 'hero_title' => 'E-Mail bestätigen, :name',
+ 'hero_subtitle' => 'Ein Klick genügt, um Ihr Konto zu aktivieren.',
+ 'body' => 'Bitte bestätigen Sie Ihre E-Mail-Adresse, indem Sie auf den Button klicken.',
+ 'expires' => 'Dieser Bestätigungslink ist :minutes Minuten gültig.',
+ 'link_fallback' => 'Falls der Button nicht funktioniert, kopieren Sie diesen Link in Ihren Browser:',
+ 'cta' => 'E-Mail bestätigen',
+ 'footer' => 'Falls Sie kein Konto erstellt haben, können Sie diese E-Mail ignorieren.',
+ ],
+ 'upload_pipeline_failed' => [
+ 'subject' => 'Upload-Pipeline Fehler: :job',
+ 'preheader' => 'In der Upload-Pipeline ist ein Fehler aufgetreten.',
+ 'hero_title' => 'Upload-Pipeline Alarm',
+ 'hero_subtitle' => 'Beim Verarbeiten der Uploads ist ein Fehler aufgetreten.',
+ 'line_job' => 'Job: :job',
+ 'line_queue' => 'Queue: :queue',
+ 'line_event' => 'Event ID: :event',
+ 'line_photo' => 'Foto ID: :photo',
+ 'line_exception' => 'Exception: :exception',
+ 'line_time' => 'Zeitpunkt: :time',
+ 'footer' => 'Bitte prüfen Sie die Queue-Logs für weitere Details.',
],
'purchase' => [
@@ -17,9 +54,7 @@ return [
'package' => 'Package: :package',
'price' => 'Preis: :price',
'activation' => 'Ihr Event-Paket ist jetzt im Tenant-Account aktiviert.',
- 'footer' => 'Mit freundlichen Grüßen,
Das Team von Die Fotospiel.App',
- 'brand_label' => 'Die Fotospiel.App',
- 'brand_footer' => 'Die Fotospiel.App · Event-Pakete mit Wow-Effekt',
+ 'footer' => 'Sie brauchen Unterstützung? Wir sind jederzeit für Sie da.',
'subtitle' => 'Ihre Bestellung wurde erfolgreich bestätigt. Hier finden Sie alle Details auf einen Blick.',
'summary_title' => 'Bestellübersicht',
'package_label' => 'Event-Paket',
@@ -57,23 +92,20 @@ return [
'subject_1w' => 'Letzte Chance: Ihr gespeichertes Paket',
'greeting' => 'Hallo :name,',
-
- 'body_1h' => 'Sie haben vor kurzem begonnen, unser :package Paket zu kaufen, aber noch nicht abgeschlossen. Ihr Warenkorb ist für Sie reserviert.',
-
- 'body_24h' => 'Erinnerung: Ihr :package Paket wartet seit 24 Stunden auf Sie. Schließen Sie jetzt Ihren Kauf ab und sichern Sie sich alle Vorteile.',
-
- 'body_1w' => 'Letzte Erinnerung: Ihr :package Paket wartet seit einer Woche auf Sie. Dies ist Ihre letzte Chance, den Kauf abzuschließen.',
-
- 'cta_button' => 'Jetzt fortfahren',
+ 'subtitle' => ':package ist nur einen Schritt entfernt.',
+ 'body_1h' => 'Sie haben vor kurzem unser :package Event-Paket ausgewählt. Ihr Checkout ist weiterhin für Sie reserviert.',
+ 'body_24h' => 'Ihr :package Event-Paket wartet seit 24 Stunden auf Sie. Schließen Sie den Kauf jetzt ab und starten Sie direkt.',
+ 'body_1w' => 'Letzte Erinnerung: Ihr :package Event-Paket ist noch reserviert. Wenn Sie möchten, können Sie den Checkout jetzt abschließen.',
+ 'cta_button' => 'Checkout fortsetzen',
'cta_link' => 'Oder kopieren Sie diesen Link: :url',
-
- 'benefits_title' => 'Warum jetzt kaufen?',
- 'benefit1' => 'Schneller Checkout in 2 Minuten',
+ 'cta_hint_title' => 'Reserviert für Sie',
+ 'cta_hint_body' => 'Ihr Angebot bleibt bestehen – Sie können jederzeit nahtlos fortfahren.',
+ 'benefits_title' => 'Was Sie erwartet',
+ 'benefit1' => 'Premium Checkout in wenigen Minuten',
'benefit2' => 'Sichere Zahlung mit Paddle',
- 'benefit3' => 'Sofortiger Zugriff nach Zahlung',
- 'benefit4' => '10% Rabatt sichern',
-
- 'footer' => 'Mit freundlichen Grüßen,
Das Fotospiel-Team',
+ 'benefit3' => 'Sofortige Aktivierung nach Zahlung',
+ 'benefit4' => 'Support durch das Die Fotospiel.App Team',
+ 'footer' => 'Wir helfen Ihnen gern weiter, falls Fragen offen sind.',
],
'contact' => [
@@ -82,10 +114,13 @@ return [
],
'contact_confirmation' => [
- 'subject' => 'Vielen Dank für Ihre Nachricht, :name!',
+ 'subject' => 'Danke für Ihre Nachricht, :name!',
'greeting' => 'Hallo :name,',
- 'body' => 'Vielen Dank für Ihre Nachricht an das Fotospiel-Team. Wir melden uns so schnell wie möglich zurück.',
- 'footer' => 'Viele Grüße
Ihr Fotospiel-Team',
+ 'subtitle' => 'Wir kümmern uns persönlich um Ihr Anliegen.',
+ 'body' => 'Vielen Dank für Ihre Nachricht. Unser Team meldet sich so schnell wie möglich mit einer passenden Lösung.',
+ 'response_time' => 'In der Regel erhalten Sie innerhalb eines Werktags eine Antwort.',
+ 'cta' => 'Support kontaktieren',
+ 'footer' => 'Viele Grüße
Ihr Die Fotospiel.App Team',
],
'package_limits' => [
@@ -163,8 +198,14 @@ return [
'receipt' => [
'subject' => 'Add-on gekauft: :addon',
'greeting' => 'Hallo :name,',
- 'body' => 'Sie haben „ :addon “ für das Event „ :event “ gebucht. Betrag: :amount.',
- 'summary' => 'Enthalten: +:photos Fotos, +:guests Gäste, +:days Tage Galerie.',
+ 'subtitle' => 'Ihr Add-on ist aktiv und sofort verfügbar.',
+ 'body' => 'Sie haben „:addon“ für das Event „:event“ gebucht. Gesamtbetrag: :amount.',
+ 'summary_title' => 'Enthaltene Upgrades',
+ 'summary' => [
+ 'photos' => '+:count Fotos',
+ 'guests' => '+:count Gäste',
+ 'gallery' => '+:count Tage Galerie',
+ ],
'unknown_amount' => 'k.A.',
'action' => 'Event-Dashboard öffnen',
],
@@ -174,12 +215,14 @@ return [
'purchaser' => [
'subject' => 'Dein Geschenkgutschein (:amount :currency)',
'greeting' => 'Danke für deinen Kauf!',
- 'body' => 'Hier ist dein Fotospiel-Geschenkgutschein im Wert von :amount :currency. Teile den Code mit deiner beschenkten Person: :recipient.',
+ 'subtitle' => 'Dein Gutschein ist bereit, Freude zu schenken.',
+ 'body' => 'Hier ist dein Fotospiel-Geschenkgutschein im Wert von :amount :currency. Teile den Code mit :recipient und schenke ein unvergessliches Event.',
'recipient_fallback' => 'dein:e Beschenkte:r',
],
'recipient' => [
'subject' => 'Du hast einen Fotospiel-Geschenkgutschein erhalten (:amount :currency)',
'greeting' => 'Du hast ein Geschenk bekommen!',
+ 'subtitle' => 'Zeit für ein Event mit Wow-Effekt.',
'body' => ':purchaser hat dir einen Fotospiel-Geschenkgutschein im Wert von :amount :currency gesendet. Löse ihn mit dem untenstehenden Code ein.',
],
'code_label' => 'Gutscheincode',
@@ -187,7 +230,7 @@ return [
'expiry' => 'Gültig bis :date.',
'message_title' => 'Persönliche Nachricht',
'withdrawal' => 'Widerrufsbelehrung: Details ansehen (14 Tage; erlischt mit Einlösung).',
- 'footer' => 'Viele Grüße,
dein Fotospiel Team',
+ 'footer' => 'Viele Grüße,
dein Die Fotospiel.App Team',
'printable' => 'Druckversion (mit QR)',
'reminder' => 'Erinnerung: Dein Gutschein ist noch nicht eingelöst.',
'expiry_soon' => 'Hinweis: Dein Gutschein läuft bald ab.',
diff --git a/resources/lang/en/emails.php b/resources/lang/en/emails.php
index e5ed1c0..82b292a 100644
--- a/resources/lang/en/emails.php
+++ b/resources/lang/en/emails.php
@@ -1,14 +1,50 @@
[
+ 'label' => 'Die Fotospiel.App',
+ 'footer' => 'Best regards,
The team at Die Fotospiel.App',
+ 'tagline' => 'Die Fotospiel.App · Event packages with wow-factor',
+ ],
'welcome' => [
- 'subject' => 'Welcome to Fotospiel, :name!',
- 'greeting' => 'Welcome to Fotospiel, :name!',
- 'body' => 'Thank you for your registration. Your account is now active.',
+ 'subject' => 'Welcome to Die Fotospiel.App, :name!',
+ 'greeting' => 'Welcome to Die Fotospiel.App, :name!',
+ 'subtitle' => 'We are glad you are here. Your event experience can start immediately.',
+ 'body' => 'Thank you for signing up. Your account is ready—now let’s launch your first event.',
+ 'account_label' => 'Your account details',
'username' => 'Username: :username',
'email' => 'Email: :email',
- 'verification' => 'Please verify your email address to access the admin panel.',
- 'footer' => 'Best regards,
The Fotospiel Team',
+ 'verification' => 'Please verify your email address to unlock full access.',
+ 'next_steps_title' => 'Next steps',
+ 'step_one' => 'Create your event and pick the right package',
+ 'step_two' => 'Invite guests and share the upload link',
+ 'step_three' => 'Collect, curate, and celebrate every photo',
+ 'cta' => 'Open Event Admin',
+ 'footer' => 'Need help? We are here whenever you need us.',
+ ],
+ 'verification' => [
+ 'subject' => 'Verify your email address',
+ 'preheader' => 'Confirm your email to unlock full access.',
+ 'hero_title' => 'Confirm your email, :name',
+ 'hero_subtitle' => 'One click to activate your account.',
+ 'body' => 'Please confirm your email address by clicking the button below.',
+ 'expires' => 'This verification link expires in :minutes minutes.',
+ 'link_fallback' => 'If the button does not work, copy and paste this link into your browser:',
+ 'cta' => 'Verify email',
+ 'footer' => 'If you did not create an account, you can ignore this email.',
+ ],
+ 'upload_pipeline_failed' => [
+ 'subject' => 'Upload pipeline error: :job',
+ 'preheader' => 'An error occurred in the upload pipeline.',
+ 'hero_title' => 'Upload pipeline alert',
+ 'hero_subtitle' => 'We hit an error while processing uploads.',
+ 'line_job' => 'Job: :job',
+ 'line_queue' => 'Queue: :queue',
+ 'line_event' => 'Event ID: :event',
+ 'line_photo' => 'Photo ID: :photo',
+ 'line_exception' => 'Exception: :exception',
+ 'line_time' => 'Time: :time',
+ 'footer' => 'Please investigate the failure in the queue logs.',
],
'purchase' => [
@@ -17,9 +53,7 @@ return [
'package' => 'Package: :package',
'price' => 'Price: :price',
'activation' => 'Your event package is now activated in your tenant account.',
- 'footer' => 'Best regards,
The team at Die Fotospiel.App',
- 'brand_label' => 'Die Fotospiel.App',
- 'brand_footer' => 'Die Fotospiel.App · Event packages with wow-factor',
+ 'footer' => 'Need assistance? We are always happy to help.',
'subtitle' => 'Your order has been confirmed successfully. Here are the details at a glance.',
'summary_title' => 'Order summary',
'package_label' => 'Event package',
@@ -57,23 +91,20 @@ return [
'subject_1w' => 'Last Chance: Your Saved Package',
'greeting' => 'Hello :name,',
-
- 'body_1h' => 'You recently started purchasing our :package package but haven\'t completed it yet. Your cart is reserved for you.',
-
- 'body_24h' => 'Reminder: Your :package package has been waiting for 24 hours. Complete your purchase now and secure all the benefits.',
-
- 'body_1w' => 'Final reminder: Your :package package has been waiting for a week. This is your last chance to complete the purchase.',
-
- 'cta_button' => 'Continue Now',
+ 'subtitle' => ':package is just one step away.',
+ 'body_1h' => 'You selected the :package event package but haven\'t completed checkout yet. Your selection is still reserved.',
+ 'body_24h' => 'Your :package event package has been waiting for 24 hours. Finish checkout now and get started instantly.',
+ 'body_1w' => 'Final reminder: Your :package event package is still reserved. You can complete your purchase at any time.',
+ 'cta_button' => 'Resume checkout',
'cta_link' => 'Or copy this link: :url',
-
- 'benefits_title' => 'Why buy now?',
- 'benefit1' => 'Quick checkout in 2 minutes',
+ 'cta_hint_title' => 'Reserved for you',
+ 'cta_hint_body' => 'Your selection stays locked—continue whenever you are ready.',
+ 'benefits_title' => 'What you get',
+ 'benefit1' => 'Premium checkout in minutes',
'benefit2' => 'Secure payment with Paddle',
- 'benefit3' => 'Instant access after payment',
- 'benefit4' => 'Secure 10% discount',
-
- 'footer' => 'Best regards,
The Fotospiel Team',
+ 'benefit3' => 'Instant activation after payment',
+ 'benefit4' => 'Support from the Die Fotospiel.App team',
+ 'footer' => 'Let us know if you need anything.',
],
'contact' => [
@@ -82,10 +113,13 @@ return [
],
'contact_confirmation' => [
- 'subject' => 'Thank you for reaching out, :name!',
+ 'subject' => 'Thanks for reaching out, :name!',
'greeting' => 'Hi :name,',
- 'body' => 'Thank you for your message to the Fotospiel team. We will get back to you as soon as possible.',
- 'footer' => 'Best regards,
The Fotospiel Team',
+ 'subtitle' => 'Your message is in good hands.',
+ 'body' => 'Thank you for contacting us. Our team will reply with a tailored answer as quickly as possible.',
+ 'response_time' => 'We usually respond within one business day.',
+ 'cta' => 'Contact support',
+ 'footer' => 'Best regards,
The Die Fotospiel.App team',
],
'package_limits' => [
@@ -163,8 +197,14 @@ return [
'receipt' => [
'subject' => 'Add-on purchase: :addon',
'greeting' => 'Hello :name,',
- 'body' => 'You purchased " :addon " for the event " :event ". Amount: :amount.',
- 'summary' => 'Included: +:photos photos, +:guests guests, +:days gallery days.',
+ 'subtitle' => 'Your add-on is active and ready to use.',
+ 'body' => 'You booked “:addon” for the event “:event”. Total: :amount.',
+ 'summary_title' => 'Included upgrades',
+ 'summary' => [
+ 'photos' => '+:count photos',
+ 'guests' => '+:count guests',
+ 'gallery' => '+:count gallery days',
+ ],
'unknown_amount' => 'n/a',
'action' => 'Open event dashboard',
],
@@ -233,12 +273,14 @@ return [
'purchaser' => [
'subject' => 'Your gift voucher (:amount :currency)',
'greeting' => 'Thank you for your purchase!',
- 'body' => 'Here is your Fotospiel gift voucher worth :amount :currency. You can share the code with your recipient: :recipient.',
+ 'subtitle' => 'Your voucher is ready to make someone smile.',
+ 'body' => 'Here is your Fotospiel gift voucher worth :amount :currency. Share the code with :recipient and gift an unforgettable event.',
'recipient_fallback' => 'your recipient',
],
'recipient' => [
'subject' => 'You received a Fotospiel gift voucher (:amount :currency)',
'greeting' => 'You have a gift!',
+ 'subtitle' => 'Time for an event with wow-factor.',
'body' => ':purchaser sent you a Fotospiel gift voucher worth :amount :currency. Redeem it with the code below.',
],
'code_label' => 'Voucher code',
@@ -246,7 +288,7 @@ return [
'expiry' => 'Valid until :date.',
'message_title' => 'Personal message',
'withdrawal' => 'Withdrawal policy: View details (14 days; expires upon redemption).',
- 'footer' => 'Best regards,
The Fotospiel Team',
+ 'footer' => 'Best regards,
The Die Fotospiel.App team',
'printable' => 'Printable version (with QR)',
'reminder' => 'Reminder: You still have an unused voucher.',
'expiry_soon' => 'Heads up: Your voucher will expire soon.',
diff --git a/resources/views/emails/abandoned-checkout.blade.php b/resources/views/emails/abandoned-checkout.blade.php
index 57fa8b8..887f328 100644
--- a/resources/views/emails/abandoned-checkout.blade.php
+++ b/resources/views/emails/abandoned-checkout.blade.php
@@ -1,47 +1,48 @@
-
-
-
{{ __('emails.abandoned_checkout.body_' . $timing, ['package' => $packageName]) }}
+@section('title', __('emails.abandoned_checkout.subject_' . $timing, ['package' => $packageName])) +@section('preheader', __('emails.abandoned_checkout.subtitle', ['package' => $packageName])) +@section('hero_title', __('emails.abandoned_checkout.greeting', ['name' => $user->fullName])) +@section('hero_subtitle', __('emails.abandoned_checkout.subtitle', ['package' => $packageName])) - +@section('content') ++ {{ __('emails.abandoned_checkout.body_' . $timing, ['package' => $packageName]) }} +
++ {{ __('emails.abandoned_checkout.cta_hint_title') }} +
++ {{ __('emails.abandoned_checkout.cta_hint_body') }} +
++ {{ __('emails.abandoned_checkout.cta_link', ['url' => $resumeUrl]) }} +
+| ✓ {{ __('emails.abandoned_checkout.benefit1') }} | +
| ✓ {{ __('emails.abandoned_checkout.benefit2') }} | +
| ✓ {{ __('emails.abandoned_checkout.benefit3') }} | +
| ✓ {{ __('emails.abandoned_checkout.benefit4') }} | +
{{ __('emails.abandoned_checkout.cta_link', ['url' => $resumeUrl]) }}
- -{!! __('emails.abandoned_checkout.footer') !!}
- - +@section('footer') + {!! __('emails.abandoned_checkout.footer') !!} +@endsection diff --git a/resources/views/emails/addons/receipt.blade.php b/resources/views/emails/addons/receipt.blade.php index 783f217..3a88582 100644 --- a/resources/views/emails/addons/receipt.blade.php +++ b/resources/views/emails/addons/receipt.blade.php @@ -1,3 +1,5 @@ +@extends('emails.partials.layout') + @php /** @var \App\Models\EventPackageAddon $addon */ $event = $addon->event; @@ -14,31 +16,45 @@ if ($addon->extra_gallery_days > 0) { $summary[] = __('emails.addons.receipt.summary.gallery', ['count' => $addon->extra_gallery_days]); } + $eventName = $event?->name['de'] ?? $event?->name['en'] ?? $event?->name ?? __('emails.package_limits.event_fallback'); + $ctaUrl = url('/tenant/events/'.($event?->slug ?? '')); @endphp -@component('mail::message') -# {{ __('emails.addons.receipt.subject', ['addon' => $label]) }} +@section('title', __('emails.addons.receipt.subject', ['addon' => $label])) +@section('preheader', __('emails.addons.receipt.subtitle', ['addon' => $label])) +@section('hero_title', __('emails.addons.receipt.greeting', ['name' => $tenant?->name ?? __('emails.package_limits.team_fallback')])) +@section('hero_subtitle', __('emails.addons.receipt.subtitle', ['addon' => $label])) -{{ __('emails.addons.receipt.greeting', ['name' => $tenant?->name ?? __('emails.package_limits.team_fallback')]) }} +@section('content') ++ {{ __('emails.addons.receipt.body', [ + 'addon' => $label, + 'event' => $eventName, + 'amount' => $amount, + ]) }} +
+ @if (! empty($summary)) ++ {{ __('emails.addons.receipt.summary_title') }} +
+| {{ $line }} | +
+ {{ __('emails.contact_confirmation.body') }} +
++ {{ __('emails.contact_confirmation.response_time') }} +
+@endsection + +@section('cta') + + {{ __('emails.contact_confirmation.cta') }} + +@endsection + +@section('footer') + {!! __('emails.contact_confirmation.footer') !!} +@endsection diff --git a/resources/views/emails/gift-voucher.blade.php b/resources/views/emails/gift-voucher.blade.php index 66dd9d4..33465c5 100644 --- a/resources/views/emails/gift-voucher.blade.php +++ b/resources/views/emails/gift-voucher.blade.php @@ -1,41 +1,48 @@ +@extends('emails.partials.layout') + @php $withdrawalUrl = app()->getLocale() === 'de' ? url('/de/widerrufsbelehrung') : url('/en/withdrawal'); + $subject = $forRecipient + ? __('emails.gift_voucher.recipient.subject', ['amount' => $amount, 'currency' => $currency]) + : __('emails.gift_voucher.purchaser.subject', ['amount' => $amount, 'currency' => $currency]); + $greeting = $forRecipient + ? __('emails.gift_voucher.recipient.greeting') + : __('emails.gift_voucher.purchaser.greeting'); + $subtitle = $forRecipient + ? __('emails.gift_voucher.recipient.subtitle') + : __('emails.gift_voucher.purchaser.subtitle'); + $body = $forRecipient + ? __('emails.gift_voucher.recipient.body', [ + 'amount' => $amount, + 'currency' => $currency, + 'purchaser' => $voucher->purchaser_email, + ]) + : __('emails.gift_voucher.purchaser.body', [ + 'amount' => $amount, + 'currency' => $currency, + 'recipient' => $voucher->recipient_email ?: __('emails.gift_voucher.purchaser.recipient_fallback'), + ]); @endphp - - - - -- {!! $forRecipient - ? __('emails.gift_voucher.recipient.body', [ - 'amount' => $amount, - 'currency' => $currency, - 'purchaser' => $voucher->purchaser_email, - ]) - : __('emails.gift_voucher.purchaser.body', [ - 'amount' => $amount, - 'currency' => $currency, - 'recipient' => $voucher->recipient_email ?: __('emails.gift_voucher.purchaser.recipient_fallback'), - ]) - !!} -
+@section('title', $subject) +@section('preheader', $subtitle) +@section('hero_title', $greeting) +@section('hero_subtitle', $subtitle) + +@section('content') ++ {!! $body !!} +
@if ($voucher->message){{ $voucher->message }}
{{ __('emails.gift_voucher.code_label') }}
++ {{ __('emails.gift_voucher.code_label') }} +
- {{ __('emails.gift_voucher.printable') }} + {{ __('emails.gift_voucher.printable') }}
@endisset{{ __('emails.gift_voucher.expiry', ['date' => optional($voucher->expires_at)->toFormattedDateString()]) }}
-{!! __('emails.gift_voucher.withdrawal', ['url' => $withdrawalUrl]) !!}
+@endsection -- {!! __('emails.gift_voucher.footer') !!} -
-+ {{ $intro }} +
+ @endisset + @if (! empty($lines)) +| {{ $line }} | +
|
+
+ + @yield('brand_footer', __('emails.brand.tagline')) + + |
+
|
-
- - {{ __('emails.purchase.brand_footer') }} - - |
+ {{ __('emails.purchase.package_label') }} | +{{ $packageName }} | +
| {{ __('emails.purchase.type_label') }} | +{{ $packageTypeLabel }} | +|
| {{ __('emails.purchase.date_label') }} | +{{ $purchaseDate }} | +|
| {{ __('emails.purchase.provider_label') }} | +{{ $providerLabel }} | +|
| {{ __('emails.purchase.order_label') }} | +{{ $orderId }} | +|
| {{ __('emails.purchase.price_label') }} | +{{ $priceFormatted }} |
+ {{ __('emails.purchase.activation_label') }} +
++ {{ __('emails.purchase.activation') }} +
+| {{ $limit['label'] }} | +{{ $limit['value'] }} | +
+ + {{ __('emails.purchase.invoice_link') }} + +
+ @endif +@endsection + +@section('cta') + + {{ __('emails.purchase.cta') }} + +@endsection + +@section('footer') + {!! __('emails.purchase.footer') !!} +@endsection diff --git a/resources/views/emails/verify-email.blade.php b/resources/views/emails/verify-email.blade.php new file mode 100644 index 0000000..0c93f94 --- /dev/null +++ b/resources/views/emails/verify-email.blade.php @@ -0,0 +1,29 @@ +@extends('emails.partials.layout') + +@section('title', __('emails.verification.subject')) +@section('preheader', __('emails.verification.preheader')) +@section('hero_title', __('emails.verification.hero_title', ['name' => $user->fullName ?? $user->name ?? $user->email])) +@section('hero_subtitle', __('emails.verification.hero_subtitle')) + +@section('content') ++ {{ __('emails.verification.body') }} +
++ {{ __('emails.verification.expires', ['minutes' => $expiresIn]) }} +
+
+ {{ __('emails.verification.link_fallback') }}
+ {{ $verificationUrl }}
+
{{ __('emails.welcome.body') }}
-{{ __('emails.welcome.username', ['username' => $user->username]) }}
-{{ __('emails.welcome.email', ['email' => $user->email]) }}
-{{ __('emails.welcome.verification') }}
-{!! __('emails.welcome.footer') !!}
- - \ No newline at end of file +@extends('emails.partials.layout') + +@section('title', __('emails.welcome.subject', ['name' => $user->fullName])) +@section('preheader', __('emails.welcome.subtitle')) +@section('hero_title', __('emails.welcome.greeting', ['name' => $user->fullName])) +@section('hero_subtitle', __('emails.welcome.subtitle')) + +@section('content') ++ {{ __('emails.welcome.body') }} +
++ {{ __('emails.welcome.account_label') }} +
+
+ {{ __('emails.welcome.username', ['username' => $user->username]) }}
+ {{ __('emails.welcome.email', ['email' => $user->email]) }}
+
+ {{ __('emails.welcome.verification') }} +
+| 01 | +{{ __('emails.welcome.step_one') }} | +
| 02 | +{{ __('emails.welcome.step_two') }} | +
| 03 | +{{ __('emails.welcome.step_three') }} | +