1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-21 08:51:34 +02:00

Remove old designs & old bootstrap theme

This commit is contained in:
Benjamin Beganović 2020-10-27 14:44:12 +01:00
parent 0453c989eb
commit 99bfadc0dc
41 changed files with 0 additions and 4326 deletions

View File

@ -1,27 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
abstract class AbstractDesign
{
abstract public function includes();
abstract public function header();
abstract public function body();
abstract public function product();
abstract public function task();
abstract public function footer();
}

View File

@ -1,141 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Bold extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page: not(:first-of-type) { size: auto; margin-top: 5mm; }
.table_header_thead_class {text-align:left;}
.table_header_td_class {padding-left:3rem; padding-right:3rem; font-size:1rem; padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem}
.table_body_td_class {background-color:#edf2f7; adding-top:1.25rem;padding-bottom:1.25rem; padding-left:3rem;}
$custom_css
</style>';
}
public function header()
{
return '<div class="bg-gray-800 p-12">
<div class="grid grid-cols-6 gap-1">
<div class="col-span-2 p-3">
<div class="p-1 rounded-lg">
$company_logo
</div>
</div>
<div class="col-span-2 p-3 text-white flex flex-col flex-wrap">
$company_details
</div>
<div class="col-span-2 p-3 text-white flex flex-col flex-wrap">
$company_address
</div>
</div>
</div>';
}
public function body()
{
return '<div class="bg-white mt-16 pl-10">
<div class="grid grid-cols-12 gap-2">
<div class="col-span-7">
<h2 class="text-2xl uppercase font-semibold text-teal-600 tracking-tight">$entity_label</h2>
<div class="flex flex-col flex-wrap">$client_details</div>
</div>
<div class="col-span-5">
<div class="bg-teal-600 px-5 py-3 text-white">
<div class="w-80 flex flex-col text-white flex-wrap">
$entity_details
</div>
</div>
</div>
</div>
</div>
<div class="mx-10 mt-8">
<table class="w-full table-auto mt-8">
<thead class="text-left">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-8">
<thead class="text-left">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
</div>
<div class="flex px-4 mt-6 w-full px-12">
<div class="w-1/2">
$entity.public_notes
</div>
<div class="w-1/2 flex">
<div class="w-1/2 text-right flex flex-col">
$subtotal_label $discount_label $total_tax_labels $line_tax_labels
</div>
<div class="w-1/2 text-right flex flex-col">
$subtotal $discount $total_tax_values $line_tax_values
</div>
</div>
</div>
<div class="flex px-4 mt-4 w-full items-end px-12">
<div class="w-1/2 flex flex-col flex-wrap">
<p class="font-semibold">$terms_label</p>
$terms
</div>
<div class="w-1/2 flex">
<div class="w-1/2 text-right flex flex-col flex-wrap">
<span class="text-xl font-semibold">$balance_due_label</span>
</div>
<div class="w-1/2 text-right flex flex-col flex-wrap">
<span class="text-xl text-teal-600 font-semibold">$balance_due</span>
</div>
</div>
</div>
';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,149 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Business extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body { font-size:90% }
@page
{
size: auto;
margin-top: 5mm;
}
thead th:first-child {
border-top-left-radius: 0.5rem;
}
thead th:last-child {
border-top-right-radius: 0.5rem;
}
.table_header_thead_class { border-top-left-radius: .5rem; text-align: left }
.table_header_td_class { color: white; padding: .5rem 1rem; font-weight: 800; background-color: #2a4365; }
.table_body_td_class { color: #c05621; padding: 1rem; border-width: 4px; border-color: white; background-color: white; }
$custom_css
</style>';
}
public function header()
{
return '<div class="m-10">
<div class="grid grid-cols-6 gap-1">
<div class="col-span-2 p-3">
$company_logo
</div>
<div class="flex flex-col flex-wrap col-span-2 p-3">
$company_details
</div>
<div class="flex flex-col flex-wrap col-span-2 p-3">
$company_address
</div>
</div>';
}
public function body()
{
return '<div class="grid grid-cols-12 gap-1 mt-8">
<div class="flex flex-col flex-wrap col-span-7 p-3">
$client_details
</div>
<div class="flex flex-col h-auto col-span-5 p-3 px-4 py-4 bg-orange-600 rounded-lg">
<div class="flex flex-col flex-wrap text-white">
$entity_details
</div>
</div>
</div>
<table class="w-full mt-20 table-auto">
<thead class="text-left">
$product_table_header
</thead>
<tbody class="whitespace-pre-line bg-gray-200">
$product_table_body
</tbody>
</table>
<table class="w-full mt-20 table-auto">
<thead class="text-left">
$task_table_header
</thead>
<tbody class="whitespace-pre-line bg-gray-200">
$task_table_body
</tbody>
</table>
<div class="flex items-center justify-between px-4 py-2 pb-4 bg-gray-200 rounded">
<div class="w-1/2">
<div class="flex flex-col">
<p>$entity.public_notes</p>
</div>
</div>
<div class="flex flex-col w-1/3">
<div class="flex px-3 mt-2">
<section class="flex flex-col w-1/2 text-right">
$discount_label
$total_tax_labels
$line_tax_labels
</section>
<section class="flex flex-col w-1/2 text-right">
$discount
$total_tax_values
$line_tax_values
</section>
</div>
</div>
</div>
<div class="flex items-center justify-between px-4 pb-4 mt-4">
<div class="w-1/2">
<div class="flex flex-col">
<p class="font-semibold">$terms_label</p>
<p>$terms</p>
</div>
</div>
<div class="flex flex-col w-2/5">
<section class="flex px-4 py-2 py-3 text-white bg-blue-900 rounded">
<p class="w-1/2">$balance_due_label</p>
<p class="w-1/2 text-right">$balance_due</p>
</section>
</div>
</div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="flex justify-between px-12 py-8 div_footer" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,150 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Clean extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page
{
size: auto;
margin-top: 5mm;
}
.table_header_thead_class { text-align: left; }
.table_header_td_class { padding: .5rem 1rem;}
.table_body_td_class { border-bottom-width: 1px; border-top-width: 1px; border-color: #cbd5e0; padding: 1rem;}
$custom_css
</style>';
}
public function header()
{
return '<div class="px-12 my-10">
<div class="flex items-center">
<div class="w-1/3">
<div class="h-14 w-14">$company_logo</div>
</div>
<div class="w-auto flex">
<div class="mr-10 text-gray-600 flex flex-col flex-wrap">
$company_details
</div>
<div class="ml-5 text-gray-600 flex flex-col flex-wrap">
$company_address
</div>
</div>
</div>';
}
public function body()
{
return '<h1 class="mt-12 uppercase text-2xl text-blue-500 ml-4">
$entity_label
</h1>
<div class="border-b border-gray-400"></div>
<div class="ml-4 py-4">
<div class="flex">
<div class="w-40 flex flex-col flex-wrap">
$entity_labels
</div>
<div class="w-48 flex flex-col flex-wrap">
$entity_details
</div>
<div class="w-56 flex flex-col flex-wrap">
$client_details
</div>
</div>
</div>
<div class="border-b border-gray-400"></div>
<table class="w-full table-auto mt-8">
<thead class="text-left">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-8">
<thead class="text-left">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="flex px-4 mt-6 w-full">
<div class="w-1/2">
$entity.public_notes
</div>
<div class="w-1/2 flex">
<div class="w-1/2 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</div>
<div class="w-1/2 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</div>
</div>
</div>
<div class="flex px-4 mt-4 w-full items-end">
<div class="w-1/2">
<p class="font-semibold">$terms_label</p>
$terms
</div>
<div class="w-1/2 flex">
<div class="w-1/2 text-right flex flex-col">
<span>$balance_due_label</span>
</div>
<div class="w-1/2 text-right flex flex-col">
<span class="text-blue-600">$balance_due</span>
</div>
</div>
</div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,128 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
/**
* @wip: Table margins act weird.
*/
class Creative extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page
{
size: auto;
margin-top: 6mm;
}
.table_header_thead_class { text-align: left; border-radius: .5rem; }
.table_header_td_class { text-transform: uppercase; font-size: 1.25rem; color: #b83280; font-weight: 500 }
.table_body_td_class { padding: 1rem;}
$custom_css
</style>';
}
public function header()
{
return '<div class="m-12">
<div class="grid grid-cols-12 gap-4">
<div class="col-span-3 flex flex-col flex-wrap break-all">$client_details</div>
<div class="col-span-3 flex flex-col flex-wrap break-all">$company_details</div>
<div class="col-span-3 flex flex-col flex-wrap break-all">$company_address</div>
<div class="col-span-3 flex flex-wrap">$company_logo</div>
</div>';
}
public function body()
{
return '<div class="grid grid-cols-12 mt-8">
<div class="col-span-7">
<p class="text-4xl text-pink-700">#$entity_number</p>
</div>
<div class="col-span-5 flex flex-col flex-wrap">$entity_details</div>
</div>
<table class="w-full table-auto border-t-4 border-pink-700 bg-white mt-8">
<thead class="text-left rounded-lg">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto border-t-4 border-pink-700 bg-white">
<thead class="text-left rounded-lg">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="border-b-4 border-pink-700 mt-8">
<div class="grid grid-cols-12 mt-2 px-4 pb-4">
<div class="col-span-7 flex flex-col">
<p>$entity.public_notes</p>
</div>
<div class="col-span-5 flex px-3 mt-2">
<div class="w-1/2 text-right flex flex-col">
$subtotal_label $discount_label $total_tax_labels $line_tax_labels
</div>
<div class="w-1/2 text-right flex flex-col">
$subtotal $discount $total_tax_values $line_tax_values
</div>
</div>
</div>
<div class="flex items-center justify-between mt-4 pb-4 px-4">
<div class="w-1/2">
<div class="flex flex-col">
<p class="font-semibold">$terms_label</p>
<p>N21</p>
</div>
</div>
</div>
</div>
<div class="w-full flex justify-end mt-4">
<p>$balance_due_label</p>
<p class="ml-8 text-pink-700 font-semibold">$balance</p>
</div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,46 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Custom
{
public $includes;
public $header;
public $body;
public $product;
public $task;
public $footer;
public $name;
public function __construct($design)
{
$this->name = $design->name;
$this->includes = $design->design->includes;
$this->header = $design->design->header;
$this->body = $design->design->body;
$this->product = $design->design->product;
$this->task = $design->design->task;
$this->footer = $design->design->footer;
}
}

View File

@ -1,396 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
use App\Models\Company;
use App\Models\Invoice;
class Designer
{
public $design;
protected $input_variables;
protected $exported_variables;
protected $html;
protected $entity_string;
protected $entity;
private static $custom_fields = [
'invoice1',
'invoice2',
'invoice3',
'invoice4',
'surcharge1',
'surcharge2',
'surcharge3',
'surcharge4',
'client1',
'client2',
'client3',
'client4',
'contact1',
'contact2',
'contact3',
'contact4',
'company1',
'company2',
'company3',
'company4',
];
public function __construct($entity, $design, $input_variables, $entity_string)
{
$this->entity = $entity;
$this->design = $design->design;
$this->input_variables = json_decode(json_encode($input_variables), 1);
$this->entity_string = $entity_string;
}
/**
* Returns the design
* formatted HTML.
* @return string The HTML design built
*/
public function build():self
{
$this->setHtml()
->exportVariables()
->setDesign($this->getSection('includes'))
->setDesign($this->getSection('header'))
->setDesign($this->getSection('body'))
->setDesign($this->getSection('footer'));
return $this;
}
public function init()
{
$this->setHtml()
->exportVariables();
return $this;
}
public function getIncludes()
{
return $this->getSection('includes');
}
public function getHeader()
{
return $this->getSection('header');
}
public function getFooter()
{
$div = '
%s <!-- Placeholder for getSection(footer) -->
<div class="flex items-center justify-between m-12">
%s <!-- Placeholder for signature -->
%s <!-- Placehoder for Invoice Ninja logo -->
</div>';
$signature = '<img class="h-40" src="$contact.signature" />';
$logo = '<div></div>';
if (! $this->entity->user->account->isPaid()) {
$logo = '<img class="h-32" src="$app_url/images/created-by-invoiceninja-new.png" />';
}
return sprintf($div, $this->getSection('footer'), $signature, $logo);
}
public function getBody()
{
return $this->getSection('body');
}
public function getHtml():string
{
return $this->html;
}
public function setHtml()
{
$this->html = '';
return $this;
}
private function setDesign($section)
{
$this->html .= $section;
return $this;
}
/**
* Returns the template section on with the
* stacked variables replaced with single variables.
*
* @param string $section the method name to be executed ie header/body/table/footer
* @return string The HTML of the template section
*/
public function getSection($section):string
{
return strtr($this->design->{$section}, $this->exported_variables);
// return str_replace(array_keys($this->exported_variables), array_values($this->exported_variables), $this->design->{$section});
}
private function exportVariables()
{
//$s = microtime(true);
$company = $this->entity->company;
$this->exported_variables['$custom_css'] = $this->entity->generateCustomCSS();
$this->exported_variables['$app_url'] = $this->entity->generateAppUrl();
$this->exported_variables['$client_details'] = $this->processVariables($this->input_variables['client_details'], $this->clientDetails($company));
$this->exported_variables['$company_details'] = $this->processVariables($this->input_variables['company_details'], $this->companyDetails($company));
$this->exported_variables['$company_address'] = $this->processVariables($this->input_variables['company_address'], $this->companyAddress($company));
if ($this->entity_string == 'invoice') {
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['invoice_details'], $this->invoiceDetails($company));
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['invoice_details'], $this->invoiceDetails($company));
} elseif ($this->entity_string == 'credit') {
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['credit_details'], $this->creditDetails($company));
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['credit_details'], $this->creditDetails($company));
} elseif ($this->entity_string == 'quote') {
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['quote_details'], $this->quoteDetails($company));
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['quote_details'], $this->quoteDetails($company));
} else {
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['invoice_details'], $this->quoteDetails($company));
}
$this->exported_variables['$product_table_header'] = $this->entity->buildTableHeader($this->input_variables['product_columns']);
$this->exported_variables['$product_table_body'] = $this->entity->buildTableBody($this->input_variables['product_columns'], $this->design->product, '$product');
$this->exported_variables['$task_table_header'] = $this->entity->buildTableHeader($this->input_variables['task_columns']);
$this->exported_variables['$task_table_body'] = $this->entity->buildTableBody($this->input_variables['task_columns'], $this->design->task, '$task');
if (strlen($this->exported_variables['$task_table_body']) == 0) {
$this->exported_variables['$task_table_header'] = '';
}
if (strlen($this->exported_variables['$product_table_body']) == 0) {
$this->exported_variables['$product_table_header'] = '';
}
return $this;
}
private function processVariables($input_variables, $variables):string
{
$output = '';
foreach (array_values($input_variables) as $value) {
if (array_key_exists($value, $variables)) {
$output .= $variables[$value];
}
}
return $output;
}
private function processLabels($input_variables, $variables):string
{
$output = '';
foreach (array_keys($input_variables) as $value) {
if (array_key_exists($value, $variables)) {
//$tmp = str_replace("</span>", "_label</span>", $variables[$value]);
$tmp = strtr($variables[$value], '</span>', '_label</span>');
$output .= $tmp;
}
}
return $output;
}
private function clientDetails(Company $company)
{
$data = [
'$client.name' => '<p>$client.name</p>',
'$client.id_number' => '<p>$client.id_number</p>',
'$client.vat_number' => '<p>$client.vat_number</p>',
'$client.address1' => '<p>$client.address1</p>',
'$client.address2' => '<p>$client.address2</p>',
'$client.city_state_postal' => '<p>$client.city_state_postal</p>',
'$client.postal_city_state' => '<p>$client.postal_city_state</p>',
'$client.country' => '<p>$client.country</p>',
'$contact.email' => '<p>$client.email</p>',
'$client.custom1' => '<p>$client.custom1</p>',
'$client.custom2' => '<p>$client.custom2</p>',
'$client.custom3' => '<p>$client.custom3</p>',
'$client.custom4' => '<p>$client.custom4</p>',
'$contact.contact1' => '<p>$contact.custom1</p>',
'$contact.contact2' => '<p>$contact.custom2</p>',
'$contact.contact3' => '<p>$contact.custom3</p>',
'$contact.contact4' => '<p>$contact.custom4</p>',
];
return $this->processCustomFields($company, $data);
}
private function companyDetails(Company $company)
{
$data = [
'$company.name' => '<span>$company.name</span>',
'$company.id_number' => '<span>$company.id_number</span>',
'$company.vat_number' => '<span>$company.vat_number</span>',
'$company.website' => '<span>$company.website</span>',
'$company.email' => '<span>$company.email</span>',
'$company.phone' => '<span>$company.phone</span>',
'$company.company1' => '<span>$company1</span>',
'$company.company2' => '<span>$company2</span>',
'$company.company3' => '<span>$company3</span>',
'$company.company4' => '<span>$company4</span>',
];
return $this->processCustomFields($company, $data);
}
private function companyAddress(Company $company)
{
$data = [
'$company.address1' => '<span>$company.address1</span>',
'$company.address2' => '<span>$company.address2</span>',
'$company.city_state_postal' => '<span>$company.city_state_postal</span>',
'$company.postal_city_state' => '<span>$company.postal_city_state</span>',
'$company.country' => '<span>$company.country</span>',
'$company.company1' => '<span>$company1</span>',
'$company.company2' => '<span>$company2</span>',
'$company.company3' => '<span>$company3</span>',
'$company.company4' => '<span>$company4</span>',
];
return $this->processCustomFields($company, $data);
}
private function invoiceDetails(Company $company)
{
$data = [
'$invoice.number' => '<span class="flex justify-between items-center"><span>$invoice.number_label:</span><span> $invoice.number</span></span>',
'$invoice.po_number' => '<span class="flex justify-between items-center"><span>$invoice.po_number_label:</span><span> $invoice.po_number</span></span>',
'$invoice.date' => '<span class="flex justify-between items-center"><span>$invoice.date_label:</span><span> $invoice.date</span></span>',
'$invoice.due_date' => '<span class="flex justify-between items-center"><span>$invoice.due_date_label:</span><span> $invoice.due_date</span></span>',
'$invoice.balance_due' => '<span class="flex justify-between items-center"><span>$invoice.balance_due_label:</span><span> $invoice.balance_due</span></span>',
'$invoice.total' => '<span class="flex justify-between items-center"><span>$invoice.total_label:</span><span> $invoice.total</span></span>',
'$invoice.partial_due' => '<span class="flex justify-between items-center"><span>$invoice.partial_due_label:</span><span> $invoice.partial_due</span></span>',
'$invoice.custom1' => '<span class="flex justify-between items-center"><span>$invoice1_label:</span><span> $invoice.custom1</span></span>',
'$invoice.custom2' => '<span class="flex justify-between items-center"><span>$invoice2_label:</span><span> $invoice.custom2</span></span>',
'$invoice.custom3' => '<span class="flex justify-between items-center"><span>$invoice3_label:</span><span> $invoice.custom3</span></span>',
'$invoice.custom4' => '<span class="flex justify-between items-center"><span>$invoice4_label:</span><span> $invoice.custom4</span></span>',
'$surcharge1' => '<span class="flex justify-between items-center"><span>$surcharge1_label:</span><span> $surcharge1</span></span>',
'$surcharge2' => '<span class="flex justify-between items-center"><span>$surcharge2_label:</span><span> $surcharge2</span></span>',
'$surcharge3' => '<span class="flex justify-between items-center"><span>$surcharge3_label:</span><span> $surcharge3</span></span>',
'$surcharge4' => '<span class="flex justify-between items-center"><span>$surcharge4_label:</span><span> $surcharge4</span></span>',
];
return $this->processCustomFields($company, $data);
}
private function quoteDetails(Company $company)
{
$data = [
'$quote.quote_number' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.number_label:</span><span> $quote.number</span></span>',
'$quote.po_number' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.po_number_label:</span><span> $quote.po_number</span></span>',
'$quote.quote_date' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.date_label:</span><span> $quote.date</span></span>',
'$quote.valid_until' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.valid_until_label:</span><span> $quote.valid_until</span></span>',
'$quote.balance_due' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.balance_due_label:</span><span> $quote.balance_due</span></span>',
'$quote.quote_total' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.total_label:</span><span> $quote.total</span></span>',
'$quote.partial_due' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.partial_due_label:</span><span> $quote.partial_due</span></span>',
'$quote.custom1' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom1_label:</span><span> $quote.custom1</span></span>',
'$quote.custom2' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom2_label:</span><span> $quote.custom2</span></span>',
'$quote.custom3' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom3_label:</span><span> $quote.custom3</span></span>',
'$quote.custom4' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom4_label:</span><span> $quote.custom4</span></span>',
'$quote.surcharge1' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge1_label:</span><span> $surcharge1</span></span>',
'$quote.surcharge2' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge2_label:</span><span> $surcharge2</span></span>',
'$quote.surcharge3' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge3_label:</span><span> $surcharge3</span></span>',
'$quote.surcharge4' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge4_label:</span><span> $surcharge4</span></span>',
];
return $this->processCustomFields($company, $data);
}
private function creditDetails(Company $company)
{
$data = [
'$credit.number' => '<span class="flex justify-between items-center">$credit.number_label<span></span><span>$credit.number</span></span>',
'$credit.po_number' => '<span class="flex justify-between items-center">$credit.po_number_label<span></span><span>$credit.po_number</span></span>',
'$credit.date' => '<span class="flex justify-between items-center">$credit.date_label<span></span><span>$credit.date</span></span>',
'$credit.balance' => '<span class="flex justify-between items-center">$credit.balance_label<span></span><span>$credit.balance</span></span>',
'$credit.total' => '<span class="flex justify-between items-center">$credit.total_label<span></span><span>$credit.total</span></span>',
'$credit.partial_due' => '<span class="flex justify-between items-center">$credit.partial_due_label<span></span><span>$credit.partial_due</span></span>',
'$credit.custom1' => '<span class="flex justify-between items-center">$credit.custom1_label<span></span><span>$credit.custom1</span></span>',
'$credit.custom2' => '<span class="flex justify-between items-center">$credit.custom2_label<span></span><span>$credit.custom2</span></span>',
'$credit.custom3' => '<span class="flex justify-between items-center">$credit.custom3_label<span></span><span>$credit.custom3</span></span>',
'$credit.custom4' => '<span class="flex justify-between items-center">$credit.custom4_label<span></span><span>$credit.custom4</span></span>',
'$credit.surcharge1' => '<span class="flex justify-between items-center">$surcharge1_label<span></span><span>$surcharge1_label: $surcharge1</span></span>',
'$credit.surcharge2' => '<span class="flex justify-between items-center">$surcharge2_label<span></span><span>$surcharge2_label: $surcharge2</span></span>',
'$credit.surcharge3' => '<span class="flex justify-between items-center">$surcharge3_label<span></span><span>$surcharge3_label: $surcharge3</span></span>',
'$credit.surcharge4' => '<span class="flex justify-between items-center">$surcharge4_label<span></span><span>$surcharge4_label: $surcharge4</span></span>',
];
return $this->processCustomFields($company, $data);
}
private function processCustomFields(Company $company, $data)
{
$custom_fields = $company->custom_fields;
if (! $custom_fields) {
return $data;
}
foreach (self::$custom_fields as $cf) {
if (! property_exists($custom_fields, $cf) || (strlen($custom_fields->{$cf}) == 0)) {
unset($data[$cf]);
}
}
return $data;
}
// private function processInputVariables($company, $variables)
// {
// if(is_object($variables))
// $variables = json_decode(json_encode($variables),true);
// $custom_fields = $company->custom_fields;
// $matches = array_intersect(self::$custom_fields, $variables);
// foreach ($matches as $match) {
// if (!property_exists($custom_fields, $match) || (strlen($custom_fields->{$match}) == 0)) {
// foreach ($variables as $key => $value) {
// if ($value == $match) {
// unset($variables[$key]);
// }
// }
// }
// }
// return $variables;
// }
}

