1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-12 14:12:44 +01:00

Fixes for license

This commit is contained in:
David Bomba 2021-06-16 20:34:30 +10:00
commit 2adb1728ea
46 changed files with 934 additions and 387 deletions

View File

@ -451,7 +451,7 @@ class BillingPortalPurchase extends Component
->first();
$mailer = new NinjaMailerObject();
$mailer->mailable = new ContactPasswordlessLogin($this->email, $this->subscription->company->id, (string)route('client.subscription.purchase', $this->subscription->hashed_id) . '?coupon=' . $this->coupon);
$mailer->mailable = new ContactPasswordlessLogin($this->email, $this->subscription->company, (string)route('client.subscription.purchase', $this->subscription->hashed_id) . '?coupon=' . $this->coupon);
$mailer->company = $this->subscription->company;
$mailer->settings = $this->subscription->company->settings;
$mailer->to_user = $contact;

View File

@ -133,7 +133,7 @@ class CSVImport implements ShouldQueue {
];
$nmo = new NinjaMailerObject;
$nmo->mailable = new ImportCompleted( $data );
$nmo->mailable = new ImportCompleted($this->company, $data);
$nmo->company = $this->company;
$nmo->settings = $this->company->settings;
$nmo->to_user = $this->company->owner();

View File

@ -37,7 +37,7 @@ class NinjaMailer extends Mailable
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject($this->mail_obj->subject)
->markdown($this->mail_obj->markdown, $this->mail_obj->data)
->view($this->mail_obj->markdown, $this->mail_obj->data)
->withSwiftMessage(function ($message) {
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
});

View File

@ -34,11 +34,12 @@ class ClientContactResetPasswordObject
$data = [
'title' => ctrans('texts.your_password_reset_link'),
'message' => ctrans('texts.reset_password'),
'content' => ctrans('texts.reset_password'),
'url' => route('client.password.reset', ['token' => $this->token, 'email' => $this->client_contact->email]),
'button' => ctrans('texts.reset'),
'signature' => $this->company->settings->email_signature,
'settings' => $this->company->settings,
'company' => $this->company,
'logo' => $this->company->present()->logo(),
];
@ -46,9 +47,9 @@ class ClientContactResetPasswordObject
$mail_obj = new \stdClass;
$mail_obj->subject = ctrans('texts.your_password_reset_link');
$mail_obj->data = $data;
$mail_obj->markdown = 'email.admin.generic';
$mail_obj->markdown = 'email.client.generic';
$mail_obj->tag = $this->company->company_key;
return $mail_obj;
}
}
}

View File

@ -21,25 +21,28 @@ use Illuminate\Queue\SerializesModels;
class ContactPasswordlessLogin extends Mailable
{
/**
* @var string
*/
/** @var string */
public $email;
/** @var string */
public $url;
/** @var Company */
public $company;
/**
* Create a new message instance.
*
* @param string $email
* @param string $redirect
*/
public function __construct(string $email, $company_id, string $redirect = '')
public function __construct(string $email, Company $company, string $redirect = '')
{
$this->email = $email;
$this->url = MagicLink::create($email, $company_id, $redirect);
$this->company = $company;
$this->url = MagicLink::create($email, $company->id, $redirect);
}
/**
@ -51,6 +54,10 @@ class ContactPasswordlessLogin extends Mailable
{
return $this
->subject(ctrans('texts.account_passwordless_login'))
->view('email.billing.passwordless-login');
->view('email.billing.passwordless-login', [
'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings,
'company' => $this->company->settings,
]);
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
@ -38,16 +39,13 @@ class DownloadBackup extends Mailable
$company = Company::where('company_key', $this->company->company_key)->first();
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.download_backup_subject', ['company' => $company->present()->name()]))
->markdown(
'email.admin.download_files',
[
'url' => $this->file_path,
'logo' => $company->present()->logo,
'whitelabel' => $company->account->isPaid() ? true : false,
'settings' => $company->settings,
'greeting' => $company->present()->name(),
]
);
->subject(ctrans('texts.download_backup_subject', ['company' => $company->present()->name()]))
->view('email.admin.download_files', [
'url' => $this->file_path,
'logo' => $company->present()->logo,
'whitelabel' => $company->account->isPaid() ? true : false,
'settings' => $company->settings,
'greeting' => $company->present()->name(),
]);
}
}

View File

@ -28,14 +28,13 @@ class DownloadInvoices extends Mailable
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.download_files'))
->markdown(
'email.admin.download_files',
[
'url' => $this->file_path,
'logo' => $this->company->present()->logo,
'whitelabel' => $this->company->account->isPaid() ? true : false,
]
);
->subject(ctrans('texts.download_files'))
->view('email.admin.download_invoices', [
'url' => $this->file_path,
'logo' => $this->company->present()->logo,
'whitelabel' => $this->company->account->isPaid() ? true : false,
'settings' => $this->company->settings,
'greeting' => $this->company->present()->name(),
]);
}
}

View File

@ -39,7 +39,8 @@ class ExistingMigration extends Mailable
$this->logo = $this->company->present()->logo();
$this->company_name = $this->company->present()->name();
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.existing');
return $this
->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.existing');
}
}

View File

@ -12,23 +12,27 @@
namespace App\Mail\Gateways;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Company;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ACHVerificationNotification extends Mailable
{
use Queueable, SerializesModels;
use SerializesModels;
/**
* @var Company
*/
public $company;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct()
public function __construct(Company $company)
{
//
$this->company = $company;
}
/**
@ -38,6 +42,12 @@ class ACHVerificationNotification extends Mailable
*/
public function build()
{
return $this->view('email.gateways.ach-verification-notification');
return $this
->subject(ctrans('texts.ach_verification_notification_label'))
->view('email.gateways.ach-verification-notification', [
'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings,
'company' => $this->company,
]);
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
@ -11,6 +12,7 @@
namespace App\Mail\Import;
use App\Models\Company;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
@ -19,6 +21,9 @@ class ImportCompleted extends Mailable
{
// use Queueable, SerializesModels;
/** @var Company */
public $company;
/**
* Create a new message instance.
*
@ -26,8 +31,10 @@ class ImportCompleted extends Mailable
*/
public $data;
public function __construct($data)
public function __construct(Company $company, $data)
{
$this->company = $company;
$this->data = $data;
}
@ -38,7 +45,14 @@ class ImportCompleted extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.import.completed', $this->data);
$data = array_merge($this->data, [
'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings,
'company' => $this->company,
]);
return $this
->from(config('mail.from.address'), config('mail.from.name'))
->view('email.import.completed', $data);
}
}

View File

@ -2,28 +2,27 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use App\Models\Company;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class MigrationFailed extends Mailable
{
public $exception;
public $content;
public $settings;
public $company;
/**
* Create a new message instance.
*
* @param $content
* @param $exception
*/
public function __construct($exception, $company, $content = null)
public function __construct($exception, Company $company, $content = null)
{
$this->exception = $exception;
$this->content = $content;
$this->settings = $company->settings;
$this->company = $company;
}
@ -34,7 +33,11 @@ class MigrationFailed extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.failed', ['settings' => $this->settings, 'company' => $this->company]);
return $this
->from(config('mail.from.address'), config('mail.from.name'))
->view('email.migration.failed', [
'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings,
]);
}
}

