Replace "usb" icons with "user-key" for WebAuthn buttons; refine button styles and layouts across templates

This commit is contained in:
2026-07-14 00:31:22 +02:00
parent bf86654e72
commit 1dd2e5099f
8 changed files with 54 additions and 56 deletions

1
.idea/ClubManager.iml generated
View File

@@ -14,6 +14,7 @@
</component> </component>
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <excludeFolder url="file://$MODULE_DIR$/.venv" />
</content> </content>
<orderEntry type="jdk" jdkName="uv (ClubManager) (3)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="uv (ClubManager) (3)" jdkType="Python SDK" />

View File

@@ -1,5 +1,3 @@
{# Hardcoded, not `base_template`: the panel is platform-only, and a branding bug
must never be able to dress it up as a club. #}
{% extends "_platform_base.html" %} {% extends "_platform_base.html" %}
{% load lucide %} {% load lucide %}

View File

@@ -33,7 +33,7 @@
</div> </div>
<div class="mt-10 flex flex-wrap items-center justify-end gap-2"> <div class="mt-10 flex flex-wrap items-center justify-end gap-2">
<a class="btn btn-accent gap-2" href="{% url 'account_reset_password' %}">{% lucide "life-buoy" size=16 %} {% trans "Forgot Password?" %}</a> <a class="btn btn-accent btn-outline gap-2" href="{% url 'account_reset_password' %}">{% lucide "life-buoy" size=16 %} {% trans "Forgot Password?" %}</a>
<button class="btn btn-primary gap-2" type="submit">{% lucide "key-round" size=16 %} {% trans "Change Password" %}</button> <button class="btn btn-primary gap-2" type="submit">{% lucide "key-round" size=16 %} {% trans "Change Password" %}</button>
</div> </div>
</form> </form>

View File

@@ -26,25 +26,23 @@
false — silently dropping every field on every form that doesn't pass `exclude`. false — silently dropping every field on every form that doesn't pass `exclude`.
{% endcomment %} {% endcomment %}
{% with exclude=attrs.exclude|default:"" %} {% with exclude=attrs.exclude|default:"" %}
{% for field in attrs.form.visible_fields %} {% for field in attrs.form.visible_fields %}
{% if not field|excluded:exclude %} {% if not field|excluded:exclude %}
<div class="form-control my-3 w-full"> <div class="form-control my-3 w-full">
{% if field.field.widget.input_type == "checkbox" %} {% if field.field.widget.input_type == "checkbox" %}
<label class="label cursor-pointer justify-start gap-3" for="{{ field.id_for_label }}"> <label class="label cursor-pointer justify-start gap-3" for="{{ field.id_for_label }}">
{{ field|daisy }} {{ field|daisy }}
<span class="label-text">{{ field.label }}</span> <span class="label-text">{{ field.label }}</span>
</label> </label>
{% else %} {% else %}
{# An otp box never takes a visible label — the boxes say what they are, and a {% if not attrs.unlabeled and not field|is_otp %}
heading above them just crowds the field. It keeps an sr-only one below. #} <label class="label" for="{{ field.id_for_label }}">
{% if not attrs.unlabeled and not field|is_otp %} <span class="label-text">{{ field.label }}</span>
<label class="label" for="{{ field.id_for_label }}"> </label>
<span class="label-text">{{ field.label }}</span> {% endif %}
</label> {% with icon=field|field_icon %}
{% endif %} {% if field|is_otp %}
{% with icon=field|field_icon %} {% comment %}
{% if field|is_otp %}
{% comment %}
daisyUI's otp is one input overlaid on the boxes. Child order is load-bearing: daisyUI's otp is one input overlaid on the boxes. Child order is load-bearing:
it places each box with `nth-child`, which counts *every* child, not just the it places each box with `nth-child`, which counts *every* child, not just the
spans — so the input must come LAST. Put it first and all six boxes shift one spans — so the input must come LAST. Put it first and all six boxes shift one
@@ -55,38 +53,38 @@
For the same reason the sr-only label lives outside the container: another For the same reason the sr-only label lives outside the container: another
child would throw the count off again. child would throw the count off again.
{% endcomment %} {% endcomment %}
<label class="sr-only" for="{{ field.id_for_label }}">{{ field.label }}</label> <label class="sr-only" for="{{ field.id_for_label }}">{{ field.label }}</label>
<div class="flex justify-center"> <div class="flex justify-center">
<div class="otp otp-lg" data-otp> <div class="otp otp-lg" data-otp>
<span></span> <span></span>
<span></span> <span></span>
<span></span> <span></span>
<span></span> <span></span>
<span></span> <span></span>
<span></span> <span></span>
{{ field|as_otp }} {{ field|as_otp }}
</div> </div>
</div> </div>
{% elif icon %} {% elif icon %}
<label class="input flex w-full items-center gap-2 {% if field.errors %}input-error{% endif %}" for="{{ field.id_for_label }}"> <label class="input flex w-full items-center gap-2 {% if field.errors %}input-error{% endif %}" for="{{ field.id_for_label }}">
<span class="opacity-50">{% lucide icon size=16 %}</span> <span class="opacity-50">{% lucide icon size=16 %}</span>
{% if attrs.unlabeled %}<span class="sr-only">{{ field.label }}</span>{% endif %} {% if attrs.unlabeled %}<span class="sr-only">{{ field.label }}</span>{% endif %}
{{ field|daisy:"grow" }} {{ field|daisy:"grow" }}
</label> </label>
{% else %} {% else %}
{{ field|daisy }} {{ field|daisy }}
{% endif %}
{% endwith %}
{% endif %} {% endif %}
{% endwith %} {% comment %}
{% endif %}
{% comment %}
The password field's help_text is allauth's "Forgot your password?" link, so it The password field's help_text is allauth's "Forgot your password?" link, so it
gets room to breathe. The id is not decorative: Django points the input's gets room to breathe. The id is not decorative: Django points the input's
aria-describedby at `<auto_id>_helptext`, and without it that reference dangles aria-describedby at `<auto_id>_helptext`, and without it that reference dangles
and the link is never announced. and the link is never announced.
{% endcomment %} {% endcomment %}
{% if field.help_text %}<span id="{{ field.auto_id }}_helptext" class="label-text-alt mt-3 block text-base-content/70">{{ field.help_text }}</span>{% endif %} {% if field.help_text %}<span id="{{ field.auto_id }}_helptext" class="label-text-alt mt-3 block text-base-content/70">{{ field.help_text }}</span>{% endif %}
{% for error in field.errors %}<span class="label-text-alt mt-1 text-error">{{ error }}</span>{% endfor %} {% for error in field.errors %}<span class="label-text-alt mt-1 text-error">{{ error }}</span>{% endfor %}
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endwith %} {% endwith %}

View File

@@ -46,7 +46,7 @@
{% endelement %} {% endelement %}
<button class="btn btn-accent gap-2" type="button" form="webauthn_form" id="mfa_webauthn_authenticate"> <button class="btn btn-accent gap-2" type="button" form="webauthn_form" id="mfa_webauthn_authenticate">
{% lucide "usb" size=16 %} {% trans "Use a security key" %} {% lucide "user-key" size=16 %} {% trans "Use a security key" %}
</button> </button>
<form id="webauthn_form" method="post" action="{% url 'mfa_authenticate' %}"> <form id="webauthn_form" method="post" action="{% url 'mfa_authenticate' %}">

View File

@@ -41,7 +41,7 @@
{% translate "Deactivate" %} {% translate "Deactivate" %}
{% endelement %} {% endelement %}
{% else %} {% else %}
{% element button href=activate_url icon="smartphone" tags="panel" %} {% element button href=activate_url icon="qr-code" tags="panel" %}
{% translate "Activate" %} {% translate "Activate" %}
{% endelement %} {% endelement %}
{% endif %} {% endif %}
@@ -73,7 +73,7 @@
{% endelement %} {% endelement %}
{% else %} {% else %}
{% url 'mfa_add_webauthn' as webauthn_add_url %} {% url 'mfa_add_webauthn' as webauthn_add_url %}
{% element button href=webauthn_add_url icon="usb" %} {% element button href=webauthn_add_url icon="user-key" %}
{% translate "Add" %} {% translate "Add" %}
{% endelement %} {% endelement %}
{% endif %} {% endif %}
@@ -90,7 +90,8 @@
{% slot body %} {% slot body %}
{% if authenticators.recovery_codes %} {% if authenticators.recovery_codes %}
{% element p %} {% element p %}
{% blocktranslate count unused_count=unused_count %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.{% endblocktranslate %} {% blocktranslate count unused_count=unused_count %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.
{% endblocktranslate %}
{% endelement %} {% endelement %}
{% else %} {% else %}
{% element p %} {% element p %}

View File

@@ -19,7 +19,7 @@
{% endslot %} {% endslot %}
{% slot actions %} {% slot actions %}
{# type="button": the webauthn script takes over the click and posts the form itself. #} {# type="button": the webauthn script takes over the click and posts the form itself. #}
{% element button id="mfa_webauthn_add" type="button" icon="usb" %} {% element button id="mfa_webauthn_add" type="button" icon="user-key" %}
{% trans "Add" %} {% trans "Add" %}
{% endelement %} {% endelement %}
{% endslot %} {% endslot %}

View File

@@ -66,7 +66,7 @@
{% endelement %} {% endelement %}
{% endif %} {% endif %}
{% url 'mfa_add_webauthn' as add_url %} {% url 'mfa_add_webauthn' as add_url %}
{% element button href=add_url icon="usb" %} {% element button href=add_url icon="user-key" %}
{% translate "Add" %} {% translate "Add" %}
{% endelement %} {% endelement %}
{% endblock %} {% endblock %}