View File

@ -1,144 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Elegant extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page
{
size: auto;
margin-top: 5mm;
}
.table_header_thead_class { text-align: left; border-bottom-width: 1px; border-style: dashed; border-color: black; }
.table_header_td_class { font-weight: normal; color: #2f855a; padding: .5rem 1rem; }
.table_body_td_class { padding: 1rem; }
$custom_css
</style>';
}
public function header()
{
return '<div class="m-10">
<div class="grid grid-cols-12 border-b-4 border-black pb-6">
<div class="col-span-8">
$company_logo
</div>
<div class="col-span-4 flex flex-col flex-wrap">
$entity_details
</div>
</div>
<div class="p-px border-b border-black mt-1"></div>';
}
public function body()
{
return '<div class="grid grid-cols-12 gap-4 mt-8">
<div class="col-span-4 mr-6 flex flex-col pr-2 border-r border-dashed border-black flex-wrap">
$client_details
</div>
<div class="col-span-4 flex flex-col mr-6 flex-wrap">
$company_details
</div>
<div class="col-span-4 flex flex-col flex-wrap">
$company_address
</div>
</div>
<table class="w-full table-auto mb-6 mt-16">
<thead class="text-left border-dashed border-b border-black">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mb-6 mt-16">
<thead class="text-left border-dashed border-b border-black">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="flex items-center justify-between mt-2 px-4 pb-4">
<div class="w-1/2">
<div class="flex flex-col">
<p>$entity.public_notes</p>
</div>
</div>
<div class="w-1/3 flex flex-col">
<div class="flex px-3 mt-2">
<section class="w-1/2 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</section>
<section class="w-1/2 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</section>
</div>
</div>
</div>
<div class="flex items-center justify-between mt-4 pb-4 px-4">
<div class="w-1/2">
<div class="flex flex-col">
<p class="font-semibold">$terms_label</p>
<p>$terms</p>
</div>
</div>
<div class="flex w-2/5 flex-col">
<section class="flex py-2 text-green-700 border-t border-b border-dashed border-black px-2 mt-1">
<p class="w-1/2">$balance_due_label</p>
<p class="text-right w-1/2">$balance</p>
</section>
</div>
</div>
<div class="flex justify-center border-b-4 border-black mt-6">
<h4 class="text-2xl font-semibold mb-4">Thanks</h4>
</div>
<div class="p-px border-b border-black mt-1"></div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,153 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Hipster extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page
{
size: auto;
margin-top: 5mm;
}
.table_header_thead_class { text-align: left }
.table_header_td_class { text-transform: uppercase; padding: .5rem 1rem; font-weight: 600; border-color: black; }
.table_body_td_class { border-left-width: 2px; border-color: black; padding: 1rem; }
$custom_css
</style>';
}
public function header()
{
return '<div class="px-12 py-16">
<div class="flex">
<div class="w-1/2 border-l pl-4 border-black mr-4">
<p class="font-semibold uppercase text-yellow-600">From:</p>
<div class="flex">
<div class="flex flex-col mr-5 flex-wrap">
$company_details
</div>
<div class="flex flex-col flex-wrap">
$company_address
</div>
</div>
</div>
<div class="w-1/3 border-l pl-4 border-black flex flex-col flex-wrap">
<p class="font-semibold uppercase text-yellow-600">To:</p>
$client_details
</div>
<div class="w-1/3 mt-5 h-16">
$company_logo
</div>
</div>';
}
public function body()
{
return '<div class="flex flex-col mx-6 mt-10">
<h1 class="font-semibold uppercase text-6xl">$entity_label</h1>
<div class="flex mt-1">
<span class="font-semibold uppercase text-yellow-600">$entity_number</span>
<div class="ml-4">
<span class="uppercase">$date_label</span>
<span>$date</span>
</div>
<div class="ml-10">
<span class="uppercase">$due_date_label</span>
<span>$due_date</span>
</div>
<div class="ml-4">
<span class="uppercase">$balance_due_label</span>
<span class="text-yellow-600">$balance_due</span>
</div>
</div>
</div>
<table class="w-full table-auto mt-24">
<thead class="text-left">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-24">
<thead class="text-left">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="flex justify-between mt-8">
<div class="w-1/2">
<div class="flex flex-col">
<p>$entity.public_notes</p>
<div class="pt-4">
<p class="font-bold">$terms_label</p>
<p>$terms</p>
</div>
</div>
</div>
<div class="w-1/3 flex flex-col">
<div class="flex px-3 mt-6">
<section class="w-1/2 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</section>
<section class="w-1/2 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</section>
</div>
<section class="flex bg-black text-white px-3 mt-1">
<p class="w-1/2 text-right">$balance_due_label</p>
<p class="text-right w-1/2">$balance_due</p>
</section>
</div>
</div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,151 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Modern extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
.table_header_thead_class {text-align:left; text-align:left; color:#fff; background-color:#1a202c;}
.table_header_td_class {padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem}
.table_body_td_class {border-top-width:1px; border-bottom-width:1px; border-color:#1a202c; padding-left:1rem;padding-right:1rem; padding-top:1rem;padding-bottom:1rem;}
$custom_css
</style>
</head>
<body>';
}
public function header()
{
return '
<div class="header bg-orange-600 flex justify-between py-12 px-12" style="page-break-inside: avoid;">
<div class="grid grid-cols-6 gap-1">
<div class="col-span-2 p-3">
<h1 class="text-white font-bold text-3xl">$company.name</h1>
</div>
<div class="col-span-2 p-3 flex flex-col text-white flex-wrap">
$company_details
</div>
<div class="col-span-2 p-3 flex flex-col text-white flex-wrap">
$entity_details
</div>
</div>
</div>';
}
public function body()
{
return '
<table class="container"><thead><tr><td><div class="header-space"></div></td></tr></thead>
<tbody><tr><td>
<div class="grid grid-cols-5 gap-1 px-12 pt-12">
<div class="col-span-2 p-3">
$company_logo
</div>
<div class="col-span-3 p-3 flex flex-col flex-wrap">
$client_details
</div>
</div>
<div class="px-12 pt-5 pb-20">
<table class="w-full table-auto mt-8">
<thead class="text-left text-white bg-gray-900 display: table-header-group;">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-8">
<thead class="text-left text-white bg-gray-900 display: table-header-group;">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="flex px-4 mt-6 w-full" style="page-break-inside: avoid;">
<div class="w-1/2">
$entity.public_notes
</div>
<div class="w-1/2 flex" style="page-break-inside: avoid;">
<div class="w-1/2 text-right flex flex-col" style="page-break-inside: avoid;">
$discount_label
$total_tax_labels
$line_tax_labels
</div>
<div class="w-1/2 text-right flex flex-col" style="page-break-inside: avoid;">
$discount
$total_tax_values
$line_tax_values
</div>
</div>
</div>
<div style="page-break-inside: avoid;">
<div class="flex px-4 mt-4 w-full items-end mt-5" >
<div class="w-1/2" style="page-break-inside: avoid;">
<p class="font-semibold">$terms_label</p>
$terms
</div>
</div>
<div class="mt-8 px-4 py-2 bg-gray-900 text-white" style="">
<div class="w-1/2"></div>
<div class="w-auto flex justify-end" style="page-break-inside: avoid;">
<div class="w-56" style="page-break-inside: avoid;">
<p class="font-bold">$balance_due_label</p>
</div>
<p>$balance_due</p>
</div>
</div>
</div>
</div>
</td></tr></tbody><tfoot><tr><td><div class="footer-space"></div></td></tr></tfoot></table>
';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<div class="footer bg-orange-600 flex justify-between py-8 px-12" style="page-break-inside: avoid;">
<div class="grid grid-cols-12 gap-4">
<div class="col-start-4 col-span-4 p-3 flex flex-col text-white text-right flex-wrap">
$company_details
</div>
<div class="col-span-4 p-3 flex flex-col text-white text-right flex-wrap">
$company_address
</div>
</div>
</div>';
}
}

View File

@ -1,154 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Photo extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page {
size: auto;
margin-top: 5mm;
}
#imageContainer {
background-image: url();
background-size: cover;
}
.table_header_thead_class { text-align: left; border-bottom-width: 4px; border-color: black; }
.table_header_td_class { font-weight: 400; text-transform: uppercase; padding: 1rem .5rem; }
.table_body_td_class { padding: 1rem; }
$custom_css
</style>';
}
public function header()
{
return '<div class="px-16 py-10">
<div class="grid grid-cols-12 mt-2">
<div class="col-span-7">
$company_logo
</div>
<div class="col-span-5">
<div class="flex flex-col flex-wrap">
$entity_details
</div>
</div>
</div>
</div>';
}
public function body()
{
return '<div class="flex content-center flex-wrap bg-gray-200 h-auto p-16" id="imageContainer">
<div class="flex flex-col">
<div class="flex">
<p class="uppercase text-orange-800">$to_label:</p>
<div class="flex flex-col ml-2 flex-wrap">
$client_details
</div>
</div>
<div class="flex mt-5">
<p class="uppercase text-orange-800">$from_label:</p>
<div class="flex flex-col ml-2 flex-wrap">
$company_details
</div>
</div>
</div>
</div>
<div class="px-16 py-16">
<table class="w-full table-auto">
<thead class="text-left border-b-4 border-black">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto">
<thead class="text-left border-b-4 border-black">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="flex items-center justify-between mt-2 px-4 pb-4">
<div class="w-1/2">
<div class="flex flex-col">
<p>$entity.public_notes</p>
</div>
</div>
<div class="w-1/3 flex flex-col">
<div class="flex px-3 mt-2">
<section class="w-1/2 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</section>
<section class="w-1/2 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</section>
</div>
</div>
</div>
<div class="flex items-center justify-between mt-4 pb-4 px-4">
<div class="w-1/2">
<div class="flex flex-col">
<p class="font-semibold">$terms_label</p>
<p>$terms</p>
</div>
</div>
<div class="flex w-2/5 flex-col">
<section class="flex bg-orange-700 py-2 text-white px-2 mt-1">
<p class="w-1/2">$balance_due_label</p>
<p class="text-right w-1/2">$balance_due</p>
</section>
</div>
</div>
</div>
</div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,131 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Plain extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page {
size: auto;
margin-top: 5mm;
}
.table_header_thead_class { text-align: left; background-color: #e2e8f0 }
.table_header_td_class { padding: 1rem .5rem; }
.table_body_td_class { padding: 1rem; border-bottom-width: 1px; border-top-width: 2px; border-color: #e2e8f0 }
$custom_css
</style>';
}
public function header()
{
return '<div class="px-12 py-8">
<div class="grid grid-cols-6 gap-1">
<div class="col-span-2 p-3">
$company_logo
</div>
<div class="col-span-2 p-3 flex flex-col flex-wrap">
$company_details
</div>
<div class="col-span-2 p-3 flex flex-col flex-wrap">
$entity_details
</div>
</div>';
}
public function body()
{
return '<div class="flex flex-col mt-8 flex-wrap">
$client_details
</div>
<table class="w-full table-auto mt-8">
<thead class="text-left bg-gray-300">
$product_table_header
</thead>
<tbody>
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-8">
<thead class="text-left bg-gray-300">
$task_table_header
</thead>
<tbody>
$task_table_body
</tbody>
</table>
<div class="grid grid-cols-12 gap-1">
<div class="col-span-6 p-3">
<div class="flex flex-col">
<p>$entity.public_notes</p>
<div class="pt-4">
<p class="font-bold">$terms_label</p>
<p>$terms</p>
</div>
</div>
</div>
<div class="col-span-6 p-3">
<div class="grid grid-cols-2 gap-1">
<div class="col-span-1 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</div>
<div class="col-span-1 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</div>
</div>
<div class="grid grid-cols-2 gap-1 bg-gray-300">
<div class="col-span-1 text-right flex flex-col">
$balance_due_label
</div>
<div class="col-span-1 text-right flex flex-col">
$balance_due
</div>
</div>
</div>
</div';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,143 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Designs;
class Playful extends AbstractDesign
{
public function __construct()
{
}
public function includes()
{
return '<title>$number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
<style>
body {font-size:90%}
@page
{
size: auto;
margin-top: 5mm;
}
.table_header_thead_class { text-align: left; background-color: #319795; border-radius: .5rem; }
.table_header_td_class { padding: .75rem 1rem; font-weight: 600; color: white; }
.table_body_td_class { padding: 1rem; border-bottom-width: 4px; border-style: dashed; border-color: #319795; color: black }
$custom_css
</style>';
}
public function header()
{
return '<div class="my-12 mx-16">
<div class="grid grid-cols-12 items-center justify-between">
<div class="col-span-7">
$company_logo
</div>
<div class="col-span-5 bg-teal-600 p-5 text-white">
<div class="flex flex-col flex-wrap">
$entity_details
</div>
</div>
</div>';
}
public function body()
{
return '<div class="flex mt-16">
<div class="w-1/2">
<div class="flex flex-col">
<p class="font-semibold text-teal-600 pl-4">$to_label:</p>
<div class="flex border-dashed border-t-4 border-b-4 border-teal-600 py-4 mt-4 pl-4">
<section class="flex flex-col flex-wrap">
$client_details
</section>
</div>
</div>
</div>
<div class="w-1/2 ml-24">
<div class="flex flex-col">
<p class="font-semibold text-teal-600 pl-4">$from_label:</p>
<div class="flex border-dashed border-t-4 border-b-4 border-teal-600 py-4 mt-4 pl-4">
<section class="flex flex-col flex-wrap">
$company_details
</section>
</div>
</div>
</div>
</div>
<table class="w-full table-auto mt-20 mb-8">
<thead class="text-left bg-teal-600 rounded-lg">
$product_table_header
</thead>
<tbody class="whitespace-pre-line">
$product_table_body
</tbody>
</table>
<table class="w-full table-auto mt-20 mb-8">
<thead class="text-left bg-teal-600 rounded-lg">
$task_table_header
</thead>
<tbody class="whitespace-pre-line">
$task_table_body
</tbody>
</table>
<div class="grid grid-cols-12 gap-4">
<div class="col-span-7 flex flex-col">
$entity.public_notes
</div>
<div class="col-span-5 flex">
<section class="w-1/2 text-right flex flex-col">
$discount_label
$total_tax_labels
$line_tax_labels
</section>
<section class="w-1/2 text-right flex flex-col">
$discount
$total_tax_values
$line_tax_values
</section>
</div>
<div class="col-span-7">
<p class="font-semibold">$terms_label</p>
<p>$terms</p>
</div>
<div class="col-span-5">
<div class="flex bg-teal-600 py-3 px-4 text-white">
<p class="w-1/2">$balance_due_label</p>
<p class="text-right w-1/2">$balance_due</p>
</div>
</div>
<div>';
}
public function task()
{
return '';
}
public function product()
{
return '';
}
public function footer()
{
return '
<footer>
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
</div>
</footer>';
}
}

View File

@ -1,103 +0,0 @@
@extends('portal.default.layouts.guest')
@section('body')
<body class="app flex-row align-items-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card-group">
<div class="card p-4">
<div class="card-body">
@if (session('info'))
<div class="row">
<div class="col-md-12">
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ session('info') }}
</div>
</div>
</div>
@elseif (session('error'))
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ session('error') }}
</div>
</div>
</div>
@endif
<form method="POST" action="{{ route('client.login') }}">
@csrf
<h1>{{ trans('texts.account_login') }}</h1>
@if (Session::has('error'))
<div class="alert alert-danger">
<li>{!! Session::get('error') !!}</li>
</div>
@endif
<p class="text-muted"></p>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-user"></i>
</span>
</div>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="{{ trans('texts.email') }}" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<div class="input-group mb-4">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-lock"></i>
</span>
</div>
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" placeholder="{{ trans('texts.password') }}" required>
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary px-4" type="submit">{{ trans('texts.login') }}</button>
</div>
<div class="col-6 text-right">
<a class="btn btn-link" href="{{ route('client.password.request') }}">
{{trans('texts.forgot_password')}}
</a>
</div>
</div>
</form>
</div>
</div>
@env('hosted')
<!--<div class="card text-white bg-primary py-5 d-md-down-none" style="width:44%">
<div class="card-body text-center">
<div>
<h2>trans('texts.sign_up_now')</h2>
<p>trans('texts.not_a_member_yet')</p>
<a class="btn btn-primary active mt-3" href=" route('signup') ">trans('texts.login_create_an_account')</a>
</div>
</div>
</div>
-->
@endenv
</div>
</div>
</div>
</div>
</body>
@endsection

View File

@ -1,51 +0,0 @@
@extends('portal.default.layouts.guest')
@section('body')
<body class="app flex-row align-items-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card-group">
<div class="card p-4">
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{ route($passwordEmailRoute) }}">
@csrf
<h1>{{trans('texts.password_recovery')}}</h1>
<p class="text-muted"></p>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-user"></i>
</span>
</div>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="{{trans('texts.email')}}" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary px-4" type="submit">{{trans('texts.send_email')}}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
@endsection