View File

@ -35,7 +35,7 @@ class ClientContactRequestCancellationObject
$data = [
'title' => ctrans('texts.recurring_cancellation_request', ['contact' => $this->client_contact->present()->name()]),
'message' => ctrans('texts.recurring_cancellation_request_body', ['contact' => $this->client_contact->present()->name(), 'client' => $this->client_contact->client->present()->name(), 'invoice' => $this->recurring_invoice->number]),
'content' => ctrans('texts.recurring_cancellation_request_body', ['contact' => $this->client_contact->present()->name(), 'client' => $this->client_contact->client->present()->name(), 'invoice' => $this->recurring_invoice->number]),
'url' => config('ninja.web_url'),
'button' => ctrans('texts.account_login'),
'signature' => $this->company->settings->email_signature,

View File

@ -62,10 +62,11 @@ class SupportMessageSent extends Mailable
return $this->from(config('mail.from.address'), config('mail.from.name'))
->replyTo($user->email, $user->present()->name())
->subject($subject)
->markdown('email.support.message', [
->view('email.support.message', [
'message' => $this->message,
'system_info' => $system_info,
'laravel_log' => $log_lines,
'logo' => $company->present()->logo(),
]);
}
}

View File

@ -49,7 +49,8 @@ class TemplateEmail extends Mailable
public function build()
{
$template_name = 'email.template.'.$this->build_email->getTemplate();
// $template_name = 'email.template.'.$this->build_email->getTemplate();
$template_name = 'email.template.client';
if($this->build_email->getTemplate() == 'custom') {
$this->build_email->setBody(str_replace('$body', $this->build_email->getBody(), $this->client->getSetting('email_style_custom')));
@ -100,6 +101,7 @@ class TemplateEmail extends Mailable
'settings' => $settings,
'company' => $company,
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
'logo' => $this->company->present()->logo(),
])
->withSwiftMessage(function ($message) use($company){
$message->getHeaders()->addTextHeader('Tag', $company->company_key);

View File

@ -1,4 +1,5 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
@ -44,16 +45,15 @@ class UserLoggedIn extends Mailable
*/
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.new_login_detected'))
->view('email.admin.notification')
->with([
'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(),
'title' => ctrans('texts.new_login_detected'),
'body' => ctrans('texts.new_login_description', ['email' =>$this->user->email, 'ip' => $this->ip, 'time' => now()]),
'whitelabel' => $this->company->account->isPaid(),
]);
->subject(ctrans('texts.new_login_detected'))
->view('email.admin.notification')
->with([
'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(),
'title' => ctrans('texts.new_login_detected'),
'body' => ctrans('texts.new_login_description', ['email' => $this->user->email, 'ip' => $this->ip, 'time' => now()]),
'whitelabel' => $this->company->account->isPaid(),
]);
}
}

View File

@ -1,4 +1,5 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
@ -35,10 +36,10 @@ class UserNotificationMailer extends Mailable
public function build()
{
return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject($this->mail_obj->subject)
->markdown($this->mail_obj->markdown, $this->mail_obj->data)
->withSwiftMessage(function ($message) {
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
});
->subject($this->mail_obj->subject)
->view($this->mail_obj->markdown, $this->mail_obj->data)
->withSwiftMessage(function ($message) {
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
});
}
}

View File

