mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Client portal improvements (#3652)
* Install livewire/livewire * Table improvements - Cleanup of InvoiceController - Added Livewire package - New Livewire component (InvoicesTable) - New WithSorting trait - Removed rendering invoices from index.blade.php - Removed Yaryabox/Datatables references in InvoiceController * Refactor: Recurring invoices * payments table & sorting improvements * payment methods table * quotes table * credits table * Add turbolinks
This commit is contained in:
parent
280e42d366
commit
ab8b05dd56
@ -16,11 +16,7 @@ class CreditController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$credits = auth()->user()->company->credits()->paginate(10);
|
return $this->render('credits.index');
|
||||||
|
|
||||||
return $this->render('credits.index', [
|
|
||||||
'credits' => $credits,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(ShowCreditRequest $request, Credit $credit)
|
public function show(ShowCreditRequest $request, Credit $credit)
|
||||||
|
@ -11,12 +11,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Filters\InvoiceFilters;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\ClientPortal\ProcessInvoicesInBulkRequest;
|
use App\Http\Requests\ClientPortal\ProcessInvoicesInBulkRequest;
|
||||||
use App\Http\Requests\ClientPortal\ShowInvoiceRequest;
|
use App\Http\Requests\ClientPortal\ShowInvoiceRequest;
|
||||||
use App\Http\Requests\Request;
|
|
||||||
use App\Jobs\Entity\ActionEntity;
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Utils\Number;
|
use App\Utils\Number;
|
||||||
use App\Utils\TempFile;
|
use App\Utils\TempFile;
|
||||||
@ -24,52 +21,26 @@ use App\Utils\Traits\MakesDates;
|
|||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use ZipStream\Option\Archive;
|
use ZipStream\Option\Archive;
|
||||||
use ZipStream\ZipStream;
|
use ZipStream\ZipStream;
|
||||||
use function GuzzleHttp\Promise\all;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class InvoiceController
|
|
||||||
* @package App\Http\Controllers\ClientPortal\InvoiceController
|
|
||||||
*/
|
|
||||||
|
|
||||||
class InvoiceController extends Controller
|
class InvoiceController extends Controller
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash, MakesDates;
|
||||||
use MakesDates;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the list of Invoices
|
* Display list of invoices.
|
||||||
*
|
|
||||||
* @param \App\Filters\InvoiceFilters $filters The filters
|
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function index(InvoiceFilters $filters)
|
public function index()
|
||||||
{
|
{
|
||||||
$invoices = Invoice::filter($filters)->get(); // @for-now
|
return $this->render('invoices.index');
|
||||||
|
|
||||||
return $this->render('invoices.index', ['invoices' => $invoices]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildClientButtons($invoice)
|
|
||||||
{
|
|
||||||
$buttons = '<div>';
|
|
||||||
|
|
||||||
if ($invoice->isPayable()) {
|
|
||||||
$buttons .= "<button type=\"button\" class=\"btn btn-sm btn-info\" onclick=\"payInvoice('".$invoice->hashed_id."')\"><i class=\"glyphicon glyphicon-edit\"></i>".ctrans('texts.pay_now')."</button>";
|
|
||||||
// $buttons .= '<a href="/client/invoices/'. $invoice->hashed_id .'" class="btn btn-sm btn-info"><i class="glyphicon glyphicon-edit"></i>'.ctrans('texts.pay_now').'</a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
$buttons .= '<a href="/client/invoices/'. $invoice->hashed_id .'" class="btn btn-sm btn-primary"><i class="glyphicon glyphicon-edit"></i>'.ctrans('texts.view').'</a>';
|
|
||||||
|
|
||||||
$buttons .="</div>";
|
|
||||||
|
|
||||||
return $buttons;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Display the specified resource.
|
* Show specific invoice.
|
||||||
*
|
*
|
||||||
* @param \App\Models\Invoice $invoice The invoice
|
* @param \App\Http\Requests\ClientPortal\ShowInvoiceRequest $request
|
||||||
|
* @param \App\Models\Invoice $invoice
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
@ -85,7 +56,7 @@ class InvoiceController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pay one or more invoices
|
* Pay one or more invoices.
|
||||||
*
|
*
|
||||||
* @param ProcessInvoicesInBulkRequest $request
|
* @param ProcessInvoicesInBulkRequest $request
|
||||||
* @return mixed
|
* @return mixed
|
||||||
@ -142,6 +113,13 @@ class InvoiceController extends Controller
|
|||||||
return $this->render('invoices.payment', $data);
|
return $this->render('invoices.payment', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to download invoice PDFs.
|
||||||
|
*
|
||||||
|
* @param array $ids
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function downloadInvoicePDF(array $ids)
|
private function downloadInvoicePDF(array $ids)
|
||||||
{
|
{
|
||||||
$invoices = Invoice::whereIn('id', $ids)
|
$invoices = Invoice::whereIn('id', $ids)
|
||||||
|
@ -35,19 +35,13 @@ class PaymentController extends Controller
|
|||||||
use MakesDates;
|
use MakesDates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the list of Invoices
|
* Show the list of payments.
|
||||||
*
|
*
|
||||||
* @param PaymentFilters $filters The filters
|
|
||||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
public function index(PaymentFilters $filters)
|
public function index()
|
||||||
{
|
{
|
||||||
//$payments = Payment::filter($filters);
|
return $this->render('payments.index');
|
||||||
$payments = Payment::with('type', 'client')->paginate(10);
|
|
||||||
|
|
||||||
return $this->render('payments.index', [
|
|
||||||
'payments' => $payments,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,17 +27,10 @@ class PaymentMethodController extends Controller
|
|||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$payment_methods = ClientGatewayToken::with('gateway_type')
|
return $this->render('payment_methods.index');
|
||||||
->whereClientId(auth()->user()->client->id)
|
|
||||||
->paginate(10);
|
|
||||||
|
|
||||||
return $this->render('payment_methods.index', [
|
|
||||||
'payment_methods' => $payment_methods,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,11 +23,7 @@ class QuoteController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$quotes = auth()->user()->company->quotes()->paginate(10);
|
return $this->render('quotes.index');
|
||||||
|
|
||||||
return $this->render('quotes.index', [
|
|
||||||
'quotes' => $quotes,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,18 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\ClientPortal\ShowRecurringInvoiceRequest;
|
|
||||||
use App\Models\RecurringInvoice;
|
|
||||||
use App\Notifications\ClientContactRequestCancellation;
|
|
||||||
use App\Notifications\ClientContactResetPassword;
|
|
||||||
use App\Utils\Number;
|
|
||||||
use App\Utils\Traits\MakesDates;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Support\Facades\Notification;
|
use App\Utils\Traits\MakesDates;
|
||||||
use Yajra\DataTables\Facades\DataTables;
|
use App\Models\RecurringInvoice;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Notifications\ClientContactRequestCancellation;
|
||||||
|
use App\Http\Requests\ClientPortal\ShowRecurringInvoiceRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvoiceController
|
* Class InvoiceController
|
||||||
@ -41,15 +36,7 @@ class RecurringInvoiceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$invoices = RecurringInvoice::whereClientId(auth()->user()->client->id)
|
return $this->render('recurring_invoices.index');
|
||||||
->whereIn('status_id', [RecurringInvoice::STATUS_PENDING, RecurringInvoice::STATUS_ACTIVE, RecurringInvoice::STATUS_COMPLETED])
|
|
||||||
->orderBy('status_id', 'asc')
|
|
||||||
->with('client')
|
|
||||||
->paginate(10);
|
|
||||||
|
|
||||||
return $this->render('recurring_invoices.index', [
|
|
||||||
'invoices' => $invoices,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
27
app/Http/Livewire/CreditsTable.php
Normal file
27
app/Http/Livewire/CreditsTable.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class CreditsTable extends Component
|
||||||
|
{
|
||||||
|
use WithPagination;
|
||||||
|
use WithSorting;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$query = Credit::query()
|
||||||
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||||
|
->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.credits-table', [
|
||||||
|
'credits' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
48
app/Http/Livewire/InvoicesTable.php
Normal file
48
app/Http/Livewire/InvoicesTable.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo: Integrate InvoiceFilters
|
||||||
|
*/
|
||||||
|
class InvoicesTable extends Component
|
||||||
|
{
|
||||||
|
use WithPagination, WithSorting;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
|
||||||
|
public $status = [];
|
||||||
|
|
||||||
|
public function statusChange($status)
|
||||||
|
{
|
||||||
|
if (in_array($status, $this->status)) {
|
||||||
|
return $this->status = array_diff($this->status, [$status]);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($this->status, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$query = Invoice::query();
|
||||||
|
$query = $query->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||||
|
|
||||||
|
// So $status_id will come in three way:
|
||||||
|
// paid, unpaid & overdue. Need to transform them to real values.
|
||||||
|
|
||||||
|
if (count($this->status)) {
|
||||||
|
$query = $query->whereIn('status_id', $this->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $query->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.invoices-table', [
|
||||||
|
'invoices' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
35
app/Http/Livewire/PaymentMethodsTable.php
Normal file
35
app/Http/Livewire/PaymentMethodsTable.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class PaymentMethodsTable extends Component
|
||||||
|
{
|
||||||
|
use WithPagination;
|
||||||
|
use WithSorting;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
public $client;
|
||||||
|
|
||||||
|
public function mount($client)
|
||||||
|
{
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$query = ClientGatewayToken::query()
|
||||||
|
->with('gateway_type')
|
||||||
|
->where('client_id', $this->client->id)
|
||||||
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||||
|
->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.payment-methods-table', [
|
||||||
|
'payment_methods' => $query,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
34
app/Http/Livewire/PaymentsTable.php
Normal file
34
app/Http/Livewire/PaymentsTable.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Payment;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class PaymentsTable extends Component
|
||||||
|
{
|
||||||
|
use WithSorting;
|
||||||
|
use WithPagination;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->user = auth()->user();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$query = Payment::query()
|
||||||
|
->with('type', 'client')
|
||||||
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||||
|
->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.payments-table', [
|
||||||
|
'payments' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
45
app/Http/Livewire/QuotesTable.php
Normal file
45
app/Http/Livewire/QuotesTable.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Quote;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class QuotesTable extends Component
|
||||||
|
{
|
||||||
|
use WithSorting;
|
||||||
|
use WithPagination;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
public $status = [];
|
||||||
|
|
||||||
|
public function statusChange($status)
|
||||||
|
{
|
||||||
|
if (in_array($status, $this->status)) {
|
||||||
|
return $this->status = array_diff($this->status, [$status]);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($this->status, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
// So $status_id will come in three way:
|
||||||
|
// draft, sent, approved & expired. Need to transform them to real values.
|
||||||
|
|
||||||
|
$query = Quote::query()
|
||||||
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||||
|
|
||||||
|
if (count($this->status)) {
|
||||||
|
$query = $query->whereIn('status_id', $this->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $query->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.quotes-table', [
|
||||||
|
'quotes' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
33
app/Http/Livewire/RecurringInvoicesTable.php
Normal file
33
app/Http/Livewire/RecurringInvoicesTable.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
use App\Traits\WithSorting;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class RecurringInvoicesTable extends Component
|
||||||
|
{
|
||||||
|
use WithPagination, WithSorting;
|
||||||
|
|
||||||
|
public $per_page = 10;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$query = RecurringInvoice::query();
|
||||||
|
|
||||||
|
// ->whereClientId(auth()->user()->client->id) // auth()->user() null.
|
||||||
|
|
||||||
|
$query = $query
|
||||||
|
->whereIn('status_id', [RecurringInvoice::STATUS_PENDING, RecurringInvoice::STATUS_ACTIVE, RecurringInvoice::STATUS_COMPLETED])
|
||||||
|
->orderBy('status_id', 'asc')
|
||||||
|
->with('client')
|
||||||
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||||
|
->paginate($this->per_page);
|
||||||
|
|
||||||
|
return render('components.livewire.recurring-invoices-table', [
|
||||||
|
'invoices' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
28
app/Utils/Traits/WithSorting.php
Normal file
28
app/Utils/Traits/WithSorting.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?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\Traits;
|
||||||
|
|
||||||
|
trait WithSorting
|
||||||
|
{
|
||||||
|
public $sort_field = 'id'; // Default sortBy. Feel free to change or pull from client/company settings.
|
||||||
|
public $sort_asc = true;
|
||||||
|
|
||||||
|
public function sortBy($field)
|
||||||
|
{
|
||||||
|
$this->sort_field === $field
|
||||||
|
? $this->sort_asc = !$this->sort_asc
|
||||||
|
: $this->sort_asc = true;
|
||||||
|
|
||||||
|
$this->sort_field = $field;
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,7 @@
|
|||||||
"league/flysystem-cached-adapter": "~1.0",
|
"league/flysystem-cached-adapter": "~1.0",
|
||||||
"league/fractal": "^0.17.0",
|
"league/fractal": "^0.17.0",
|
||||||
"league/omnipay": "^3.0",
|
"league/omnipay": "^3.0",
|
||||||
|
"livewire/livewire": "^1.0",
|
||||||
"maennchen/zipstream-php": "^1.2",
|
"maennchen/zipstream-php": "^1.2",
|
||||||
"nwidart/laravel-modules": "^6.0",
|
"nwidart/laravel-modules": "^6.0",
|
||||||
"omnipay/paypal": "^3.0",
|
"omnipay/paypal": "^3.0",
|
||||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -8532,6 +8532,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||||
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
|
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
|
||||||
},
|
},
|
||||||
|
"turbolinks": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/turbolinks/-/turbolinks-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw=="
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"resolve-url-loader": "^3.1.0",
|
"resolve-url-loader": "^3.1.0",
|
||||||
"sass": "^1.15.2",
|
"sass": "^1.15.2",
|
||||||
"sass-loader": "^8.0.0",
|
"sass-loader": "^8.0.0",
|
||||||
"tailwindcss": "^1.2.0"
|
"tailwindcss": "^1.2.0",
|
||||||
|
"turbolinks": "^5.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"/js/app.js": "/js/app.js?id=8b49701583f407403ddf",
|
"/js/app.js": "/js/app.js?id=49b0ee243139f6e72bd9",
|
||||||
"/css/app.css": "/css/app.css?id=9015e72c9d7c1403f034",
|
"/css/app.css": "/css/app.css?id=c317169666198ce30427",
|
||||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=caec43815d9a13168a38",
|
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=caec43815d9a13168a38",
|
||||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=af49e24958be5fc00c92",
|
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=af49e24958be5fc00c92",
|
||||||
"/js/clients/payment_methods/authorize-stripe-card.js": "/js/clients/payment_methods/authorize-stripe-card.js?id=f4c45f0da9868d840799",
|
"/js/clients/payment_methods/authorize-stripe-card.js": "/js/clients/payment_methods/authorize-stripe-card.js?id=f4c45f0da9868d840799",
|
||||||
|
11
resources/js/app.js
vendored
11
resources/js/app.js
vendored
@ -4,4 +4,13 @@
|
|||||||
* Promise based HTTP client for the browser and node.js
|
* Promise based HTTP client for the browser and node.js
|
||||||
* https://github.com/axios/axios
|
* https://github.com/axios/axios
|
||||||
*/
|
*/
|
||||||
window.axios = require('axios');
|
window.axios = require("axios");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turoblinks
|
||||||
|
*
|
||||||
|
* Turbolinks makes navigating your web application faster
|
||||||
|
* https://github.com/turbolinks/turbolinks
|
||||||
|
*/
|
||||||
|
const Turbolinks = require("turbolinks");
|
||||||
|
Turbolinks.start();
|
||||||
|
@ -3199,6 +3199,7 @@ return [
|
|||||||
'authorize_for_future_use' => 'Authorize payment method for future use',
|
'authorize_for_future_use' => 'Authorize payment method for future use',
|
||||||
|
|
||||||
'page' => 'Page',
|
'page' => 'Page',
|
||||||
|
'per_page' => 'Per page',
|
||||||
'of' => 'Of',
|
'of' => 'Of',
|
||||||
'view_credit' => 'View Credit',
|
'view_credit' => 'View Credit',
|
||||||
'to_view_entity_password' => 'To view the :entity you need to enter password.',
|
'to_view_entity_password' => 'To view the :entity you need to enter password.',
|
||||||
|
22
resources/sass/app.scss
vendored
22
resources/sass/app.scss
vendored
@ -11,6 +11,28 @@
|
|||||||
@import 'components/badge';
|
@import 'components/badge';
|
||||||
@import 'components/datatables';
|
@import 'components/datatables';
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
@apply flex items-center #{!important};
|
||||||
|
|
||||||
|
.page-link {
|
||||||
|
@apply -mt-px border-t-2 border-transparent pt-4 px-4 inline-flex items-center text-sm leading-5 font-medium text-gray-500 transition ease-in-out duration-150 cursor-pointer #{!important};
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link:hover {
|
||||||
|
@apply text-gray-700 border-gray-300 #{!important};
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link:focus {
|
||||||
|
@apply outline-none text-gray-700 border-gray-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active > span {
|
||||||
|
@apply text-blue-600 border-blue-600 #{!important};
|
||||||
|
}
|
||||||
|
|
||||||
|
// hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-400 transition ease-in-out duration-150
|
||||||
|
}
|
||||||
|
|
||||||
.active-page {
|
.active-page {
|
||||||
@apply bg-blue-900 #{!important};
|
@apply bg-blue-900 #{!important};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('amount')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.amount') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('balance')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.balance') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.credit_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('public_notes')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.public_notes') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($credits as $credit)
|
||||||
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ App\Utils\Number::formatMoney($credit->amount, $credit->client) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ App\Utils\Number::formatMoney($credit->balance, $credit->client) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $credit->formatDate($credit->date, $credit->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ empty($credit->public_notes) ? '/' : $credit->public_notes }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
<a href="{{ route('client.credits.show', $credit->hashed_id) }}" class="button-link">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $credits->firstItem() }} to {{ $credits->lastItem() }} out of {{ $credits->total() }}</span>
|
||||||
|
{{ $credits->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,112 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange(paid)" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="paid" class="text-sm">{{ ctrans('texts.status_paid') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange(unpaid)" value="unpaid" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="unpaid" class="text-sm">{{ ctrans('texts.status_unpaid') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange(overdue)" value="overdue" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="overdue" class="text-sm">{{ ctrans('texts.overdue') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" class="form-check form-check-parent">
|
||||||
|
</label>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('number')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.invoice_number') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.invoice_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('balance')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.balance') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('due_date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.due_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('status_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.status') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($invoices as $invoice)
|
||||||
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" class="form-check form-check-child" data-value="{{ $invoice->hashed_id }}">
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->number }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->formatDate($invoice->date, $invoice->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ App\Utils\Number::formatMoney($invoice->balance, $invoice->client) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->formatDate($invoice->due_date, $invoice->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{!! App\Models\Invoice::badgeForStatus($invoice->status) !!}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
|
@if($invoice->isPayable())
|
||||||
|
<button class="button button-primary py-1 px-2 text-xs uppercase mr-3 pay-now-button" data-value="{{ $invoice->hashed_id }}">
|
||||||
|
@lang('texts.pay_now')
|
||||||
|
</button>
|
||||||
|
@endif
|
||||||
|
<a href="{{ route('client.invoice.show', $invoice->hashed_id) }}" class="button-link">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $invoices->firstItem() }} to {{ $invoices->lastItem() }} out of {{ $invoices->total() }}</span>
|
||||||
|
{{ $invoices->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script src="{{ asset('js/clients/invoices/action-selectors.js') }}"></script>
|
||||||
|
@endpush
|
@ -0,0 +1,87 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('created_at')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.created_at') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('type_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.payment_type_id') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{{ ctrans('texts.type') }}
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{{ ctrans('texts.expires') }}
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{{ ctrans('texts.card_number') }}
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
{{ ctrans('texts.default') }}
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($payment_methods as $payment_method)
|
||||||
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $payment_method->formatDateTimestamp($payment_method->created_at, $client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
||||||
|
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
@isset($payment_method->meta->last4)
|
||||||
|
**** {{ $payment_method->meta->last4 }}
|
||||||
|
@endisset
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
@if($payment_method->is_default)
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check">
|
||||||
|
<path d="M20 6L9 17l-5-5" />
|
||||||
|
</svg>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
|
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}" class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $payment_methods->firstItem() }} to {{ $payment_methods->lastItem() }} out of {{ $payment_methods->total() }}</span>
|
||||||
|
{{ $payment_methods->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,77 @@
|
|||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded mt-4">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.payment_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('type_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.payment_type_id') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('amount')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.amount') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('transaction_reference')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.transaction_reference') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('status_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.status') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($payments as $payment)
|
||||||
|
<tr class="cursor-pointer bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $payment->formatDate($payment->date, $payment->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ optional($payment->type)->name }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{!! \App\Utils\Number::formatMoney($payment->amount, $payment->client) !!}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $payment->transaction_reference }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{!! \App\Models\Payment::badgeForStatus($payment->status_id) !!}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
|
<a href="{{ route('client.payments.show', $payment->hashed_id) }}" class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $payments->firstItem() }} to {{ $payments->lastItem() }} out of {{ $payments->total() }}</span>
|
||||||
|
{{ $payments->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,111 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange('draft')" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="draft" class="text-sm">{{ ctrans('texts.status_draft') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange('sent')" value="sent" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="sent" class="text-sm">{{ ctrans('texts.status_sent') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange('approved')" value="approved" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="approved" class="text-sm">{{ ctrans('texts.approved') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="mr-3">
|
||||||
|
<input wire:click="statusChange('expired')" value="expired" type="checkbox" class="form-checkbox">
|
||||||
|
<label for="expired" class="text-sm">{{ ctrans('texts.expired') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" class="form-check form-check-parent">
|
||||||
|
</label>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('number')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.quote_number') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.quote_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('balance')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.balance') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.valid_until') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('status_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.status_id') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($quotes as $quote)
|
||||||
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" class="form-check form-check-child" data-value="{{ $quote->hashed_id }}">
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $quote->number }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $quote->formatDate($quote->date, $quote->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ App\Utils\Number::formatMoney($quote->balance, $quote->client) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $quote->formatDate($quote->date, $quote->client->date_format()) }} <!-- Fix valid until -->
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{!! App\Models\Quote::badgeForStatus($quote->status_id) !!}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
|
<a href="{{ route('client.quotes.show', $quote->hashed_id) }}" class="button-link">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $quotes->firstItem() }} to {{ $quotes->lastItem() }} out of {{ $quotes->total() }}</span>
|
||||||
|
{{ $quotes->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script src="{{ asset('js/clients/quotes/action-selectors.js') }}"></script>
|
||||||
|
@endpush
|
@ -0,0 +1,83 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="mr-2 text-sm hidden md:block">{{ ctrans('texts.per_page') }}</span>
|
||||||
|
<select wire:model="per_page" class="form-select py-1 text-sm">
|
||||||
|
<option>5</option>
|
||||||
|
<option selected>10</option>
|
||||||
|
<option>15</option>
|
||||||
|
<option>20</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
|
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||||
|
<table class="min-w-full shadow rounded border border-gray-200 mt-4">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('frequency_id')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.frequency') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.start_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('next_send_date')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.next_send_date') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('remaining_cycles')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.cycles_remaining') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
<span role="button" wire:click="sortBy('amount')" class="cursor-pointer">
|
||||||
|
{{ ctrans('texts.amount') }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($invoices as $invoice)
|
||||||
|
<tr class="bg-white group hover:bg-gray-100">
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ \App\Models\RecurringInvoice::frequencyForKey($invoice->frequency_id) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->formatDate($invoice->date, $invoice->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->formatDate($invoice->next_send_date, $invoice->client->date_format()) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ $invoice->remaining_cycles }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||||
|
{{ \App\Utils\Number::formatMoney($invoice->amount, $invoice->client) }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||||
|
<a href="{{ route('client.recurring_invoices.show', $invoice->hashed_id) }}" class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||||
|
@lang('texts.view')
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center md:justify-between mt-6 mb-6">
|
||||||
|
<span class="text-gray-700 text-sm hidden md:block">Showing {{ $invoices->firstItem() }} to {{ $invoices->lastItem() }} out of {{ $invoices->total() }}</span>
|
||||||
|
{{ $invoices->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script src="{{ asset('js/clients/invoices/action-selectors.js') }}"></script>
|
||||||
|
@endpush
|
@ -1,10 +1,6 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.credits'))
|
@section('meta_title', ctrans('texts.credits'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('credits') }}
|
{{ Breadcrumbs::render('credits') }}
|
||||||
|
|
||||||
@ -36,64 +32,6 @@
|
|||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<div class="flex flex-col mt-4">
|
<div class="flex flex-col mt-4">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('credits-table')
|
||||||
<div
|
|
||||||
class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.amount') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.balance') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.credit_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.public_notes') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($credits as $credit)
|
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ App\Utils\Number::formatMoney($credit->amount, $credit->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ App\Utils\Number::formatMoney($credit->balance, $credit->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $credit->formatDate($credit->date, $credit->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ empty($credit->public_notes) ? '/' : $credit->public_notes }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
<a href="{{ route('client.credits.show', $credit->hashed_id) }}"
|
|
||||||
class="button-link">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/clients/quotes/action-selectors.js') }}"></script>
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.invoices'))
|
@section('meta_title', ctrans('texts.invoices'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('invoices') }}
|
{{ Breadcrumbs::render('invoices') }}
|
||||||
|
|
||||||
@ -44,84 +40,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col mt-4">
|
<div class="flex flex-col mt-4">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('invoices-table')
|
||||||
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" class="form-check form-check-parent">
|
|
||||||
</label>
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.invoice_number') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.invoice_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.balance') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.due_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.status') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($invoices as $invoice)
|
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" class="form-check form-check-child" data-value="{{ $invoice->hashed_id }}">
|
|
||||||
</label>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->number }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->due_date }} <!-- $invoice->formatDate($invoice->date, $invoice->client->date_format())-->
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ App\Utils\Number::formatMoney($invoice->balance, $invoice->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->formatDate($invoice->due_date, $invoice->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{!! App\Models\Invoice::badgeForStatus($invoice->status) !!}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
|
||||||
@if($invoice->isPayable())
|
|
||||||
<button class="button button-primary py-1 px-2 text-xs uppercase mr-3 pay-now-button" data-value="{{ $invoice->hashed_id }}">
|
|
||||||
@lang('texts.pay_now')
|
|
||||||
</button>
|
|
||||||
@endif
|
|
||||||
<a href="{{ route('client.invoice.show', $invoice->hashed_id) }}" class="button-link">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/vendor/jquery-3.3.1/jquery-3.3.1.min.js') }}"></script>
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
<script src="{{ asset('js/clients/invoices/action-selectors.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
@ -60,6 +60,8 @@
|
|||||||
{!! $client->getSetting('portal_custom_css') !!}
|
{!! $client->getSetting('portal_custom_css') !!}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@livewireStyles
|
||||||
|
|
||||||
{{-- Feel free to push anything to header using @push('header') --}}
|
{{-- Feel free to push anything to header using @push('header') --}}
|
||||||
@stack('head')
|
@stack('head')
|
||||||
|
|
||||||
@ -70,6 +72,8 @@
|
|||||||
@component('portal.ninja2020.components.general.sidebar.main')
|
@component('portal.ninja2020.components.general.sidebar.main')
|
||||||
@yield('body')
|
@yield('body')
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
|
@livewireScripts
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.payment_methods'))
|
@section('meta_title', ctrans('texts.payment_methods'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('payment_methods') }}
|
{{ Breadcrumbs::render('payment_methods') }}
|
||||||
|
|
||||||
<div class="bg-white shadow rounded mb-4" translate>
|
<div class="bg-white shadow rounded mb-4" translate>
|
||||||
<div class="px-4 py-5 sm:p-6">
|
<div class="px-4 py-5 sm:p-6">
|
||||||
<div class="sm:flex sm:items-start sm:justify-between">
|
<div class="sm:flex sm:items-start sm:justify-between">
|
||||||
@ -25,7 +20,7 @@
|
|||||||
<div class="inline-flex rounded-md shadow-sm">
|
<div class="inline-flex rounded-md shadow-sm">
|
||||||
<input type="hidden" name="hashed_ids">
|
<input type="hidden" name="hashed_ids">
|
||||||
<input type="hidden" name="action" value="payment">
|
<input type="hidden" name="action" value="payment">
|
||||||
@if(auth()->user()->client->getCreditCardGateway())
|
@if($client->getCreditCardGateway())
|
||||||
<a href="{{ route('client.payment_methods.create') }}" class="button button-primary">@lang('texts.add_payment_method')</a>
|
<a href="{{ route('client.payment_methods.create') }}" class="button button-primary">@lang('texts.add_payment_method')</a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@ -37,85 +32,6 @@
|
|||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('payment-methods-table', ['client' => $client])
|
||||||
<div
|
|
||||||
class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.created_at') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.payment_type_id') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.type') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.expires') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.card_number') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.default') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($payment_methods as $payment_method)
|
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $payment_method->formatDateTimestamp($payment_method->created_at, auth()->user()->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
|
||||||
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
@isset($payment_method->meta->last4)
|
|
||||||
**** {{ $payment_method->meta->last4 }}
|
|
||||||
@endisset
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
@if($payment_method->is_default)
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
|
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
||||||
stroke-linejoin="round" class="feather feather-check">
|
|
||||||
<path d="M20 6L9 17l-5-5"/>
|
|
||||||
</svg>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
|
||||||
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}"
|
|
||||||
class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
@ -1,13 +1,8 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.payments'))
|
@section('meta_title', ctrans('texts.payments'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('payments') }}
|
{{ Breadcrumbs::render('payments') }}
|
||||||
|
|
||||||
<div class="bg-white shadow rounded mb-4" translate>
|
<div class="bg-white shadow rounded mb-4" translate>
|
||||||
<div class="px-4 py-5 sm:p-6">
|
<div class="px-4 py-5 sm:p-6">
|
||||||
<div class="sm:flex sm:items-start sm:justify-between">
|
<div class="sm:flex sm:items-start sm:justify-between">
|
||||||
@ -28,69 +23,6 @@
|
|||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('payments-table')
|
||||||
<div
|
|
||||||
class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.payment_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.payment_type_id') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.amount') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.transaction_reference') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.status') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($payments as $payment)
|
|
||||||
<tr class="cursor-pointer bg-white group hover:bg-gray-100" @click="window.location = '{{ route('client.payments.show', $payment->hashed_id) }}'">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $payment->formatDate($payment->date, $payment->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $payment->type->name }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ \App\Utils\Number::formatMoney($payment->amount, $payment->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $payment->transaction_reference }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{!! \App\Models\Payment::badgeForStatus($payment->status_id) !!}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
|
||||||
<a href="{{ route('client.payments.show', $payment->hashed_id) }}"
|
|
||||||
class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
@ -1,10 +1,6 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.quotes'))
|
@section('meta_title', ctrans('texts.quotes'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('quotes') }}
|
{{ Breadcrumbs::render('quotes') }}
|
||||||
|
|
||||||
@ -46,80 +42,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col mt-4">
|
<div class="flex flex-col mt-4">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('quotes-table')
|
||||||
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" class="form-check form-check-parent">
|
|
||||||
</label>
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.quote_number') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.quote_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.balance') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.valid_until') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.status') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($quotes as $quote)
|
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" class="form-check form-check-child"
|
|
||||||
data-value="{{ $quote->hashed_id }}">
|
|
||||||
</label>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $quote->number }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $quote->formatDate($quote->date, $quote->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ App\Utils\Number::formatMoney($quote->balance, $quote->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $quote->formatDate($quote->date, $quote->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{!! App\Models\Quote::badgeForStatus($quote->status_id) !!}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
|
||||||
<a href="{{ route('client.quotes.show', $quote->hashed_id) }}"
|
|
||||||
class="button-link">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/clients/quotes/action-selectors.js') }}"></script>
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
@extends('portal.ninja2020.layout.app')
|
@extends('portal.ninja2020.layout.app')
|
||||||
@section('meta_title', ctrans('texts.recurring_invoices'))
|
@section('meta_title', ctrans('texts.recurring_invoices'))
|
||||||
|
|
||||||
@push('head')
|
|
||||||
<link rel="stylesheet" href="{{ asset('js/vendor/datatables/datatables.min.css') }}">
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('header')
|
@section('header')
|
||||||
{{ Breadcrumbs::render('recurring_invoices') }}
|
{{ Breadcrumbs::render('recurring_invoices') }}
|
||||||
|
|
||||||
@ -28,70 +24,6 @@
|
|||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
@livewire('recurring-invoices-table')
|
||||||
<div
|
|
||||||
class="align-middle inline-block min-w-full overflow-hidden rounded">
|
|
||||||
<table class="min-w-full shadow rounded border border-gray-200">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.frequency') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.start_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.next_send_date') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.cycles_remaining') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
|
||||||
{{ ctrans('texts.amount') }}
|
|
||||||
</th>
|
|
||||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($invoices as $invoice)
|
|
||||||
<tr class="bg-white group hover:bg-gray-100">
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ \App\Models\RecurringInvoice::frequencyForKey($invoice->frequency_id) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->formatDate($invoice->date, $invoice->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->formatDate($invoice->next_send_date, $invoice->client->date_format()) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ $invoice->remaining_cycles }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
|
||||||
{{ \App\Utils\Number::formatMoney($invoice->amount, $invoice->client) }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
|
||||||
<a href="{{ route('client.recurring_invoices.show', $invoice->hashed_id) }}"
|
|
||||||
class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
|
||||||
@lang('texts.view')
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@push('footer')
|
|
||||||
<script src="{{ asset('js/vendor/datatables/datatables.min.js') }}"></script>
|
|
||||||
<script src="{{ asset('js/clients/invoices/action-selectors.js') }}"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('table').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
Loading…
x
Reference in New Issue
Block a user