Add account company logo for customer event emails.
Deploy Ladill Events / deploy (push) Successful in 1m39s

Upload logo in account settings and prefer it over Ladill product marks in event notification headers.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-12 20:07:55 +00:00
co-authored by Cursor
parent 407f1364fb
commit b5debd79c4
15 changed files with 377 additions and 36 deletions
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Qr;
use App\Http\Controllers\Controller;
use App\Models\QrSetting;
use App\Services\Billing\BillingClient;
use App\Support\AccountBranding;
use App\Support\Qr\QrCornerStyleCatalog;
use App\Support\Qr\QrFrameStyleCatalog;
use App\Support\Qr\QrModuleStyleCatalog;
@@ -112,11 +113,25 @@ class AccountController extends Controller
'default_style.gradient_color1' => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
'default_style.gradient_color2' => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
'default_style.gradient_rotation' => ['nullable', 'integer', 'min:0', 'max:360'],
'logo' => ['nullable', 'image', 'mimes:jpeg,png,jpg,webp,svg', 'max:2048'],
'remove_logo' => ['nullable', 'boolean'],
]);
$eventDefaults = $data['event_defaults'] ?? [];
$eventDefaults['registration_open'] = $request->boolean('event_defaults.registration_open');
$settings = $account->getOrCreateQrSetting();
$logoPath = $settings->logo_path;
if ($request->boolean('remove_logo')) {
AccountBranding::deleteStoredLogo($settings);
$logoPath = null;
}
if ($request->hasFile('logo')) {
$logoPath = AccountBranding::storeLogo($settings, $request->file('logo'));
}
QrSetting::updateOrCreate(
['user_id' => $account->id],
[
@@ -127,6 +142,7 @@ class AccountController extends Controller
'notify_payouts' => $request->boolean('notify_payouts'),
'event_defaults' => QrSetting::sanitizeEventDefaults($eventDefaults),
'default_style' => QrSetting::sanitizeDefaultStyle($data['default_style'] ?? null),
'logo_path' => $logoPath,
],
);
+1
View File
@@ -20,6 +20,7 @@ class QrSetting extends Model
'default_type',
'default_style',
'event_defaults',
'logo_path',
];
protected $casts = [
@@ -2,6 +2,7 @@
namespace App\Services\Events;
use App\Support\AccountBranding;
use Illuminate\Support\Facades\View;
class EventEmailService
@@ -129,6 +130,10 @@ class EventEmailService
?string $replyToEmail = null,
?string $replyToName = null,
): bool {
$brandingSettings = AccountBranding::forOwnerRef($ownerPublicId);
$viewData['logoUrl'] = AccountBranding::emailLogoUrl($brandingSettings);
$viewData['companyName'] = AccountBranding::companyName($brandingSettings);
$html = View::make($view, $viewData)->render();
$text = strip_tags(str_replace(['<br>', '<br/>', '<br />'], "\n", $html));
+90
View File
@@ -0,0 +1,90 @@
<?php
namespace App\Support;
use App\Models\QrSetting;
use App\Models\User;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
class AccountBranding
{
public static function forUser(User $user): QrSetting
{
return $user->getOrCreateQrSetting();
}
public static function forOwnerRef(string $ownerPublicId): ?QrSetting
{
$user = User::query()->where('public_id', $ownerPublicId)->first();
return $user ? $user->getOrCreateQrSetting() : null;
}
public static function companyName(?QrSetting $settings, ?User $user = null): string
{
if ($user) {
return (string) ($user->name ?: 'Company');
}
if ($settings?->user) {
return (string) ($settings->user->name ?: 'Company');
}
if ($settings?->user_id) {
$owner = User::query()->find($settings->user_id);
return (string) ($owner?->name ?: 'Company');
}
return 'Company';
}
public static function hasCustomLogo(?QrSetting $settings): bool
{
return $settings !== null
&& $settings->logo_path !== null
&& Storage::disk('public')->exists($settings->logo_path);
}
public static function emailLogoUrl(?QrSetting $settings): ?string
{
if (! self::hasCustomLogo($settings)) {
return null;
}
$ext = strtolower(pathinfo((string) $settings->logo_path, PATHINFO_EXTENSION));
if ($ext === 'svg') {
return null;
}
$version = $settings->updated_at?->getTimestamp() ?? time();
return Storage::disk('public')->url($settings->logo_path).'?v='.$version;
}
public static function logoUrl(?QrSetting $settings): ?string
{
if (! self::hasCustomLogo($settings)) {
return null;
}
$version = $settings->updated_at?->getTimestamp() ?? time();
return Storage::disk('public')->url($settings->logo_path).'?v='.$version;
}
public static function storeLogo(QrSetting $settings, UploadedFile $file): string
{
self::deleteStoredLogo($settings);
return $file->store('events/accounts/'.$settings->user_id, 'public');
}
public static function deleteStoredLogo(QrSetting $settings): void
{
if ($settings->logo_path) {
Storage::disk('public')->delete($settings->logo_path);
}
}
}