@ -67,12 +67,12 @@ class ACH
$client_gateway_token = $this->storePaymentMethod($source, $request->input('method'), $customer);
$mailer = new NinjaMailerObject();
$mailer->mailable = new ACHVerificationNotification();
$mailer->mailable = new ACHVerificationNotification(auth('contact')->user()->client->company);
$mailer->company = auth('contact')->user()->client->company;
$mailer->settings = auth('contact')->user()->client->company->settings;
$mailer->to_user = auth('contact')->user();
NinjaMailerJob::dispatchNow($mailer);
NinjaMailerJob::dispatch($mailer);
return redirect()->route('client.payment_methods.verification', ['payment_method' => $client_gateway_token->hashed_id, 'method' => GatewayType::BANK_TRANSFER]);
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Providers;
use App\Utils\CssInlinerPlugin;
use Illuminate\Mail\MailManager;
use Illuminate\Support\ServiceProvider;
class MailCssInlinerServiceProvider extends ServiceProvider
{
// Thanks to @fedeisas/laravel-mail-css-inliner
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__ . '/../config/css-inliner.php' => base_path('config/css-inliner.php'),
], 'config');
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(CssInlinerPlugin::class, function ($app) {
return new CssInlinerPlugin([]);
});
$this->app->afterResolving('mail.manager', function (MailManager $mailManager) {
$mailManager->getSwiftMailer()->registerPlugin($this->app->make(CssInlinerPlugin::class));
return $mailManager;
});
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace App\Utils;
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
class CssInlinerPlugin implements \Swift_Events_SendListener
{
/**
* @var CssToInlineStyles
*/
protected $converter;
/**
* @var string[]
*/
protected $cssCache;
/**
* @var array
*/
protected $options;
/**
* @param array $options options defined in the configuration file.
*/
public function __construct(array $options)
{
$this->converter = new CssToInlineStyles();
$this->options = $options;
}
/**
* @param \Swift_Events_SendEvent $evt
*/
public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
{
$message = $evt->getMessage();
if ($message->getContentType() === 'text/html'
|| ($message->getContentType() === 'multipart/alternative' && $message->getBody())
|| ($message->getContentType() === 'multipart/mixed' && $message->getBody())
) {
[$body, $cssResources] = $this->messageSieve($message->getBody());
$css = $this->concatCss($cssResources);
$message->setBody($this->converter->convert($body, $css));
}
foreach ($message->getChildren() as $part) {
if (strpos($part->getContentType(), 'text/html') === 0) {
[$body, $cssResources] = $this->messageSieve($part->getBody());
$css = $this->concatCss($cssResources);
$part->setBody($this->converter->convert($body, $css));
}
}
}
/**
* Do nothing
*
* @param \Swift_Events_SendEvent $evt
*/
public function sendPerformed(\Swift_Events_SendEvent $evt)
{
// Do Nothing
}
protected function concatCss(array $cssResources): string
{
$output = '';
foreach ($cssResources as $cssResource) {
$output.= $this->fetchCss($cssResource);
}
return $output;
}
protected function fetchCss(string $filename): string
{
if (isset($this->cssCache[$filename])) {
return $this->cssCache[$filename];
}
$fixedFilename = $filename;
// Fix relative protocols on hrefs. Assume https.
if (substr($filename, 0, 2) === '//') {
$fixedFilename = 'https:' . $filename;
}
$content = file_get_contents($fixedFilename);
if (! $content) {
return '';
}
$this->cssCache[$filename] = $content;
return $content;
}
protected function messageSieve(string $message): array
{
$cssResources = [];
// Initialize with config defaults, if any
if (isset($this->options['css-files'])) {
$cssResources = $this->options['css-files'];
}
$dom = new \DOMDocument();
// set error level
$internalErrors = libxml_use_internal_errors(true);
$dom->loadHTML($message);
// Restore error level
libxml_use_internal_errors($internalErrors);
$link_tags = $dom->getElementsByTagName('link');
/** @var \DOMElement $link */
foreach ($link_tags as $link) {
if ($link->getAttribute('rel') === 'stylesheet') {
array_push($cssResources, $link->getAttribute('href'));
}
}
$link_tags = $dom->getElementsByTagName('link');
for ($i = $link_tags->length; --$i >= 0;) {
$link = $link_tags->item($i);
if ($link->getAttribute('rel') === 'stylesheet') {
$link->parentNode->removeChild($link);
}
}
if (count($cssResources)) {
return [$dom->saveHTML(), $cssResources];
}
return [$message, []];
}
}

View File

@ -194,6 +194,7 @@ class TemplateEngine
$data['title'] = '';
$data['body'] = '$body';
$data['footer'] = '';
$data['logo'] = auth()->user()->company()->present()->logo();
$data = array_merge($data, Helpers::sharedEmailVariables($this->entity_obj->client));
@ -211,11 +212,17 @@ class TemplateEngine
} else {
$wrapper = '';
}
} else {
}
elseif ($email_style == 'plain') {
$wrapper = view($this->getTemplatePath($email_style), $data)->render();
$injection = '';
$wrapper = str_replace('<head>', $injection, $wrapper);
}
else {
$wrapper = view($this->getTemplatePath('client'), $data)->render();
$injection = '';
$wrapper = str_replace('<head>', $injection, $wrapper);
}
$data = [
'subject' => $this->subject,

View File

@ -181,7 +181,7 @@ return [
App\Providers\MultiDBProvider::class,
App\Providers\ClientPortalServiceProvider::class,
App\Providers\NinjaTranslationServiceProvider::class,
App\Providers\MailCssInlinerServiceProvider::class,
],
/*

18
config/css-inliner.php Normal file
View File

@ -0,0 +1,18 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Css Files
|--------------------------------------------------------------------------
|
| Css file of your style for your emails
| The content of these files will be added directly into the inliner
| Use absolute paths, ie. public_path('css/main.css')
|
*/
'css-files' => [],
];

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -4254,6 +4254,16 @@ $LANG = array(
'account_passwordless_login' => 'Account passwordless login',
'user_duplicate_error' => 'Cannot add the same user to the same company',
'user_cross_linked_error' => 'User exists but cannot be crossed linked to multiple accounts',
'ach_verification_notification_label' => 'ACH verification',
'ach_verification_notification' => 'Connecting bank accounts require verification. Stripe will automatically sends two small deposits for this purpose. These deposits take 1-2 business days to appear on the customer\'s online statement.',
'login_link_requested_label' => 'Login link requested',
'login_link_requested' => 'There was a request to login using link. If you did not request this, it\'s safe to ignore it.',
'invoices_backup_subject' => 'Your invoices are ready for download',
'migration_failed_label' => 'Migration failed',
'migration_failed' => 'Looks like something went wrong with the migration for the following company:',
'client_email_company_contact_label' => 'If you have any questions please contact us, we\'re here to help!',
'quote_was_approved_label' => 'Quote was approved',
'quote_was_approved' => 'We would like to inform you that quote was approved.',
'company_import_failure_subject' => 'Error importing :company',
'company_import_failure_body' => 'There was an error importing the company data, the error message was:',
);

View File

