mivita/resources/views/web/templates/widerruf.blade.php
Kevin 63c36555a5 Widerruf: Gesetzliche Online-Widerrufsfunktion (Formular, Bestätigungsmail, Admin-Verwaltung)
- Öffentliches Widerrufsformular /widerruf mit Bestell-Lookup (throttled)
- Bestätigungsmail an Kunde + Weiterleitung an bestellungen@ (config app.withdrawal_mail)
- Admin-Übersicht/-Detail unter /admin/withdrawals inkl. Sidenav-Eintrag
- Widerruf-Button in Portal-Bestellansicht und Footer-Links
- Model OrderWithdrawal + Migration + Factory + Tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 15:56:02 +00:00

160 lines
7.8 KiB
PHP

@extends($user_shop ? 'web.user.layouts.layout' : 'web.layouts.layout')
@section('content')
<section class="page-header page-header-xlg parallax parallax-3"
style="background-image:url('/assets/images/vision-min.jpg')">
<div class="overlay dark-1"></div>
<div class="container"></div>
</section>
<style type="text/css">
.withdrawal-box {
max-width: 760px;
margin: 0 auto;
}
.withdrawal-box .alert.error {
font-weight: bold;
}
.withdrawal-scope label {
display: block;
font-size: 15px;
margin-bottom: 8px;
}
.withdrawal-items .qty-input {
max-width: 90px;
}
.legal-note {
font-size: 13px;
color: #6b7758;
}
</style>
<section>
<div class="container">
<div class="withdrawal-box box-static box-transparent box-bordered padding-20">
<h1>{{ __('withdrawal.page_title') }}</h1>
<p>{{ __('withdrawal.intro') }}</p>
@if (session('alert-error'))
<div class="alert alert-danger error">{{ session('alert-error') }}</div>
@endif
@if (! $order)
{{-- Phase 1: Bestellung identifizieren --}}
<hr>
<h3>{{ __('withdrawal.identify_hl') }}</h3>
{!! Form::open(['route' => 'withdrawal.lookup', 'method' => 'post']) !!}
<div class="form-group">
{!! Form::label('order_number', __('withdrawal.order_number') . '*') !!}
{!! Form::text('order_number', old('order_number', $prefill_order), ['class' => 'form-control ' . ($errors->has('order_number') ? 'error is-invalid' : ''), 'placeholder' => __('withdrawal.order_number_placeholder')]) !!}
<small class="form-text text-muted">{{ __('withdrawal.order_number_help') }}</small>
@if ($errors->has('order_number'))
<div class="alert alert-danger error">{{ $errors->first('order_number') }}</div>
@endif
</div>
<div class="form-group">
{!! Form::label('email', __('withdrawal.email') . '*') !!}
{!! Form::email('email', old('email', $prefill_email), ['class' => 'form-control ' . ($errors->has('email') ? 'error is-invalid' : ''), 'placeholder' => __('withdrawal.email_placeholder')]) !!}
@if ($errors->has('email'))
<div class="alert alert-danger error">{{ $errors->first('email') }}</div>
@endif
</div>
<button type="submit" class="btn btn-primary btn-text-500">
<i class="fa fa-search"></i> {{ __('withdrawal.find_order') }}
</button>
{!! Form::close() !!}
@else
{{-- Phase 2: Umfang wählen und absenden --}}
<hr>
<h3>{{ __('withdrawal.order_found_hl') }}</h3>
<p>
<strong>{{ __('withdrawal.order_number') }}:</strong> #{{ $order->id }}<br>
<strong>{{ __('withdrawal.order_date') }}:</strong> {{ optional($order->created_at)->format('d.m.Y H:i') }}
</p>
{!! Form::open(['route' => 'withdrawal.store', 'method' => 'post']) !!}
{!! Form::hidden('order_number', $order->id) !!}
{!! Form::hidden('email', $prefill_email) !!}
<hr>
<h4>{{ __('withdrawal.choose_scope_hl') }}</h4>
<div class="withdrawal-scope">
<label class="radio">
{!! Form::radio('scope', \App\Models\OrderWithdrawal::TYPE_FULL, old('scope', 'full') === 'full', ['id' => 'scope_full']) !!}
<i></i> {{ __('withdrawal.scope_full') }}
</label>
<label class="radio">
{!! Form::radio('scope', \App\Models\OrderWithdrawal::TYPE_PARTIAL, old('scope') === 'partial', ['id' => 'scope_partial']) !!}
<i></i> {{ __('withdrawal.scope_partial') }}
</label>
@if ($errors->has('scope'))
<div class="alert alert-danger error">{{ $errors->first('scope') }}</div>
@endif
</div>
<div id="withdrawal_items" class="withdrawal-items" style="display: none;">
<hr>
<h4>{{ __('withdrawal.select_items_hl') }}</h4>
<table class="table table-striped">
<thead>
<tr>
<th>{{ __('withdrawal.product') }}</th>
<th class="text-center">{{ __('withdrawal.quantity') }}</th>
<th class="text-center">{{ __('withdrawal.withdraw_quantity') }}</th>
</tr>
</thead>
<tbody>
@foreach ($order->shopping_order_items as $item)
<tr>
<td>{{ $item->product?->getLang('name') ?? ('#' . $item->product_id) }}</td>
<td class="text-center">{{ (int) $item->qty }}</td>
<td class="text-center">
{!! Form::number('items[' . $item->id . ']', old('items.' . $item->id, 0), ['class' => 'form-control qty-input mx-auto', 'min' => 0, 'max' => (int) $item->qty]) !!}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<hr>
<div class="form-group">
{!! Form::label('reason', __('withdrawal.reason')) !!}
{!! Form::textarea('reason', old('reason'), ['class' => 'form-control', 'rows' => 3, 'placeholder' => __('withdrawal.reason_placeholder')]) !!}
</div>
<p class="legal-note">{{ __('withdrawal.legal_note') }}</p>
<div class="mt-3">
<a href="{{ route('withdrawal.create') }}" class="btn btn-default btn-text-500">
<i class="fa fa-angle-left"></i> {{ __('withdrawal.back') }}
</a>
<button type="submit" class="btn btn-primary btn-text-500">
<i class="fa fa-check"></i> {{ __('withdrawal.submit') }}
</button>
</div>
{!! Form::close() !!}
@endif
</div>
</div>
</section>
@endsection
@section('scripts')
<script>
$(document).ready(function () {
function toggleItems() {
if ($('#scope_partial').is(':checked')) {
$('#withdrawal_items').show();
} else {
$('#withdrawal_items').hide();
}
}
$('input[type=radio][name=scope]').on('change', toggleItems);
toggleItems();
});
</script>
@endsection