From 4c43bf2193496d6c52e2ac176c67ad7317e86012 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 6 Feb 2025 11:08:30 +0100 Subject: [PATCH] Make dashboard configurable. --- .../Controllers/Api/DashboardController.php | 27 ++ app/Models/Dashboard.php | 54 ++++ app/Providers/AppServiceProvider.php | 4 +- app/View/Composers/MonthGraph.php | 10 +- ...5_02_04_064726_create_dashboards_table.php | 76 +++++ lang/de/dashboard.php | 18 +- .../views/components/close-icon.blade.php | 3 + .../dashboard_graph_month.blade.php | 40 +++ .../components/dashboard_graph_year.blade.php | 34 ++ .../components/dashboard_incoming.blade.php | 15 + .../components/dashboard_no_address.blade.php | 13 + .../components/dashboard_not_paid.blade.php | 15 + .../components/dashboard_not_sent.blade.php | 13 + .../views/components/gear-icon.blade.php | 5 + .../views/components/graph-month.blade.php | 30 -- .../views/components/graph-year.blade.php | 30 -- resources/views/dashboard.blade.php | 302 +++++++++++++----- routes/api.php | 2 + routes/web.php | 3 +- 19 files changed, 535 insertions(+), 159 deletions(-) create mode 100644 app/Http/Controllers/Api/DashboardController.php create mode 100644 app/Models/Dashboard.php create mode 100644 database/migrations/2025_02_04_064726_create_dashboards_table.php create mode 100644 resources/views/components/close-icon.blade.php create mode 100644 resources/views/components/dashboard_graph_month.blade.php create mode 100644 resources/views/components/dashboard_graph_year.blade.php create mode 100644 resources/views/components/dashboard_incoming.blade.php create mode 100644 resources/views/components/dashboard_no_address.blade.php create mode 100644 resources/views/components/dashboard_not_paid.blade.php create mode 100644 resources/views/components/dashboard_not_sent.blade.php create mode 100644 resources/views/components/gear-icon.blade.php delete mode 100644 resources/views/components/graph-month.blade.php delete mode 100644 resources/views/components/graph-year.blade.php diff --git a/app/Http/Controllers/Api/DashboardController.php b/app/Http/Controllers/Api/DashboardController.php new file mode 100644 index 0000000..9a4c102 --- /dev/null +++ b/app/Http/Controllers/Api/DashboardController.php @@ -0,0 +1,27 @@ +json(Dashboard::all()); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, Dashboard $dashboard): JsonResponse + { + return response()->json($dashboard->update($request->all())); + } +} diff --git a/app/Models/Dashboard.php b/app/Models/Dashboard.php new file mode 100644 index 0000000..a20a23a --- /dev/null +++ b/app/Models/Dashboard.php @@ -0,0 +1,54 @@ + + */ + protected $fillable = [ + 'width', + 'height', + 'sort', + 'active', + 'settings' + ]; + + protected $appends = [ + 'title', + ]; + + public function getTitleAttribute() + { + return __('dashboard.title_' . $this->name); + } + + public static function toObject() + { + $all = self::orderBy('sort')->get(); + $tiles = new \stdClass(); + foreach ($all as $tile) { + $key = $tile->name; + $tiles->$key = $tile; + } + return $tiles; + } + + public static function activeToObject() + { + $all = self::where('active', true)->orderBy('sort')->get(); + $tiles = new \stdClass(); + foreach ($all as $tile) { + $key = $tile->name; + $tiles->$key = $tile; + } + return collect($tiles); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0a964e8..d4edd76 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -38,8 +38,8 @@ class AppServiceProvider extends ServiceProvider { View::composer('components.tax-dropdown', TaxDropdown::class); View::composer('components.company-logo', OptionLogo::class); - View::composer('components.graph-year', YearGraph::class); - View::composer('components.graph-month', MonthGraph::class); + View::composer('components.dashboard_graph_year', YearGraph::class); + View::composer('components.dashboard_graph_month', MonthGraph::class); Number::useLocale(config('app.locale')); Number::useCurrency(config('app.currency')); diff --git a/app/View/Composers/MonthGraph.php b/app/View/Composers/MonthGraph.php index aa33c2a..644fc19 100644 --- a/app/View/Composers/MonthGraph.php +++ b/app/View/Composers/MonthGraph.php @@ -2,6 +2,7 @@ namespace App\View\Composers; +use App\Models\Dashboard; use App\Models\Incoming; use App\Models\Invoice; use Illuminate\Support\Carbon; @@ -11,7 +12,10 @@ class MonthGraph { public function compose(View $view): void { - $monthly_invoices = Invoice::whereYear('created_at', '=', Carbon::now()->year)->get() + $config = Dashboard::where('id', '=', 6)->first(); + $config_year = (is_null($config->settings)) ? Carbon::now()->year : intval($config->settings); + + $monthly_invoices = Invoice::whereYear('created_at', '=', $config_year)->get() ->groupBy(function ($invoice) { return $invoice->created_at->format('n'); }) @@ -19,7 +23,7 @@ class MonthGraph return $month->sum('sum'); }); - $monthly_incoming = Incoming::whereYear('issue_date', '=', Carbon::now()->year)->get() + $monthly_incoming = Incoming::whereYear('issue_date', '=', $config_year)->get() ->groupBy(function ($incoming) { return Carbon::parse($incoming->issue_date)->format('n'); }) @@ -36,6 +40,6 @@ class MonthGraph $monthly_invoices[$year] = 0; } - $view->with(['monthly_invoices' => $monthly_invoices, 'monthly_incoming' => $monthly_incoming]); + $view->with(['monthly_invoices' => $monthly_invoices, 'monthly_incoming' => $monthly_incoming, 'year' => $config_year]); } } diff --git a/database/migrations/2025_02_04_064726_create_dashboards_table.php b/database/migrations/2025_02_04_064726_create_dashboards_table.php new file mode 100644 index 0000000..eb55438 --- /dev/null +++ b/database/migrations/2025_02_04_064726_create_dashboards_table.php @@ -0,0 +1,76 @@ +id(); + $table->string('name'); + $table->integer('width'); + $table->integer('height'); + $table->integer('sort'); + $table->boolean('active'); + $table->json('settings')->nullable(); + }); + + DB::table('dashboards')->insert([ + 'name' => 'dashboard_not_paid', + 'width' => 2, + 'height' => 1, + 'sort' => 0, + 'active' => true, + ]); + DB::table('dashboards')->insert([ + 'name' => 'dashboard_not_sent', + 'width' => 1, + 'height' => 2, + 'sort' => 1, + 'active' => true, + ]); + DB::table('dashboards')->insert([ + 'name' => 'dashboard_no_address', + 'width' => 1, + 'height' => 1, + 'sort' => 2, + 'active' => true, + ]); + DB::table('dashboards')->insert([ + 'name' => 'dashboard_incoming', + 'width' => 1, + 'height' => 1, + 'sort' => 3, + 'active' => true, + ]); + DB::table('dashboards')->insert([ + 'name' => 'dashboard_graph_year', + 'width' => 2, + 'height' => 1, + 'sort' => 4, + 'active' => true, + ]); + DB::table('dashboards')->insert([ + 'name' => 'dashboard_graph_month', + 'width' => 4, + 'height' => 1, + 'sort' => 5, + 'active' => true, + ]); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('dashboards'); + } +}; diff --git a/lang/de/dashboard.php b/lang/de/dashboard.php index e242777..d0969f4 100644 --- a/lang/de/dashboard.php +++ b/lang/de/dashboard.php @@ -13,10 +13,18 @@ return [ */ 'Dashboard' => 'Dashboard', - 'Customers without address' => 'Kunden ohne Rechnungsadresse', - 'Invoices not sent' => 'Nicht versendete Rechnungen', - 'Invoices not paid' => 'Nicht bezahlte Rechnungen', - 'Incoming not paid' => 'Nicht bezahlte Eingangsrechnungen', - 'Incoming paid' => 'Bezahlte Eingangsrechnungen', + 'title_dashboard_graph_month' => 'Monatliche Entwicklung', + 'title_dashboard_graph_year' => 'Jährliche Entwicklung', + 'title_dashboard_not_paid' => 'Nicht bezahlte Rechnungen', + 'title_dashboard_not_sent' => 'Nicht versendete Rechnungen', + 'title_dashboard_incoming' => 'Nicht bezahlte Eingangsrechnungen', + 'title_dashboard_no_address' => 'Kunden ohne Rechnungsadresse', + 'Available' => 'Verfügbare Dashboard Kacheln', + 'Configuration' => 'Konfiguration', + 'Tile type' => 'Kachel Typ', + 'Tile width' => 'Kachel Breite', + 'Tile height' => 'Kachel Höhe', + 'Tile year' => 'Jahr der Daten', + 'No data' => 'Keine Daten gefunden.', ]; diff --git a/resources/views/components/close-icon.blade.php b/resources/views/components/close-icon.blade.php new file mode 100644 index 0000000..21e0702 --- /dev/null +++ b/resources/views/components/close-icon.blade.php @@ -0,0 +1,3 @@ +merge(['class' => 'size-8 p-1']) }}> + + diff --git a/resources/views/components/dashboard_graph_month.blade.php b/resources/views/components/dashboard_graph_month.blade.php new file mode 100644 index 0000000..dd6c891 --- /dev/null +++ b/resources/views/components/dashboard_graph_month.blade.php @@ -0,0 +1,40 @@ +@if( $monthly_incoming->count() === 0 && $monthly_invoices->count() === 0) +
{{ __('dashboard.No data') }}
+@else +
+ +
+ + +@endif diff --git a/resources/views/components/dashboard_graph_year.blade.php b/resources/views/components/dashboard_graph_year.blade.php new file mode 100644 index 0000000..0a25d63 --- /dev/null +++ b/resources/views/components/dashboard_graph_year.blade.php @@ -0,0 +1,34 @@ +@if( $yearly_incoming->count() === 0 && $yearly_invoices->count() === 0) +
{{ __('dashboard.No data') }}
+@else +
+ +
+ + +@endif diff --git a/resources/views/components/dashboard_incoming.blade.php b/resources/views/components/dashboard_incoming.blade.php new file mode 100644 index 0000000..604c75a --- /dev/null +++ b/resources/views/components/dashboard_incoming.blade.php @@ -0,0 +1,15 @@ +@php + $unpaid_incoming = \App\Models\Incoming::where('pay_date', '=', null)->orderBy('due_date')->get(); +@endphp +@if($unpaid_incoming->count() === 0) +
{{ __('dashboard.No data') }}
+@endif +@foreach($unpaid_incoming as $incoming) + +
{{ $incoming->invoice_number }}
+
{{ $incoming->supplier->name }}
+
{{ \Illuminate\Support\Number::currency($incoming->gross) }}
+
{{ $incoming->due }}
+
+@endforeach diff --git a/resources/views/components/dashboard_no_address.blade.php b/resources/views/components/dashboard_no_address.blade.php new file mode 100644 index 0000000..e8cb5ab --- /dev/null +++ b/resources/views/components/dashboard_no_address.blade.php @@ -0,0 +1,13 @@ +@php + $customers = \App\Models\Customer::doesntHave('address')->get(); +@endphp +@if($customers->count() === 0) +
{{ __('dashboard.No data') }}
+@endif +@foreach($customers as $customer) + +
{{ $customer->name }}
+
{{ $customer->email }}
+
+@endforeach diff --git a/resources/views/components/dashboard_not_paid.blade.php b/resources/views/components/dashboard_not_paid.blade.php new file mode 100644 index 0000000..0f286d7 --- /dev/null +++ b/resources/views/components/dashboard_not_paid.blade.php @@ -0,0 +1,15 @@ +@php + $sent_invoices = \App\Models\Invoice::where('status', '=', 'sent')->orderBy('created_at')->get(); +@endphp +@if($sent_invoices->count() === 0) +
{{ __('dashboard.No data') }}
+@endif +@foreach($sent_invoices as $invoice) + +
{{ $invoice->number }}
+
{{ $invoice->customer->name }}
+
{{ \Illuminate\Support\Number::currency($invoice->sum) }}
+
{{ $invoice->created }}
+
+@endforeach diff --git a/resources/views/components/dashboard_not_sent.blade.php b/resources/views/components/dashboard_not_sent.blade.php new file mode 100644 index 0000000..9a388f2 --- /dev/null +++ b/resources/views/components/dashboard_not_sent.blade.php @@ -0,0 +1,13 @@ +@php + $created_invoices = \App\Models\Invoice::where('status', '=', 'created')->orderBy('created_at')->get(); +@endphp +@if($created_invoices->count() === 0) +
{{ __('dashboard.No data') }}
+@endif +@foreach($created_invoices as $invoice) + +
{{ $invoice->number }}
+
{{ $invoice->customer->name }}
+
+@endforeach diff --git a/resources/views/components/gear-icon.blade.php b/resources/views/components/gear-icon.blade.php new file mode 100644 index 0000000..8abb118 --- /dev/null +++ b/resources/views/components/gear-icon.blade.php @@ -0,0 +1,5 @@ +merge(['class' => 'size-8 p-1']) }}> + + + + diff --git a/resources/views/components/graph-month.blade.php b/resources/views/components/graph-month.blade.php deleted file mode 100644 index c99a21e..0000000 --- a/resources/views/components/graph-month.blade.php +++ /dev/null @@ -1,30 +0,0 @@ -
- -
- - diff --git a/resources/views/components/graph-year.blade.php b/resources/views/components/graph-year.blade.php deleted file mode 100644 index 8deaf09..0000000 --- a/resources/views/components/graph-year.blade.php +++ /dev/null @@ -1,30 +0,0 @@ -
- -
- - diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 5a7fc5d..2f6a79b 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -1,110 +1,236 @@ -@php - $customers = \App\Models\Customer::doesntHave('address')->get(); - $created_invoices = \App\Models\Invoice::where('status', '=', 'created')->orderBy('created_at')->get(); - $sent_invoices = \App\Models\Invoice::where('status', '=', 'sent')->orderBy('created_at')->get(); - $unpaid_incoming = \App\Models\Incoming::where('pay_date', '=', null)->orderBy('due_date')->get(); -@endphp - -