View File

@ -1,71 +0,0 @@
@extends('portal.default.layouts.guest')
@section('body')
<body class="app flex-row align-items-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card-group">
<div class="card p-4">
<div class="card-body">
<div class="card-body">
<form method="POST" action="{{ route('client.password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<h1>{{trans('texts.change_password')}}</h1>
<p class="text-muted"></p>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-user"></i>
</span>
</div>
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="{{trans('texts.email')}}" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<div class="input-group mb-4">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-lock"></i>
</span>
</div>
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" placeholder="{{trans('texts.password')}}" required>
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
<div class="input-group mb-4">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="icon-lock"></i>
</span>
</div>
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" placeholder="{{trans('texts.confirm_password')}}" required>
</div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary px-4" type="submit">{{trans('texts.change_password')}}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
@endsection

View File

@ -1,160 +0,0 @@
@extends('portal.default.layouts.master')
@push('css')
<link href="/vendors/css/select2.min.css" rel="stylesheet">
<link href="/vendors/css/select2-bootstrap4.css" rel="stylesheet">
<style>
select {border: 1px solid !important;}
.select2-container--bootstrap4 .select2-selection--single
{
border: 1px solid #e4e7ea !important;
}
</style>
@endpush
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col-sm-3" style="padding-bottom: 10px;">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('update_contact')
->route('client.profile.update', auth()->user()->hashed_id)
->method('PUT'); !!}
<div class="card">
<div class="card-header">
<strong>{{ ctrans('texts.avatar') }}</strong>
</div>
<div class="card-body">
</div>
</div>
</div>
<div class="col-sm-9" style="padding-bottom: 10px;">
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.client_information') }}</strong>
</div>
<div class="card-body">
{!! Former::text('name')->placeholder( ctrans('texts.first_name'))->label('') !!}
{!! Former::text('phone')->placeholder( ctrans('texts.phone'))->label('') !!}
{!! Former::text('website')->placeholder( ctrans('texts.website'))->label('') !!}
{!! Former::text('address1')->placeholder( ctrans('texts.address1'))->label('') !!}
{!! Former::text('address2')->placeholder( ctrans('texts.address2'))->label('') !!}
{!! Former::text('city')->placeholder( ctrans('texts.city'))->label('') !!}
{!! Former::text('state')->placeholder( ctrans('texts.state'))->label('') !!}
{!! Former::text('postal_code')->placeholder( ctrans('texts.postal_code'))->label('') !!}
{!! Former::select('country_id')
->addOption('','')
->autocomplete('off')
->label('')
->fromQuery($countries, 'name', 'id') !!}
{!! Former::text('shipping_address1')->placeholder( ctrans('texts.shipping_address1'))->label('') !!}
{!! Former::text('shipping_address2')->placeholder( ctrans('texts.shipping_address2'))->label('') !!}
{!! Former::text('shipping_city')->placeholder( ctrans('texts.shipping_city'))->label('') !!}
{!! Former::text('shipping_state')->placeholder( ctrans('texts.shipping_state'))->label('') !!}
{!! Former::text('shipping_postal_code')->placeholder( ctrans('texts.shipping_postal_code'))->label('') !!}
{!! Former::select('shipping_country_id')
->addOption('','')
->autocomplete('off')
->label('')
->fromQuery($countries, 'name', 'id') !!}
</div>
</div>
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.user_details') }}</strong>
</div>
<div class="card-body">
{!! Former::text('first_name')->placeholder( ctrans('texts.first_name'))->label('') !!}
{!! Former::text('last_name')->placeholder( ctrans('texts.last_name'))->label('') !!}
{!! Former::text('email')->placeholder( ctrans('texts.email'))->label('') !!}
{!! Former::text('phone')->placeholder( ctrans('texts.phone'))->label('') !!}
</div>
</div>
{!! Former::close() !!}
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
<script src="/vendors/js/select2.min.js"></script>
@endpush
@section('footer')
<script>
$(document).ready(function() {
$('#shipping_country_id').select2({
placeholder: "{{ ctrans('texts.country') }}",
//allowClear: true,
theme: "bootstrap4",
}).on('change', function() {
});
$('#country_id').each(function () {
$(this).select2({
placeholder: "{{ ctrans('texts.country') }}",
theme: 'bootstrap4',
width: 'style',
allowClear: Boolean($(this).data('allow-clear')),
});
});
});
</script>
@endsection

