10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
111
resources/views/user/abo/_abo_chart.blade.php
Normal file
111
resources/views/user/abo/_abo_chart.blade.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
@php
|
||||
$chartId = 'aboChart_' . str_replace('.', '', microtime(true));
|
||||
$chartDataJson = json_encode(array_values($chartData));
|
||||
$chartLabelsJson = json_encode(array_values($chartMonths));
|
||||
$nonNullValues = array_filter($chartData, fn($v) => $v !== null);
|
||||
$maxVal = count($nonNullValues) ? max($nonNullValues) : 0;
|
||||
|
||||
// Großzügige Schritte für die Y-Achse
|
||||
if ($maxVal <= 5) { $stepSize = 1; }
|
||||
elseif ($maxVal <= 10) { $stepSize = 2; }
|
||||
elseif ($maxVal <= 20) { $stepSize = 5; }
|
||||
elseif ($maxVal <= 50) { $stepSize = 10; }
|
||||
elseif ($maxVal <= 100) { $stepSize = 20; }
|
||||
elseif ($maxVal <= 200) { $stepSize = 50; }
|
||||
elseif ($maxVal <= 500) { $stepSize = 100; }
|
||||
elseif ($maxVal <= 1000) { $stepSize = 200; }
|
||||
else { $stepSize = 500; }
|
||||
|
||||
// Genug Platz nach oben, damit das Label nicht abgeschnitten wird
|
||||
$suggestedMax = $maxVal + $stepSize;
|
||||
@endphp
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body pb-2">
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap">
|
||||
<h6 class="font-weight-bold mb-2">
|
||||
{{ __('abo.chart_monthly_abos') }}
|
||||
<span class="text-muted font-weight-normal ml-1">{{ $chartYear }}</span>
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
@foreach($chartYears as $y)
|
||||
<a href="{{ url()->current() }}?year={{ $y }}"
|
||||
class="btn btn-xs btn-sm {{ $chartYear == $y ? 'btn-secondary' : 'btn-outline-secondary' }} mr-1 mb-1">
|
||||
{{ $y }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="m-0">
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<canvas id="{{ $chartId }}" height="80"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/vendor/libs/chartjs/chartjs.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
// Inline data-labels plugin für Chart.js v2
|
||||
var dataLabelsPlugin = {
|
||||
afterDatasetsDraw: function (chart) {
|
||||
var ctx = chart.ctx;
|
||||
chart.data.datasets.forEach(function (dataset, i) {
|
||||
var meta = chart.getDatasetMeta(i);
|
||||
if (meta.hidden) { return; }
|
||||
meta.data.forEach(function (bar, index) {
|
||||
var value = dataset.data[index];
|
||||
if (value === null || value === undefined || value === 0) { return; }
|
||||
ctx.save();
|
||||
ctx.fillStyle = '#495057';
|
||||
ctx.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'bottom';
|
||||
ctx.fillText(value, bar._model.x, bar._model.y - 3);
|
||||
ctx.restore();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var ctx = document.getElementById('{{ $chartId }}').getContext('2d');
|
||||
new Chart(ctx, {
|
||||
type: 'bar',
|
||||
plugins: [dataLabelsPlugin],
|
||||
data: {
|
||||
labels: {!! $chartLabelsJson !!},
|
||||
datasets: [{
|
||||
label: '{{ __('abo.chart_active_abos') }}',
|
||||
data: {!! $chartDataJson !!},
|
||||
backgroundColor: 'rgba(102, 110, 232, 0.2)',
|
||||
borderColor: 'rgba(102, 110, 232, 0.8)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
legend: { display: false },
|
||||
tooltips: { enabled: false },
|
||||
layout: {
|
||||
padding: { top: 20 }
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true,
|
||||
stepSize: {{ $stepSize }},
|
||||
suggestedMax: {{ $suggestedMax }},
|
||||
callback: function (value) {
|
||||
return Number.isInteger(value) ? value : null;
|
||||
}
|
||||
},
|
||||
gridLines: { color: 'rgba(0,0,0,0.05)' }
|
||||
}],
|
||||
xAxes: [{
|
||||
gridLines: { display: false }
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
|
|
@ -1,27 +1,39 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
<a href="{{route('user_abos', [$view])}}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
|
||||
<a href="{{ route('user_abos', [$view]) }}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
|
||||
|
||||
<div>
|
||||
@if($view === 'ot') {{ __('navigation.customerabo') }} @endif
|
||||
@if($view === 'me') {{ __('navigation.myabo') }} @endif
|
||||
<span class="text-muted">{{ '#'.$user_abo->payone_userid }}</span>
|
||||
@if ($view === 'ot')
|
||||
{{ __('navigation.customerabo') }}
|
||||
@endif
|
||||
@if ($view === 'me')
|
||||
{{ __('navigation.myabo') }}
|
||||
@endif
|
||||
<span class="text-muted">{{ '#' . $user_abo->payone_userid }}</span>
|
||||
</div>
|
||||
</h4>
|
||||
|
||||
|
||||
@if(Session::has('alert-error'))
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger p-2 mt-2">
|
||||
<ul>
|
||||
<li>{{ Session::get('alert-error') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (Session::has('alert-error'))
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger p-2 mt-2">
|
||||
<ul>
|
||||
<li>{{ Session::get('alert-error') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (Session::has('alert-warning'))
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-warning p-2 mt-2">
|
||||
<ul>
|
||||
<li>{{ Session::get('alert-warning') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card">
|
||||
@include('admin.abo._detail')
|
||||
</div>
|
||||
|
|
@ -34,13 +46,18 @@
|
|||
@php
|
||||
$addOnlyMode = App\Services\AboHelper::isAddOnlyMode($user_abo, $view);
|
||||
@endphp
|
||||
{!! Form::open(['action' => route('user_abos_update', [$view, $user_abo->id]), 'class' => 'form-horizontal', 'id'=>'cart-order-form', 'data-add-only-mode' => $addOnlyMode ? '1' : '0']) !!}
|
||||
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
|
||||
{!! Form::open([
|
||||
'action' => route('user_abos_update', [$view, $user_abo->id]),
|
||||
'class' => 'form-horizontal',
|
||||
'id' => 'cart-order-form',
|
||||
'data-add-only-mode' => $addOnlyMode ? '1' : '0',
|
||||
]) !!}
|
||||
<input type="hidden" name="is_for" value="{{ $user_abo->is_for }}">
|
||||
<div class="card mt-3">
|
||||
@include('admin.abo._order_abo', ['add_only_mode' => $addOnlyMode])
|
||||
</div>
|
||||
|
||||
@if($comp_products && Yard::instance('shopping')->getNumComp() > 0)
|
||||
@if ($comp_products && Yard::instance('shopping')->getNumComp() > 0)
|
||||
<div id="holder_html_view_comp_product">
|
||||
@include('user.order.comp_product')
|
||||
</div>
|
||||
|
|
@ -52,48 +69,49 @@
|
|||
</div>
|
||||
|
||||
|
||||
<a href="{{route('user_abos', [$view])}}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
|
||||
<a href="{{ route('user_abos', [$view]) }}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
|
||||
|
||||
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label" aria-hidden="true"
|
||||
data-title-add-only="{{ __('abo.confirm_add_title') }}"
|
||||
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
|
||||
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
|
||||
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-warning mb-3">
|
||||
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
|
||||
<div class="modal fade" id="modal-confirm-add" tabindex="-1" role="dialog" aria-labelledby="modal-confirm-add-label"
|
||||
aria-hidden="true" data-title-add-only="{{ __('abo.confirm_add_title') }}"
|
||||
data-title-normal="{{ __('abo.confirm_add_title_normal') }}"
|
||||
data-warning-add-only="{{ __('abo.confirm_add_warning') }}"
|
||||
data-warning-normal="{{ __('abo.confirm_add_warning_normal') }}">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modal-confirm-add-label"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-warning mb-3">
|
||||
<i class="fa fa-exclamation-triangle"></i> <span id="confirm-add-warning-text"></span>
|
||||
</div>
|
||||
<table class="table table-sm mb-0">
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('order.article') }}:</td>
|
||||
<td id="confirm-add-product-name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
|
||||
<td id="confirm-add-product-price"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
|
||||
<td id="confirm-add-qty-info"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default"
|
||||
data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary"
|
||||
id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
|
||||
</div>
|
||||
<table class="table table-sm mb-0">
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('order.article') }}:</td>
|
||||
<td id="confirm-add-product-name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.price') }}:</td>
|
||||
<td id="confirm-add-product-price"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-bold">{{ __('tables.quantity') }}:</td>
|
||||
<td id="confirm-add-qty-info"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('abo.confirm_add_cancel') }}</button>
|
||||
<button type="button" class="btn btn-primary" id="confirm-add-btn">{{ __('abo.confirm_add_ok') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
|
|
@ -105,4 +123,4 @@
|
|||
|
||||
|
||||
</script>
|
||||
@endsection
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
</div>
|
||||
</h4>
|
||||
|
||||
@if(isset($chartData))
|
||||
@include('user.abo._abo_chart')
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
|
|
@ -82,8 +86,13 @@
|
|||
{{ $user_abo->getCountOrders() }}
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="text-muted small">{{ __('tables.amount') }}</div>
|
||||
{{ $user_abo->getFormattedAmount() }} €
|
||||
@if($view === 'ot')
|
||||
<div class="text-muted small">{{ __('navigation.points') }}</div>
|
||||
<strong class="text-primary">{{ $user_abo->getFormattedTotalPoints() }} Pkt.</strong>
|
||||
@else
|
||||
<div class="text-muted small">{{ __('tables.amount') }}</div>
|
||||
{{ $user_abo->getFormattedAmount() }} €
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="text-muted small">{{ __('tables.payment') }}</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue