mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
view composers for client portal
This commit is contained in:
parent
baabfb9a06
commit
1823a23b2d
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
@ -113,16 +114,31 @@ class InvoiceFilters extends QueryFilters
|
||||
* @param $company_id The company Id
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function entityFilter()
|
||||
public function entityFilter()
|
||||
{
|
||||
|
||||
if(auth('contact')->user())
|
||||
return $this->builder->whereCompanyId(auth('contact')->user()->company->id);
|
||||
return $this->contactViewFilter();
|
||||
else
|
||||
return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We need additional filters when showing invoices for the
|
||||
* client portal. Need to automatically exclude drafts and cancelled invoices
|
||||
*
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
*/
|
||||
private function contactViewFilter() : Builder
|
||||
{
|
||||
|
||||
return $this->builder
|
||||
->whereCompanyId(auth('contact')->user()->company->id)
|
||||
->whereNotIn('status_id', [Invoice::STATUS_DRAFT, Invoice::STATUS_CANCELLED]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
85
app/Http/Controllers/ClientPortal/InvoiceController.php
Normal file
85
app/Http/Controllers/ClientPortal/InvoiceController.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Filters\InvoiceFilters;
|
||||
use App\Jobs\Entity\ActionEntity;
|
||||
use App\Models\Invoice;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class InvoiceController
|
||||
* @package App\Http\Controllers\ClientPortal\InvoiceController
|
||||
*/
|
||||
|
||||
class InvoiceController extends BaseController
|
||||
{
|
||||
|
||||
use MakesHash;
|
||||
|
||||
|
||||
/**
|
||||
* InvoiceController constructor.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the list of Invoices
|
||||
*
|
||||
* @param \App\Filters\InvoiceFilters $filters The filters
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(InvoiceFilters $filters)
|
||||
{
|
||||
|
||||
$invoices = Invoice::filter($filters);
|
||||
|
||||
return $this->listResponse($invoices);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Invoice $invoice The invoice
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Invoice $invoice)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bulk actions on the list view
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -26,23 +26,36 @@ class PortalComposer
|
||||
* @param View $view
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
public function compose(View $view) :void
|
||||
{
|
||||
$view->with('header', $this->portalData());
|
||||
$view->with('portal', $this->portalData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function portalData()
|
||||
private function portalData() :array
|
||||
{
|
||||
if(!auth()->user())
|
||||
return [];
|
||||
|
||||
$data = [];
|
||||
$data['sidebar'] = $this->sidebarMenu();
|
||||
$data['header'] = [];
|
||||
$data['footer'] = [];
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function sidebarMenu() :array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
|
||||
$data[] = [ 'title' => ctrans('texts.dashboard'), 'url' => 'client.dashboard', 'icon' => 'fa fa-tachometer'];
|
||||
$data[] = [ 'title' => ctrans('texts.invoices'), 'url' => 'client.invoices.index', 'icon' => 'fa fa-file-excel-o'];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
@ -18,4 +18,12 @@ namespace App\Models\Presenters;
|
||||
class ClientContactPresenter extends EntityPresenter
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->entity->first_name . ' ' . $this->entity->last_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,12 +14,12 @@
|
||||
<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="icon-list"></i>
|
||||
<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>You have 5 pending tasks</strong>
|
||||
<strong>@lang('texts.notifications')</strong>
|
||||
</div>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="small mb-1">Mr Miyagi todos
|
||||
@ -31,88 +31,29 @@
|
||||
<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" href="#">
|
||||
<div class="small mb-1">First, wash all car.
|
||||
<span class="float-right">
|
||||
<strong>25%</strong>
|
||||
</span>
|
||||
</div>
|
||||
<span class="progress progress-xs">
|
||||
<div class="progress-bar bg-danger" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</span>
|
||||
</a>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="small mb-1">Then wax. Wax on...
|
||||
<span class="float-right">
|
||||
<strong>50%</strong>
|
||||
</span>
|
||||
</div>
|
||||
<span class="progress progress-xs">
|
||||
<div class="progress-bar bg-warning" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</span>
|
||||
</a>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="small mb-1">No questions!
|
||||
<span class="float-right">
|
||||
<strong>75%</strong>
|
||||
</span>
|
||||
</div>
|
||||
<span class="progress progress-xs">
|
||||
<div class="progress-bar bg-info" role="progressbar" style="width: 75%" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</span>
|
||||
</a>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="small mb-1">Wax on... wax off. Wax on... wax off.
|
||||
<span class="float-right">
|
||||
<strong>100%</strong>
|
||||
</span>
|
||||
</div>
|
||||
<span class="progress progress-xs">
|
||||
<div class="progress-bar bg-success" role="progressbar" style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</span>
|
||||
</a>
|
||||
<a class="dropdown-item text-center" href="#">
|
||||
<strong>View all tasks</strong>
|
||||
<strong>@lang('texts.more')</strong>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<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-building" aria-hidden="true"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-lg">
|
||||
<div class="dropdown-header text-center">
|
||||
<strong>@lang('texts.manage_companies')</strong>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<img class="img-avatar" src="/images/logo.png" alt=""> {{ auth()->user()->first_name }}
|
||||
<img class="img-avatar" src="/images/logo.png" alt=""> {{ auth()->user()->present()->name() }}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<div class="dropdown-header text-center">
|
||||
<strong>Settings</strong>
|
||||
<strong>@lang('texts.settings')</strong>
|
||||
</div>
|
||||
<a class="dropdown-item" href="#">
|
||||
<i class="fa fa-user"></i> Profile</a>
|
||||
<i class="fa fa-user"></i> @lang('texts.profile')</a>
|
||||
<a class="dropdown-item" href="">
|
||||
<i class="fa fa-wrench"></i> @lang('texts.settings')</a>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="">
|
||||
<i class="fa fa-lock"></i> Logout</a>
|
||||
<a class="dropdown-item" href="{{ route('client.logout') }}">
|
||||
<i class="fa fa-lock"></i> @lang('texts.logout')</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="navbar-toggler aside-menu-toggler d-md-down-none" type="button" data-toggle="aside-menu-lg-show">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<button class="navbar-toggler aside-menu-toggler d-lg-none" type="button" data-toggle="aside-menu-show">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</header>
|
||||
|
@ -45,7 +45,7 @@
|
||||
@yield('head')
|
||||
</head>
|
||||
|
||||
@include('portal.default.header', $header)
|
||||
@include('portal.default.header')
|
||||
@yield('header')
|
||||
|
||||
@include('portal.default.sidebar')
|
||||
|
@ -2,67 +2,13 @@
|
||||
<div class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
<ul class="nav">
|
||||
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" href="{{ route('dashboard.index') }}">
|
||||
<i class="nav-icon icon-speedometer"></i> @lang('texts.dashboard')
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/clients">
|
||||
<i class="nav-icon icon-user"></i> @lang('texts.clients')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('invoices.index') }}">
|
||||
<i class="nav-icon icon-notebook"></i> @lang('texts.invoices')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-wallet"></i> @lang('texts.payments')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-docs"></i> @lang('texts.recurring')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-badge"></i> @lang('texts.credits')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-vector"></i> @lang('texts.quotes')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-wrench"></i> @lang('texts.projects')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-grid"></i> @lang('texts.tasks')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-envelope-open"></i> @lang('texts.expenses')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-bell"></i> @lang('texts.vendors')</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="typography.html">
|
||||
<i class="nav-icon icon-printer"></i> @lang('texts.reports')</a>
|
||||
</li>
|
||||
@foreach($portal['sidebar'] as $row)
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" href="{{ $row['url'] }}">
|
||||
<i class="{{$row['icon']}}"></i> {{ $row['title'] }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</nav>
|
||||
<button class="sidebar-minimizer brand-minimizer" type="button"></button>
|
||||
|
@ -13,6 +13,7 @@ Route::post('client/password/reset', 'Auth\ContactResetPasswordController@reset'
|
||||
Route::group(['middleware' => ['auth:contact'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||
|
||||
Route::get('dashboard', 'ClientPortal\DashboardController@index')->name('dashboard'); // name = (dashboard. index / create / show / update / destroy / edit
|
||||
Route::get('invoices', 'ClientPortal\InvoiceController@index')->name('invoices.index'); // name = (dashboard. index / create / show / update / destroy / edit
|
||||
|
||||
Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user