View File

@ -1,109 +0,0 @@
@extends('portal.default.layouts.master')
@section('body')
<main class="main">
<div class="container-fluid">
@if($settings->enable_client_portal_dashboard == 'true')
<div class="row" style="margin-top: 30px;">
<div class="col-6 col-lg-4">
<div class="card">
<div class="card-body p-3 d-flex align-items-center">
<i class="fa fa-money bg-primary p-3 font-2xl mr-3"></i>
<div>
<div class="text-value-sm text-primary">$1.999,50</div>
<div class="text-muted text-uppercase font-weight-bold small">{{ ctrans('texts.total_invoiced')}}</div>
</div>
</div>
</div>
</div>
<div class="col-6 col-lg-4">
<div class="card">
<div class="card-body p-3 d-flex align-items-center">
<i class="fa fa-hourglass-end bg-info p-3 font-2xl mr-3"></i>
<div>
<div class="text-value-sm text-info">$1.999,50</div>
<div class="text-muted text-uppercase font-weight-bold small">{{ ctrans('texts.paid_to_date') }}</div>
</div>
</div>
</div>
</div>
<div class="col-6 col-lg-4">
<div class="card">
<div class="card-body p-3 d-flex align-items-center">
<i class="fa fa-exclamation-triangle bg-warning p-3 font-2xl mr-3"></i>
<div>
<div class="text-value-sm text-warning">$1.999,50</div>
<div class="text-muted text-uppercase font-weight-bold small">{{ ctrans('texts.open_balance')}}</div>
</div>
</div>
</div>
</div>
</div>
@endif
<!-- client and supplier information -->
<div class="row">
<div class="col-sm-6 col-md-6">
<div class="card">
<div class="card-header">{{ctrans('texts.client_information')}}</div>
<div class="card-body">
<h2>{{ $client->present()->name() }}</h2>
<br>
{!! $client->present()->address() !!}
</div>
</div>
</div>
<div class="col-sm-6 col-md-6">
<div class="card">
<div class="card-header">{{ctrans('texts.contact_us')}}</div>
<div class="card-body">
@if ($company->logo)
{!! Html::image($company->logo) !!}
@else
<h2>{{ $company->present()->name() }}</h2>
@endif
<br>
{!! $company->present()->address() !!}
</div>
</div>
</div>
</div>
<!-- update payment methods
<div class="row" style="margin-top: 30px;">
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-warning h-100">
<div class="card-body">
<div class="btn-group float-right">
<button class="btn btn-transparent dropdown-toggle p-0" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-cog"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#">Remove card</a>
</div>
</div>
<div class="w-50 p-0"><img class="card-img embed-responsive-item" src="/images/visa.png" alt="Visa Card"></div>
<div>{{ ctrans('texts.expires')}}: 10/20</div>
<small class="text-value">Mr Joe Citizen - ({{ctrans('texts.default')}})</small>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-secondary h-100">
<div class="card-body align-items-center d-flex justify-content-center">
<a class="btn btn-primary btn-lg" href="{{ route('client.payment_methods.create') }}"><i class="fa fa-plus" style="" aria-hidden="true"></i> {{ ctrans('texts.add_payment_method')}}</a>
</div>
</div>
</div>
</div>
-->
</div>
</main>
</body>
@endsection

