10 Commits

Author SHA1 Message Date
Arne Weiss 9bd62125d5 Bump version to 0.1.5
Build / build (push) Successful in 14s
Release / release (push) Successful in 12s
2026-06-01 08:52:56 +02:00
Arne Weiss 058937bd64 Add CSS hook, URL ref prefill, order prefill, and Widerrufsfrist display
- Fix CSS loading: register stylesheet via actionFrontControllerSetMedia
  hook instead of initContent() — guaranteed to fire before page render
- Upgrade script registers new hook on existing installations
- Feature 1: pre-fill order_reference from ?ref= URL parameter
- Feature 2: pre-fill customer name/email from logged-in account when
  navigating with ?ref= (already worked; now order ref is also pre-filled)
- Feature 4: compute Widerrufsfrist (order date +14 days) from DB and
  display on form (when ref in URL), confirm, and success pages
- Feature 3: EN mail templates were already present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:52:53 +02:00
Arne Weiss c4b104108a Bump version to 0.1.4
Build / build (push) Successful in 12s
Release / release (push) Successful in 12s
2026-06-01 08:40:36 +02:00
Arne Weiss 16fa6de209 Redesign withdrawal form: step indicator, refined CSS, print button
Add scoped CSS with Navy/warm-white palette, system serif headings, and
card-style radio inputs. Add 3-step progress indicator across all views.
Add print/PDF button on success page. Register CSS via registerStylesheet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:39:34 +02:00
Arne Weiss a9d8966e22 Bump version to 0.1.3
Build / build (push) Successful in 12s
Release / release (push) Successful in 11s
2026-06-01 08:32:02 +02:00
Arne Weiss b742a833d1 Fix admin controller l() error and redundant CI runs
Add l() wrapper to AdminSimpleWithdrawalController so PS8 routing does
not throw UndefinedMethodError; restrict build workflow to branch pushes
only so tag pushes no longer trigger a redundant build run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 08:26:10 +02:00
Arne Weiss 8ed50fa8e6 Bump version to 0.1.2
Build / build (push) Successful in 12s
Release / release (push) Successful in 12s
2026-06-01 08:24:40 +02:00
Arne Weiss 03ef0f0a99 Bump version to 0.1.1
Build / build (push) Successful in 14s
Release / release (push) Successful in 11s
2026-06-01 08:17:53 +02:00
Arne Weiss b3547946cc Add release.sh for patch version bumping
Build / build (push) Successful in 13s
2026-06-01 08:17:18 +02:00
Arne Weiss d838a4dcc0 Fix admin controller: call parent::__construct() before fields_list translations
Build / build (push) Successful in 13s
2026-06-01 08:13:46 +02:00
13 changed files with 867 additions and 139 deletions
+4 -1
View File
@@ -2,6 +2,8 @@ name: Build
on:
push:
branches:
- '**'
pull_request:
jobs:
@@ -27,7 +29,8 @@ jobs:
cp -rp . /tmp/$MODULE
rm -rf /tmp/$MODULE/.git \
/tmp/$MODULE/.gitea \
/tmp/$MODULE/CLAUDE.md
/tmp/$MODULE/CLAUDE.md \
/tmp/$MODULE/release.sh
cd /tmp && zip -r ${MODULE}.zip $MODULE/
mkdir -p $GITHUB_WORKSPACE/dist
mv /tmp/${MODULE}.zip $GITHUB_WORKSPACE/dist/
+2 -1
View File
@@ -30,7 +30,8 @@ jobs:
cp -rp . /tmp/$MODULE
rm -rf /tmp/$MODULE/.git \
/tmp/$MODULE/.gitea \
/tmp/$MODULE/CLAUDE.md
/tmp/$MODULE/CLAUDE.md \
/tmp/$MODULE/release.sh
cd /tmp && zip -r ${MODULE}.zip $MODULE/
mkdir -p $GITHUB_WORKSPACE/dist
mv /tmp/${MODULE}.zip $GITHUB_WORKSPACE/dist/
@@ -20,6 +20,8 @@ class AdminSimpleWithdrawalController extends ModuleAdminController
$this->list_no_link = false;
$this->actions = ['view'];
parent::__construct();
$this->fields_list = [
'id_withdrawal_request' => [
'title' => $this->l('ID'),
@@ -56,8 +58,15 @@ class AdminSimpleWithdrawalController extends ModuleAdminController
'filter_key' => 'a!status',
],
];
}
parent::__construct();
protected function l($string, $class = null, $addslashes = false, $htmlentities = true)
{
if ($this->module) {
return $this->module->l($string, 'AdminSimpleWithdrawalController');
}
return $string;
}
public function renderScopeLabel($value, $row)
+23 -1
View File
@@ -34,6 +34,7 @@ class Simple_withdrawalbuttonWithdrawModuleFrontController extends ModuleFrontCo
'success_data' => $this->successData,
'privacy_url' => (string) Configuration::get(Simple_withdrawalbutton::CONF_PRIVACY_URL),
'revocation_url' => (string) Configuration::get(Simple_withdrawalbutton::CONF_REVOCATION_URL),
'withdrawal_deadline' => $this->computeDeadline(),
]);
if ($this->currentView === 'confirm') {
@@ -179,16 +180,37 @@ class Simple_withdrawalbuttonWithdrawModuleFrontController extends ModuleFrontCo
$customerEmail = (string) $this->context->customer->email;
}
$orderRef = $this->module->cleanText(Tools::getValue('ref'), 64);
return [
'customer_name' => $customerName,
'customer_email' => $customerEmail,
'order_reference' => '',
'order_reference' => $orderRef,
'withdrawal_scope' => 'full',
'withdrawal_items_text' => '',
'message' => '',
];
}
private function computeDeadline()
{
$ref = isset($this->formData['order_reference']) ? $this->formData['order_reference'] : '';
if ($ref === '') {
$ref = $this->module->cleanText(Tools::getValue('ref'), 64);
}
if ($ref === '') {
return '';
}
$orderInfo = $this->module->lookupOrderInfoByReference($ref);
if (!$orderInfo) {
return '';
}
$isoCode = Language::getIsoById((int) $this->context->language->id) ?: 'de';
return (string) $this->module->computeWithdrawalDeadline($orderInfo['date_add'], $isoCode);
}
private function validateData(array $data)
{
$errors = [];
Executable
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
set -e
FILE=simple_withdrawalbutton.php
# Read current version
CURRENT=$(grep "version = '" "$FILE" | grep -o "'[0-9]*\.[0-9]*\.[0-9]*'" | tr -d "'")
if [ -z "$CURRENT" ]; then
echo "Error: could not read version from $FILE" >&2
exit 1
fi
# Increment patch
MAJOR=$(echo "$CURRENT" | cut -d. -f1)
MINOR=$(echo "$CURRENT" | cut -d. -f2)
PATCH=$(echo "$CURRENT" | cut -d. -f3)
NEW="$MAJOR.$MINOR.$((PATCH + 1))"
echo "Version: $CURRENT$NEW"
# Write new version into module file
sed -i "s/version = '$CURRENT'/version = '$NEW'/" "$FILE"
# Commit, tag, push — triggers release pipeline on Gitea
git add "$FILE"
git commit -m "Bump version to $NEW"
git tag "v$NEW"
git push
git push origin "v$NEW"
+53 -1
View File
@@ -27,7 +27,7 @@ class Simple_withdrawalbutton extends Module
{
$this->name = 'simple_withdrawalbutton';
$this->tab = 'administration';
$this->version = '0.1.0';
$this->version = '0.1.5';
$this->author = 'Arne Weiss';
$this->need_instance = 0;
$this->bootstrap = true;
@@ -50,6 +50,7 @@ class Simple_withdrawalbutton extends Module
&& $this->installTab()
&& $this->registerHook('displayFooter')
&& $this->registerHook('displayCustomerAccount')
&& $this->registerHook('actionFrontControllerSetMedia')
&& Configuration::updateValue(self::CONF_SHOP_EMAIL, (string) Configuration::get('PS_SHOP_EMAIL'))
&& Configuration::updateValue(self::CONF_RATE_LIMIT, '5')
&& Configuration::updateValue(self::CONF_PRIVACY_URL, '')
@@ -295,6 +296,20 @@ class Simple_withdrawalbutton extends Module
return $this->display(__FILE__, 'views/templates/hook/customer_account.tpl');
}
public function hookActionFrontControllerSetMedia()
{
if (
Tools::getValue('module') === $this->name
&& Tools::getValue('controller') === 'withdraw'
) {
$this->context->controller->registerStylesheet(
'cyp-withdrawal',
'modules/' . $this->name . '/views/css/withdrawal.css',
['media' => 'all', 'priority' => 200]
);
}
}
public function getWithdrawalLink()
{
return $this->context->link->getModuleLink($this->name, 'withdraw', [], true);
@@ -342,6 +357,43 @@ class Simple_withdrawalbutton extends Module
return $idOrder > 0 ? $idOrder : null;
}
public function lookupOrderInfoByReference($orderReference)
{
$orderReference = $this->cleanText($orderReference, 64);
if ($orderReference === '') {
return null;
}
$sql = 'SELECT `id_order`, `date_add`, `id_customer`
FROM `' . _DB_PREFIX_ . 'orders`
WHERE `reference` = "' . pSQL($orderReference) . '"
AND `id_shop` = ' . (int) $this->context->shop->id . '
ORDER BY `id_order` DESC';
$row = Db::getInstance()->getRow($sql);
if (!$row) {
return null;
}
return [
'id_order' => (int) $row['id_order'],
'date_add' => $row['date_add'],
'id_customer' => (int) $row['id_customer'],
];
}
public function computeWithdrawalDeadline($orderDateAdd, $isoCode = 'de')
{
$timestamp = strtotime((string) $orderDateAdd);
if (!$timestamp) {
return null;
}
$deadline = strtotime('+14 days', $timestamp);
return ($isoCode === 'de') ? date('d.m.Y', $deadline) : date('d/m/Y', $deadline);
}
public function hashForPrivacy($value)
{
$value = trim((string) $value);
+8
View File
@@ -0,0 +1,8 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;
+10
View File
@@ -0,0 +1,10 @@
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_0_1_5($object)
{
return $object->registerHook('actionFrontControllerSetMedia');
}
+8
View File
@@ -0,0 +1,8 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;
+466
View File
@@ -0,0 +1,466 @@
:root {
--cyw-bg: #faf8f5;
--cyw-surface: #ffffff;
--cyw-border: #e2ddd8;
--cyw-text: #1c1a17;
--cyw-text-muted: #6b645e;
--cyw-accent: #1e3a5f;
--cyw-accent-hover: #162d4b;
--cyw-accent-light: #eef2f8;
--cyw-success: #1e5c3a;
--cyw-success-bg: #f0f7f3;
--cyw-error: #8b1e2d;
--cyw-error-bg: #fdf2f3;
--cyw-warning: #7a5a1e;
--cyw-warning-bg: #fdf7ee;
}
/* ── Layout ─────────────────────────────────────────────── */
.cyp-withdrawal-page {
max-width: 660px;
margin: 0 auto;
padding: 0 16px 56px;
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
color: var(--cyw-text);
}
.cyp-withdrawal-page .page-header {
margin-bottom: 32px;
padding-bottom: 20px;
border-bottom: 1px solid var(--cyw-border);
}
.cyp-withdrawal-page .page-header h1 {
font-family: Georgia, 'Times New Roman', serif;
font-size: 26px;
font-weight: normal;
letter-spacing: -0.02em;
margin: 0;
color: var(--cyw-text);
}
.cyp-withdrawal-page .card,
.cyp-withdrawal-page .card-block {
border: 1px solid var(--cyw-border);
border-radius: 8px;
padding: 32px;
background: var(--cyw-surface);
box-shadow: 0 1px 4px rgba(28,26,23,0.05);
}
/* ── Step indicator ─────────────────────────────────────── */
.cyp-steps {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 36px;
gap: 0;
}
.cyp-step {
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
min-width: 72px;
}
.cyp-step-bubble {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 600;
border: 2px solid var(--cyw-border);
background: var(--cyw-surface);
color: var(--cyw-text-muted);
flex-shrink: 0;
}
.cyp-step.active .cyp-step-bubble {
background: var(--cyw-accent);
border-color: var(--cyw-accent);
color: #fff;
}
.cyp-step.done .cyp-step-bubble {
background: var(--cyw-success);
border-color: var(--cyw-success);
color: #fff;
font-size: 15px;
}
.cyp-step-label {
font-size: 10px;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--cyw-text-muted);
font-weight: 500;
white-space: nowrap;
}
.cyp-step.active .cyp-step-label {
color: var(--cyw-accent);
font-weight: 700;
}
.cyp-step.done .cyp-step-label {
color: var(--cyw-success);
}
.cyp-step-line {
height: 2px;
width: 56px;
background: var(--cyw-border);
flex-shrink: 0;
margin-bottom: 19px;
}
.cyp-step-line.done {
background: var(--cyw-success);
}
/* ── Intro block ────────────────────────────────────────── */
.cyp-intro {
font-size: 14px;
color: var(--cyw-text-muted);
line-height: 1.7;
margin-bottom: 24px;
padding-bottom: 24px;
border-bottom: 1px solid var(--cyw-border);
}
.cyp-intro a {
color: var(--cyw-accent);
text-underline-offset: 3px;
}
/* ── Alerts ─────────────────────────────────────────────── */
.cyp-withdrawal-page .alert {
border-radius: 6px;
padding: 12px 16px;
font-size: 14px;
margin-bottom: 20px;
border: 1px solid transparent;
}
.cyp-withdrawal-page .alert ul {
margin: 4px 0 0 16px;
padding: 0;
}
.cyp-withdrawal-page .alert-danger {
background: var(--cyw-error-bg);
border-color: #f0c0c7;
color: var(--cyw-error);
}
.cyp-withdrawal-page .alert-success {
background: var(--cyw-success-bg);
border-color: #b8dfc9;
color: var(--cyw-success);
}
.cyp-withdrawal-page .alert-warning {
background: var(--cyw-warning-bg);
border-color: #e8d5a8;
color: var(--cyw-warning);
}
/* ── Form elements ──────────────────────────────────────── */
.cyp-withdrawal-page .form-group {
margin-bottom: 20px;
}
.cyp-withdrawal-page .form-control-label,
.cyp-withdrawal-page fieldset.form-group legend {
display: block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--cyw-text-muted);
margin-bottom: 7px;
}
.cyp-withdrawal-page .form-control {
width: 100%;
padding: 10px 13px;
border: 1px solid var(--cyw-border);
border-radius: 6px;
font-size: 15px;
color: var(--cyw-text);
background: var(--cyw-surface);
font-family: inherit;
box-sizing: border-box;
transition: border-color 0.15s, box-shadow 0.15s;
appearance: none;
}
.cyp-withdrawal-page .form-control:focus {
outline: none;
border-color: var(--cyw-accent);
box-shadow: 0 0 0 3px var(--cyw-accent-light);
}
.cyp-withdrawal-page textarea.form-control {
resize: vertical;
min-height: 96px;
}
.cyp-withdrawal-page .form-text {
font-size: 12px;
color: var(--cyw-text-muted);
margin-top: 5px;
display: block;
}
/* ── Radio card buttons ─────────────────────────────────── */
.cyp-withdrawal-page fieldset.form-group {
border: none;
padding: 0;
margin-bottom: 20px;
}
.cyp-radio-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.cyp-radio-label {
display: flex;
align-items: center;
gap: 11px;
cursor: pointer;
padding: 12px 14px;
border: 1px solid var(--cyw-border);
border-radius: 6px;
font-size: 15px;
color: var(--cyw-text);
user-select: none;
transition: border-color 0.12s, background 0.12s;
}
.cyp-radio-label:hover {
border-color: var(--cyw-accent);
background: var(--cyw-accent-light);
}
.cyp-radio-label input[type="radio"] {
width: 17px;
height: 17px;
accent-color: var(--cyw-accent);
cursor: pointer;
flex-shrink: 0;
}
.cyp-radio-label.cyp-selected {
border-color: var(--cyw-accent);
background: var(--cyw-accent-light);
}
/* ── Buttons ────────────────────────────────────────────── */
.cyp-actions {
display: flex;
align-items: center;
gap: 12px;
margin-top: 28px;
padding-top: 24px;
border-top: 1px solid var(--cyw-border);
flex-wrap: wrap;
}
.cyp-withdrawal-page .btn-primary {
background: var(--cyw-accent) !important;
border: 1px solid var(--cyw-accent) !important;
color: #fff !important;
padding: 11px 28px;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
letter-spacing: 0.03em;
cursor: pointer;
transition: background 0.15s;
font-family: inherit;
}
.cyp-withdrawal-page .btn-primary:hover {
background: var(--cyw-accent-hover) !important;
border-color: var(--cyw-accent-hover) !important;
color: #fff !important;
}
.cyp-withdrawal-page .btn-secondary {
background: transparent !important;
border: 1px solid var(--cyw-border) !important;
color: var(--cyw-text-muted) !important;
padding: 11px 22px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: border-color 0.15s, color 0.15s;
font-family: inherit;
}
.cyp-withdrawal-page .btn-secondary:hover {
border-color: var(--cyw-text-muted) !important;
color: var(--cyw-text) !important;
}
/* ── Summary table (confirm + success) ─────────────────── */
.cyp-summary {
border: 1px solid var(--cyw-border);
border-radius: 6px;
overflow: hidden;
margin-bottom: 24px;
}
.cyp-summary-row {
display: grid;
grid-template-columns: 176px 1fr;
border-bottom: 1px solid var(--cyw-border);
}
.cyp-summary-row:last-child {
border-bottom: none;
}
.cyp-summary-key {
padding: 11px 14px;
background: #f7f5f2;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--cyw-text-muted);
border-right: 1px solid var(--cyw-border);
display: flex;
align-items: center;
}
.cyp-summary-val {
padding: 11px 14px;
font-size: 14px;
color: var(--cyw-text);
line-height: 1.5;
}
/* ── Legal fine print ───────────────────────────────────── */
.cyp-legal {
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid var(--cyw-border);
font-size: 12px;
color: var(--cyw-text-muted);
line-height: 1.65;
}
.cyp-legal a {
color: var(--cyw-accent);
text-underline-offset: 2px;
}
/* ── Success page ───────────────────────────────────────── */
.cyp-success-header {
text-align: center;
padding-bottom: 24px;
margin-bottom: 24px;
border-bottom: 1px solid var(--cyw-border);
}
.cyp-success-icon {
width: 52px;
height: 52px;
background: var(--cyw-success-bg);
border: 2px solid #b8dfc9;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16px;
font-size: 22px;
color: var(--cyw-success);
}
.cyp-success-header h2 {
font-family: Georgia, serif;
font-size: 20px;
font-weight: normal;
color: var(--cyw-success);
margin: 0 0 6px;
}
.cyp-success-header p {
font-size: 14px;
color: var(--cyw-text-muted);
margin: 0;
}
.cyp-print-btn {
background: none;
border: 1px solid var(--cyw-border);
color: var(--cyw-text-muted);
padding: 9px 18px;
border-radius: 6px;
font-size: 13px;
cursor: pointer;
font-family: inherit;
display: inline-flex;
align-items: center;
gap: 7px;
transition: border-color 0.15s, color 0.15s;
margin-top: 16px;
}
.cyp-print-btn:hover {
border-color: var(--cyw-text-muted);
color: var(--cyw-text);
}
/* ── Responsive ─────────────────────────────────────────── */
@media (max-width: 576px) {
.cyp-withdrawal-page .card,
.cyp-withdrawal-page .card-block {
padding: 20px 16px;
}
.cyp-summary-row {
grid-template-columns: 1fr;
}
.cyp-summary-key {
border-right: none;
border-bottom: 1px solid var(--cyw-border);
padding-bottom: 4px;
}
.cyp-step-line {
width: 28px;
}
}
@media print {
.cyp-withdrawal-page .page-header,
.cyp-steps,
.cyp-actions,
.cyp-print-btn,
.cyp-legal {
display: none !important;
}
}
+80 -41
View File
@@ -3,9 +3,26 @@
<h1>{l s='Widerruf bestätigen' mod='simple_withdrawalbutton'}</h1>
</header>
<div class="cyp-steps">
<div class="cyp-step done">
<div class="cyp-step-bubble">✓</div>
<div class="cyp-step-label">{l s='Angaben' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line done"></div>
<div class="cyp-step active">
<div class="cyp-step-bubble">2</div>
<div class="cyp-step-label">{l s='Prüfen' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line"></div>
<div class="cyp-step">
<div class="cyp-step-bubble">3</div>
<div class="cyp-step-label">{l s='Bestätigt' mod='simple_withdrawalbutton'}</div>
</div>
</div>
<div class="card card-block">
{if $errors_list|@count > 0}
<div class="alert alert-danger">
<div class="alert alert-danger" role="alert">
<ul>
{foreach from=$errors_list item=error}
<li>{$error|escape:'html':'UTF-8'}</li>
@@ -14,57 +31,79 @@
</div>
{/if}
<p>{l s='Bitte prüfen Sie Ihre Angaben. Wenn die Angaben korrekt sind, können Sie Ihren Widerruf jetzt absenden.' mod='simple_withdrawalbutton'}</p>
<dl class="row">
<dt class="col-sm-4">{l s='Name' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$form_data.customer_name|escape:'html':'UTF-8'}</dd>
<dt class="col-sm-4">{l s='E-Mail-Adresse' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$form_data.customer_email|escape:'html':'UTF-8'}</dd>
<dt class="col-sm-4">{l s='Bestellnummer / Bestellreferenz' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$form_data.order_reference|escape:'html':'UTF-8'}</dd>
<dt class="col-sm-4">{l s='Widerruf betrifft' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">
{if $form_data.withdrawal_scope == 'partial'}
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
{else}
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
{/if}
</dd>
<p style="font-size:14px;color:var(--cyw-text-muted);margin-bottom:20px;">
{l s='Bitte prüfen Sie Ihre Angaben. Wenn alles korrekt ist, klicken Sie auf „Widerruf absenden".' mod='simple_withdrawalbutton'}
</p>
<div class="cyp-summary">
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Name' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$form_data.customer_name|escape:'html':'UTF-8'}</div>
</div>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='E-Mail' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$form_data.customer_email|escape:'html':'UTF-8'}</div>
</div>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Bestellnummer' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$form_data.order_reference|escape:'html':'UTF-8'}</div>
</div>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Betrifft' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">
{if $form_data.withdrawal_scope == 'partial'}
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
{else}
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
{/if}
</div>
</div>
{if $form_data.withdrawal_scope == 'partial'}
<dt class="col-sm-4">{l s='Betroffene Artikel / Mengen' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$form_data.withdrawal_items_text|escape:'html':'UTF-8'|nl2br nofilter}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Betroffene Artikel' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$form_data.withdrawal_items_text|escape:'html':'UTF-8'|nl2br nofilter}</div>
</div>
{/if}
{if $form_data.message != ''}
<dt class="col-sm-4">{l s='Nachricht / Bemerkung' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$form_data.message|escape:'html':'UTF-8'|nl2br nofilter}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Nachricht' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$form_data.message|escape:'html':'UTF-8'|nl2br nofilter}</div>
</div>
{/if}
</dl>
{if isset($withdrawal_deadline) && $withdrawal_deadline != ''}
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Frist' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val" style="color:var(--cyw-accent);font-weight:600;">
{l s='bis' mod='simple_withdrawalbutton'} {$withdrawal_deadline|escape:'html':'UTF-8'}
<span style="font-size:12px;font-weight:400;color:var(--cyw-text-muted);">
({l s='14 Tage ab Bestelldatum' mod='simple_withdrawalbutton'})
</span>
</div>
</div>
{/if}
</div>
<form method="post" action="{$action_url|escape:'html':'UTF-8'}">
<input type="hidden" name="csrf_token" value="{$csrf_token|escape:'html':'UTF-8'}">
<input type="hidden" name="customer_name" value="{$form_data.customer_name|escape:'html':'UTF-8'}">
<input type="hidden" name="customer_email" value="{$form_data.customer_email|escape:'html':'UTF-8'}">
<input type="hidden" name="order_reference" value="{$form_data.order_reference|escape:'html':'UTF-8'}">
<input type="hidden" name="withdrawal_scope" value="{$form_data.withdrawal_scope|escape:'html':'UTF-8'}">
<input type="hidden" name="withdrawal_items_text" value="{$form_data.withdrawal_items_text|escape:'html':'UTF-8'}">
<input type="hidden" name="message" value="{$form_data.message|escape:'html':'UTF-8'}">
<div style="position:absolute; left:-10000px; top:auto; width:1px; height:1px; overflow:hidden;" aria-hidden="true">
<input type="hidden" name="csrf_token" value="{$csrf_token|escape:'html':'UTF-8'}">
<input type="hidden" name="customer_name" value="{$form_data.customer_name|escape:'html':'UTF-8'}">
<input type="hidden" name="customer_email" value="{$form_data.customer_email|escape:'html':'UTF-8'}">
<input type="hidden" name="order_reference" value="{$form_data.order_reference|escape:'html':'UTF-8'}">
<input type="hidden" name="withdrawal_scope" value="{$form_data.withdrawal_scope|escape:'html':'UTF-8'}">
<input type="hidden" name="withdrawal_items_text" value="{$form_data.withdrawal_items_text|escape:'html':'UTF-8'}">
<input type="hidden" name="message" value="{$form_data.message|escape:'html':'UTF-8'}">
<div style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;" aria-hidden="true">
<label for="cyp_withdrawal_hp_confirm">Website</label>
<input type="text" id="cyp_withdrawal_hp_confirm" name="cyp_hp_v1" value="" tabindex="-1" autocomplete="off">
</div>
<button type="submit" name="submit_withdrawal_confirm" value="1" class="btn btn-primary">
{l s='Widerruf bestätigen' mod='simple_withdrawalbutton'}
</button>
<button type="submit" name="submit_withdrawal_back" value="1" class="btn btn-secondary" formaction="{$action_url|escape:'html':'UTF-8'}">
{l s='Angaben ändern' mod='simple_withdrawalbutton'}
</button>
<div class="cyp-actions">
<button type="submit" name="submit_withdrawal_confirm" value="1" class="btn btn-primary">
{l s='Widerruf absenden' mod='simple_withdrawalbutton'}
</button>
<button type="submit" name="submit_withdrawal_back" value="1" class="btn btn-secondary">
{l s='Angaben ändern' mod='simple_withdrawalbutton'}
</button>
</div>
</form>
</div>
</section>
+96 -57
View File
@@ -1,23 +1,48 @@
<section class="cyp-withdrawal-page">
<header class="page-header">
<h1>{l s='Vertrag widerrufen' mod='simple_withdrawalbutton'}</h1>
<h1>{l s='Widerruf erklären' mod='simple_withdrawalbutton'}</h1>
</header>
<div class="card card-block">
<p>
{l s='Sie können hier den Vertrag zu einer Bestellung vollständig oder teilweise widerrufen. Bitte geben Sie die Bestellnummer und bei einem Teilwiderruf die betroffenen Artikel und Mengen an.' mod='simple_withdrawalbutton'}
</p>
<div class="cyp-steps">
<div class="cyp-step active">
<div class="cyp-step-bubble">1</div>
<div class="cyp-step-label">{l s='Angaben' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line"></div>
<div class="cyp-step">
<div class="cyp-step-bubble">2</div>
<div class="cyp-step-label">{l s='Prüfen' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line"></div>
<div class="cyp-step">
<div class="cyp-step-bubble">3</div>
<div class="cyp-step-label">{l s='Bestätigt' mod='simple_withdrawalbutton'}</div>
</div>
</div>
{if isset($revocation_url) && $revocation_url != ''}
<p>
<a href="{$revocation_url|escape:'html':'UTF-8'}" target="_blank" rel="noopener">
{l s='Unsere Widerrufsbelehrung (14-Tage-Frist)' mod='simple_withdrawalbutton'}
</a>
</p>
<div class="card card-block">
<div class="cyp-intro">
{l s='Sie können hier den Vertrag zu einer Bestellung vollständig oder teilweise widerrufen. Bitte geben Sie die Bestellnummer und bei einem Teilwiderruf die betroffenen Artikel und Mengen an.' mod='simple_withdrawalbutton'}
{if isset($revocation_url) && $revocation_url != ''}
&nbsp;&nbsp;<a href="{$revocation_url|escape:'html':'UTF-8'}" target="_blank" rel="noopener">{l s='Widerrufsbelehrung lesen (14-Tage-Frist)' mod='simple_withdrawalbutton'}</a>
{/if}
</div>
{if isset($withdrawal_deadline) && $withdrawal_deadline != ''}
<div class="cyp-deadline-notice" style="
display:flex; align-items:center; gap:10px; background:#eef2f8;
border:1px solid #c5d4eb; border-radius:6px; padding:11px 14px;
font-size:13px; color:var(--cyw-accent); margin-bottom:24px;">
<span style="font-size:16px;">📅</span>
<span>
{l s='Widerrufsfrist (14 Tage ab Bestelldatum): bis' mod='simple_withdrawalbutton'}
<strong>{$withdrawal_deadline|escape:'html':'UTF-8'}</strong>
</span>
</div>
{/if}
{if $errors_list|@count > 0}
<div class="alert alert-danger">
<div class="alert alert-danger" role="alert">
<ul>
{foreach from=$errors_list item=error}
<li>{$error|escape:'html':'UTF-8'}</li>
@@ -28,7 +53,7 @@
<form method="post" action="{$action_url|escape:'html':'UTF-8'}" class="cyp-withdrawal-form" novalidate>
<input type="hidden" name="csrf_token" value="{$csrf_token|escape:'html':'UTF-8'}">
<div style="position:absolute; left:-10000px; top:auto; width:1px; height:1px; overflow:hidden;" aria-hidden="true">
<div style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;" aria-hidden="true">
<label for="cyp_withdrawal_hp">Website</label>
<input type="text" id="cyp_withdrawal_hp" name="cyp_hp_v1" value="" tabindex="-1" autocomplete="off">
</div>
@@ -37,91 +62,105 @@
<label for="cyp_withdrawal_customer_name" class="form-control-label">
{l s='Name' mod='simple_withdrawalbutton'} <span aria-hidden="true">*</span>
</label>
<input class="form-control" type="text" id="cyp_withdrawal_customer_name" name="customer_name" maxlength="255" required value="{$form_data.customer_name|default:''|escape:'html':'UTF-8'}">
<input class="form-control" type="text" id="cyp_withdrawal_customer_name" name="customer_name"
maxlength="255" required
value="{$form_data.customer_name|default:''|escape:'html':'UTF-8'}">
</div>
<div class="form-group">
<label for="cyp_withdrawal_customer_email" class="form-control-label">
{l s='E-Mail-Adresse für die Eingangsbestätigung' mod='simple_withdrawalbutton'} <span aria-hidden="true">*</span>
{l s='E-Mail für die Eingangsbestätigung' mod='simple_withdrawalbutton'} <span aria-hidden="true">*</span>
</label>
<input class="form-control" type="email" id="cyp_withdrawal_customer_email" name="customer_email" maxlength="255" required value="{$form_data.customer_email|default:''|escape:'html':'UTF-8'}">
<input class="form-control" type="email" id="cyp_withdrawal_customer_email" name="customer_email"
maxlength="255" required
value="{$form_data.customer_email|default:''|escape:'html':'UTF-8'}">
</div>
<div class="form-group">
<label for="cyp_withdrawal_order_reference" class="form-control-label">
{l s='Bestellnummer / Bestellreferenz' mod='simple_withdrawalbutton'} <span aria-hidden="true">*</span>
</label>
<input class="form-control" type="text" id="cyp_withdrawal_order_reference" name="order_reference" maxlength="64" required value="{$form_data.order_reference|default:''|escape:'html':'UTF-8'}">
<input class="form-control" type="text" id="cyp_withdrawal_order_reference" name="order_reference"
maxlength="64" required
value="{$form_data.order_reference|default:''|escape:'html':'UTF-8'}">
</div>
<fieldset class="form-group">
<legend class="form-control-label">
{l s='Widerruf betrifft' mod='simple_withdrawalbutton'} <span aria-hidden="true">*</span>
</legend>
<label class="custom-radio" for="cyp_withdrawal_scope_full">
<input type="radio" id="cyp_withdrawal_scope_full" name="withdrawal_scope" value="full" {if !isset($form_data.withdrawal_scope) || $form_data.withdrawal_scope != 'partial'}checked{/if}>
<span></span>
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
</label>
<br>
<label class="custom-radio" for="cyp_withdrawal_scope_partial">
<input type="radio" id="cyp_withdrawal_scope_partial" name="withdrawal_scope" value="partial" {if isset($form_data.withdrawal_scope) && $form_data.withdrawal_scope == 'partial'}checked{/if}>
<span></span>
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
</label>
<div class="cyp-radio-group">
<label class="cyp-radio-label{if !isset($form_data.withdrawal_scope) || $form_data.withdrawal_scope != 'partial'} cyp-selected{/if}" for="cyp_withdrawal_scope_full">
<input type="radio" id="cyp_withdrawal_scope_full" name="withdrawal_scope" value="full"
{if !isset($form_data.withdrawal_scope) || $form_data.withdrawal_scope != 'partial'}checked{/if}>
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
</label>
<label class="cyp-radio-label{if isset($form_data.withdrawal_scope) && $form_data.withdrawal_scope == 'partial'} cyp-selected{/if}" for="cyp_withdrawal_scope_partial">
<input type="radio" id="cyp_withdrawal_scope_partial" name="withdrawal_scope" value="partial"
{if isset($form_data.withdrawal_scope) && $form_data.withdrawal_scope == 'partial'}checked{/if}>
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
</label>
</div>
</fieldset>
<div class="form-group" id="cyp-withdrawal-items-group">
<label for="cyp_withdrawal_items_text" class="form-control-label">
{l s='Welche Artikel / Mengen möchten Sie widerrufen?' mod='simple_withdrawalbutton'}
{l s='Welche Artikel / Mengen?' mod='simple_withdrawalbutton'}
</label>
<textarea class="form-control" id="cyp_withdrawal_items_text" name="withdrawal_items_text" rows="4" maxlength="5000" placeholder="{l s='Beispiel: 1x Tomizu 720 ml, 2x Magokoro 300 ml' mod='simple_withdrawalbutton'}">{$form_data.withdrawal_items_text|default:''|escape:'html':'UTF-8'}</textarea>
<small class="form-text text-muted">
{l s='Nur bei einem Teilwiderruf erforderlich.' mod='simple_withdrawalbutton'}
</small>
<textarea class="form-control" id="cyp_withdrawal_items_text" name="withdrawal_items_text"
rows="4" maxlength="5000"
placeholder="{l s='Beispiel: 1x Tomizu 720 ml, 2x Magokoro 300 ml' mod='simple_withdrawalbutton'}">{$form_data.withdrawal_items_text|default:''|escape:'html':'UTF-8'}</textarea>
<small class="form-text">{l s='Nur bei einem Teilwiderruf erforderlich.' mod='simple_withdrawalbutton'}</small>
</div>
<div class="form-group">
<label for="cyp_withdrawal_message" class="form-control-label">
{l s='Nachricht / Bemerkung optional' mod='simple_withdrawalbutton'}
{l s='Nachricht / Bemerkung' mod='simple_withdrawalbutton'} <span style="font-weight:400;text-transform:none;letter-spacing:0;">({l s='optional' mod='simple_withdrawalbutton'})</span>
</label>
<textarea class="form-control" id="cyp_withdrawal_message" name="message" rows="4" maxlength="5000">{$form_data.message|default:''|escape:'html':'UTF-8'}</textarea>
<textarea class="form-control" id="cyp_withdrawal_message" name="message"
rows="4" maxlength="5000">{$form_data.message|default:''|escape:'html':'UTF-8'}</textarea>
</div>
<p class="small text-muted">
{l s='Pflichtfelder sind mit * gekennzeichnet. Ein Widerrufsgrund ist nicht erforderlich.' mod='simple_withdrawalbutton'}
</p>
<div class="cyp-legal">
<p>{l s='Pflichtfelder sind mit * gekennzeichnet. Ein Widerrufsgrund ist nicht erforderlich.' mod='simple_withdrawalbutton'}</p>
<p>
{l s='Ihre Angaben (Name, E-Mail-Adresse) werden zur Bearbeitung Ihrer Widerrufserklärung verarbeitet. Rechtsgrundlage: Art. 6 Abs. 1 lit. b und c DSGVO.' mod='simple_withdrawalbutton'}
{if isset($privacy_url) && $privacy_url != ''}
<a href="{$privacy_url|escape:'html':'UTF-8'}" target="_blank" rel="noopener">{l s='Datenschutzerklärung' mod='simple_withdrawalbutton'}</a>
{/if}
</p>
</div>
<p class="small text-muted">
{l s='Ihre Angaben (Name, E-Mail-Adresse) werden zur Bearbeitung Ihrer Widerrufserklärung verarbeitet. Rechtsgrundlage: Art. 6 Abs. 1 lit. b und c DSGVO.' mod='simple_withdrawalbutton'}
{if isset($privacy_url) && $privacy_url != ''}
<a href="{$privacy_url|escape:'html':'UTF-8'}" target="_blank" rel="noopener">
{l s='Datenschutzerklärung' mod='simple_withdrawalbutton'}
</a>
{/if}
</p>
<button type="submit" name="submit_withdrawal_prepare" value="1" class="btn btn-primary">
{l s='Angaben prüfen' mod='simple_withdrawalbutton'}
</button>
<div class="cyp-actions">
<button type="submit" name="submit_withdrawal_prepare" value="1" class="btn btn-primary">
{l s='Angaben prüfen →' mod='simple_withdrawalbutton'}
</button>
</div>
</form>
</div>
</section>
<script>
(function () {
var partial = document.getElementById('cyp_withdrawal_scope_partial');
var full = document.getElementById('cyp_withdrawal_scope_full');
var group = document.getElementById('cyp-withdrawal-items-group');
var partial = document.getElementById('cyp_withdrawal_scope_partial');
var full = document.getElementById('cyp_withdrawal_scope_full');
var group = document.getElementById('cyp-withdrawal-items-group');
var textarea = document.getElementById('cyp_withdrawal_items_text');
var labels = document.querySelectorAll('.cyp-radio-label');
function update() {
if (!group || !partial || !textarea) return;
var show = partial.checked;
group.style.display = show ? '' : 'none';
textarea.required = show;
var isPartial = partial.checked;
group.style.display = isPartial ? '' : 'none';
textarea.required = isPartial;
labels.forEach(function (label) {
var input = label.querySelector('input[type="radio"]');
label.classList.toggle('cyp-selected', input && input.checked);
});
}
if (partial) partial.addEventListener('change', update);
if (full) full.addEventListener('change', update);
if (full) full.addEventListener('change', update);
update();
})();
</script>
+78 -36
View File
@@ -3,57 +3,99 @@
<h1>{l s='Widerruf übermittelt' mod='simple_withdrawalbutton'}</h1>
</header>
<div class="cyp-steps">
<div class="cyp-step done">
<div class="cyp-step-bubble">✓</div>
<div class="cyp-step-label">{l s='Angaben' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line done"></div>
<div class="cyp-step done">
<div class="cyp-step-bubble">✓</div>
<div class="cyp-step-label">{l s='Prüfen' mod='simple_withdrawalbutton'}</div>
</div>
<div class="cyp-step-line done"></div>
<div class="cyp-step active">
<div class="cyp-step-bubble">3</div>
<div class="cyp-step-label">{l s='Bestätigt' mod='simple_withdrawalbutton'}</div>
</div>
</div>
<div class="card card-block">
{if isset($success_data.mail_ok) && $success_data.mail_ok}
<div class="alert alert-success">
{l s='Ihr Widerruf wurde übermittelt. Eine Eingangsbestätigung wurde an die angegebene E-Mail-Adresse gesendet.' mod='simple_withdrawalbutton'}
</div>
{else}
<div class="alert alert-warning">
{l s='Ihr Widerruf wurde gespeichert, aber die automatische Eingangsbestätigung konnte möglicherweise nicht versendet werden. Bitte kontaktieren Sie uns zusätzlich per E-Mail, falls Sie keine Bestätigung erhalten.' mod='simple_withdrawalbutton'}
</div>
{/if}
<div class="cyp-success-header">
<div class="cyp-success-icon" aria-hidden="true">✓</div>
{if isset($success_data.mail_ok) && $success_data.mail_ok}
<h2>{l s='Ihr Widerruf wurde erfolgreich übermittelt.' mod='simple_withdrawalbutton'}</h2>
<p>{l s='Eine Eingangsbestätigung wurde an Ihre E-Mail-Adresse gesendet.' mod='simple_withdrawalbutton'}</p>
{else}
<h2 style="color:var(--cyw-warning);">{l s='Ihr Widerruf wurde gespeichert.' mod='simple_withdrawalbutton'}</h2>
<p class="alert alert-warning" style="display:inline-block;text-align:left;margin-top:8px;">
{l s='Die automatische Eingangsbestätigung konnte möglicherweise nicht versendet werden. Bitte kontaktieren Sie uns zusätzlich per E-Mail, falls Sie keine Bestätigung erhalten.' mod='simple_withdrawalbutton'}
</p>
{/if}
</div>
<dl class="row">
<div class="cyp-summary">
{if isset($success_data.created_at)}
<dt class="col-sm-4">{l s='Eingang:' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$success_data.created_at|escape:'html':'UTF-8'}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Eingangsdatum' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$success_data.created_at|escape:'html':'UTF-8'}</div>
</div>
{/if}
{if isset($success_data.customer_email)}
<dt class="col-sm-4">{l s='E-Mail-Adresse:' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$success_data.customer_email|escape:'html':'UTF-8'}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='E-Mail' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$success_data.customer_email|escape:'html':'UTF-8'}</div>
</div>
{/if}
{if isset($success_data.order_reference) && $success_data.order_reference != ''}
<dt class="col-sm-4">{l s='Bestellnummer / Bestellreferenz' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$success_data.order_reference|escape:'html':'UTF-8'}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Bestellnummer' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$success_data.order_reference|escape:'html':'UTF-8'}</div>
</div>
{/if}
{if isset($success_data.withdrawal_scope)}
<dt class="col-sm-4">{l s='Widerruf betrifft' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">
{if $success_data.withdrawal_scope == 'partial'}
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
{else}
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
{/if}
</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Betrifft' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">
{if $success_data.withdrawal_scope == 'partial'}
{l s='einen Teil der Bestellung' mod='simple_withdrawalbutton'}
{else}
{l s='die gesamte Bestellung' mod='simple_withdrawalbutton'}
{/if}
</div>
</div>
{/if}
{if isset($success_data.withdrawal_items_text) && $success_data.withdrawal_items_text != ''}
<dt class="col-sm-4">{l s='Betroffene Artikel / Mengen' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$success_data.withdrawal_items_text|escape:'html':'UTF-8'|nl2br nofilter}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Betroffene Artikel' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$success_data.withdrawal_items_text|escape:'html':'UTF-8'|nl2br nofilter}</div>
</div>
{/if}
{if isset($success_data.message) && $success_data.message != ''}
<dt class="col-sm-4">{l s='Nachricht / Bemerkung' mod='simple_withdrawalbutton'}</dt>
<dd class="col-sm-8">{$success_data.message|escape:'html':'UTF-8'|nl2br nofilter}</dd>
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Nachricht' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val">{$success_data.message|escape:'html':'UTF-8'|nl2br nofilter}</div>
</div>
{/if}
</dl>
{if isset($withdrawal_deadline) && $withdrawal_deadline != ''}
<div class="cyp-summary-row">
<div class="cyp-summary-key">{l s='Frist' mod='simple_withdrawalbutton'}</div>
<div class="cyp-summary-val" style="color:var(--cyw-accent);font-weight:600;">
{l s='bis' mod='simple_withdrawalbutton'} {$withdrawal_deadline|escape:'html':'UTF-8'}
<span style="font-size:12px;font-weight:400;color:var(--cyw-text-muted);">
({l s='14 Tage ab Bestelldatum' mod='simple_withdrawalbutton'})
</span>
</div>
</div>
{/if}
</div>
<p class="small text-muted">
<div class="cyp-legal">
{l s='Diese Bestätigung betrifft nur den Eingang Ihrer Widerrufserklärung. Die weitere Bearbeitung und Prüfung erfolgt separat.' mod='simple_withdrawalbutton'}
</p>
</div>
<button class="cyp-print-btn" onclick="window.print()" type="button">
{l s='Seite drucken / als PDF speichern' mod='simple_withdrawalbutton'}
</button>
</div>
</section>