diff options
| author | Roger Rehnelt <noreply@maennchen1.de> | 2026-10-03 15:54:38 +0200 |
|---|---|---|
| committer | Roger Rehnelt <noreply@maennchen1.de> | 2026-10-03 15:54:38 +0200 |
| commit | 578c435846e3195688104776b92253752b63ea8a (patch) | |
| tree | fbbf8956e07af5e4470b925ac413781cfb897842 /views | |
| parent | f786f0c59d9a95d6829aaf58d99c882a609355ed (diff) | |
Widerrufsformular: Schutz vor Massenabsendungen, Liste nicht zugeordneter Widerrufe
Bot-Feld und Drosselung auf fünf Absendungen je Absender und Stunde (S21). Nicht zugeordnete Widerrufe stehen in den Moduleinstellungen und lassen sich löschen (S20).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'views')
| -rw-r--r-- | views/mods/mod_revocation/ajaxDialogContent.phtml | 6 | ||||
| -rw-r--r-- | views/mods/mod_revocation/page_form.phtml | 6 | ||||
| -rw-r--r-- | views/mods/mod_revocation/settings_edit.phtml | 40 | ||||
| -rw-r--r-- | views/mods/mod_revocation/wpsg_revocation.css | 2 |
4 files changed, 54 insertions, 0 deletions
diff --git a/views/mods/mod_revocation/ajaxDialogContent.phtml b/views/mods/mod_revocation/ajaxDialogContent.phtml index e10202c..960dc20 100644 --- a/views/mods/mod_revocation/ajaxDialogContent.phtml +++ b/views/mods/mod_revocation/ajaxDialogContent.phtml @@ -138,6 +138,12 @@ $arReason = \wpsgRevocation\Revocation::getReasons(); <?php } ?> + <?php /* Bot-Falle (S21): für Menschen und Screenreader unsichtbar, nicht in der Tab-Reihenfolge */ ?> + <div class="wpsg_revocation_hp" aria-hidden="true"> + <label class="label" for="wpsg_rvd_url"><?php echo __('Bitte leer lassen', 'wpsg'); ?></label> + <input type="text" id="wpsg_rvd_url" name="wpsg_revocation_reason[url]" value="" tabindex="-1" autocomplete="off" /> + </div> + <div class="form_field"> <label class="label" for="wpsg_rvd_name"><?php echo __('Name', 'wpsg'); ?></label> <div class="value"> diff --git a/views/mods/mod_revocation/page_form.phtml b/views/mods/mod_revocation/page_form.phtml index f76b2b8..1dfcbc9 100644 --- a/views/mods/mod_revocation/page_form.phtml +++ b/views/mods/mod_revocation/page_form.phtml @@ -87,6 +87,12 @@ </fieldset> + <?php /* Bot-Falle (S21): für Menschen und Screenreader unsichtbar, nicht in der Tab-Reihenfolge */ ?> + <div class="wpsg_revocation_hp" aria-hidden="true"> + <label class="label" for="wpsg_rvp_url"><?php echo \__('Bitte leer lassen', 'wpsg'); ?></label> + <input type="text" id="wpsg_rvp_url" name="wpsg_revocation_reason[url]" value="" tabindex="-1" autocomplete="off" /> + </div> + <div class="form_field"> <label class="label" for="wpsg_rvp_name"><?php echo \__('Name', 'wpsg'); ?></label> <div class="value"> diff --git a/views/mods/mod_revocation/settings_edit.phtml b/views/mods/mod_revocation/settings_edit.phtml index ee771eb..835535f 100644 --- a/views/mods/mod_revocation/settings_edit.phtml +++ b/views/mods/mod_revocation/settings_edit.phtml @@ -19,6 +19,7 @@ <ul class="nav nav-tabs" role="tablist"> <li role="presentation" :class="{ 'active': tab === 1 }"><a href="#tab1" @click.prevent.stop="tab = 1"><?php echo __('Einstellungen', 'wpsg'); ?></a></li> <li role="presentation" :class="{ 'active': tab === 2 }"><a href="#tab2" @click.prevent.stop="tab = 2"><?php echo __('Gründe für Retouren', 'wpsg'); ?></a></li> + <li role="presentation" :class="{ 'active': tab === 3 }"><a href="#tab3" @click.prevent.stop="tab = 3"><?php echo __('Nicht zugeordnete Widerrufe', 'wpsg'); ?></a></li> </ul> <input type="hidden" name="wpsg_mod_revocation_reason" v-model="jsonString" /> @@ -69,6 +70,45 @@ <a href="#" @click.prevent.stop="addReason" class="addReason"><span class="wpsg-glyphicon glyphicon glyphicon-plus"></span><?php echo __('Neuen Grund anlegen', 'wpsg'); ?></a> </div> + <div v-show="tab === 3" class="tab-pane active"> + <?php /* S20: Widerrufe ohne passende Bestellung; v-pre, damit eingetragene Texte keine Vue-Vorlage sind. Löschen über das Modulformular (POST, Nonce, wpsg_conf) */ $arUnassigned = \wpsgRevocation\Revocation::unassignedEntries(); ?> + <div v-pre class="wpsg_mod_revocation_unassigned"> + <p><?php echo esc_html(wpsg_translate(__('Widerrufe, zu denen keine Bestellung oder Position gefunden wurde. Gespeichert werden höchstens die letzten #1#.', 'wpsg'), \wpsgRevocation\Revocation::UNASSIGNED_MAX)); ?></p> + <?php if (sizeof($arUnassigned) === 0) { ?> + <p><?php echo esc_html__('Keine Einträge.', 'wpsg'); ?></p> + <?php } else { ?> + <?php /* Der Admin-Controller speichert nur mit „submit“; auch die Löschknöpfe gehen diesen Weg (Nonce, wpsg_conf) */ ?> + <input type="hidden" name="submit" value="1" /> + <table class="table"> + <thead><tr> + <th scope="col"><?php echo esc_html__('Datum', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('Name', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('E-Mail', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('Bestellnummer', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('Artikelnummer', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('Menge', 'wpsg'); ?></th> + <th scope="col"><?php echo esc_html__('Vermerk', 'wpsg'); ?></th> + <th scope="col"><span class="screen-reader-text"><?php echo esc_html__('Löschen', 'wpsg'); ?></span></th> + </tr></thead> + <tbody> + <?php foreach (array_reverse($arUnassigned) as $entry) { ?> + <tr> + <td><?php echo esc_html(\mysql2date('d.m.Y H:i', (string)($entry['time']??''))); ?></td> + <td><?php echo esc_html((string)($entry['name']??'')); ?></td> + <td><?php echo esc_html((string)($entry['contact']??'')); ?></td> + <td><?php echo esc_html((string)($entry['order_nr']??'')); ?></td> + <td><?php echo esc_html((string)($entry['product_nr']??'')); ?></td> + <td><?php echo intval($entry['amount']??0); ?></td> + <td><?php echo esc_html(implode(', ', \wpsgRevocation\Revocation::noteTexts((array)($entry['notes']??[])))); ?></td> + <td><button type="submit" class="button" name="wpsg_mod_revocation_unassigned_delete" value="<?php echo esc_attr($entry['id']); ?>"><?php echo esc_html__('Löschen', 'wpsg'); ?></button></td> + </tr> + <?php } ?> + </tbody> + </table> + <button type="submit" class="button" name="wpsg_mod_revocation_unassigned_delete" value="all" onclick="return confirm(<?php echo esc_attr(wp_json_encode(__('Alle nicht zugeordneten Widerrufe löschen?', 'wpsg'))); ?>);"><?php echo esc_html__('Alle löschen', 'wpsg'); ?></button> + <?php } ?> + </div> + </div> </div> </div> diff --git a/views/mods/mod_revocation/wpsg_revocation.css b/views/mods/mod_revocation/wpsg_revocation.css index aae1758..5fe4b7d 100644 --- a/views/mods/mod_revocation/wpsg_revocation.css +++ b/views/mods/mod_revocation/wpsg_revocation.css @@ -53,6 +53,8 @@ #wpsg_revocation_form legend, #wpsg_revocation_page_form legend { padding:0 0.3684em; font-size:0.95em; font-weight:600; } #wpsg_revocation_form .form_field, #wpsg_revocation_page_form .form_field { display:flex; flex-direction:column; gap:0.3em; width:100%; } #wpsg_revocation_form .form_field .label, #wpsg_revocation_page_form .form_field .label { color:inherit; font-size:0.85em; opacity:0.7; } +/* Bot-Falle (S21): aus dem Bild, ohne display:none, damit Programme sie ausfüllen */ +.wpsg_revocation_hp { position:absolute; left:-10000px; top:auto; width:1px; height:1px; overflow:hidden; } /* Links in Schriftfarbe: Die Linkfarbe des Themes ist auf dem Dialog sonst zu blass (W5) */ #wpsg_revocation_dialog .inner a, .wpsg_revocation_page a { color:inherit; text-decoration:underline; } #wpsg_revocation_form .form_field .value, #wpsg_revocation_page_form .form_field .value { display:flex; gap:0.5em; justify-content:stretch; } |