- {{ __('dashboard.Dashboard') }} -

+
+

+ {{ __('dashboard.Dashboard') }} +

+ +
-
-
+
+
- @if($sent_invoices->count() != 0) - -
-
-

{{ __('dashboard.Invoices not paid') }}

- @foreach($sent_invoices as $invoice) - -
{{ $invoice->number }}
-
{{ $invoice->customer->name }}
-
{{ \Illuminate\Support\Number::currency($invoice->sum) }}
-
{{ $invoice->created }}
-
- @endforeach -
-
- @endif - - @if($created_invoices->count() != 0) - -
-
-

{{ __('dashboard.Invoices not sent') }}

- @foreach($created_invoices as $invoice) - -
{{ $invoice->number }}
-
{{ $invoice->customer->name }}
-
- @endforeach -
-
- @endif - - @if($customers->count() != 0) - -
-
-

{{ __('dashboard.Customers without address') }}

- @foreach($customers as $customer) - -
{{ $customer->name }}
-
{{ $customer->email }}
-
- @endforeach -
-
- @endif - - @if($unpaid_incoming->count() != 0) - -
- -
- @endif - -
+ + -
+ + + + + +
+ @php + $i = 0; + @endphp + @foreach($tiles as $name => $tile) +
+
+
+

{{ $tile->title }}

+
+ + +
+
+ @switch($name) + @case('dashboard_not_paid') + + @break + @case('dashboard_not_sent') + + @break + @case('dashboard_no_address') + + @break + @case('dashboard_incoming') + + @break + @case('dashboard_graph_year') + + @break + @case('dashboard_graph_month') + + @break + @endswitch +
+
+ @php($i++) + @endforeach +
+
+ +