View File

@ -1,40 +0,0 @@
<div class="justify-content-center align-items-center pd-10 pm-10">
@if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
@endif
@if ($message = Session::get('error'))
<div class="alert alert-danger alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
@endif
@if ($message = Session::get('warning'))
<div class="alert alert-warning alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
@endif
@if ($message = Session::get('info'))
<div class="alert alert-info alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
Please check the form below for errors
</div>
@endif
</div>

View File

@ -1,18 +0,0 @@
</div>
<footer class="app-footer">
<div class="ml-auto">
@if(!$user->company->account->isPaid())
<span>Powered by</span>
<a href="https://invoiceninja.com">InvoiceNinja</a> &copy; 2019 Invoice Ninja LLC.
@endif
</div>
</footer>
<!-- Bootstrap and necessary plugins-->
<script src="/vendors/js/jquery.min.js"></script>
<script src="/vendors/js/bootstrap.bundle.min.js"></script>
<script src="/vendors/js/perfect-scrollbar.min.js"></script>
<script src="/vendors/js/coreui.min.js"></script>
@stack('scripts')
<script>
$('#ui-view').ajaxLoad();
</script>

View File

@ -1,27 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.add_payment_method')}}
</div>
<div class="card-body">
@yield('credit_card')
</div>
</div>
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
@endpush

View File

@ -1,71 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.payment')}}
</div>
<div class="card-body">
<div class="list-group">
@foreach($invoices as $invoice)
<a class="list-group-item list-group-item-action flex-column align-items-start" href="javascript:void(0);">
<div class="d-flex w-100 justify-content-between">
<h5 class="mr-4"># {{ $invoice->number }}</h5>
<small>{{ $invoice->due_date }}</small>
</div>
<p class="mb-1 pull-right">{{ $invoice->balance }}</p>
<small>
@if($invoice->po_number)
{{ $invoice->po_number }}
@elseif($invoice->public_notes)
{{ $invoice->public_notes }}
@else
{{ $invoice->invoice_date}}
@endif
</small>
</a>
@endforeach
</div>
<div class="py-md-5">
<ul class="list-group">
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center"><strong>{{ ctrans('texts.total')}}</strong>
<h3><span class="badge badge-primary badge-pill"><strong>{{ $amount }}</strong></span></h3>
</li>
@if($credit_totals > 0)
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center"><strong>{{ ctrans('texts.credit_amount')}}</strong>
<h3><span class="badge badge-primary badge-pill"><strong>{{ $credit_totals }}</strong></span></h3>
</li>
@endif
@if($fee > 0)
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center"><strong>{{ ctrans('texts.gateway_fee')}}</strong>
<h3><span class="badge badge-primary badge-pill"><strong>{{ $fee }}</strong></span></h3>
</li>
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center"><strong>{{ ctrans('texts.amount_due')}}</strong>
<h3><span class="badge badge-primary badge-pill"><strong>{{ $amount_with_fee }}</strong></span></h3>
</li>
@endif
</ul>
</div>
@yield('pay_now')
</div>
</div>
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
@endpush
@section('footer')
@endsection

View File

@ -1,139 +0,0 @@
@extends('portal.default.gateways.authorize')
@section('credit_card')
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('server_response')
->route('client.payment_methods.store')
->method('POST'); !!}
{!! Former::hidden('company_gateway_id')->value($gateway->gateway_id) !!}
{!! Former::hidden('gateway_type_id')->value(1) !!}
{!! Former::hidden('gateway_response')->id('gateway_response') !!}
{!! Former::hidden('is_default')->id('is_default') !!}
{!! Former::close() !!}
<div class="py-md-5 ninja stripe">
<div class="form-group">
<input class="form-control" id="cardholder-name" type="text" placeholder="{{ ctrans('texts.name') }}">
</div>
<!-- placeholder for Elements -->
<div class="form-group">
<div id="card-element" class="form-control"></div>
</div>
<div class="form-check form-check-inline mr-1">
<input class="form-check-input" id="proxy_is_default" type="checkbox">
<label class="form-check-label" for="proxy_is_default">{{ ctrans('texts.save_as_default') }}</label>
</div>
<div id="card-errors" role="alert"></div>
<div class="form-group">
<button id="card-button" class="btn btn-primary pull-right" data-secret="{{ $intent->client_secret }}">
{{ ctrans('texts.save') }}
</button>
</div>
</div>
@endsection
@push('scripts')
<script src="https://js.stripe.com/v3/"></script>
<script type="text/javascript">
var stripe = Stripe('{{ $gateway->getPublishableKey() }}');
var elements = stripe.elements();
var cardElement = elements.create('card');
cardElement.mount('#card-element');
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', function(ev) {
stripe.handleCardSetup(
clientSecret, cardElement, {
payment_method_data: {
billing_details: {name: cardholderName.value}
}
}
).then(function(result) {
if (result.error) {
// Display error.message in your UI.
// console.log(result.error);
// console.log(result.error.message);
$("#card-errors").empty();
$("#card-errors").append("<b>" + result.error.message + "</b>");
$("#card-button").removeAttr("disabled");
} else {
// The card has been successfullly stored.
postResult(result);
}
});
});
$("#card-button").attr("disabled", true);
$('#cardholder-name').on('input',function(e){
if($("#cardholder-name").val().length >=1)
$("#card-button").removeAttr("disabled");
else
$("#card-button").attr("disabled", true);
});
function postResult(result)
{
$("#gateway_response").val(JSON.stringify(result.setupIntent));
$("#is_default").val($('#proxy_is_default').is(":checked"));
$("#card-button").attr("disabled", true);
$('#server_response').submit();
}
</script>
@endpush
@push('css')
<style type="text/css">
.StripeElement {
box-sizing: border-box;
height: 40px;
padding: 10px 12px;
border: 1px solid transparent;
border-radius: 4px;
background-color: white;
box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease;
}
.StripeElement--focus {
box-shadow: 0 1px 3px 0 #cfd7df;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
</style>
@endpush

View File

@ -1,174 +0,0 @@
@extends('portal.default.gateways.pay_now')
@section('pay_now')
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('server_response')
->route('client.payments.response')
->method('POST'); !!}
{!! Former::hidden('gateway_response')->id('gateway_response') !!}
{!! Former::hidden('store_card')->id('store_card') !!}
{!! Former::hidden('payment_hash')->value($payment_hash) !!}
{!! Former::hidden('company_gateway_id')->value($payment_method_id) !!}
{!! Former::hidden('payment_method_id')->value($gateway->getCompanyGatewayId()) !!}
{!! Former::close() !!}
@if($token)
<div class="py-md-5 ninja stripe">
<div class="form-group">
<button id="card-button" class="btn btn-primary pull-right" data-secret="{{ $intent->client_secret }}">
{{ ctrans('texts.pay_now') }} - {{ $token->meta->brand }} - {{ $token ->meta->last4}}
</button>
</div>
</div>
@else
<div class="py-md-5 ninja stripe">
<div class="form-group">
<input class="form-control" id="cardholder-name" type="text" placeholder="{{ ctrans('texts.name') }}">
</div>
<!-- placeholder for Elements -->
<div class="form-group">
<div id="card-element" class="form-control"></div>
</div>
<div class="form-check form-check-inline mr-1">
<input class="form-check-input" id="token_billing_checkbox" type="checkbox">
<label class="form-check-label" for="token_billing_checkbox">{{ ctrans('texts.token_billing_checkbox') }}</label>
</div>
<div id="card-errors" role="alert"></div>
<div class="form-group">
<button id="card-button" class="btn btn-primary pull-right" data-secret="{{ $intent->client_secret }}">
{{ ctrans('texts.pay_now') }}
</button>
</div>
</div>
@endif
@endsection
@push('scripts')
<script src="https://js.stripe.com/v3/"></script>
<script type="text/javascript">
var stripe = Stripe('{{ $gateway->getPublishableKey() }}');
var elements = stripe.elements();
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = cardButton.dataset.secret;
@if($token)
cardButton.addEventListener('click', function(ev) {
stripe.handleCardPayment(
clientSecret, {
payment_method: '{{$token->token}}',
}
).then(function(result) {
if (result.error) {
$("#card-errors").empty();
$("#card-errors").append("<b>" + result.error.message + "</b>");
$("#card-button").removeAttr("disabled");
$("#store_card").val(0);
} else {
// The setup has succeeded. Display a success message.
console.log(result);
postResult(result);
}
});
});
@else
var cardElement = elements.create('card');
cardElement.mount('#card-element');
cardButton.addEventListener('click', function(ev) {
stripe.handleCardPayment(
clientSecret, cardElement, {
payment_method_data: {
billing_details: {name: cardholderName.value}
}
}
).then(function(result) {
if (result.error) {
$("#card-errors").empty();
$("#card-errors").append("<b>" + result.error.message + "</b>");
$("#card-button").removeAttr("disabled");
} else {
// The setup has succeeded. Display a success message.
console.log(result);
postResult(result);
}
});
});
$("#card-button").attr("disabled", true);
$('#cardholder-name').on('input',function(e){
if($("#cardholder-name").val().length >=1)
$("#card-button").removeAttr("disabled");
else
$("#card-button").attr("disabled", true);
});
@endif
function postResult(result)
{
$("#gateway_response").val(JSON.stringify(result.paymentIntent));
$("#store_card").val($('#token_billing_checkbox').is(":checked"));
$("#card-button").attr("disabled", true);
$('#server_response').submit();
}
</script>
@endpush
@push('css')
<style type="text/css">
.StripeElement {
box-sizing: border-box;
height: 40px;
padding: 10px 12px;
border: 1px solid transparent;
border-radius: 4px;
background-color: white;
box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease;
}
.StripeElement--focus {
box-shadow: 0 1px 3px 0 #cfd7df;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
</style>
@endpush

View File

@ -1,61 +0,0 @@
<body class="app header-fixed sidebar-fixed aside-menu-fixed sidebar-lg-show">
<header class="app-header navbar">
<button class="navbar-toggler sidebar-toggler d-lg-none mr-auto" type="button" data-toggle="sidebar-show">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="{!! $settings->website ?: 'https://invoiceninja.com' !!}">
<img class="navbar-brand-full" src="{!! $settings->company_logo ?: '/images/logo.png' !!}" width="50" height="50" alt="Invoice Ninja Logo">
<img class="navbar-brand-minimized" src="{!! $settings->company_logo ?: '/images/logo.png' !!}" width="30" height="30" alt="Invoice Ninja Logo">
</a>
<button class="navbar-toggler sidebar-toggler sidebar-minimizer" type="button" data-toggle="sidebar-show">
<span class="navbar-toggler-icon"></span>
</button>
<ul class="nav navbar-nav ml-auto">
<li class="nav-item dropdown d-md-down-none" style="padding-left:20px; padding-right: 20px;">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-envelope" aria-hidden="true"></i>
<span class="badge badge-pill badge-warning">15</span>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-lg">
<div class="dropdown-header text-center">
<strong>{{ trans('texts.notifications')}}</strong>
</div>
<a class="dropdown-item" href="#">
<div class="small mb-1">Mr Miyagi todos
<span class="float-right">
<strong>0%</strong>
</span>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
<a class="dropdown-item text-center" href="#">
<strong>{{ trans('texts.more')}}</strong>
</a>
</div>
</li>
<li class="nav-item dropdown" style="padding-right: 20px;">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
@if(auth()->user()->avatar)
<img class="img-avatar" src="{{ auth()->user()->avatar }}" alt="" class="img-fluid"> {{ auth()->user()->present()->name() }}
@else
<img class="img-avatar" src="/images/logo.png" alt="" class="img-fluid"> {{ auth()->user()->present()->name() }}
@endif
</a>
<div class="dropdown-menu dropdown-menu-sm">
<div class="dropdown-header text-center">
<strong>{{ trans('texts.settings')}} </strong>
</div>
<a class="dropdown-item" href="{{ route('client.profile.edit', ['client_contact' => auth()->user()->hashed_id])}}">
<i class="fa fa-user"></i> @lang('texts.profile')</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ route('client.logout') }}">
<i class="fa fa-lock"></i> @lang('texts.logout')</a>
</div>
</li>
</ul>
</header>

