From a1bf7be2441eb484a303fa9f9c7576fac9a86d66 Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Fri, 29 Nov 2024 14:16:40 +0100 Subject: [PATCH] [A11y] Improve customer account pages (#4654) --- src/pretix/base/models/memberships.py | 14 + src/pretix/base/templatetags/icon.py | 34 +++ src/pretix/base/templatetags/textbubble.py | 42 +++ .../event/fragment_order_status.html | 22 +- .../pretixpresale/fragment_login_status.html | 4 +- .../organizers/customer_address_delete.html | 34 ++- .../organizers/customer_addresses.html | 42 +++ .../organizers/customer_base.html | 55 ++++ .../organizers/customer_login.html | 4 +- .../organizers/customer_membership.html | 167 +++++++----- .../organizers/customer_memberships.html | 111 ++++++++ .../organizers/customer_orders.html | 83 ++++++ .../organizers/customer_profile.html | 253 ------------------ .../organizers/customer_profile_delete.html | 34 ++- .../organizers/customer_profiles.html | 42 +++ src/pretix/presale/urls.py | 7 +- src/pretix/presale/views/customer.py | 105 ++++++-- .../pretixbase/scss/_bootstrap_vars.scss | 2 +- .../static/pretixpresale/scss/main.scss | 79 +++++- src/tests/presale/test_customer.py | 2 +- 20 files changed, 738 insertions(+), 398 deletions(-) create mode 100644 src/pretix/base/templatetags/icon.py create mode 100644 src/pretix/base/templatetags/textbubble.py create mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_addresses.html create mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_base.html create mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_memberships.html create mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_orders.html delete mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_profile.html create mode 100644 src/pretix/presale/templates/pretixpresale/organizers/customer_profiles.html diff --git a/src/pretix/base/models/memberships.py b/src/pretix/base/models/memberships.py index 540cba623..14640b2cf 100644 --- a/src/pretix/base/models/memberships.py +++ b/src/pretix/base/models/memberships.py @@ -159,10 +159,24 @@ class Membership(models.Model): de = date_format(self.date_end, 'SHORT_DATE_FORMAT') return f'{self.membership_type.name}: {self.attendee_name} ({ds} – {de})' + @property + def percentage_used(self): + if self.membership_type.max_usages and self.usages: + return int(self.usages / self.membership_type.max_usages * 100) + return 0 + @property def attendee_name(self): return build_name(self.attendee_name_parts, fallback_scheme=lambda: self.customer.organizer.settings.name_scheme) + @property + def expired(self): + return time_machine_now() > self.date_end + + @property + def not_yet_valid(self): + return time_machine_now() < self.date_start + def is_valid(self, ev=None, ticket_valid_from=None, valid_from_not_chosen=False): if valid_from_not_chosen: return not self.canceled and self.date_end >= time_machine_now() diff --git a/src/pretix/base/templatetags/icon.py b/src/pretix/base/templatetags/icon.py new file mode 100644 index 000000000..d71319b01 --- /dev/null +++ b/src/pretix/base/templatetags/icon.py @@ -0,0 +1,34 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from django import template +from django.utils.html import format_html + +register = template.Library() + + +@register.simple_tag +def icon(key, *args, **kwargs): + return format_html( + '', + key, + kwargs["class"] if "class" in kwargs else "", + ) diff --git a/src/pretix/base/templatetags/textbubble.py b/src/pretix/base/templatetags/textbubble.py new file mode 100644 index 000000000..a0c3a3d30 --- /dev/null +++ b/src/pretix/base/templatetags/textbubble.py @@ -0,0 +1,42 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from django import template +from django.utils.html import format_html, mark_safe + +register = template.Library() + + +@register.simple_tag +def textbubble(type, *args, **kwargs): + return format_html( + '{}', + type or "info", + "" if "icon" not in kwargs else format_html( + ' ', + kwargs["icon"] + ) + ) + + +@register.simple_tag +def endtextbubble(): + return mark_safe('') diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_order_status.html b/src/pretix/presale/templates/pretixpresale/event/fragment_order_status.html index 7f213c2ed..d11f4ac5c 100644 --- a/src/pretix/presale/templates/pretixpresale/event/fragment_order_status.html +++ b/src/pretix/presale/templates/pretixpresale/event/fragment_order_status.html @@ -1,31 +1,29 @@ {% load i18n %} {% load bootstrap3 %} +{% load textbubble %} {# Changes should be replicated in pretixcontrol/orders/fragment_order_status.html and in pretix/base/models/orders.py #} {% if order.status == "n" %} {% if order.require_approval %} - {% trans "Approval pending" %} + {% textbubble "warning" icon="exclamation-triangle" %}{% trans "Approval pending" %}{% endtextbubble %} {% elif order.total == 0 %} - {% trans "Confirmation pending" context "order state" %} + {% textbubble "warning" icon="exclamation-triangle" %}{% trans "Confirmation pending" context "order state" %}{% endtextbubble %} {% elif event.settings.payment_pending_hidden %} {# intentionally left blank #} {% elif order.valid_if_pending %} - {% trans "Confirmed" context "order state" %} + {% textbubble "info" icon="info-circle" %}{% trans "Confirmed" context "order state" %}{% endtextbubble %} {% else %} - {% trans "Payment pending" %} - {% endif %} - {% if not event.settings.payment_pending_hidden %} - + {% textbubble "warning" icon="exclamation-triangle" %}{% trans "Payment pending" %}{% endtextbubble %} {% endif %} {% elif order.status == "p" %} {% if order.count_positions == 0 %} - {% trans "Canceled (paid fee)" %} + {% textbubble "info" icon="info-circle" %}{% trans "Canceled (paid fee)" %}{% endtextbubble %} {% elif order.total == 0 %} - {% trans "Confirmed" context "order state" %} + {% textbubble "success" icon="check" %}{% trans "Confirmed" context "order state" %}{% endtextbubble %} {% else %} - {% trans "Paid" %} + {% textbubble "success" icon="check" %}{% trans "Paid" %}{% endtextbubble %} {% endif %} {% elif order.status == "e" %} - {% trans "Expired" %} + {% textbubble "danger" icon="minus" %}{% trans "Expired" %}{% endtextbubble %} {% elif order.status == "c" %} - {% trans "Canceled" %} + {% textbubble "danger" icon="times" %}{% trans "Canceled" %}{% endtextbubble %} {% endif %} diff --git a/src/pretix/presale/templates/pretixpresale/fragment_login_status.html b/src/pretix/presale/templates/pretixpresale/fragment_login_status.html index c722072f8..a0e90b80a 100644 --- a/src/pretix/presale/templates/pretixpresale/fragment_login_status.html +++ b/src/pretix/presale/templates/pretixpresale/fragment_login_status.html @@ -4,9 +4,9 @@ {% if request.organizer.settings.customer_accounts %}