From 1def8cf716d8755efb849bc705e336cc1a555038 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sun, 12 Jul 2026 20:10:26 +0000 Subject: [PATCH] Brand Frontdesk Laravel mail for hosts and report recipients. Pass organization logo/name through ContactMessageMail for daily reports and campaigns, and drop the Ladill product footer. Co-authored-by: Cursor --- .../Commands/SendDailyReportCommand.php | 2 +- app/Jobs/SendCampaignMessageJob.php | 4 +++ app/Mail/ContactMessageMail.php | 4 +++ app/Services/Comms/EmailService.php | 23 ++++++++++--- .../views/email/contact-message.blade.php | 23 +++++++++---- tests/Feature/FrontdeskEmailBrandingTest.php | 33 +++++++++++++++++++ 6 files changed, 78 insertions(+), 11 deletions(-) diff --git a/app/Console/Commands/SendDailyReportCommand.php b/app/Console/Commands/SendDailyReportCommand.php index 1a9bdfa..0118c16 100644 --- a/app/Console/Commands/SendDailyReportCommand.php +++ b/app/Console/Commands/SendDailyReportCommand.php @@ -39,7 +39,7 @@ class SendDailyReportCommand extends Command foreach ($recipients as $address) { if (is_string($address) && filter_var($address, FILTER_VALIDATE_EMAIL)) { - $email->send($address, $subject, $body); + $email->send($address, $subject, $body, $organization->name, null, $organization); $sent++; } } diff --git a/app/Jobs/SendCampaignMessageJob.php b/app/Jobs/SendCampaignMessageJob.php index b11ed93..68760bb 100644 --- a/app/Jobs/SendCampaignMessageJob.php +++ b/app/Jobs/SendCampaignMessageJob.php @@ -5,6 +5,7 @@ namespace App\Jobs; use App\Models\Activity; use App\Models\Campaign; use App\Models\CampaignRecipient; +use App\Models\Organization; use App\Models\User; use App\Services\Campaigns\CampaignBillingService; use App\Services\Campaigns\CampaignMessageService; @@ -56,6 +57,8 @@ class SendCampaignMessageJob implements ShouldQueue return; } + $organization = Organization::query()->where('owner_ref', $campaign->owner_ref)->first(); + $sent = $campaign->channel === Campaign::CHANNEL_SMS ? $sms->send((string) $recipient->recipient_phone, $body) : $email->send( @@ -64,6 +67,7 @@ class SendCampaignMessageJob implements ShouldQueue $body, $this->senderName($campaign), $this->senderEmail($campaign), + $organization, ); if (! $sent) { diff --git a/app/Mail/ContactMessageMail.php b/app/Mail/ContactMessageMail.php index 8081ad8..842ccad 100644 --- a/app/Mail/ContactMessageMail.php +++ b/app/Mail/ContactMessageMail.php @@ -17,6 +17,8 @@ class ContactMessageMail extends Mailable public string $bodyText, public ?string $fromName = null, public ?string $replyToAddress = null, + public ?string $logoUrl = null, + public ?string $companyName = null, ) {} public function envelope(): Envelope @@ -34,6 +36,8 @@ class ContactMessageMail extends Mailable with: [ 'bodyText' => $this->bodyText, 'fromName' => $this->fromName, + 'logoUrl' => $this->logoUrl, + 'companyName' => $this->companyName, ], ); } diff --git a/app/Services/Comms/EmailService.php b/app/Services/Comms/EmailService.php index bf33e0b..0c92f2d 100644 --- a/app/Services/Comms/EmailService.php +++ b/app/Services/Comms/EmailService.php @@ -3,6 +3,8 @@ namespace App\Services\Comms; use App\Mail\ContactMessageMail; +use App\Models\Organization; +use App\Support\OrganizationBranding; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; @@ -13,18 +15,31 @@ use Illuminate\Support\Facades\Mail; */ class EmailService { - public function send(string $to, string $subject, string $body, ?string $fromName = null, ?string $replyTo = null): bool - { + public function send( + string $to, + string $subject, + string $body, + ?string $fromName = null, + ?string $replyTo = null, + ?Organization $organization = null, + ): bool { if (! filter_var($to, FILTER_VALIDATE_EMAIL)) { return false; } + $logoUrl = null; + $companyName = null; + if ($organization) { + $logoUrl = OrganizationBranding::emailLogoUrl($organization); + $companyName = $organization->name; + } + try { - Mail::to($to)->send(new ContactMessageMail($subject, $body, $fromName, $replyTo)); + Mail::to($to)->send(new ContactMessageMail($subject, $body, $fromName, $replyTo, $logoUrl, $companyName)); return true; } catch (\Throwable $e) { - Log::warning('CRM email send failed', ['to' => $to, 'error' => $e->getMessage()]); + Log::warning('Frontdesk email send failed', ['to' => $to, 'error' => $e->getMessage()]); return false; } diff --git a/resources/views/email/contact-message.blade.php b/resources/views/email/contact-message.blade.php index 3cb5cc9..d4111db 100644 --- a/resources/views/email/contact-message.blade.php +++ b/resources/views/email/contact-message.blade.php @@ -4,15 +4,26 @@ - -
-
-
{{ $bodyText }}
+ +
+ @if (! empty($logoUrl) || ! empty($companyName)) +
+ @if (! empty($logoUrl)) + {{ $companyName }} + @else +
{{ $companyName }}
+ @endif +
+ @endif +
+
{{ $bodyText }}
@if (! empty($fromName)) -

— {{ $fromName }}

+

— {{ $fromName }}

@endif
-

Sent via Ladill Frontdesk

+ @if (! empty($companyName)) +

{{ $companyName }}

+ @endif
diff --git a/tests/Feature/FrontdeskEmailBrandingTest.php b/tests/Feature/FrontdeskEmailBrandingTest.php index 20ad2a2..58df062 100644 --- a/tests/Feature/FrontdeskEmailBrandingTest.php +++ b/tests/Feature/FrontdeskEmailBrandingTest.php @@ -121,4 +121,37 @@ class FrontdeskEmailBrandingTest extends TestCase && ! str_contains($html, 'Sent via Ladill'); }); } + + public function test_laravel_mail_uses_organization_branding(): void + { + Storage::fake('public'); + \Illuminate\Support\Facades\Mail::fake(); + + $path = UploadedFile::fake()->image('hq-logo.png', 400, 120) + ->store('frontdesk/organizations/'.$this->organization->id, 'public'); + $this->organization->update(['logo_path' => $path]); + + $logoUrl = OrganizationBranding::emailLogoUrl($this->organization->fresh()); + + $sent = app(\App\Services\Comms\EmailService::class)->send( + 'admin@example.com', + 'Daily summary', + "Visitors checked in: 3\nDeliveries: 1", + $this->organization->name, + null, + $this->organization->fresh(), + ); + + $this->assertTrue($sent); + + \Illuminate\Support\Facades\Mail::assertSent(\App\Mail\ContactMessageMail::class, function (\App\Mail\ContactMessageMail $mail) use ($logoUrl) { + $html = $mail->render(); + + return $mail->logoUrl === $logoUrl + && $mail->companyName === 'Frontdesk HQ' + && str_contains($html, 'Frontdesk HQ') + && str_contains($html, $logoUrl) + && ! str_contains($html, 'Sent via Ladill'); + }); + } }