View File

@ -1,271 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@parent
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet" type="text/css"/>
<link href="/vendors/css/select2.min.css" rel="stylesheet">
@stop
@section('body')
<main class="main">
<div class="container-fluid">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('payment_form')
->route('client.invoices.bulk')
->method('POST'); !!}
{!! Former::hidden('hashed_ids')->id('hashed_ids') !!}
{!! Former::hidden('action')->id('action') !!}
{!! Former::close() !!}
<div class="row" style="padding-top: 30px;">
@include('portal.default.flash-message')
<div class="col-lg-12" style="padding-bottom: 10px;">
<div class="pull-left">
<div class="btn-group">
<button type="button" class="btn btn-success" id="pay_invoices">{{ ctrans('texts.pay_now') }}</button>
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" id="pay_invoices_drop" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" id="download_invoices">{{ctrans('texts.download_pdf')}}</a>
</div>
</div>
<select class="form-control" style="width: 220px;" id="statuses" name="client_status[]" multiple="multiple">
<option value="paid">{{ ctrans('texts.status_paid') }}</option>
<option value="unpaid">{{ ctrans('texts.status_unpaid') }}</option>
<option value="overdue">{{ ctrans('texts.overdue') }}</option>
</select>
</div>
<!-- Filters / Buttons in here.-->
<div id="top_right_buttons" class="pull-right">
<input id="table_filter" type="text" style="width:180px;background-color: white !important"
class="form-control pull-left" placeholder="{{ trans('texts.filter')}}" value=""/>
</div>
</div>
</div>
<div class="row">
<div class="animated fadeIn col-lg-12 card mt-10">
{!! $html->table(['class' => 'table table-hover table-striped', 'id' => 'datatable'], true) !!}
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
<script src="/vendors/js/select2.min.js"></script>
<script>
/*global json payload*/
var data;
/*status filter variable - comma separated*/
var client_statuses;
var table_filter;
var data_table;
$(function() {
data_table = $('#datatable').DataTable({
processing: true,
serverSide: true,
searching: false,
bLengthChange: false,
language: {
processing: " {{ trans('texts.processing_request') }}",
search: "{{ trans('texts.search') }}:",
// info: "{{ trans('texts.info') }}",
infoPostFix: "",
loadingRecords: "{{ trans('texts.loading') }}",
zeroRecords: "{{ trans('texts.no_records_found') }}"
},
ajax: {
url: '{!! route('client.invoices.index') !!}',
data: function(data) {
data.client_status = client_statuses;
data.filter = table_filter;
}
},
drawCallback: function(settings){
data = this.api().ajax.json().data;
},
columns: [
{data: 'checkbox', name: 'checkbox', title: '<input type="checkbox" class="select_all" >', searchable: false, orderable: false},
{data: 'number', name: 'number', title: '{{ctrans('texts.invoice_number')}}', visible: true},
{data: 'date', name: 'date', title: '{{ctrans('texts.invoice_date')}}', visible: true},
{data: 'amount', name: 'amount', title: '{{ctrans('texts.total')}}', visible: true},
{data: 'balance', name: 'balance', title: '{{ctrans('texts.balance')}}', visible: true},
{data: 'due_date', name: 'due_date', title: '{{ctrans('texts.due_date')}}', visible: true},
{data: 'status_id', name: 'status_id', title: '{{ctrans('texts.status')}}', visible: true},
{data: 'action', name: 'action', title: '', searchable: false, orderable: false, width: '10%'},
]
});
});
</script>
<script>
var searchTimeout = false;
var selected = [];
$(document).ready(function() {
toggleButtonGroup();
$('#datatable').on('click', '.odd, .even' ,function(e) {
if($(e.target).is(':checkbox')) return; //ignore when click on the checkbox
var $cb= $(this).find('input[type="checkbox"]');
$cb.prop('checked', !$cb.is(':checked'));
buildCheckboxArray();
});
$("#datatable").on('change', 'input[type=checkbox]', function() {
buildCheckboxArray();
});
$('#table_filter').on('keyup', function(){
if (searchTimeout) {
window.clearTimeout(searchTimeout);
}
searchTimeout = setTimeout(function() {
filterTable();
}, 500);
});
$('.select_all').change(function() {
$(this).closest('table').find(':checkbox:not(:disabled)').prop('checked', this.checked);
});
$('#pay_invoices').click(function() {
$('#pay_invoices').addClass('disabled');
$('#pay_invoices_drop').addClass('disabled');
$('#download_invoices').addClass('disabled');
$('#hashed_ids').val(selected);
$('#action').val('payment');
$('#payment_form').submit();
});
$('#download_invoices').click(function() {
$('#hashed_ids').val(selected);
$('#action').val('download');
$('#payment_form').submit();
});
});
function buildCheckboxArray()
{
selected = [];
$.each($("input[name='hashed_ids[]']:checked"), function(){
selected.push($(this).val());
});
toggleButtonGroup();
}
function toggleButtonGroup()
{
if(selected.length == 0)
{
$('#pay_invoices').addClass('disabled');
$('#pay_invoices_drop').addClass('disabled');
$('#download_invoices').addClass('disabled');
}
else
{
$('#pay_invoices').removeClass('disabled');
$('#pay_invoices_drop').removeClass('disabled');
$('#download_invoices').removeClass('disabled');
}
}
function filterTable() {
table_filter = $('#table_filter').val();
data_table.ajax.reload();
}
function payInvoice(hashed_id) {
$('#pay_invoices_drop').addClass('disabled');
$('#download_invoices').addClass('disabled');
$('#hashed_ids').val(hashed_id);
$('#action').val('payment');
$('#payment_form').submit();
}
// Setup status filter
$('#statuses').select2({
placeholder: "{{ ctrans('texts.status') }}",
//allowClear: true,
templateSelection: function(data, container) {
if (data.id == 'paid') {
$(container).css('color', '#fff');
$(container).css('background-color', '#00c979');
$(container).css('border-color', '#00a161');
} else if (data.id == 'unpaid') {
$(container).css('color', '#fff');
$(container).css('background-color', '#f0ad4e');
$(container).css('border-color', '#eea236');
} else if (data.id == 'overdue') {
$(container).css('color', '#fff');
$(container).css('background-color', '#d9534f');
$(container).css('border-color', '#d43f3a');
}
return data.text;
}
}).on('change', function() {
client_statuses = $('#statuses').val();
if (client_statuses) {
client_statuses = client_statuses.join(',');
} else {
client_statuses = '';
}
data_table.ajax.reload();
});
</script>
@endpush

View File

@ -1,222 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@stop
@section('body')
<main class="main">
<div class="container-fluid">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('payment_form')
->route('client.payments.process')
->method('POST'); !!}
{!! Former::hidden('hashed_ids')->id('hashed_ids')->value($hashed_ids) !!}
{!! Former::hidden('company_gateway_id')->id('company_gateway_id') !!}
{!! Former::hidden('payment_method_id')->id('payment_method_id') !!}
{!! Former::close() !!}
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.payment')}}
</div>
<div class="card-body">
<div class="list-group">
@foreach($invoices as $invoice)
<a class="list-group-item list-group-item-action flex-column align-items-start" href="javascript:void(0);">
<div class="d-flex w-100 justify-content-between">
<h5 class="mr-4"># {{ $invoice->number }}</h5>
<small>{{ $invoice->due_date }}</small>
</div>
<p class="mb-1 pull-right">{{ $invoice->balance }}</p>
<small>
@if($invoice->po_number)
{{ $invoice->po_number }}
@elseif($invoice->public_notes)
{{ $invoice->public_notes }}
@else
{{ $invoice->invoice_date}}
@endif
</small>
</a>
@endforeach
</div>
<div class="py-md-5">
<ul class="list-group">
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center"><strong>{{ ctrans('texts.total')}}</strong>
<h3><span class="badge badge-primary badge-pill"><strong>{{ $formatted_total }}</strong></span></h3>
</li>
</ul>
</div>
<div class="btn-group pull-right" role="group">
<button class="btn btn-primary dropdown-toggle" id="pay_now" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ ctrans('texts.pay_now') }}</button>
<div class="dropdown-menu" aria-labelledby="pay_now">
@foreach($payment_methods as $payment_method)
<a class="dropdown-item" onClick="paymentMethod({{ $payment_method['company_gateway_id'] }}, {{ $payment_method['gateway_type_id'] }})">{{$payment_method['label']}}</a>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Terms Modal -->
<div class="modal fade" id="terms_modal" tabindex="-1" role="dialog" aria-labelledby="terms_modal_ttle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="terms_modal_ttle">{{ ctrans('texts.terms') }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{!! $invoice->terms !!}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ ctrans('texts.close') }}</button>
<button type="button" class="btn btn-primary" id="terms_accepted">{{ trans('texts.agree_to_terms', ['terms' => trans('texts.invoice_terms')]) }}</button>
</div>
</div>
</div>
</div>
<!-- Authorization / Signature Modal -->
<div class="modal fade" id="signature_modal" tabindex="-1" role="dialog" aria-labelledby="authorizationModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="terms_modal_ttle">{{ ctrans('texts.authorization') }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" style="height:400px;">
<div>
{{ trans('texts.sign_here') }}
</div>
<div id="signature"></div><br/>
</div>
<div class="modal-footer">
<button id="modal_pay_now_button" type="button" class="btn btn-success" onclick="onModalPayNowClick()" disabled="">
{{ ctrans('texts.pay_now') }}
</button>
</div>
</div>
</div>
</div>
</body>
@endsection
@push('css')
<style type="text/css">
#signature {
border: 2px dotted black;
background-color:lightgrey;
}
</style>
@endpush
@push('scripts')
<script src="/vendors/js/jSignature.min.js"></script>
<script type="text/javascript">
var terms_accepted = false;
$('#pay_now').on('click', function(e) {
//check if terms must be accepted
@if($settings->show_accept_invoice_terms)
$('#terms_modal').modal('show');
@endif
@if($settings->require_invoice_signature)
getSignature();
@endif
});
$('#terms_accepted').on('click', function(e){
terms_accepted = true;
$('#terms_modal').modal('hide');
//push to payment
});
$("#modal_pay_now_button").on('click', function(e){
//disable to prevent firing twice
$("#modal_pay_now_button").attr("disabled", true);
});
function paymentMethod(company_gateway_id, payment_method_id)
{
$('#company_gateway_id').val(company_gateway_id);
$('#payment_method_id').val(payment_method_id);
$('#payment_form').submit();
}
function getSignature()
{
//check in signature is required
$("#signature").jSignature({ 'UndoButton': true, }).bind('change', function(e) {
if( $("#signature").jSignature('getData', 'native').length >= 1) {
$("#modal_pay_now_button").removeAttr("disabled");
} else {
$("#modal_pay_now_button").attr("disabled", true);
}
});
$("#signature").resize();
$("#signature").jSignature('reset');
$('#signature_modal').modal();
}
function onModalPayNowClick() {
var data = {
signature: $('#signature').jSignature('getData', 'svgbase64')[1]
};
//var data = false;
}
</script>
@endpush
@section('footer')
@endsection