@ -1,36 +1,10 @@
@component('email.template.master', ['design' => 'light', 'settings' =>$settings])
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.download_backup_subject') }}</h1>
<p>{{ ctrans('texts.download_timeframe') }}</p>
@slot('header')
@component('email.components.header', ['p' => '', 'logo' => $logo])
@lang('texts.download')
@endcomponent
@endslot
@if(isset($greeting))
<p style="padding-top:20px">{{ $greeting }}</p>
@endif
<p style="padding-top:20px">
@lang('texts.download_timeframe')
</p>
<p style="padding-top:20px">
@component('email.components.button', ['url' => $url])
@lang('texts.download')
@endcomponent
</p>
@slot('signature')
InvoiceNinja (contact@invoiceninja.com)
@endslot
@if(!$whitelabel)
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@endif
@endcomponent
<a target="_blank" class="button" href="{{ $url }}">
{{ ctrans('texts.download') }}
</a>
</div>
@endcomponent

View File

@ -0,0 +1,10 @@
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.invoices_backup_subject') }}</h1>
<p>{{ ctrans('texts.download_timeframe') }}</p>
<a target="_blank" class="button" href="{{ $url }}">
{{ ctrans('texts.download') }}
</a>
</div>
@endcomponent

View File

@ -1,32 +1,33 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@component('email.template.admin', ['design' => 'light', 'settings' => $settings, 'logo' => $logo])
<div class="center">
@isset($greeting)
<p>{{ $greeting }}</p>
@endisset
@slot('header')
@include('email.components.header', ['logo' => $logo])
@endslot
@isset($title)
<h1>{{ $title }}</h1>
@endisset
@if(isset($greeting))
<p>{{ $greeting }}</p>
@endif
@isset($h2)
<h2>{{ $title }}</h2>
@endisset
<h2>{{ $title }}</h2>
<div style="margin-top: 10px; margin-bottom: 30px;">
@isset($content)
{{ $content }}
@endisset
<p>{{ $message }}</p>
@isset($slot)
{{ $slot }}
@endisset
</div>
@if(isset($additional_info))
@isset($additional_info)
<p>{{ $additional_info }}</p>
@endisset
<p> {{ $additional_info }}</p>
@endif
@component('email.components.button', ['url' => $url])
@lang($button)
@endcomponent
@if(isset($whitelabel) && !$whitelabel)
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@endif
@endcomponent
@isset($url)
<a href="{{ $url }}" class="button" target="_blank">{{ ctrans($button) }}</a>
@endisset
</div>
@endcomponent

View File

@ -1,28 +1,15 @@
@component('email.template.master', ['design' => 'light', 'settings' =>$settings])
@component('email.template.admin', ['settings' => $settings, 'logo' => $logo])
<div class="center">
<h1>{{ $title }}</h1>
@slot('header')
@component('email.components.header', ['p' => $title, 'logo' => $logo])
@endcomponent
@endslot
{{ ctrans("texts.{$body}") }}
@slot('greeting')
@lang($body)
@endslot
@if(isset($view_link))
@component('email.components.button', ['url' => $view_link])
{{ $view_text }}
@endcomponent
@endif
@if(isset($signature))
{{ $signature }}
@endif
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@isset($view_link)
<a class="button" href="{{ $view_link}}" target="_blank">{{{ $view_text }}}</a>
@endisset
@isset($signature)
<p>{{ $signature }}</p>
@endisset
</div>
@endcomponent

View File

@ -1,18 +1,6 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@slot('header')
@include('email.components.header', ['logo' => $logo])
@endslot
<h2>{!! $title !!}</h2>
<p>{!! $body !!}</p>
@if(isset($whitelabel) && !$whitelabel)
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@endif
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h2>{!! $title !!}</h2>
<p>{!! $body !!}</p>
</div>
@endcomponent

View File

@ -1,14 +1,9 @@
@component('email.template.master', ['design' => 'light', 'whitelabel' => false, 'company' => $company])
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<p>{{ ctrans('texts.reset_password') }}</p>
@slot('header')
@include('email.components.header', ['logo' => $logo])
@endslot
<p>{{ ctrans('texts.reset_password') }}</p>
<a href="{{ $link }}" target="_blank" class="button">
{{ ctrans('texts.reset') }}
</a>
<a href="{{ $link }}">{{ $link }}</a>
<a href="{{ $link }}" target="_blank" class="button">
{{ ctrans('texts.reset') }}
</a>
</div>
@endcomponent

View File

