feat(api): organisation email branding and shared mail layout
- Add email branding columns to organisations table (logo, color, reply-to, sender name, footer)
- Create MailBrandingService for resolving per-org branding with defaults
- Create CrewliMailable abstract base class with branded from/reply-to
- Create shared Blade layout (mail.layouts.crewli) with inline CSS
- Refactor Registration*Mail and InvitationMail to extend CrewliMailable
- Add config/crewli.php for platform-wide defaults (portal_url, app_url, logo)
- Add dev-only /mail-preview/{type} route for browser email previewing
- Update Organisation model, resource, and form requests with branding fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
70
api/resources/views/mail/layouts/crewli.blade.php
Normal file
70
api/resources/views/mail/layouts/crewli.blade.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title')</title>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; background-color: #f4f4f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color: #f4f4f5;">
|
||||
<tr>
|
||||
<td align="center" style="padding: 32px 16px;">
|
||||
<table role="presentation" width="600" cellpadding="0" cellspacing="0" style="max-width: 600px; width: 100%; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.08);">
|
||||
{{-- Accent line --}}
|
||||
<tr>
|
||||
<td style="height: 4px; background-color: {{ $branding['primary_color'] }};"></td>
|
||||
</tr>
|
||||
|
||||
{{-- Header: logo + org name --}}
|
||||
<tr>
|
||||
<td align="center" style="padding: 32px 40px 24px;">
|
||||
@if($branding['logo_url'])
|
||||
<img src="{{ $branding['logo_url'] }}" alt="{{ $branding['organisation_name'] }}" style="max-height: 60px; max-width: 200px; display: block; margin-bottom: 12px;">
|
||||
@endif
|
||||
<p style="margin: 0; font-size: 15px; color: #6b7280; font-weight: 500;">{{ $branding['organisation_name'] }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{{-- Body --}}
|
||||
<tr>
|
||||
<td style="padding: 0 40px 32px;">
|
||||
{{-- Title --}}
|
||||
<h1 style="margin: 0 0 20px; font-size: 22px; font-weight: 700; color: #1f2937; line-height: 1.3;">
|
||||
@yield('title')
|
||||
</h1>
|
||||
|
||||
{{-- Content --}}
|
||||
<div style="font-size: 16px; color: #1f2937; line-height: 1.6;">
|
||||
@yield('content')
|
||||
</div>
|
||||
|
||||
{{-- Action button --}}
|
||||
@hasSection('action')
|
||||
<div style="margin-top: 28px;">
|
||||
@yield('action')
|
||||
</div>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{{-- Footer --}}
|
||||
<tr>
|
||||
<td style="padding: 24px 40px; border-top: 1px solid #e5e7eb;">
|
||||
@if($branding['footer_text'])
|
||||
<p style="margin: 0 0 16px; font-size: 13px; color: #6b7280; text-align: center; line-height: 1.5;">
|
||||
{{ $branding['footer_text'] }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<p style="margin: 0; font-size: 11px; color: #9ca3af; text-align: center; line-height: 1.5;">
|
||||
Powered by Crewli<br>
|
||||
Je ontvangt deze email omdat je bent aangemeld bij {{ $branding['organisation_name'] }}.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user