View File

@ -1,46 +0,0 @@
@extends('portal.default.layouts.master')
@section('body')
<main class="main">
<div class="container-fluid">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('payment_form')
->route('client.invoices.bulk')
->method('POST'); !!}
{!! Former::hidden('hashed_ids')->id('hashed_ids')->value( $invoice->hashed_id ) !!}
{!! Former::hidden('action')->id('action')->value('payment') !!}
<div class="row mt-4">
<div class="col-md-12">
@if($invoice->isPayable())
<div class="float-right">
<button class="btn btn-primary">{{ ctrans('texts.pay_now') }}</button>
</div>
@endif
</div>
</div>
{!! Former::close() !!}
<div class="row mt-4">
<div class="col-md-12">
<embed src="{{ $invoice->pdf_file_path() }}#toolbar=1&navpanes=1&scrollbar=1" type="application/pdf" width="100%" height="1180px" />
<div id="pdfCanvas" style="display:none;width:100%;background-color:#525659;border:solid 2px #9a9a9a;padding-top:40px;text-align:center">
<canvas id="theCanvas" style="max-width:100%;border:solid 1px #CCCCCC;"></canvas>
</div>
</div>
</div>
</main>
</body>
@endsection

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<!-- Source: https://github.com/invoiceninja/invoiceninja -->
<!-- Error: {{ session('error') }} -->
@if (config('services.analytics.tracking_id'))
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-122229484-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{ config('services.analytics.tracking_id') }}', { 'anonymize_ip': true });
function trackEvent(category, action) {
ga('send', 'event', category, action, this.src);
}
</script>
<script>
Vue.config.devtools = true;
</script>
@else
<script>
function gtag(){}
</script>
@endif
<meta charset="utf-8">
<title>@yield('meta_title', 'Invoice Ninja') | {{ config('app.name') }}</title>
<meta name="description" content="@yield('meta_description')"/>
<link href="{{ asset('favicon.png') }}" rel="shortcut icon" type="image/png">
<base href="./">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="author" content="">
<meta name="keyword" content="">
<!-- Icons-->
<link href="/vendors/css/coreui-icons.min.css" rel="stylesheet">
<link href="/vendors/css/font-awesome.min.css" rel="stylesheet">
<!-- Main styles for this application-->
<link href="/vendors/css/bootstrap.min.css" rel="stylesheet">
<link href="/vendors/css/coreui.min.css" rel="stylesheet">
@yield('head')
</head>
@section('body')
@yield('body')
</html>

View File

@ -1,71 +0,0 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<!-- Source: https://github.com/invoiceninja/invoiceninja -->
<!-- Error: {{ session('error') }} -->
@if (config('services.analytics.tracking_id'))
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-122229484-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{ config('services.analytics.tracking_id') }}', { 'anonymize_ip': true });
function trackEvent(category, action) {
ga('send', 'event', category, action, this.src);
}
</script>
<script>
Vue.config.devtools = true;
</script>
@else
<script>
function gtag(){}
</script>
@endif
@php
$user = auth()->guard('contact')->user();
@endphp
<meta charset="utf-8">
<title>@yield('meta_title', 'Invoice Ninja') | {{ config('app.name') }}</title>
<meta name="description" content="@yield('meta_description')"/>
<link href="{{ asset('favicon.png') }}" rel="shortcut icon" type="image/png">
<base href="./">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="author" content="Hillel Coren, David Bomba">
<meta name="keyword" content="">
<!-- Icons-->
<link href="/vendors/css/coreui-icons.min.css" rel="stylesheet">
<link href="/vendors/css/font-awesome.min.css" rel="stylesheet">
<!-- Main styles for this application-->
<link href="/vendors/css/bootstrap.min.css" rel="stylesheet">
<link href="/vendors/css/coreui.min.css" rel="stylesheet">
<style type="text/css">
.nav {min-height: calc(100% - 55px);}
</style>
@stack('css')
@yield('head')
</head>
@include('portal.default.header')
@yield('header')
@include('portal.default.sidebar')
@yield('sidebar')
@section('body')
@yield('body')
@include('portal.default.footer')
@yield('footer')
</html>
<script type="text/javascript">
@if($settings->enable_client_portal === false)
$('.navbar-toggler-icon').hide();
$('.app').removeClass("sidebar-lg-show");
$('.app').addClass("sidebar-hidden");
@endif
</script>

View File

@ -1,92 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@parent
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet" type="text/css"/>
<link href="/vendors/css/select2.min.css" rel="stylesheet">
@stop
@section('body')
<main class="main">
<div class="container-fluid">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('payment_form')
->route('client.invoices.bulk')
->method('POST'); !!}
{!! Former::hidden('hashed_ids')->id('hashed_ids') !!}
{!! Former::hidden('action')->id('action') !!}
{!! Former::close() !!}
<div class="row" style="padding-top: 30px;">
<div class="col-lg-12" style="padding-bottom: 10px;">
<!-- Filters / Buttons in here.-->
@if(auth()->user()->client->getCreditCardGateway())
<div id="top_right_buttons" class="pull-right">
<a href="{{ route('client.payment_methods.create')}}" class="btn btn-success">{{ ctrans('texts.add_payment_method') }}</a>
</div>
@endif
</div>
</div>
<div class="row">
<div class="animated fadeIn col-lg-12 card mt-10">
{!! $html->table(['class' => 'table table-hover table-striped', 'id' => 'datatable'], true) !!}
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
<script>
/*global json payload*/
var data;
var data_table;
$(function() {
data_table = $('#datatable').DataTable({
processing: true,
serverSide: true,
searching: false,
bLengthChange: false,
language: {
processing: " {{ trans('texts.processing_request') }}",
search: "{{ trans('texts.search') }}:",
// info: "{{ trans('texts.info') }}",
infoPostFix: "",
loadingRecords: "{{ trans('texts.loading') }}",
zeroRecords: "{{ trans('texts.no_records_found') }}"
},
ajax: {
url: '{!! route('client.payment_methods.index') !!}'
},
columns: [
{data: 'created_at', name: 'created_at', title: '{{ctrans('texts.created_at')}}', visible: true},
{data: 'gateway_type_id', name: 'gateway_type_id', title: '{{ctrans('texts.payment_type_id')}}', visible: true},
{data: 'brand', name: 'brand', title: '{{ctrans('texts.type')}}', visible: true},
{data: 'meta', name: 'meta', title: '{{ctrans('texts.expires')}}', visible: true},
{data: 'last4', name: 'last4', title: '{{ctrans('texts.card_number')}}', visible: true},
{data: 'is_default', name: 'is_default', title: '{{ctrans('texts.default')}}', visible: true},
{data: 'action', name: 'action', title: '', searchable: false, orderable: false},
]
});
});
</script>
@endpush

View File

@ -1,67 +0,0 @@
@section('meta_title', __('texts.payment_methods'))
@extends('portal.default.layouts.master')
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row mt-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
</div>
<div class="card-body">
<p>
<b>{{ ctrans('texts.payment_type') }}:</b>
{{ $payment_method->gateway_type->name }}
</p>
<p>
<b>{{ ctrans('texts.type') }}:</b>
{{ ucfirst($payment_method->meta->brand) }}
</p>
<p>
<b>{{ ctrans('texts.card_number') }}:</b>
**** **** **** {{ ucfirst($payment_method->meta->last4) }}
</p>
@isset($payment_method->meta->exp_month)
<p>
<b>{{ ctrans('texts.expires') }}:</b>
{{ "{$payment_method->meta->exp_month}/{$payment_method->meta->exp_year}" }}
</p>
@endisset
<p>
<b>{{ ctrans('texts.date_created') }}:</b>
{{ date(auth()->user()->client->date_format(), $payment_method->created_at) }}
</p>
<p class="mb-0">
<b>{{ ctrans('texts.default') }}:</b>
{{ $payment_method->is_default ? ctrans('texts.yes') : ctrans('texts.no') }}
</p>
</div>
</div>
</div>
<div class="col-md-12">
<div class="card">
<div class="card-header">
{{ ctrans("texts.delete_payment_method") }}
</div>
<div class="card-body">
<p class="mb-0">
{{ ctrans('texts.about_to_delete_payment_method') }}
{{ ctrans('texts.action_cant_be_reversed') }}.
</p>
</div>
<div class="card-footer d-flex justify-content-end">
{!! Former::horizontal_open()->route('client.payment_methods.destroy', $payment_method->hashed_id)->method('DELETE') !!}
<button class="btn btn-danger btn-sm">{{ ctrans('texts.i_understand_delete') }}</button>
{!! Former::close() !!}
</div>
</div>
</div>
</div>
</div>
</main>
@endsection

View File

@ -1,82 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@parent
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet" type="text/css"/>
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col-lg-12" style="padding-bottom: 10px;">
<div class="animated fadeIn">
<div class="col-md-12 card">
{!! $html->table(['class' => 'table table-hover table-striped', 'id' => 'datatable'], true) !!}
</div>
</div>
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
@endpush
@section('footer')
<script>
/*global json payload*/
var data;
var data_table;
$(function() {
data_table = $('#datatable').DataTable({
processing: true,
serverSide: true,
searching: false,
bLengthChange: false,
language: {
processing: " {{ trans('texts.processing_request') }}",
search: "{{ trans('texts.search') }}:",
// info: "{{ trans('texts.info') }}",
infoPostFix: "",
loadingRecords: "{{ trans('texts.loading') }}",
zeroRecords: "{{ trans('texts.no_records_found') }}"
},
ajax: {
url: '{!! route('client.payments.index') !!}',
data: function(data) {
}
},
drawCallback: function(settings){
data = this.api().ajax.json().data;
},
columns: [
{data: 'date', name: 'date', title: '{{ctrans('texts.payment_date')}}', visible: true},
{data: 'type_id', name: 'type_id', title: '{{ctrans('texts.payment_type_id')}}', visible: true},
{data: 'amount', name: 'amount', title: '{{ctrans('texts.amount')}}', visible: true},
{data: 'transaction_reference', name: 'transaction_reference', title: '{{ctrans('texts.transaction_reference')}}', visible: true},
{data: 'status_id', name: 'status_id', title: '{{ctrans('texts.status')}}', visible: true},
{data: 'action', name: 'action', title: '', searchable: false, orderable: false}
]
});
});
</script>
@endsection

View File

@ -1,43 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.payment')}}
</div>
<div class="card-body">
<table class="table table-responsive-sm table-bordered">
<tr><td style="text-align: right;">{{ctrans('texts.payment_date')}}</td><td>{!! $payment->clientPaymentDate() !!}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.transaction_reference')}}</td><td>{{$payment->transaction_reference}}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.method')}}</td><td>{{$payment->type->name}}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.amount')}}</td><td>{{$payment->formattedAmount()}}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.status')}}</td><td>{!! $payment::badgeForStatus($payment->status_id) !!}</td></tr>
</table>
<table class="table table-responsive-sm table-sm">
@foreach($payment->invoices as $invoice)
<tr><td style="text-align: right;">{{ ctrans('texts.invoice_number')}}</td><td><a href="{{ route('client.invoice.show', ['invoice' => $invoice->hashed_id])}}">{{ $invoice->number }}</a></td></tr>
@endforeach
</table>
</div>
</div>
</div>
</div>
</div>
</main>
</body>
@endsection
@push('css')
@endpush
@push('scripts')
@endpush
@section('footer')
@endsection