@ -1,12 +1,9 @@
@component('email.template.master', ['design' => 'light', 'whitelabel' => false])
@component('email.template.admin', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png', 'settings' => $settings])
<div class="center">
<p>{{ ctrans('texts.confirmation_message') }}</p>
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
<p>{{ ctrans('texts.confirmation_message') }}</p>
<a href="{{ url("/user/confirm/{$user->confirmation_code}") }}" target="_blank" class="button">
{{ ctrans('texts.confirm') }}
</a>
<a href="{{ url("/user/confirm/{$user->confirmation_code}") }}" target="_blank" class="button">
{{ ctrans('texts.confirm') }}
</a>
</div>
@endcomponent

View File

@ -1,16 +1,8 @@
@component('email.template.master', ['design' => 'light'])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
@component('email.template.client', ['logo' => $logo, 'settings' => $settings, 'company' => $company])
<div class="center">
<h1>{{ ctrans('texts.login_link_requested_label') }}</h1>
<p>{{ ctrans('texts.login_link_requested') }}</p>
<h2>Login link requested</h2>
<p>Hey, there was a request to log in using link.</p>
<a href="{{ $url }}" target="_blank" class="button">Sign in to Invoice Ninja</a>
<span style="margin-top: 35px; display: block;">Link above is only for you. Don't share it anyone.</span>
<span>If you didn't request this, just ignore it.</span>
<span style="margin-top: 25px; display: block;">If you can't click on the button, copy following link:</span>
<a href="{{ $url }}">{{ $url }}</a>
<a href="{{ $url }}" target="_blank" class="button">Sign in to Invoice Ninja</a>
</div>
@endcomponent

View File

@ -0,0 +1,27 @@
@component('email.template.client', ['design' => 'light', 'settings' => $settings, 'logo' => $logo, 'company' => $company ?? ''])
<div class="center">
@isset($greeting)
<p>{{ $greeting }}</p>
@endisset
@isset($title)
<h1>{{ $title }}</h1>
@endisset
@isset($h2)
<h2>{{ $title }}</h2>
@endisset
<div style="margin-top: 10px; margin-bottom: 30px;">
{{ $content }}
</div>
@isset($additional_info)
<p>{{ $additional_info }}</p>
@endisset
@isset($url)
<a href="{{ $url }}" class="button" target="_blank">{{ ctrans($button) }}</a>
@endisset
</div>
@endcomponent

View File

@ -1,14 +1,6 @@
@component('email.template.master', ['design' => 'light'])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
<p>Hello,</p>
<p>Connecting bank accounts require verification. Stripe will automatically sends two
small deposits for this purpose. These deposits take 1-2 business days to appear on the customer's online
statement.
</p>
<p>Thank you!</p>
@component('email.template.client', ['logo' => $logo, 'settings' => $settings, 'company' => $company])
<div class="center">
<h1>{{ ctrans('texts.ach_verification_notification_label') }}</h1>
<p>{{ ctrans('texts.ach_verification_notification') }}</p>
</div>
@endcomponent

View File

@ -1,106 +1,105 @@
@component('email.template.master', ['design' => 'light', 'settings' => $company->settings])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings, 'company' => $company ?? ''])
<div class="center">
<h1>{{ ctrans('texts.import_complete') }}</h1>
<p>Hello, here is the output of your recent import job.</p>
<h1>Import completed</h1>
<p>Hello, here is the output of your recent import job.</p>
<p><b>If your logo imported correctly it will display below. If it didn't import, you'll need to reupload your logo</b></p>
<p><b>If your logo imported correctly it will display below. If it didn't import, you'll need to reupload your logo</b></p>
<p><img src="{{ $company->present()->logo() }}"></p>
<p><img src="{{ $company->present()->logo() }}"></p>
@if(isset($company) && $company->clients->count() >=1)
<p><b>{{ ctrans('texts.clients') }}:</b> {{ $company->clients->count() }} </p>
@endif
@if(isset($company) && $company->clients->count() >=1)
<p><b>{{ ctrans('texts.clients') }}:</b> {{ $company->clients->count() }} </p>
@endif
@if(isset($company) && count($company->products) >=1)
<p><b>{{ ctrans('texts.products') }}:</b> {{ count($company->products) }} </p>
@endif
@if(isset($company) && count($company->products) >=1)
<p><b>{{ ctrans('texts.products') }}:</b> {{ count($company->products) }} </p>
@endif
@if(isset($company) && count($company->invoices) >=1)
<p><b>{{ ctrans('texts.invoices') }}:</b> {{ count($company->invoices) }} </p>
@endif
@if(isset($company) && count($company->invoices) >=1)
<p><b>{{ ctrans('texts.invoices') }}:</b> {{ count($company->invoices) }} </p>
@endif
@if(isset($company) && count($company->payments) >=1)
<p><b>{{ ctrans('texts.payments') }}:</b> {{ count($company->payments) }} </p>
@endif
@if(isset($company) && count($company->payments) >=1)
<p><b>{{ ctrans('texts.payments') }}:</b> {{ count($company->payments) }} </p>
@endif
@if(isset($company) && count($company->recurring_invoices) >=1)
<p><b>{{ ctrans('texts.recurring_invoices') }}:</b> {{ count($company->recurring_invoices) }} </p>
@endif
@if(isset($company) && count($company->recurring_invoices) >=1)
<p><b>{{ ctrans('texts.recurring_invoices') }}:</b> {{ count($company->recurring_invoices) }} </p>
@endif
@if(isset($company) && count($company->quotes) >=1)
<p><b>{{ ctrans('texts.quotes') }}:</b> {{ count($company->quotes) }} </p>
@endif
@if(isset($company) && count($company->quotes) >=1)
<p><b>{{ ctrans('texts.quotes') }}:</b> {{ count($company->quotes) }} </p>
@endif
@if(isset($company) && count($company->credits) >=1)
<p><b>{{ ctrans('texts.credits') }}:</b> {{ count($company->credits) }} </p>
@endif
@if(isset($company) && count($company->credits) >=1)
<p><b>{{ ctrans('texts.credits') }}:</b> {{ count($company->credits) }} </p>
@endif
@if(isset($company) && count($company->projects) >=1)
<p><b>{{ ctrans('texts.projects') }}:</b> {{ count($company->projects) }} </p>
@endif
@if(isset($company) && count($company->projects) >=1)
<p><b>{{ ctrans('texts.projects') }}:</b> {{ count($company->projects) }} </p>
@endif
@if(isset($company) && count($company->tasks) >=1)
<p><b>{{ ctrans('texts.tasks') }}:</b> {{ count($company->tasks) }} </p>
@endif
@if(isset($company) && count($company->tasks) >=1)
<p><b>{{ ctrans('texts.tasks') }}:</b> {{ count($company->tasks) }} </p>
@endif
@if(isset($company) && count($company->vendors) >=1)
<p><b>{{ ctrans('texts.vendors') }}:</b> {{ count($company->vendors) }} </p>
@endif
@if(isset($company) && count($company->vendors) >=1)
<p><b>{{ ctrans('texts.vendors') }}:</b> {{ count($company->vendors) }} </p>
@endif
@if(isset($company) && count($company->expenses) >=1)
<p><b>{{ ctrans('texts.expenses') }}:</b> {{ count($company->expenses) }} </p>
@endif
@if(isset($company) && count($company->expenses) >=1)
<p><b>{{ ctrans('texts.expenses') }}:</b> {{ count($company->expenses) }} </p>
@endif
@if(isset($company) && count($company->company_gateways) >=1)
<p><b>{{ ctrans('texts.gateways') }}:</b> {{ count($company->company_gateways) }} </p>
@endif
@if(isset($company) && count($company->company_gateways) >=1)
<p><b>{{ ctrans('texts.gateways') }}:</b> {{ count($company->company_gateways) }} </p>
@endif
@if(isset($company) && count($company->client_gateway_tokens) >=1)
<p><b>{{ ctrans('texts.tokens') }}:</b> {{ count($company->client_gateway_tokens) }} </p>
@endif
@if(isset($company) && count($company->client_gateway_tokens) >=1)
<p><b>{{ ctrans('texts.tokens') }}:</b> {{ count($company->client_gateway_tokens) }} </p>
@endif
@if(isset($company) && count($company->tax_rates) >=1)
<p><b>{{ ctrans('texts.tax_rates') }}:</b> {{ count($company->tax_rates) }} </p>
@endif
@if(isset($company) && count($company->tax_rates) >=1)
<p><b>{{ ctrans('texts.tax_rates') }}:</b> {{ count($company->tax_rates) }} </p>
@endif
@if(isset($company) && count($company->documents) >=1)
<p><b>{{ ctrans('texts.documents') }}:</b> {{ count($company->documents) }} </p>
@endif
@if(isset($company) && count($company->documents) >=1)
<p><b>{{ ctrans('texts.documents') }}:</b> {{ count($company->documents) }} </p>
@endif
@if($check_data)
<p><b>Data Quality:</b></p>
<p> {!! $check_data !!} </p>
@endif
@if(isset($check_data))
<p><b>Data Quality:</b></p>
<p> {!! $check_data !!} </p>
@endif
@if(!empty($errors) )
<p>{{ ctrans('texts.errors') }}:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Data</th>
<th>Error</th>
</tr>
</thead>
<tbody>
@foreach($errors as $entityType=>$entityErrors)
@foreach($entityErrors as $error)
<tr>
<td>{{$entityType}}</td>
<td>{{json_encode($error[$entityType]??null)}}</td>
<td>{{json_encode($error['error'])}}</td>
</tr>
@if(!empty($errors) )
<p>{{ ctrans('texts.errors') }}:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Data</th>
<th>Error</th>
</tr>
</thead>
<tbody>
@foreach($errors as $entityType=>$entityErrors)
@foreach($entityErrors as $error)
<tr>
<td>{{$entityType}}</td>
<td>{{json_encode($error[$entityType]??null)}}</td>
<td>{{json_encode($error['error'])}}</td>
</tr>
@endforeach
@endforeach
@endforeach
</tbody>
</table>
@endif
</tbody>
</table>
@endif
<a href="{{ url('/') }}" target="_blank" class="button">{{ ctrans('texts.account_login')}}</a>
<p>{{ ctrans('texts.email_signature')}}<br/> {{ ctrans('texts.email_from') }}</p>
<a href="{{ url('/') }}" target="_blank" class="button">{{ ctrans('texts.account_login')}}</a>
<p>{{ ctrans('texts.email_signature')}}</p>
<p>{{ ctrans('texts.email_from') }}</p>
</div>
@endcomponent

