mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Dynamically apply locale (#3140)
* Minor fixes for OpenAPI docs for clients * Add fields to company transformer * Padding email templates, system level and custom * Minor fixes for email template subject * Working on Email Templates * Clean up User model, remove redundant permissions methods * Implement Locale for API * Implement Locale middleware for client routes
This commit is contained in:
parent
ec5cbe66a0
commit
550cb42722
74
app/Console/Commands/SendTestEmails.php
Normal file
74
app/Console/Commands/SendTestEmails.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendTestEmails extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:send-test-emails';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Sends Test Emails to check templates';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->sendTemplateEmails('plain');
|
||||
$this->sendTemplateEmails('light');
|
||||
$this->sendTemplateEmails('dark');
|
||||
}
|
||||
|
||||
private function sendTemplateEmails($template)
|
||||
{
|
||||
$message = [
|
||||
'title' => 'Invoice XJ-3838',
|
||||
'body' => '<div>"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</div>',
|
||||
'subject' => 'The Test Subject',
|
||||
'footer' => 'Lovely Footer Texts',
|
||||
];
|
||||
|
||||
$user = User::whereEmail('user@example.com')->first();
|
||||
|
||||
if(!$user){
|
||||
$user = factory(\App\Models\User::class)->create([
|
||||
'confirmation_code' => '123',
|
||||
]);
|
||||
}
|
||||
|
||||
$cc_emails = [config('ninja.testvars.test_email')];
|
||||
$bcc_emails = [config('ninja.testvars.test_email')];
|
||||
|
||||
Mail::to(config('ninja.testvars.test_email'))
|
||||
->cc($cc_emails)
|
||||
->bcc($bcc_emails)
|
||||
//->replyTo(also_available_if_needed)
|
||||
->send(new TemplateEmail($message, $template, $user));
|
||||
}
|
||||
}
|
@ -17,7 +17,8 @@ class EmailTemplateDefaults
|
||||
{
|
||||
public static function emailInvoiceSubject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('invoice_subject'));
|
||||
return ctrans('invoice_subject', ['number'=>'$number', 'account'=>'$company']);
|
||||
//return Parsedown::instance()->line(self::transformText('invoice_subject'));
|
||||
}
|
||||
|
||||
public static function emailInvoiceTemplate()
|
||||
@ -27,7 +28,9 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailQuoteSubject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('quote_subject'));
|
||||
return ctrans('quote_subject', ['number'=>'$number', 'account'=>'$company']);
|
||||
|
||||
//return Parsedown::instance()->line(self::transformText('quote_subject'));
|
||||
}
|
||||
|
||||
public static function emailQuoteTemplate()
|
||||
@ -37,7 +40,8 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailPaymentSubject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('payment_subject'));
|
||||
return ctrans('texts.payment_subject');
|
||||
//return Parsedown::instance()->line(self::transformText('payment_subject'));
|
||||
}
|
||||
|
||||
public static function emailPaymentTemplate()
|
||||
@ -47,7 +51,9 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailReminder1Subject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
return ctrans('reminder_subject', ['invoice'=>'$number', 'account'=>'$company']);
|
||||
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminder1Template()
|
||||
@ -57,7 +63,8 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailReminder2Subject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
return ctrans('reminder_subject', ['invoice'=>'$number', 'account'=>'$company']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminder2Template()
|
||||
@ -67,7 +74,8 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailReminder3Subject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
return ctrans('reminder_subject', ['invoice'=>'$number', 'account'=>'$company']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminder3Template()
|
||||
@ -77,7 +85,8 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailReminderEndlessSubject()
|
||||
{
|
||||
return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
return ctrans('reminder_subject', ['invoice'=>'$number', 'account'=>'$company']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminderEndlessTemplate()
|
||||
|
@ -20,10 +20,10 @@ use Illuminate\Support\Facades\Cache;
|
||||
* @param string translation string key
|
||||
* @return string
|
||||
*/
|
||||
function ctrans(string $string) : string
|
||||
function ctrans(string $string, $replace = [], $locale = null) : string
|
||||
{
|
||||
//todo pass through the cached version of the custom strings here else return trans();
|
||||
|
||||
return trans($string);
|
||||
return trans($string, $replace, $locale);
|
||||
|
||||
}
|
@ -72,15 +72,6 @@ class Kernel extends HttpKernel
|
||||
\App\Http\Middleware\StartupCheck::class,
|
||||
\App\Http\Middleware\QueryLogging::class,
|
||||
],
|
||||
'api_db' => [
|
||||
\App\Http\Middleware\SetDb::class,
|
||||
],
|
||||
'web_db' => [
|
||||
\App\Http\Middleware\SetWebDb::class,
|
||||
],
|
||||
'url_db' => [
|
||||
\App\Http\Middleware\UrlSetDb::class,
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
@ -111,5 +102,9 @@ class Kernel extends HttpKernel
|
||||
'password_protected' => \App\Http\Middleware\PasswordProtection::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'portal_enabled' => \App\Http\Middleware\ClientPortalEnabled::class,
|
||||
'url_db' => \App\Http\Middleware\UrlSetDb::class,
|
||||
'web_db' => \App\Http\Middleware\SetWebDb::class,
|
||||
'api_db' => \App\Http\Middleware\SetDb::class,
|
||||
'locale' => \App\Http\Middleware\Locale::class,
|
||||
];
|
||||
}
|
||||
|
36
app/Http/Middleware/Locale.php
Normal file
36
app/Http/Middleware/Locale.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Language;
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class Locale
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
/*LOCALE SET */
|
||||
if ($request->has('lang')) {
|
||||
$locale = $request->input('lang');
|
||||
App::setLocale($locale);
|
||||
} elseif (auth('contact')->user()) {
|
||||
App::setLocale(auth('contact')->user()->client->locale());
|
||||
} elseif (auth()->user()) {
|
||||
App::setLocale(auth()->user()->company()->getLocale());
|
||||
}
|
||||
else
|
||||
App::setLocale(config('ninja.i18n.locale'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -11,13 +11,15 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Language;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request as Input;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Closure;
|
||||
|
||||
|
||||
/**
|
||||
@ -64,10 +66,7 @@ class StartupCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// $end = microtime(true) - $start;
|
||||
// Log::error("middleware cost = {$end} ms");
|
||||
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
return $response;
|
||||
|
49
app/Mail/TemplateEmail.php
Normal file
49
app/Mail/TemplateEmail.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class TemplateEmail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private $template; //the template to use
|
||||
|
||||
private $message; //the message array (subject and body)
|
||||
|
||||
private $user; //the user the email will be sent from
|
||||
|
||||
public function __construct($message, $template, $user)
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
/*Alter Run Time Mailer configuration (driver etc etc) to regenerate the Mailer Singleton*/
|
||||
|
||||
//if using a system level template
|
||||
$template_name = 'email.template.'.$this->template;
|
||||
|
||||
return $this->from($this->user->email, $this->user->present()->name()) //todo this needs to be fixed to handle the hosted version
|
||||
->subject($this->message['subject'])
|
||||
->view($template_name, [
|
||||
'body' => $this->message['body'],
|
||||
'footer' => $this->message['footer'],
|
||||
'title' => $this->message['title'],
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ use App\Models\DatetimeFormat;
|
||||
use App\Models\Filterable;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Models\Language;
|
||||
use App\Models\Timezone;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\CompanyGatewaySettings;
|
||||
@ -174,6 +175,16 @@ class Client extends BaseModel
|
||||
return Timezone::find($this->getSetting('timezone_id'));
|
||||
}
|
||||
|
||||
public function language()
|
||||
{
|
||||
return Language::find($this->getSetting('language_id'));
|
||||
}
|
||||
|
||||
public function locale()
|
||||
{
|
||||
return $this->language()->locale;
|
||||
}
|
||||
|
||||
public function date_format()
|
||||
{
|
||||
$date_formats = Cache::get('date_formats');
|
||||
|
@ -90,7 +90,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
protected $casts = [
|
||||
'settings' => 'object',
|
||||
'permissions' => 'object',
|
||||
'updated_at' => 'timestamp',
|
||||
'created_at' => 'timestamp',
|
||||
'deleted_at' => 'timestamp',
|
||||
@ -197,19 +196,15 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a object of user permissions
|
||||
* Returns a comma separated list of user permissions
|
||||
*
|
||||
* @return stdClass
|
||||
* @return comma separated list
|
||||
*/
|
||||
public function permissions()
|
||||
{
|
||||
|
||||
$permissions = json_decode($this->company_user->permissions);
|
||||
|
||||
if (! $permissions)
|
||||
return [];
|
||||
return $this->company_user->permissions;
|
||||
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -274,18 +269,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a stdClass representation of the User Permissions
|
||||
* into a Collection
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function permissionsFlat() :Collection
|
||||
{
|
||||
|
||||
return collect($this->permissions())->flatten();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if permissions exist in the map
|
||||
@ -296,27 +279,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
public function hasPermission($permission) : bool
|
||||
{
|
||||
|
||||
|
||||
return (stripos($this->company_user->permissions, $permission) !== false);
|
||||
|
||||
|
||||
// return $this->permissionsFlat()->contains($permission);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a array of permission for the mobile application
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function permissionsMap() : array
|
||||
{
|
||||
|
||||
$keys = array_values((array) $this->permissions());
|
||||
$values = array_fill(0, count($keys), true);
|
||||
|
||||
return array_combine($keys, $values);
|
||||
|
||||
}
|
||||
|
||||
public function documents()
|
||||
|
@ -59,6 +59,7 @@ return [
|
||||
'stripe' => env('STRIPE_KEYS',''),
|
||||
'paypal' => env('PAYPAL_KEYS', ''),
|
||||
'travis' => env('TRAVIS', false),
|
||||
'test_email' => env('TEST_EMAIL',''),
|
||||
],
|
||||
'contact' => [
|
||||
'email' => env('MAIL_FROM_ADDRESS'),
|
||||
|
@ -0,0 +1,10 @@
|
||||
@extends('email.template.master')
|
||||
@section('title')
|
||||
{{ $title }}
|
||||
@endsection
|
||||
@section('content')
|
||||
{!! $body !!}
|
||||
@endsection
|
||||
@section('footer')
|
||||
{!! $footer !!}
|
||||
@endsection
|
@ -0,0 +1,10 @@
|
||||
@extends('email.template.master')
|
||||
@section('title')
|
||||
{{ $title }}
|
||||
@endsection
|
||||
@section('content')
|
||||
{!! $body !!}
|
||||
@endsection
|
||||
@section('footer')
|
||||
{!! $footer !!}
|
||||
@endsection
|
339
resources/views/email/template/master.blade.php
Normal file
339
resources/views/email/template/master.blade.php
Normal file
@ -0,0 +1,339 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>@yield('title')</title>
|
||||
<style>
|
||||
/* -------------------------------------
|
||||
GLOBAL RESETS
|
||||
------------------------------------- */
|
||||
|
||||
/*All the styling goes here*/
|
||||
|
||||
img {
|
||||
border: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
max-width: 100%;
|
||||
}
|
||||
body {
|
||||
background-color: #f6f6f6;
|
||||
font-family: sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
table {
|
||||
border-collapse: separate;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
width: 100%; }
|
||||
table td {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
vertical-align: top;
|
||||
}
|
||||
/* -------------------------------------
|
||||
BODY & CONTAINER
|
||||
------------------------------------- */
|
||||
.body {
|
||||
background-color: #f6f6f6;
|
||||
width: 100%;
|
||||
}
|
||||
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
||||
.container {
|
||||
display: block;
|
||||
margin: 0 auto !important;
|
||||
/* makes it centered */
|
||||
max-width: 580px;
|
||||
padding: 10px;
|
||||
width: 580px;
|
||||
}
|
||||
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 580px;
|
||||
padding: 10px;
|
||||
}
|
||||
/* -------------------------------------
|
||||
HEADER, FOOTER, MAIN
|
||||
------------------------------------- */
|
||||
.main {
|
||||
background: #ffffff;
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
}
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
.content-block {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.footer {
|
||||
clear: both;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
.footer td,
|
||||
.footer p,
|
||||
.footer span,
|
||||
.footer a {
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
/* -------------------------------------
|
||||
TYPOGRAPHY
|
||||
------------------------------------- */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
color: #000000;
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 35px;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
p li,
|
||||
ul li,
|
||||
ol li {
|
||||
list-style-position: inside;
|
||||
margin-left: 5px;
|
||||
}
|
||||
a {
|
||||
color: #3498db;
|
||||
text-decoration: underline;
|
||||
}
|
||||
/* -------------------------------------
|
||||
BUTTONS
|
||||
------------------------------------- */
|
||||
.btn {
|
||||
box-sizing: border-box;
|
||||
width: 100%; }
|
||||
.btn > tbody > tr > td {
|
||||
padding-bottom: 15px; }
|
||||
.btn table {
|
||||
width: auto;
|
||||
}
|
||||
.btn table td {
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.btn a {
|
||||
background-color: #ffffff;
|
||||
border: solid 1px #3498db;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
color: #3498db;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 12px 25px;
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.btn-primary table td {
|
||||
background-color: #3498db;
|
||||
}
|
||||
.btn-primary a {
|
||||
background-color: #3498db;
|
||||
border-color: #3498db;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* -------------------------------------
|
||||
OTHER STYLES THAT MIGHT BE USEFUL
|
||||
------------------------------------- */
|
||||
.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.first {
|
||||
margin-top: 0;
|
||||
}
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.mt0 {
|
||||
margin-top: 0;
|
||||
}
|
||||
.mb0 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.preheader {
|
||||
color: transparent;
|
||||
display: none;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
mso-hide: all;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
}
|
||||
.powered-by a {
|
||||
text-decoration: none;
|
||||
}
|
||||
hr {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
margin: 20px 0;
|
||||
}
|
||||
/* -------------------------------------
|
||||
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||
------------------------------------- */
|
||||
@media only screen and (max-width: 620px) {
|
||||
table[class=body] h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
table[class=body] p,
|
||||
table[class=body] ul,
|
||||
table[class=body] ol,
|
||||
table[class=body] td,
|
||||
table[class=body] span,
|
||||
table[class=body] a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
table[class=body] .wrapper,
|
||||
table[class=body] .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
table[class=body] .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
table[class=body] .container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
table[class=body] .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
/* -------------------------------------
|
||||
PRESERVE THESE STYLES IN THE HEAD
|
||||
------------------------------------- */
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
#MessageViewBody a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="">
|
||||
<span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td class="container">
|
||||
<div class="content">
|
||||
|
||||
@yield('content')
|
||||
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td class="content-block">
|
||||
<span class="apple-link">Footerish stuff</span>
|
||||
@yield('footer')
|
||||
<br> Don't like these emails? <a href="#">Unsubscribe</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content-block powered-by">
|
||||
Powered by <a href="#">InvoiceNinja</a>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- END FOOTER -->
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,4 @@
|
||||
{{ $body }}
|
||||
<br>
|
||||
<br>
|
||||
{{ $footer}}
|
@ -32,7 +32,7 @@ Route::group(['api_secret_check','email_db'], function () {
|
||||
|
||||
});
|
||||
|
||||
Route::group(['middleware' => ['api_db','api_secret_check','token_auth'], 'prefix' =>'api/v1', 'as' => 'api.'], function () {
|
||||
Route::group(['middleware' => ['api_db','api_secret_check','token_auth','locale'], 'prefix' =>'api/v1', 'as' => 'api.'], function () {
|
||||
|
||||
Route::resource('activities', 'ActivityController'); // name = (clients. index / create / show / update / destroy / edit
|
||||
|
||||
@ -111,6 +111,4 @@ Route::group(['middleware' => ['api_db','api_secret_check','token_auth'], 'prefi
|
||||
Route::post('support/messages/send', 'Support\Messages\SendingController');
|
||||
});
|
||||
|
||||
Route::get('test_email', '\App\Helpers\Mail\GmailTransportConfig@test');
|
||||
|
||||
Route::fallback('BaseController@notFound');
|
||||
Route::fallback('BaseController@notFound');
|
@ -2,16 +2,16 @@
|
||||
|
||||
Route::get('client', 'Auth\ContactLoginController@showLoginForm')->name('client.login'); //catch all
|
||||
|
||||
Route::get('client/login', 'Auth\ContactLoginController@showLoginForm')->name('client.login');
|
||||
Route::get('client/login', 'Auth\ContactLoginController@showLoginForm')->name('client.login')->middleware('locale');
|
||||
Route::post('client/login', 'Auth\ContactLoginController@login')->name('client.login.submit');
|
||||
|
||||
Route::get('client/password/reset', 'Auth\ContactForgotPasswordController@showLinkRequestForm')->name('client.password.request');
|
||||
Route::post('client/password/email', 'Auth\ContactForgotPasswordController@sendResetLinkEmail')->name('client.password.email');
|
||||
Route::get('client/password/reset/{token}', 'Auth\ContactResetPasswordController@showResetForm')->name('client.password.reset');
|
||||
Route::post('client/password/reset', 'Auth\ContactResetPasswordController@reset')->name('client.password.update');
|
||||
Route::get('client/password/reset', 'Auth\ContactForgotPasswordController@showLinkRequestForm')->name('client.password.request')->middleware('locale');
|
||||
Route::post('client/password/email', 'Auth\ContactForgotPasswordController@sendResetLinkEmail')->name('client.password.email')->middleware('locale');
|
||||
Route::get('client/password/reset/{token}', 'Auth\ContactResetPasswordController@showResetForm')->name('client.password.reset')->middleware('locale');
|
||||
Route::post('client/password/reset', 'Auth\ContactResetPasswordController@reset')->name('client.password.update')->middleware('locale');
|
||||
|
||||
//todo implement domain DB
|
||||
Route::group(['middleware' => ['auth:contact'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||
Route::group(['middleware' => ['auth:contact','locale'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||
|
||||
Route::get('dashboard', 'ClientPortal\DashboardController@index')->name('dashboard'); // name = (dashboard. index / create / show / update / destroy / edit
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user