View File

@ -1,135 +0,0 @@
<div class="row">
<div class="col-sm-12">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open_for_files()
->id('update_settings')
->route('client.profile.edit_client', auth()->user()->hashed_id)
->method('PUT'); !!}
{!! Former::populate(auth()->user()->client) !!}
@csrf
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.client_information') }} </strong>
</div>
<div class="card-body">
<div class="row">
<div class="col-sm-4">
<div class="card align-items-center">
<div class="card-body">
@if(auth()->user()->client->logo)
<img src="{{ auth()->user()->client->logo }}" class="img-fluid">
@else
<i class="fa fa-user fa-5x"></i>
@endif
{!! Former::file('logo')
->max(2, 'MB')
->accept('image')
->label('')
->inlineHelp(trans('texts.logo_help')) !!}
</div>
</div>
</div>
<div class="col-sm-6 pull-left">
<div class="card card-body">
{!! Former::text('name')->label( ctrans('texts.name')) !!}
{!! Former::text('website')->label( ctrans('texts.website')) !!}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.address') }} </strong>
</div>
<div class="card-body">
{!! Former::text('address1')->label( ctrans('texts.address1')) !!}
{!! Former::text('address2')->label( ctrans('texts.address2')) !!}
{!! Former::text('city')->label( ctrans('texts.city')) !!}
{!! Former::text('state')->label( ctrans('texts.state')) !!}
{!! Former::text('postal_code')->label( ctrans('texts.postal_code')) !!}
{!! Former::select('country_id')
->addOption('','')
->autocomplete('off')
->label(ctrans('texts.country'))
->fromQuery($countries, 'name', 'id') !!}
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.shipping_address') }} </strong>
</div>
<div class="card-body">
{!! Former::text('shipping_address1')->label( ctrans('texts.shipping_address1')) !!}
{!! Former::text('shipping_address2')->label( ctrans('texts.shipping_address2')) !!}
{!! Former::text('shipping_city')->label(ctrans('texts.shipping_city')) !!}
{!! Former::text('shipping_state')->label(ctrans('texts.shipping_state')) !!}
{!! Former::text('shipping_postal_code')->label(ctrans('texts.shipping_postal_code')) !!}
{!! Former::select('shipping_country_id')
->addOption('','')
->autocomplete('off')
->label(ctrans('texts.shipping_country'))
->fromQuery($countries, 'name', 'id') !!}
</div>
</div>
</div>
</div>
<button class="btn btn-primary pull-right">{{ ctrans('texts.save') }}</button>
</div>
{!! Former::close() !!}
</div>
@push('scripts')
<script src="/vendors/js/select2.min.js"></script>
<script>
$(document).ready(function() {
$('#shipping_country_id').each(function () {
$(this).select2({
placeholder: "{{ ctrans('texts.country') }}",
theme: 'bootstrap4',
width: 'style',
allowClear: Boolean($(this).data('allow-clear')),
}).on('change', function() {
});
});
$('#country_id').each(function () {
$(this).select2({
placeholder: "{{ ctrans('texts.country') }}",
theme: 'bootstrap4',
width: 'style',
allowClear: Boolean($(this).data('allow-clear')),
});
});
});
</script>
@endpush

View File

@ -1,35 +0,0 @@
<div class="row">
<div class="col-sm-12">
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open()
->id('update_settings')
->route('client.profile.edit_localization', auth()->user()->hashed_id)
->method('PUT'); !!}
{!! Former::populate(auth()->user()->client->settings) !!}
@csrf
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.localization') }} </strong>
</div>
<div class="card-body">
{!! Former::text('timezone_id')->label( ctrans('texts.timezone_id')) !!}
{!! Former::text('language_id')->label( ctrans('texts.language')) !!}
{!! Former::text('date_format')->label( ctrans('texts.date_format')) !!}
{!! Former::text('datetime_format')->label( ctrans('texts.datetime_format')) !!}
<button class="btn btn-primary pull-right">{{ ctrans('texts.save') }}</button>
</div>
{!! Former::close() !!}
</div>

View File

@ -1,68 +0,0 @@
@extends('portal.default.layouts.master')
@push('css')
<link href="/vendors/css/select2.min.css" rel="stylesheet">
<link href="/vendors/css/select2-bootstrap4.css" rel="stylesheet">
<style>
select {border: 1px solid !important;}
.select2-container--bootstrap4 .select2-selection--single {border: 1px solid #e4e7ea !important;}
.control-label {text-align:right;}
</style>
@endpush
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col-sm-12">
<div class="card">
<div class="card-header">
<strong> {{ ctrans('texts.details') }}</strong>
</div>
{!! Former::framework('TwitterBootstrap4'); !!}
{!! Former::horizontal_open_for_files()
->id('update_contact')
->route('client.profile.update', auth()->user()->hashed_id)
->method('PUT'); !!}
@csrf
<div class="card-body">
<div class="row">
<div class="col-sm-8">
<div class="card">
<div class="card-body">
{!! Former::text('first_name')->label( ctrans('texts.first_name'))->value(auth()->user()->first_name) !!}
{!! Former::text('last_name')->placeholder('')->label( ctrans('texts.last_name'))->value(auth()->user()->last_name) !!}
{!! Former::text('email')->placeholder('')->label(ctrans('texts.email'))->value(auth()->user()->email) !!}
{!! Former::text('phone')->placeholder('')->label(ctrans('texts.phone'))->value(auth()->user()->phone) !!}
{!! Former::password('password')->placeholder('')->label(ctrans('texts.password')) !!}
{!! Former::password('password_confirmation')->placeholder('')->label(ctrans('texts.confirm_password')) !!}
<div>
<button class="btn btn-primary pull-right">{{ ctrans('texts.save') }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{!! Former::close() !!}
@include('portal.default.profile.client_information')
</div>
</main>
</body>
@endsection
@section('footer')
@endsection

View File

@ -1,82 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@parent
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet" type="text/css"/>
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col-lg-12" style="padding-bottom: 10px;">
<div class="animated fadeIn">
<div class="col-md-12 card">
{!! $html->table(['class' => 'table table-hover table-striped', 'id' => 'datatable'], true) !!}
</div>
</div>
</div>
</div>
</div>
</main>
</body>
@endsection
@push('scripts')
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
@endpush
@section('footer')
<script>
/*global json payload*/
var data;
var data_table;
$(function() {
data_table = $('#datatable').DataTable({
processing: true,
serverSide: true,
searching: false,
bLengthChange: false,
language: {
processing: " {{ trans('texts.processing_request') }}",
search: "{{ trans('texts.search') }}:",
// info: "{{ trans('texts.info') }}",
infoPostFix: "",
loadingRecords: "{{ trans('texts.loading') }}",
zeroRecords: "{{ trans('texts.no_records_found') }}"
},
ajax: {
url: '{!! route('client.recurring_invoices.index') !!}',
data: function(data) {
}
},
drawCallback: function(settings){
data = this.api().ajax.json().data;
},
columns: [
{data: 'frequency_id', name: 'frequency_id', title: '{{trans('texts.frequency')}}', visible: true},
{data: 'start_date', name: 'start_date', title: '{{trans('texts.start_date')}}', visible: true},
{data: 'next_send_date', name: 'next_send_date', title: '{{trans('texts.next_send_date')}}', visible: true},
{data: 'remaining_cycles', name: 'remaining_cycles', title: '{{trans('texts.cycles_remaining')}}', visible: true},
{data: 'amount', name: 'amount', title: '{{trans('texts.amount')}}', visible: true},
{data: 'action', name: 'action', title: '', searchable: false, orderable: false},
]
});
});
</script>
@endsection

View File

@ -1,43 +0,0 @@
@extends('portal.default.layouts.master')
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.cancellation') }}
</div>
<div class="card-body">
<table class="table table-responsive-sm table-bordered">
<tr>
<td style="text-align: right;">{{ctrans('texts.start_date')}}</td>
<td>{!! $invoice->start_date !!}</td>
</tr>
<tr>
<td style="text-align: right;">{{ctrans('texts.next_send_date')}}</td>
<td>{!! $invoice->next_send_date !!}</td>
</tr>
<tr>
<td style="text-align: right;">{{ctrans('texts.frequency')}}</td>
<td>{!! App\Models\RecurringInvoice::frequencyForKey($invoice->frequency_id) !!}</td>
</tr>
<tr>
<td style="text-align: right;">{{ctrans('texts.cycles_remaining')}}</td>
<td>{!! $invoice->remaining_cycles !!}</td>
</tr>
<tr>
<td style="text-align: right;">{{ctrans('texts.amount')}}</td>
<td>{!! $invoice->amount !!}</td>
</tr>
</table>
<div class="alert alert-primary" role="alert">{{ ctrans('texts.cancellation_pending') }}</div>
</div>
</div>
</div>
</div>
</div>
</main>
@endsection

View File

@ -1,70 +0,0 @@
@extends('portal.default.layouts.master')
@section('header')
@stop
@section('body')
<main class="main">
<div class="container-fluid">
<div class="row" style="padding-top: 30px;">
<div class="col d-flex justify-content-center">
<div class="card w-50 p-10">
<div class="card-header">
{{ ctrans('texts.recurring_invoice')}}
</div>
<div class="card-body">
<table class="table table-responsive-sm table-bordered">
<tr><td style="text-align: right;">{{ctrans('texts.start_date')}}</td><td>{!! $invoice->formatDate($invoice->start_date,$invoice->client->date_format()) !!}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.next_send_date')}}</td><td>{!! $invoice->formatDate($invoice->next_send_date,$invoice->client->date_format()) !!}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.frequency')}}</td><td>{!! App\Models\RecurringInvoice::frequencyForKey($invoice->frequency_id) !!}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.cycles_remaining')}}</td><td>{!! $invoice->remaining_cycles !!}</td></tr>
<tr><td style="text-align: right;">{{ctrans('texts.amount')}}</td><td>{!! App\Utils\Number::formatMoney($invoice->amount, $invoice->client) !!}</td></tr>
</table>
<table class="table table-responsive-sm table-sm">
@foreach($invoice->invoices as $inv)
{{ $inv->id }} - {{ $inv->amount }}
@endforeach
</table>
@if($invoice->remaining_cycles >=1)
<div class="pull-right">
<button class="btn btn-danger mb-1" type="button" data-toggle="modal" data-target="#cancel_recurring">Request Cancellation</button>
</div>
@endif
</div>
</div>
</div>
</div>
</div>
</main>
<div class="modal fade show" id="cancel_recurring" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-danger" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Request Cancellation</h4>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Warning! You are requesting a cancellation of this service.</p>
<p>Your service may be cancelled with no further notification to you.</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Close</button>
<a href="{{ route('client.recurring_invoices.request_cancellation',['recurring_invoice' => $invoice->hashed_id]) }}" class="btn btn-danger">Confirm Cancellation</a>
</div>
</div>
</div>
</div>
</body>
@endsection
@push('css')
@endpush
@push('scripts')
@endpush
@section('footer')
@endsection

View File

@ -1,15 +0,0 @@
<div class="app-body">
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
@foreach($sidebar as $row)
<li class="nav-item">
<a class="nav-link" href="{{ route($row['url']) }}">
<i class="nav-icon {{$row['icon']}}"></i> {{ $row['title'] }}
</a>
</li>
@endforeach
</ul>
</nav>
<button class="sidebar-minimizer brand-minimizer" type="button"></button>
</div>