View File

@ -1,13 +1,12 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@component('email.template.admin', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png', 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.migration_completed')}}</h1>
<p>{{ ctrans('texts.migration_completed_description')}}</p>
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
<a href="{{ url('/') }}" target="_blank" class="button">
{{ ctrans('texts.account_login')}}
</a>
<h1>{{ ctrans('texts.migration_completed')}}</h1>
<p>{{ ctrans('texts.migration_completed_description')}}</p>
<a href="{{ url('/') }}" target="_blank" class="button">{{ ctrans('texts.account_login')}}</a>
<p>{{ ctrans('texts.email_signature')}}<br/> {{ ctrans('texts.email_from') }}</p>
<p>{{ ctrans('texts.email_signature')}}<br/> {{ ctrans('texts.email_from') }}</p>
</div>
@endcomponent

View File

@ -1,18 +1,6 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@slot('header')
@include('email.components.header', ['logo' => $logo])
@endslot
<h2>{{ctrans('texts.migration_already_completed')}}</h2>
<p>{{ctrans('texts.migration_already_completed_desc', ['company_name' => $company_name])}}</p>
@if(isset($whitelabel) && !$whitelabel)
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@endif
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.migration_already_completed') }}</h1>
<p>{!! ctrans('texts.migration_already_completed_desc', ['company_name' => $company_name]) !!}</p>
</div>
@endcomponent

View File

@ -1,17 +1,15 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.migration_failed_label') }}</h1>
<p>{{ ctrans('texts.migration_failed') }} {{ $company->present()->name() }}</p>
<h1>Whoops, migration failed for {{ $company->present()->name() }}.</h1>
<p>Looks like your migration failed. Here's the error message:</p>
<pre>
@if(\App\Utils\Ninja::isSelfHost())
{!! $exception->getMessage() !!}
{!! $content !!}
@else
<p>Please contact us at contact@invoiceninja.com for more information on this error.</p>
@endif
</pre>
<pre>
@if(\App\Utils\Ninja::isSelfHost())
{!! $exception->getMessage() !!}
{!! $content !!}
@else
<p>Please contact us at contact@invoiceninja.com for more information on this error.</p>
@endif
</pre>
</div>
@endcomponent

View File

@ -1,18 +1,6 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@slot('header')
@include('email.components.header', ['logo' => $logo])
@endslot
<h2>{{ctrans('texts.max_companies')}}</h2>
<p>{{ctrans('texts.max_companies_desc')}}</p>
@if(isset($whitelabel) && !$whitelabel)
@slot('footer')
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '&copy; InvoiceNinja'])
For any info, please visit InvoiceNinja.
@endcomponent
@endslot
@endif
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.max_companies') }}</h1>
<p>{{ ctrans('texts.max_companies_desc') }}</p>
</div>
@endcomponent

View File

@ -1,10 +1,6 @@
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
<h1>Quote approved!</h1>
<p>We want to inform you that quote was approved.</p>
<a href="https://invoiceninja.com" target="_blank" class="button">Visit Invoice Ninja</a>
@component('email.template.admin', ['settings' => $settings])
<div class="center">
<h1>{{ ctrans('texts.quote_was_approved') }}</h1>
<p>{{ ctrans('texts.quote_was_approved') }}</p>
</div>
@endcomponent

View File

@ -1,7 +1,3 @@
@component('email.template.master', ['design' => 'light'])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
{{ $message }}
@component('email.template.admin', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
{!! $message !!}
@endcomponent

View File

@ -1,8 +1,4 @@
@component('email.template.master', ['design' => 'light'])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@endslot
@component('email.template.admin', ['logo' => $logo ?? 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
{{-- Body --}}
{{ $message }}

View File

@ -0,0 +1,195 @@
@php
$primary_color = isset($settings) ? $settings->primary_color : '#4caf50';
@endphp
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
<style>
@import url("https://use.typekit.net/zxn7pho.css");
</style>
<style type="text/css">
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
@if(isset($settings) && $settings->email_style === 'dark')
body,
[data-ogsc] {
background-color: #1a1a1a !important;
color: #ffffff !important;
}
div, tr, td,
[data-ogsc] div,
[data-ogsc] tr,
[data-ogsc] td {
border-color: #222222 !important;
}
h1, h2, h3, p, td,
[data-ogsc] h1, [data-ogsc] h2, [data-ogsc] h3, [data-ogsc] p, [data-ogsc] td, {
color: #ffffff !important;
}
p,
[data-ogsc] p {
color: #bbbbbc !important;
}
.dark-bg-base,
[data-ogsc] .dark-bg-base {
background-color: #222222 !important;
}
.dark-bg,
[data-ogsc] .dark-bg {
background-color: #3a3a3c !important;
}
.logo-dark,
[data-ogsc] .logo-dark {
display: block !important;
}
.logo-light,
[data-ogsc] .logo-light {
display: none !important;
}
.btn-white,
[data-ogsc] .btn-white {
background-color: #fefefe !important;
}
@endif
/** Content-specific styles. **/
#content .button {
display: inline-block;
background-color: {{ $primary_color }};
color: #ffffff;
text-transform: uppercase;
letter-spacing: 2px;
text-decoration: none;
font-size: 13px;
padding: 15px 70px;
font-weight: 600;
margin-bottom: 30px;
}
#content h1 {
font-family: 'canada-type-gibson', 'roboto', Arial, Helvetica, sans-serif;
font-weight: 600;
font-size: 32px;
margin-top: 5px;
margin-bottom: 30px;
}
#content > p {
font-size: 16px;
color: red;
}
#content .center {
text-align: center;
}
</style>
</head>
<body class="body"
style="margin: 0; padding: 0; font-family: 'roboto', Arial, Helvetica, sans-serif; color: #3b3b3b;-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td>
<table align="center" border="0" cellpadding="0" cellspacing="0" width="570"
style="border-collapse: collapse;">
<tr>
<div style="text-align: center;margin-top: 25px; margin-bottom: 10px;">
<!-- Top side spacing. -->
</div>
</tr>
<tr>
<td>
<div class="dark-bg"
style="background-color:#f9f9f9; border: 1px solid #c2c2c2; border-bottom: none; padding-bottom: 20px; border-top-left-radius: 3px; border-top-right-radius: 3px;">
<img class="logo-light"
style="margin-top: 20px; max-width: 155px; display: block; margin-left: auto; margin-right: auto; "
src="{{ $logo ?? '' }}"/>
<img class="logo-dark"
style="display: none; margin-top: 20px; max-width: 155px; margin-left: auto; margin-right: auto; "
src="{{ $logo ?? '' }}"/>
</div>
</td>
</tr>
<tr>
<td>
<div class="dark-bg-base" id="content"
style="border: 1px solid #c2c2c2; border-top: none; border-bottom: none; padding: 20px;">
{{ $slot }}
</div> <!-- End replaceable content. -->
</td>
</tr>
<tr class="dark-bg"
style="background-color: {{ $primary_color }}; border: 1px solid #c2c2c2; border-top: none; border-bottom-color: {{ $primary_color }};">
<td>
<div style="text-align: center; margin-top: 25px;">
<h2
style="color: #ffffff; font-family: 'canada-type-gibson', 'roboto', Arial, Helvetica, sans-serif; font-weight: 500; font-size: 26px;">
Questions? We're here to help!</h2>
</div>
<div style="text-align:center; margin-bottom: 35px; margin-top: 25px;">
<a href="https://forum.invoiceninja.com" target="_blank" class="btn-white"
style="vertical-align: middle;display: inline-block;background-color: #ffffff; color: {{ $primary_color }}; display: inline-block; text-decoration: none; width: 100px; text-align: center; font-size: 12px; height: 35px; line-height: 35px; margin-left: 10px; margin-right: 10px;">
<img style="width: 13px; margin-right: 4px; display: inline-block; vertical-align:middle;" src="{{ asset('images/emails/forum.png') }}">
<span>Forums</span>
</a>
<a href="http://slack.invoiceninja.com/" target="_blank" class="btn-white"
style="vertical-align: middle;display: inline-block;background-color: #ffffff; color: {{ $primary_color }}; display: inline-block; text-decoration: none; width: 100px; text-align: center; font-size: 12px; height: 35px; line-height: 35px; margin-left: 10px; margin-right: 10px;">
<img style="width: 13px; margin-right: 4px; display: inline-block; vertical-align:middle;" src="{{ asset('images/emails/slack.png') }}">
<span>Slack</span>
</a>
<a href="https://www.invoiceninja.com/contact/" target="_blank" class="btn-white"
style="vertical-align: middle;display: inline-block;background-color: #ffffff; color: {{ $primary_color }}; display: inline-block; text-decoration: none; width: 100px; text-align: center; font-size: 12px; height: 35px; line-height: 35px; margin-left: 10px; margin-right: 10px;">
<img style="width: 13px; margin-right: 4px; display: inline-block; vertical-align:middle;" src="{{ asset('images/emails/email.png') }}">
<span>E-mail</span>
</a>
<a href="https://invoiceninja.github.io/" target="_blank" class="btn-white"
style="vertical-align: middle;display: inline-block;background-color: #ffffff; color: {{ $primary_color }}; display: inline-block; text-decoration: none; width: 100px; text-align: center; font-size: 12px; height: 35px; line-height: 35px; margin-left: 10px; margin-right: 10px;">
<span>Support Docs</span>
</a>
</div>
</td>
</tr>
<tr>
<td class="dark-bg-base"
style="background-color: #242424; border: 1px solid #c2c2c2; border-top-color: #242424; border-bottom-color: #242424;">
<div style="padding-top: 10px;padding-bottom: 10px;">
<p style="text-align: center; color: #ffffff; font-size: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;"{{ date('Y') }} Invoice Ninja, All Rights Reserved
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,176 @@
@php
$primary_color = isset($settings) ? $settings->primary_color : '#4caf50';
@endphp
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
<style>
@import url("https://use.typekit.net/zxn7pho.css");
</style>
<style type="text/css">
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
@if(isset($settings) && $settings->email_style === 'dark')
body {
background-color: #1a1a1a !important;
color: #ffffff !important;
}
div, tr, td {
border-color: #222222 !important;
}
h1, h2, h3, p, td {
color: #ffffff !important;
}
p {
color: #bbbbbc !important;
}
.dark-bg-base {
background-color: #222222 !important;
}
.dark-bg {
background-color: #3a3a3c !important;
}
.dark-text-white p {
color: #ffffff !important;
}
hr {
border-color: #474849 !important;
}
@endif
/** Content-specific styles. **/
#content .button {
display: inline-block;
background-color: {{ $primary_color }};
color: #ffffff;
text-transform: uppercase;
letter-spacing: 2px;
text-decoration: none;
font-size: 13px;
padding: 15px 50px;
font-weight: 600;
margin-bottom: 30px;
}
#content h1 {
font-family: 'canada-type-gibson', 'roboto', Arial, Helvetica, sans-serif;
font-weight: 600;
font-size: 32px;
margin-top: 20px;
margin-bottom: 30px;
}
#content > p {
font-size: 16px;
font-family: 'roboto', Arial, Helvetica, sans-serif;
font-weight: 500;
}
#content .center {
text-align: center;
}
</style>
</head>
<body
style="margin: 0; padding: 0; font-family: 'roboto', Arial, Helvetica, sans-serif; color: #3b3b3b;-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td>
<table align="center" border="0" cellpadding="0" cellspacing="0" width="570"
style="border-collapse: collapse;" class="dark-bg-base">
<tr>
<div style="text-align: center;margin-top: 25px; margin-bottom: 10px;"></div>
</tr>
<tr>
<td>
<div
style="border: 1px solid #c2c2c2; border-bottom: none; padding-bottom: 10px; border-top-left-radius: 3px; border-top-right-radius: 3px;">
<img
style="margin-top: 40px; height: 40px; display: block; margin-left: auto; margin-right: auto;"
src="{{ $logo ?? '' }}"/>
</div>
</td>
</tr>
<tr>
<td>
<div style="border: 1px solid #c2c2c2; border-top: none; border-bottom: none; padding: 20px;" id="content">
<div style="padding-top: 10px;"></div>
{{ $slot ?? '' }}
{!! $body ?? '' !!}
<div>
<a href="#"
style="display: inline-block;background-color: {{ $primary_color }}; color: #ffffff; text-transform: uppercase;letter-spacing: 2px; text-decoration: none; font-size: 13px; font-weight: 600;">
</a>
</div>
</div>
</td>
</tr>
@if(isset($company) && $company instanceof \App\Models\Company)
<tr>
<td>
<div class="dark-bg dark-text-white"
style="text-align: center; padding-top: 10px; padding-bottom: 25px; background-color: #f9f9f9; border: 1px solid #c2c2c2; border-top: none; border-bottom-color: #f9f9f9;">
<p style="font-size: 15px; color: #2e2e2e; font-family: 'roboto', Arial, Helvetica, sans-serif; font-weight: 400; margin-bottom: 30px;">
{{ ctrans('texts.client_email_company_contact_label') }}
</p>
<p style="font-size: 15px; color: #2e2e2e; font-family: 'roboto', Arial, Helvetica, sans-serif; font-weight: 500; margin-bottom:0;">
{{ $company->present()->name() }}</p>
<p style="font-size: 15px; color: #2e2e2e; font-family: 'roboto', Arial, Helvetica, sans-serif; font-weight: 400; margin-top: 5px;">
<span>{{ $company->settings->phone }}</span>
<span style="font-weight: 500"> {{ $company->settings->website }}</span>
</p>
</div>
</td>
</tr>
@endif
<tr>
<td>
<div class="dark-bg-base"
style="padding-top: 10px;padding-bottom: 10px; background-color: #242424; border: 1px solid #c2c2c2; border-top-color: #242424; border-bottom-color: #242424;">
@if(isset($company) && !$company->account->isPaid())
<p style="text-align: center; color: #ffffff; font-size: 10px;
font-family: Verdana, Geneva, Tahoma, sans-serif;"{{ date('Y') }} Invoice Ninja, All
Rights Reserved
</p>
@else
<p style="text-align: center; color: #ffffff; font-size: 10px; font-family: Verdana, Geneva, Tahoma, sans-serif;">
© {{ date('Y') }} Invoice Ninja, All Rights Reserved
</p>
@endif
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>